power_play/src/ui/ui.h
2025-10-23 03:03:12 -05:00

249 lines
5.9 KiB
C

////////////////////////////////////////////////////////////
//~ Key types
#define UI_NilKey ((UI_Key) { 0 })
#define UI_RootKey ((UI_Key) { 0xa3deb3749ef35a7aUll })
Struct(UI_Key)
{
u64 hash;
};
////////////////////////////////////////////////////////////
//~ Size types
Enum(UI_SizeKind)
{
UI_SizeKind_Children,
UI_SizeKind_Ratio,
UI_SizeKind_Pixel,
UI_SizeKind_Text,
};
Struct(UI_Size)
{
UI_SizeKind kind;
f32 v;
f32 strictness;
};
////////////////////////////////////////////////////////////
//~ Box types
/* NOTE: UI flags are located here since they are shared between application & shader code */
Enum(UI_BoxFlag)
{
UI_BoxFlag_None = 0,
UI_BoxFlag_DrawText = (1 << 0),
UI_BoxFlag_DrawImage = (1 << 1),
};
Struct(UI_Box)
{
//- Hash list
UI_Box *next_in_bin;
UI_Box *prev_in_bin;
//- Tree
UI_Box *parent;
UI_Box *first;
UI_Box *last;
UI_Box *next;
UI_Box *prev;
u64 count;
//- Persistent data
UI_Key key;
//- Per-build data
UI_BoxFlag flags;
String display_text;
GPU_Resource *display_image;
Axis layout_axis;
UI_Size pref_size[Axis_CountXY];
u32 background_color;
u32 border_color;
f32 border;
f32 text_padding;
Resource font_resource;
f32 font_size;
//- Layout data
F_Run glyph_run;
F_Font *font;
f32 solved_dims[Axis_CountXY];
f32 layout_cursor;
//- Post-solve data
Vec2 p0;
Vec2 p1;
};
Struct(UI_BoxBin)
{
UI_Box *first;
UI_Box *last;
};
////////////////////////////////////////////////////////////
//~ Style types
#define UI_StyleKindsXMacro(x) \
x(Tag, u64) \
x(Parent, UI_Box *) \
x(LayoutAxis, Axis) \
x(Width, UI_Size) \
x(Height, UI_Size) \
x(BackgroundColor, u32) \
x(BorderColor, u32) \
x(Border, f32) \
x(Font, Resource) \
x(FontSize, u32) \
x(TextPadding, f32) \
/* ----------------------------------- */
Enum(UI_StyleKind)
{
#define X(name, type) UI_StyleKind_##name,
UI_StyleKind_None,
UI_StyleKindsXMacro(X)
UI_StyleKind_Count,
#undef X
};
Struct(UI_Style)
{
UI_StyleKind kind;
/* Union of all style fields */
union
{
#define X(name, type) type name;
UI_StyleKindsXMacro(X)
#undef X
};
};
Struct(UI_StyleNode)
{
UI_StyleNode *next;
b32 pop_when_used;
u64 checkpoint;
UI_Style style;
};
////////////////////////////////////////////////////////////
//~ Checkpoint types
Struct(UI_Checkpoint)
{
UI_Checkpoint *next;
u64 v;
};
////////////////////////////////////////////////////////////
//~ State types
#define UI_NumBoxLookupBins 16384
Struct(UI_SharedState)
{
//- Build state
Arena *build_arena;
Arena *back_build_arena;
UI_BoxBin *box_bins;
UI_BoxBin *back_box_bins;
UI_Box *root_box;
UI_Box *back_root_box;
u64 boxes_count;
u64 back_boxes_count;
UI_Checkpoint *top_checkpoint;
UI_Checkpoint *first_free_checkpoint;
UI_StyleNode *style_tops[UI_StyleKind_Count];
UI_StyleNode *first_free_style_node;
//- Render state
GPU_Resource *render_target;
i64 render_fence_target;
GPU_TransientBuffer draw_rects_tbuff;
Arena *draw_rects_arena;
} extern UI_shared_state;
////////////////////////////////////////////////////////////
//~ Startup
void UI_Startup(void);
////////////////////////////////////////////////////////////
//~ Font helpers
Resource UI_GetDefaultFontResource(void);
////////////////////////////////////////////////////////////
//~ Key helpers
u64 UI_HashFromTop(void);
u64 UI_HashFromString(u64 seed, String str);
UI_Key UI_KeyFromString(u64 seed, String str);
////////////////////////////////////////////////////////////
//~ Checkpoint helpers
void UI_PushCheckpoint(void);
void UI_PopCheckpoint(void);
////////////////////////////////////////////////////////////
//~ Style stack helpers
UI_StyleNode *UI_PushStyleNode(UI_StyleKind kind, b32 pop_when_used, UI_Style desc);
UI_Style UI_PopStyleNode(UI_StyleKind kind);
UI_StyleNode *UI_PeekTopStyleNode(UI_StyleKind kind);
UI_Style UI_StyleFromTopNode(UI_StyleKind kind, b32 use);
#define UI_SetNext(name, v) UI_PushStyleNode(UI_StyleKind_##name, 1, (UI_Style) { .name = v })
#define UI_Push(name, v) UI_PushStyleNode(UI_StyleKind_##name, 0, (UI_Style) { .name = v })
#define UI_Pop(name, v) UI_PopStyleNode(UI_StyleKind_##name).name
#define UI_UseTop(name) UI_StyleFromTopNode(UI_StyleKind_##name, 1).name
#define UI_PeekTop(name) UI_StyleFromTopNode(UI_StyleKind_##name, 0).name
////////////////////////////////////////////////////////////
//~ Size helpers
#define UI_ChildrenSize(_strictness) ((UI_Size) { .kind = UI_SizeKind_Children, .strictness = strictness_ })
#define UI_RatioSize(_ratio, _strictness) ((UI_Size) { .kind = UI_SizeKind_Ratio, .v = _ratio, .strictness = _strictness })
#define UI_PixelSize(_pixels, _strictness) ((UI_Size) { .kind = UI_SizeKind_Pixel, .v = _pixels, .strictness = _strictness })
#define UI_TextSize(_strictness) ((UI_Size) { .kind = UI_SizeKind_Text, .strictness = _strictness })
////////////////////////////////////////////////////////////
//~ Box
UI_Box *UI_BuildBox(UI_BoxFlag flags, UI_Key key);
void UI_SetDisplayText(UI_Box *box, String str);
void UI_SetDisplayImage(UI_Box *box, GPU_Resource *img);
////////////////////////////////////////////////////////////
//~ Image
void UI_SetDisplayImage(UI_Box *box, GPU_Resource *img);
////////////////////////////////////////////////////////////
//~ Begin build
void UI_BeginBuild(void);
////////////////////////////////////////////////////////////
//~ End build
GPU_Resource *UI_EndBuild(Rect render_viewport);