Lumenarium/src_v2/editor/lumenarium_editor_ui.h

231 lines
4.6 KiB
C

/* date = March 28th 2022 10:52 pm */
#ifndef LUMENARIUM_UI_H
#define LUMENARIUM_UI_H
/////////////////////////////////////////////////////////////
// Interface
struct UI_Vertex
{
v4 pos;
v2 uv;
v4 color;
};
#define UI_WIDGET_ID_VALID_BIT 1 << 31
union UI_Widget_Id
{
// equality of widget id's only relies on the value field
// which is a hash of the widget's string
u32 value;
// this struct tracks the index of the widget only to be able
// to override next hot in cases where an earlier element became
// next hot that is in the same location as the current one
u32 index;
};
typedef u32 UI_Widget_Style_Flags;
enum
{
UIWidgetStyle_None = 0,
UIWidgetStyle_Bg = 1 << 0,
UIWidgetStyle_TextClip = 1 << 1,
UIWidgetStyle_TextWrap = 1 << 2,
UIWidgetStyle_Outline = 1 << 3,
UIWidgetStyle_MouseClick = 1 << 4,
UIWidgetStyle_MouseDragH = 1 << 5,
UIWidgetStyle_MouseDragV = 1 << 6,
UIWidgetStyle_FillH = 1 << 7,
UIWidgetStyle_FillV = 1 << 8,
UIWidgetStyle_LineInsteadOfFill = 1 << 9,
};
// akin to a css class, could be used to style multiple
// elements
struct UI_Widget_Style
{
UI_Widget_Style_Flags flags;
v4 color_bg;
v4 color_fg;
u32 sprite;
};
// combination of style info and per-instance data
struct UI_Widget_Desc
{
UI_Widget_Style style;
v2 fill_pct;
String string;
v2 p_min;
v2 p_max;
};
struct UI_Widget
{
UI_Widget_Id id;
UI_Widget_Desc desc;
UI_Widget* parent;
UI_Widget* next;
UI_Widget* child_first;
UI_Widget* child_last;
};
typedef u32 UI_Widget_Result_Flags;
enum
{
UIWidgetResult_None = 0,
UIWidgetResult_MouseLeft_IsDown = 1,
UIWidgetResult_MouseLeft_WentUp = 2,
};
struct UI_Widget_Result
{
UI_Widget_Id id;
UI_Widget_Result_Flags flags;
v2 drag;
};
enum UI_Widget_Kind
{
UIWidget_Text,
// Buttons
UIWidget_Button,
UIWidget_Toggle,
UIWidget_Menu,
UIWidget_Dropdown,
// Sliders
UIWidget_HSlider,
UIWidget_VSlider,
UIWidget_HScroll,
UIWidget_VScroll,
// Panels
UIWidget_Window,
UIWidget_Count,
};
struct UI_Style_Sheet
{
UI_Widget_Style styles[UIWidget_Count];
};
struct UI_Widget_State
{
v2 scroll;
};
struct UI_Widget_Pool
{
UI_Widget* free;
u32 free_cap;
u32 free_len;
UI_Widget* root;
UI_Widget* active_parent;
UI_Widget_State* states;
u32* states_hash;
u32 states_cap;
};
enum UI_Layout_Mode
{
// each element takes up a whole row
UILayout_Columns,
// each element takes up one column in the row. If you overflow,
// the layout manager overflows to the next row
UILayout_Rows,
};
struct UI_Layout
{
UI_Layout_Mode mode;
UI_Layout* parent;
v2 bounds_min;
v2 bounds_max;
r32 row_height;
r32 row_gap;
r32 col_gap;
v2 at;
u32 cols;
};
struct UI_Layout_Bounds
{
v2 min;
v2 max;
};
struct UI
{
UI_Vertex* verts;
u32 verts_len;
u32 verts_cap;
u32* indices;
u32 indices_len;
u32 indices_cap;
Texture_Atlas atlas;
r32 font_ascent, font_descent, font_line_gap, font_space_width;
UI_Widget_Pool widgets;
UI_Style_Sheet* style_sheet;
UI_Widget_Id widget_next_hot;
UI_Widget_Id widget_hot;
UI_Layout* layout;
// frames since these values were set
u16 widget_next_hot_frames;
u16 widget_hot_frames;
Input_State* input;
m44 proj;
Platform_Shader shader;
Platform_Texture atlas_texture;
Platform_Geometry_Buffer per_frame_buffer;
};
// Interface
internal UI ui_create();
internal void ui_quad_push(UI* ui, v3 pmin, v3 pmax, v2 tmin, v2 tmax, v4 c);
internal void ui_sprite_register(UI* ui, u8* pixels, u32 w, u32 h, u32 id);
internal void ui_sprite_push(UI* ui, v3 pmin, v3 pmax, u32 id, v4 color);
internal void ui_sprite_push(UI* ui, v3 pmin, v3 pmax, u32 id);
internal v3 ui_sprite_char_push(UI* ui, v2 at, u32 codepoint, v4 color);
internal void ui_draw(UI* ui);
// Widgets
internal void ui_create_default_style_sheet();
internal UI_Widget_Id ui_widget_id_create(u32 index_in_parent, String string);
internal bool ui_widget_id_equals(UI_Widget_Id a, UI_Widget_Id b);
internal bool ui_widget_id_is_valid(UI_Widget_Id h);
internal void ui_widget_next_hot_set(UI* ui, UI_Widget* w);
internal void ui_widget_hot_set(UI* ui, UI_Widget* w);
internal UI_Widget* ui_widget_pool_push(UI_Widget_Pool* pool, String string);
internal void ui_widget_pool_pop(UI_Widget_Pool* pool);
internal UI_Widget_Result ui_widget_push(UI* ui, UI_Widget_Desc desc);
internal void ui_widget_pop(UI* ui, UI_Widget* widget);
internal r32 ui_widgets_to_geometry_recursive(UI* ui, UI_Widget* widget, r32 z_start, r32 z_step);
#endif //LUMENARIUM_UI_H