a0ad653d7d
* gui resizelayout #51 * checkbox icons * updates * weather reset * embedded logo asset
688 lines
20 KiB
C++
688 lines
20 KiB
C++
#pragma once
|
|
#include "CommonInclude.h"
|
|
#include "wiGraphicsDevice.h"
|
|
#include "wiPrimitive.h"
|
|
#include "wiCanvas.h"
|
|
#include "wiVector.h"
|
|
#include "wiColor.h"
|
|
#include "wiScene.h"
|
|
#include "wiSprite.h"
|
|
#include "wiSpriteFont.h"
|
|
|
|
#include <string>
|
|
#include <functional>
|
|
|
|
namespace wi::gui
|
|
{
|
|
|
|
struct EventArgs
|
|
{
|
|
XMFLOAT2 clickPos;
|
|
XMFLOAT2 startPos;
|
|
XMFLOAT2 deltaPos;
|
|
XMFLOAT2 endPos;
|
|
float fValue;
|
|
bool bValue;
|
|
int iValue;
|
|
wi::Color color;
|
|
std::string sValue;
|
|
uint64_t userdata;
|
|
};
|
|
|
|
enum WIDGETSTATE
|
|
{
|
|
IDLE, // widget is doing nothing
|
|
FOCUS, // widget got pointer dragged on or selected
|
|
ACTIVE, // widget is interacted with right now
|
|
DEACTIVATING, // widget has last been active but no more interactions are occuring
|
|
WIDGETSTATE_COUNT,
|
|
};
|
|
|
|
// These can be used to target a setting for a specific widget control and state:
|
|
enum WIDGET_ID
|
|
{
|
|
// IDs for normal widget states:
|
|
WIDGET_ID_IDLE = IDLE,
|
|
WIDGET_ID_FOCUS = FOCUS,
|
|
WIDGET_ID_ACTIVE = ACTIVE,
|
|
WIDGET_ID_DEACTIVATING = DEACTIVATING,
|
|
|
|
// IDs for special widget states:
|
|
|
|
// Slider:
|
|
WIDGET_ID_SLIDER_BEGIN, // do not use!
|
|
WIDGET_ID_SLIDER_BASE_IDLE,
|
|
WIDGET_ID_SLIDER_BASE_FOCUS,
|
|
WIDGET_ID_SLIDER_BASE_ACTIVE,
|
|
WIDGET_ID_SLIDER_BASE_DEACTIVATING,
|
|
WIDGET_ID_SLIDER_KNOB_IDLE,
|
|
WIDGET_ID_SLIDER_KNOB_FOCUS,
|
|
WIDGET_ID_SLIDER_KNOB_ACTIVE,
|
|
WIDGET_ID_SLIDER_KNOB_DEACTIVATING,
|
|
WIDGET_ID_SLIDER_END, // do not use!
|
|
|
|
// Scrollbar:
|
|
WIDGET_ID_SCROLLBAR_BEGIN, // do not use!
|
|
WIDGET_ID_SCROLLBAR_BASE_IDLE,
|
|
WIDGET_ID_SCROLLBAR_BASE_FOCUS,
|
|
WIDGET_ID_SCROLLBAR_BASE_ACTIVE,
|
|
WIDGET_ID_SCROLLBAR_BASE_DEACTIVATING,
|
|
WIDGET_ID_SCROLLBAR_KNOB_INACTIVE,
|
|
WIDGET_ID_SCROLLBAR_KNOB_HOVER,
|
|
WIDGET_ID_SCROLLBAR_KNOB_GRABBED,
|
|
WIDGET_ID_SCROLLBAR_END, // do not use!
|
|
|
|
// Combo box:
|
|
WIDGET_ID_COMBO_DROPDOWN,
|
|
|
|
// Window:
|
|
WIDGET_ID_WINDOW_BASE,
|
|
|
|
// other user-defined widget states can be specified after this:
|
|
// And you will of course need to handle it yourself in a SetColor() override for example
|
|
WIDGET_ID_USER,
|
|
};
|
|
|
|
struct Theme
|
|
{
|
|
// Reduced version of wi::image::Params, excluding position, alignment, etc.
|
|
struct Image
|
|
{
|
|
XMFLOAT4 color = wi::image::Params().color;
|
|
wi::enums::BLENDMODE blendFlag = wi::image::Params().blendFlag;
|
|
wi::image::SAMPLEMODE sampleFlag = wi::image::Params().sampleFlag;
|
|
wi::image::QUALITY quality = wi::image::Params().quality;
|
|
bool background = wi::image::Params().isBackgroundEnabled();
|
|
|
|
void Apply(wi::image::Params& params) const
|
|
{
|
|
params.color = color;
|
|
params.blendFlag = blendFlag;
|
|
params.sampleFlag = sampleFlag;
|
|
params.quality = quality;
|
|
if (background)
|
|
{
|
|
params.enableBackground();
|
|
}
|
|
else
|
|
{
|
|
params.disableBackground();
|
|
}
|
|
}
|
|
void CopyFrom(const wi::image::Params& params)
|
|
{
|
|
color = params.color;
|
|
blendFlag = params.blendFlag;
|
|
sampleFlag = params.sampleFlag;
|
|
quality = params.quality;
|
|
if (params.isBackgroundEnabled())
|
|
{
|
|
background = true;
|
|
}
|
|
else
|
|
{
|
|
background = false;
|
|
}
|
|
}
|
|
} image;
|
|
|
|
// Reduced version of wi::font::Params, excluding position, alignment, etc.
|
|
struct Font
|
|
{
|
|
wi::Color color = wi::font::Params().color;
|
|
wi::Color shadow_color = wi::font::Params().shadowColor;
|
|
int style = wi::font::Params().style;
|
|
float softness = wi::font::Params().softness;
|
|
float bolden = wi::font::Params().bolden;
|
|
float shadow_softness = wi::font::Params().shadow_softness;
|
|
float shadow_bolden = wi::font::Params().shadow_bolden;
|
|
float shadow_offset_x = wi::font::Params().shadow_offset_x;
|
|
float shadow_offset_y = wi::font::Params().shadow_offset_y;
|
|
|
|
void Apply(wi::font::Params& params) const
|
|
{
|
|
params.color = color;
|
|
params.shadowColor = shadow_color;
|
|
params.style = style;
|
|
params.softness = softness;
|
|
params.bolden = bolden;
|
|
params.shadow_softness = shadow_softness;
|
|
params.shadow_bolden = shadow_bolden;
|
|
params.shadow_offset_x = shadow_offset_x;
|
|
params.shadow_offset_y = shadow_offset_y;
|
|
}
|
|
void CopyFrom(const wi::font::Params& params)
|
|
{
|
|
color = params.color;
|
|
shadow_color = params.shadowColor;
|
|
style = params.style;
|
|
softness = params.softness;
|
|
bolden = params.bolden;
|
|
shadow_softness = params.shadow_softness;
|
|
shadow_bolden = params.shadow_bolden;
|
|
shadow_offset_x = params.shadow_offset_x;
|
|
shadow_offset_y = params.shadow_offset_y;
|
|
}
|
|
} font;
|
|
|
|
wi::Color shadow_color = wi::Color::Shadow(); // shadow color for whole widget
|
|
|
|
Image tooltipImage;
|
|
Font tooltipFont;
|
|
wi::Color tooltip_shadow_color = wi::Color::Shadow();
|
|
};
|
|
|
|
class Widget;
|
|
|
|
class GUI
|
|
{
|
|
private:
|
|
wi::vector<Widget*> widgets;
|
|
bool focus = false;
|
|
bool visible = true;
|
|
public:
|
|
|
|
void Update(const wi::Canvas& canvas, float dt);
|
|
void Render(const wi::Canvas& canvas, wi::graphics::CommandList cmd) const;
|
|
|
|
void AddWidget(Widget* widget);
|
|
void RemoveWidget(Widget* widget);
|
|
Widget* GetWidget(const std::string& name);
|
|
|
|
// returns true if any gui element has the focus
|
|
bool HasFocus();
|
|
|
|
void SetVisible(bool value) { visible = value; }
|
|
bool IsVisible() { return visible; }
|
|
|
|
void SetColor(wi::Color color, int id = -1);
|
|
void SetShadowColor(wi::Color color);
|
|
void SetTheme(const Theme& theme, int id = -1);
|
|
};
|
|
|
|
class Widget : public wi::scene::TransformComponent
|
|
{
|
|
private:
|
|
int tooltipTimer = 0;
|
|
protected:
|
|
std::string name;
|
|
bool enabled = true;
|
|
bool visible = true;
|
|
float shadow = 1; // shadow radius
|
|
wi::Color shadow_color = wi::Color::Shadow();
|
|
WIDGETSTATE state = IDLE;
|
|
float tooltip_shadow = 1; // shadow radius
|
|
wi::Color tooltip_shadow_color = wi::Color::Shadow();
|
|
mutable wi::Sprite tooltipSprite;
|
|
mutable wi::SpriteFont tooltipFont;
|
|
mutable wi::SpriteFont scripttipFont;
|
|
|
|
public:
|
|
Widget();
|
|
virtual ~Widget() = default;
|
|
|
|
const std::string& GetName() const;
|
|
void SetName(const std::string& value);
|
|
const std::string GetText() const;
|
|
void SetText(const std::string& value);
|
|
void SetText(std::string&& value);
|
|
void SetTooltip(const std::string& value);
|
|
void SetTooltip(std::string&& value);
|
|
void SetScriptTip(const std::string& value);
|
|
void SetScriptTip(std::string&& value);
|
|
void SetPos(const XMFLOAT2& value);
|
|
void SetSize(const XMFLOAT2& value);
|
|
XMFLOAT2 GetPos() const;
|
|
virtual XMFLOAT2 GetSize() const;
|
|
WIDGETSTATE GetState() const;
|
|
virtual void SetEnabled(bool val);
|
|
bool IsEnabled() const;
|
|
virtual void SetVisible(bool val);
|
|
bool IsVisible() const;
|
|
wi::Color GetColor() const;
|
|
float GetShadowRadius() const { return shadow; }
|
|
void SetShadowRadius(float value) { shadow = value; }
|
|
|
|
virtual void ResizeLayout() {};
|
|
virtual void Update(const wi::Canvas& canvas, float dt);
|
|
virtual void Render(const wi::Canvas& canvas, wi::graphics::CommandList cmd) const {}
|
|
virtual void RenderTooltip(const wi::Canvas& canvas, wi::graphics::CommandList cmd) const;
|
|
|
|
// last param default: set color for all states
|
|
// you can specify a WIDGET_ID here, or your own custom ID if you use your own widget type
|
|
virtual void SetColor(wi::Color color, int id = -1);
|
|
virtual void SetShadowColor(wi::Color color);
|
|
virtual void SetImage(wi::Resource textureResource, int id = -1);
|
|
virtual void SetTheme(const Theme& theme, int id = -1);
|
|
|
|
wi::Sprite sprites[WIDGETSTATE_COUNT];
|
|
wi::SpriteFont font;
|
|
|
|
XMFLOAT3 translation = XMFLOAT3(0, 0, 0);
|
|
XMFLOAT3 scale = XMFLOAT3(1, 1, 1);
|
|
|
|
wi::primitive::Hitbox2D hitBox;
|
|
wi::graphics::Rect scissorRect;
|
|
|
|
Widget* parent = nullptr;
|
|
void AttachTo(Widget* parent);
|
|
void Detach();
|
|
|
|
void Activate();
|
|
void Deactivate();
|
|
|
|
void ApplyScissor(const wi::Canvas& canvas, const wi::graphics::Rect rect, wi::graphics::CommandList cmd, bool constrain_to_parent = true) const;
|
|
wi::primitive::Hitbox2D GetPointerHitbox(bool constrained = true) const;
|
|
|
|
wi::primitive::Hitbox2D active_area; // Pointer hitbox constrain area
|
|
void HitboxConstrain(wi::primitive::Hitbox2D& hb) const;
|
|
|
|
bool priority_change = true;
|
|
uint32_t priority = 0;
|
|
bool force_disable = false;
|
|
};
|
|
|
|
// Clickable, draggable box
|
|
class Button : public Widget
|
|
{
|
|
protected:
|
|
std::function<void(EventArgs args)> onClick;
|
|
std::function<void(EventArgs args)> onDragStart;
|
|
std::function<void(EventArgs args)> onDrag;
|
|
std::function<void(EventArgs args)> onDragEnd;
|
|
XMFLOAT2 dragStart = XMFLOAT2(0, 0);
|
|
XMFLOAT2 prevPos = XMFLOAT2(0, 0);
|
|
public:
|
|
void Create(const std::string& name);
|
|
|
|
wi::SpriteFont font_description;
|
|
void SetDescription(const std::string& desc) { font_description.SetText(desc); }
|
|
|
|
void Update(const wi::Canvas& canvas, float dt) override;
|
|
void Render(const wi::Canvas& canvas, wi::graphics::CommandList cmd) const override;
|
|
void SetTheme(const Theme& theme, int id = -1) override;
|
|
|
|
void OnClick(std::function<void(EventArgs args)> func);
|
|
void OnDragStart(std::function<void(EventArgs args)> func);
|
|
void OnDrag(std::function<void(EventArgs args)> func);
|
|
void OnDragEnd(std::function<void(EventArgs args)> func);
|
|
};
|
|
|
|
// Generic scroll bar
|
|
class ScrollBar : public Widget
|
|
{
|
|
protected:
|
|
float scrollbar_delta = 0;
|
|
float scrollbar_length = 0;
|
|
float scrollbar_value = 0;
|
|
float scrollbar_granularity = 1;
|
|
float list_length = 0;
|
|
float list_offset = 0;
|
|
float overscroll = 0;
|
|
bool vertical = true;
|
|
XMFLOAT2 grab_pos = {};
|
|
float grab_delta = 0;
|
|
|
|
public:
|
|
// Set the list's length that will be scrollable and moving
|
|
void SetListLength(float size) { list_length = size; }
|
|
// The scrolling offset that should be applied to the list items
|
|
float GetOffset() const { return list_offset; }
|
|
// This can be called by user for extra scrolling on top of base functionality
|
|
void Scroll(float amount) { scrollbar_delta -= amount; }
|
|
// How much the max scrolling will offset the list even further than it would be necessary for fitting
|
|
// this value is in percent of a full scrollbar's worth of extra offset
|
|
// 0: no extra offset
|
|
// 1: full extra offset
|
|
void SetOverScroll(float amount) { overscroll = amount; }
|
|
// Check whether the scrollbar is required (when the items don't fit and scrolling could be used)
|
|
bool IsScrollbarRequired() const { return scrollbar_granularity < 0.999f; }
|
|
|
|
enum SCROLLBAR_STATE
|
|
{
|
|
SCROLLBAR_INACTIVE,
|
|
SCROLLBAR_HOVER,
|
|
SCROLLBAR_GRABBED,
|
|
SCROLLBAR_STATE_COUNT,
|
|
} scrollbar_state = SCROLLBAR_INACTIVE;
|
|
wi::Sprite sprites_knob[SCROLLBAR_STATE_COUNT];
|
|
XMFLOAT2 knob_inset_border = {};
|
|
|
|
void Update(const wi::Canvas& canvas, float dt) override;
|
|
void Render(const wi::Canvas& canvas, wi::graphics::CommandList cmd) const override;
|
|
void SetColor(wi::Color color, int id = -1) override;
|
|
void SetTheme(const Theme& theme, int id = -1) override;
|
|
|
|
void SetVertical(bool value) { vertical = value; }
|
|
bool IsVertical() const { return vertical; }
|
|
};
|
|
|
|
// Static box that holds text
|
|
class Label : public Widget
|
|
{
|
|
protected:
|
|
public:
|
|
void Create(const std::string& name);
|
|
|
|
void Update(const wi::Canvas& canvas, float dt) override;
|
|
void Render(const wi::Canvas& canvas, wi::graphics::CommandList cmd) const override;
|
|
void SetColor(wi::Color color, int id = -1) override;
|
|
void SetTheme(const Theme& theme, int id = -1) override;
|
|
|
|
float scrollbar_width = 18;
|
|
ScrollBar scrollbar;
|
|
};
|
|
|
|
// Text input box
|
|
class TextInputField : public Widget
|
|
{
|
|
protected:
|
|
std::function<void(EventArgs args)> onInputAccepted;
|
|
static wi::SpriteFont font_input;
|
|
|
|
public:
|
|
void Create(const std::string& name);
|
|
|
|
wi::SpriteFont font_description;
|
|
|
|
void SetValue(const std::string& newValue);
|
|
void SetValue(int newValue);
|
|
void SetValue(float newValue);
|
|
const std::string GetValue();
|
|
void SetDescription(const std::string& desc) { font_description.SetText(desc); }
|
|
const std::string GetDescription() const { return font_description.GetTextA(); }
|
|
|
|
// There can only be ONE active text input field, so these methods modify the active one
|
|
static void AddInput(const char inputChar);
|
|
static void DeleteFromInput();
|
|
|
|
void Update(const wi::Canvas& canvas, float dt) override;
|
|
void Render(const wi::Canvas& canvas, wi::graphics::CommandList cmd) const override;
|
|
void SetTheme(const Theme& theme, int id = -1) override;
|
|
|
|
void OnInputAccepted(std::function<void(EventArgs args)> func);
|
|
};
|
|
|
|
// Define an interval and slide the control along it
|
|
class Slider : public Widget
|
|
{
|
|
protected:
|
|
std::function<void(EventArgs args)> onSlide;
|
|
float start = 0, end = 1;
|
|
float step = 1000;
|
|
float value = 0;
|
|
public:
|
|
// start : slider minimum value
|
|
// end : slider maximum value
|
|
// defaultValue : slider default Value
|
|
// step : slider step size
|
|
void Create(float start, float end, float defaultValue, float step, const std::string& name);
|
|
|
|
wi::Sprite sprites_knob[WIDGETSTATE_COUNT];
|
|
|
|
void SetValue(float value);
|
|
float GetValue() const;
|
|
void SetRange(float start, float end);
|
|
|
|
void Update(const wi::Canvas& canvas, float dt) override;
|
|
void Render(const wi::Canvas& canvas, wi::graphics::CommandList cmd) const override;
|
|
void RenderTooltip(const wi::Canvas& canvas, wi::graphics::CommandList cmd) const override;
|
|
void SetColor(wi::Color color, int id = -1) override;
|
|
void SetTheme(const Theme& theme, int id = -1) override;
|
|
|
|
void OnSlide(std::function<void(EventArgs args)> func);
|
|
|
|
TextInputField valueInputField;
|
|
};
|
|
|
|
// Two-state clickable box
|
|
class CheckBox :public Widget
|
|
{
|
|
protected:
|
|
std::function<void(EventArgs args)> onClick;
|
|
bool checked = false;
|
|
public:
|
|
void Create(const std::string& name);
|
|
|
|
void SetCheck(bool value);
|
|
bool GetCheck() const;
|
|
|
|
void Update(const wi::Canvas& canvas, float dt) override;
|
|
void Render(const wi::Canvas& canvas, wi::graphics::CommandList cmd) const override;
|
|
|
|
void OnClick(std::function<void(EventArgs args)> func);
|
|
|
|
static void SetCheckText(const std::string& text);
|
|
};
|
|
|
|
// Drop-down list
|
|
class ComboBox :public Widget
|
|
{
|
|
protected:
|
|
std::function<void(EventArgs args)> onSelect;
|
|
int selected = -1;
|
|
int maxVisibleItemCount = 8;
|
|
int firstItemVisible = 0;
|
|
|
|
// While the widget is active (rolled down) these are the inner states that control behaviour
|
|
enum COMBOSTATE
|
|
{
|
|
COMBOSTATE_INACTIVE, // When the list is just being dropped down, or the widget is not active
|
|
COMBOSTATE_HOVER, // The widget is in drop-down state with the last item hovered highlited
|
|
COMBOSTATE_SELECTING, // The hovered item is clicked
|
|
COMBOSTATE_SCROLLBAR_HOVER, // scrollbar is to be selected
|
|
COMBOSTATE_SCROLLBAR_GRABBED, // scrollbar is moved
|
|
COMBOSTATE_COUNT,
|
|
} combostate = COMBOSTATE_INACTIVE;
|
|
int hovered = -1;
|
|
|
|
float scrollbar_delta = 0;
|
|
|
|
struct Item
|
|
{
|
|
std::string name;
|
|
uint64_t userdata = 0;
|
|
};
|
|
wi::vector<Item> items;
|
|
|
|
wi::Color drop_color = wi::Color::Ghost();
|
|
|
|
float GetDropOffset(const wi::Canvas& canvas) const;
|
|
float GetItemOffset(const wi::Canvas& canvas, int index) const;
|
|
public:
|
|
void Create(const std::string& name);
|
|
|
|
void AddItem(const std::string& name, uint64_t userdata = 0);
|
|
void RemoveItem(int index);
|
|
void ClearItems();
|
|
void SetMaxVisibleItemCount(int value);
|
|
bool HasScrollbar() const;
|
|
|
|
void SetSelected(int index);
|
|
void SetSelectedWithoutCallback(int index); // SetSelected() but the OnSelect callback will not be executed
|
|
void SetSelectedByUserdata(uint64_t userdata);
|
|
void SetSelectedByUserdataWithoutCallback(uint64_t userdata); // SetSelectedByUserdata() but the OnSelect callback will not be executed
|
|
int GetSelected() const;
|
|
void SetItemText(int index, const std::string& text);
|
|
void SetItemUserdata(int index, uint64_t userdata);
|
|
std::string GetItemText(int index) const;
|
|
uint64_t GetItemUserData(int index) const;
|
|
size_t GetItemCount() const { return items.size(); }
|
|
|
|
void Update(const wi::Canvas& canvas, float dt) override;
|
|
void Render(const wi::Canvas& canvas, wi::graphics::CommandList cmd) const override;
|
|
void SetColor(wi::Color color, int id = -1) override;
|
|
void SetTheme(const Theme& theme, int id = -1) override;
|
|
|
|
void OnSelect(std::function<void(EventArgs args)> func);
|
|
|
|
wi::SpriteFont selected_font;
|
|
};
|
|
|
|
// Widget container
|
|
class Window :public Widget
|
|
{
|
|
protected:
|
|
wi::vector<Widget*> widgets;
|
|
bool minimized = false;
|
|
Widget scrollable_area;
|
|
float control_size = 20;
|
|
std::function<void(EventArgs args)> onClose;
|
|
std::function<void(EventArgs args)> onCollapse;
|
|
|
|
public:
|
|
enum class WindowControls
|
|
{
|
|
NONE = 0,
|
|
RESIZE_TOPLEFT = 1 << 0,
|
|
RESIZE_TOPRIGHT = 1 << 1,
|
|
RESIZE_BOTTOMLEFT = 1 << 2,
|
|
RESIZE_BOTTOMRIGHT = 1 << 3,
|
|
MOVE = 1 << 4,
|
|
CLOSE = 1 << 5,
|
|
COLLAPSE = 1 << 6,
|
|
|
|
RESIZE = RESIZE_TOPLEFT | RESIZE_TOPRIGHT | RESIZE_BOTTOMLEFT | RESIZE_BOTTOMRIGHT,
|
|
CLOSE_AND_COLLAPSE = CLOSE | COLLAPSE,
|
|
ALL = RESIZE | MOVE | CLOSE | COLLAPSE,
|
|
};
|
|
void Create(const std::string& name, WindowControls window_controls = WindowControls::ALL);
|
|
|
|
enum class AttachmentOptions
|
|
{
|
|
NONE = 0,
|
|
SCROLLABLE = 1 << 0,
|
|
};
|
|
void AddWidget(Widget* widget, AttachmentOptions options = AttachmentOptions::SCROLLABLE);
|
|
void RemoveWidget(Widget* widget);
|
|
void RemoveWidgets();
|
|
|
|
void ResizeLayout() override;
|
|
void Update(const wi::Canvas& canvas, float dt) override;
|
|
void Render(const wi::Canvas& canvas, wi::graphics::CommandList cmd) const override;
|
|
void RenderTooltip(const wi::Canvas& canvas, wi::graphics::CommandList cmd) const override;
|
|
void SetColor(wi::Color color, int id = -1) override;
|
|
void SetShadowColor(wi::Color color) override;
|
|
void SetTheme(const Theme& theme, int id = -1) override;
|
|
|
|
void SetVisible(bool value) override;
|
|
void SetEnabled(bool value) override;
|
|
void SetCollapsed(bool value);
|
|
bool IsCollapsed() const;
|
|
void SetMinimized(bool value); // Same as SetCollapsed()
|
|
bool IsMinimized() const; // Same as IsCollapsed()
|
|
void SetControlSize(float value);
|
|
float GetControlSize() const;
|
|
XMFLOAT2 GetSize() const override; // For the window, the returned size can be modified by collapsed state
|
|
XMFLOAT2 GetWidgetAreaSize() const;
|
|
|
|
void OnClose(std::function<void(EventArgs args)> func);
|
|
void OnCollapse(std::function<void(EventArgs args)> func);
|
|
|
|
Button closeButton;
|
|
Button collapseButton;
|
|
Button resizeDragger_UpperLeft;
|
|
Button resizeDragger_UpperRight;
|
|
Button resizeDragger_BottomLeft;
|
|
Button resizeDragger_BottomRight;
|
|
Button moveDragger;
|
|
Label label;
|
|
ScrollBar scrollbar_vertical;
|
|
ScrollBar scrollbar_horizontal;
|
|
};
|
|
|
|
// HSV-Color Picker
|
|
class ColorPicker : public Window
|
|
{
|
|
protected:
|
|
std::function<void(EventArgs args)> onColorChanged;
|
|
enum COLORPICKERSTATE
|
|
{
|
|
CPS_IDLE,
|
|
CPS_HUE,
|
|
CPS_SATURATION,
|
|
} colorpickerstate = CPS_IDLE;
|
|
float hue = 0.0f; // [0, 360] degrees
|
|
float saturation = 0.0f; // [0, 1]
|
|
float luminance = 1.0f; // [0, 1]
|
|
|
|
void FireEvents();
|
|
public:
|
|
void Create(const std::string& name, WindowControls window_controls = WindowControls::ALL);
|
|
|
|
void Update(const wi::Canvas& canvas, float dt) override;
|
|
void Render(const wi::Canvas& canvas, wi::graphics::CommandList cmd) const override;
|
|
|
|
wi::Color GetPickColor() const;
|
|
void SetPickColor(wi::Color value);
|
|
|
|
void OnColorChanged(std::function<void(EventArgs args)> func);
|
|
|
|
TextInputField text_R;
|
|
TextInputField text_G;
|
|
TextInputField text_B;
|
|
TextInputField text_H;
|
|
TextInputField text_S;
|
|
TextInputField text_V;
|
|
Slider alphaSlider;
|
|
};
|
|
|
|
// List of items in a tree (parent-child relationships)
|
|
class TreeList : public Widget
|
|
{
|
|
public:
|
|
struct Item
|
|
{
|
|
std::string name;
|
|
int level = 0;
|
|
uint64_t userdata = 0;
|
|
bool open = false;
|
|
bool selected = false;
|
|
};
|
|
protected:
|
|
std::function<void(EventArgs args)> onSelect;
|
|
int item_highlight = -1;
|
|
int opener_highlight = -1;
|
|
|
|
wi::primitive::Hitbox2D GetHitbox_ListArea() const;
|
|
wi::primitive::Hitbox2D GetHitbox_Item(int visible_count, int level) const;
|
|
wi::primitive::Hitbox2D GetHitbox_ItemOpener(int visible_count, int level) const;
|
|
|
|
wi::vector<Item> items;
|
|
|
|
float GetItemOffset(int index) const;
|
|
public:
|
|
void Create(const std::string& name);
|
|
|
|
void AddItem(const Item& item);
|
|
void ClearItems();
|
|
bool HasScrollbar() const;
|
|
|
|
void ClearSelection();
|
|
void Select(int index);
|
|
|
|
int GetItemCount() const { return (int)items.size(); }
|
|
const Item& GetItem(int index) const;
|
|
|
|
void Update(const wi::Canvas& canvas, float dt) override;
|
|
void Render(const wi::Canvas& canvas, wi::graphics::CommandList cmd) const override;
|
|
void SetColor(wi::Color color, int id = -1) override;
|
|
void SetTheme(const Theme& theme, int id = -1) override;
|
|
|
|
void OnSelect(std::function<void(EventArgs args)> func);
|
|
|
|
ScrollBar scrollbar;
|
|
};
|
|
|
|
}
|
|
|
|
template<>
|
|
struct enable_bitmask_operators<wi::gui::Window::WindowControls> {
|
|
static const bool enable = true;
|
|
};
|
|
|
|
template<>
|
|
struct enable_bitmask_operators<wi::gui::Window::AttachmentOptions> {
|
|
static const bool enable = true;
|
|
};
|