replace ui double buffering with persistent cmd-driven state

This commit is contained in:
jacob 2025-11-08 18:14:54 -06:00
parent a7c286d912
commit 9850de005c
8 changed files with 606 additions and 482 deletions

View File

@ -434,8 +434,10 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t);
#endif #endif
//- struct region //- struct region
#define StructRegion(name) i8 name #define BeginFieldRegion(name) i8 __begfieldreg__##name
#define CopyStructRegion(dst, src, r0, r1) CopyBytes(&dst->r0, &src->r0, (u8 *)&dst->r1 - (u8 *)&dst->r0) #define EndFieldRegion(name) i8 __endfieldreg___##name
#define CopyFieldRegion(dst, src, r) CopyBytes(&dst->(__begfieldreg__##r), &src->(__begfieldreg__##r), (u8 *)&dst->(__endfieldreg__##r) - (u8 *)&dst->(__begfieldreg__##r))
#define ZeroFieldRegion(dst, src, r) ZeroBytes(&dst->(__begfieldreg__##r), &src->(__begfieldreg__##r), (u8 *)&dst->(__endfieldreg__##r) - (u8 *)&dst->(__begfieldreg__##r))
//- Packed //- Packed
#if CompilerIsMsvc #if CompilerIsMsvc

View File

@ -113,9 +113,11 @@ JobDef(PP_VisWorker, sig, job_id)
{ {
PP_CommandsWidget commands_widget; PP_CommandsWidget commands_widget;
b32 ui_debug; b32 ui_debug;
b32 show_console;
}; };
VisPersist persist = ZI; VisPersist persist = ZI;
String window_restore = ZI; String window_restore = ZI;
// persist.ui_debug = 1;
////////////////////////////// //////////////////////////////
//- Swap in //- Swap in
@ -174,6 +176,7 @@ JobDef(PP_VisWorker, sig, job_id)
////////////////////////////// //////////////////////////////
//- Build console //- Build console
if (persist.show_console)
{ {
b32 minimized = 1; b32 minimized = 1;
PP_BuildConsoleWidget(minimized); PP_BuildConsoleWidget(minimized);
@ -188,6 +191,15 @@ JobDef(PP_VisWorker, sig, job_id)
{ {
persist.ui_debug = !persist.ui_debug; persist.ui_debug = !persist.ui_debug;
} }
if (PP_PushCommandsWidgetItem(&persist.commands_widget, Lit("Console")).m1_presses > 0)
{
b32 new = !persist.show_console;
if (new)
{
LogInfoF("Enabled console");
}
persist.show_console = new;
}
if (PP_PushCommandsWidgetItem(&persist.commands_widget, Lit("Fullscreen")).m1_presses > 0) if (PP_PushCommandsWidgetItem(&persist.commands_widget, Lit("Fullscreen")).m1_presses > 0)
{ {
b32 new = !window_frame.fullscreen; b32 new = !window_frame.fullscreen;

View File

@ -32,16 +32,16 @@ void PP_PushWidgetThemeStyles(PP_WidgetTheme theme)
void PP_BeginCommandsWidget(PP_CommandsWidget *widget) void PP_BeginCommandsWidget(PP_CommandsWidget *widget)
{ {
ZeroStruct(&widget->build); ZeroStruct(&widget->build);
widget->build.cp = UI_PushCP(0); widget->build.cp = UI_PushCP(UI_NilKey);
UI_Push(Tag, HashF("commands widget")); UI_Push(Tag, HashF("commands widget"));
} }
UI_Report PP_PushCommandsWidgetItem(PP_CommandsWidget *widget, String name) UI_Report PP_PushCommandsWidgetItem(PP_CommandsWidget *widget, String name)
{ {
Arena *build_arena = UI_GetFrameArena(); Arena *frame_arena = UI_FrameArena();
UI_Key key = UI_KeyF("btn%F", FmtSint(widget->build.num_items)); UI_Key key = UI_KeyF("btn%F", FmtSint(widget->build.num_items));
PP_CommandsWidgetItem *item = PushStruct(build_arena, PP_CommandsWidgetItem); PP_CommandsWidgetItem *item = PushStruct(frame_arena, PP_CommandsWidgetItem);
item->name = name; item->name = name;
item->key = key; item->key = key;
QueuePush(widget->build.first_item, widget->build.last_item, item); QueuePush(widget->build.first_item, widget->build.last_item, item);
@ -53,7 +53,7 @@ UI_Report PP_PushCommandsWidgetItem(PP_CommandsWidget *widget, String name)
void PP_EndCommandsWidget(PP_CommandsWidget *widget) void PP_EndCommandsWidget(PP_CommandsWidget *widget)
{ {
PP_WidgetTheme theme = PP_GetWidgetTheme(); PP_WidgetTheme theme = PP_GetWidgetTheme();
Vec2 cursor_pos = UI_GetCursorPos(); Vec2 cursor_pos = UI_CursorPos();
UI_Push(Tag, HashF("commands widget")); UI_Push(Tag, HashF("commands widget"));
@ -83,10 +83,10 @@ void PP_EndCommandsWidget(PP_CommandsWidget *widget)
UI_Push(ChildLayoutAxis, Axis_Y); UI_Push(ChildLayoutAxis, Axis_Y);
UI_Push(FloatingPos, widget->pos); UI_Push(FloatingPos, widget->pos);
UI_SetNext(Flags, UI_BoxFlag_Floating); UI_SetNext(Flags, UI_BoxFlag_Floating);
UI_PushCP(UI_BuildBox(UI_KeyF("titlebar"))); UI_PushCP(UI_BuildBoxEx(UI_KeyF("titlebar")));
{ {
/* Title bar */ /* Title bar */
UI_PushCP(0); UI_PushCP(UI_NilKey);
{ {
UI_Push(BackgroundColor, titlebar_color); UI_Push(BackgroundColor, titlebar_color);
UI_Push(BorderColor, titlebar_border_color); UI_Push(BorderColor, titlebar_border_color);
@ -95,13 +95,13 @@ void PP_EndCommandsWidget(PP_CommandsWidget *widget)
UI_Push(Width, UI_GROW(1, 0)); UI_Push(Width, UI_GROW(1, 0));
UI_Push(Height, UI_FNT(2, 1)); UI_Push(Height, UI_FNT(2, 1));
UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_Interactable); UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_Interactable);
UI_PushCP(UI_BuildBox(titlebar_key)); UI_PushCP(UI_BuildBoxEx(titlebar_key));
{ {
UI_Push(Width, UI_GROW(1, 0)); UI_Push(Width, UI_GROW(1, 0));
UI_Push(BorderColor, 0); UI_Push(BorderColor, 0);
/* Left title box */ /* Left title box */
UI_BuildRow(UI_NilKey); UI_BuildRow();
/* Title box */ /* Title box */
UI_SetNext(FontSize, theme.window_title_font_size); UI_SetNext(FontSize, theme.window_title_font_size);
@ -109,10 +109,10 @@ void PP_EndCommandsWidget(PP_CommandsWidget *widget)
UI_SetNext(Width, UI_SHRINK(0, 1)); UI_SetNext(Width, UI_SHRINK(0, 1));
UI_SetNext(Text, Lit("Commands")); UI_SetNext(Text, Lit("Commands"));
UI_SetNext(Flags, UI_BoxFlag_DrawText); UI_SetNext(Flags, UI_BoxFlag_DrawText);
UI_BuildBox(UI_NilKey); UI_BuildBox();
/* Right title box */ /* Right title box */
UI_BuildRow(UI_NilKey); UI_BuildRow();
} }
UI_PopCP(UI_TopCP()); UI_PopCP(UI_TopCP());
} }
@ -122,18 +122,18 @@ void PP_EndCommandsWidget(PP_CommandsWidget *widget)
f32 padding = theme.window_border; f32 padding = theme.window_border;
UI_SetNext(Tint, 0); UI_SetNext(Tint, 0);
UI_SetNext(Rounding, 0); UI_SetNext(Rounding, 0);
UI_PushCP(UI_BuildRow(UI_NilKey)); UI_PushCP(UI_BuildRow());
{ {
UI_BuildSpacer(UI_PIX(padding, 1)); UI_BuildSpacer(UI_PIX(padding, 1), Axis_X);
{ {
UI_SetNext(Tint, 0); UI_SetNext(Tint, 0);
UI_SetNext(Rounding, 0); UI_SetNext(Rounding, 0);
UI_SetNext(Width, UI_GROW(1, 0)); UI_SetNext(Width, UI_GROW(1, 0));
UI_PushCP(UI_BuildColumn(UI_NilKey)); UI_PushCP(UI_BuildColumn());
{ {
for (PP_CommandsWidgetItem *item = widget->build.first_item; item; item = item->next) for (PP_CommandsWidgetItem *item = widget->build.first_item; item; item = item->next)
{ {
UI_BuildDivider(UI_PIX(1, 1), theme.divider_color); UI_BuildDivider(UI_PIX(1, 1), theme.divider_color, Axis_Y);
UI_Key btn_key = item->key; UI_Key btn_key = item->key;
UI_Report btn_rep = UI_ReportFromKey(btn_key); UI_Report btn_rep = UI_ReportFromKey(btn_key);
@ -153,7 +153,7 @@ void PP_EndCommandsWidget(PP_CommandsWidget *widget)
UI_SetNext(Rounding, 0); UI_SetNext(Rounding, 0);
UI_SetNext(Tint, 0); UI_SetNext(Tint, 0);
UI_PushCP(UI_BuildRow(UI_NilKey)); UI_PushCP(UI_BuildRow());
{ {
UI_SetNext(BorderColor, border_color); UI_SetNext(BorderColor, border_color);
UI_SetNext(BackgroundColor, color); UI_SetNext(BackgroundColor, color);
@ -162,16 +162,16 @@ void PP_EndCommandsWidget(PP_CommandsWidget *widget)
UI_SetNext(Height, UI_FNT(1.5, 1)); UI_SetNext(Height, UI_FNT(1.5, 1));
UI_SetNext(ChildAlignment, UI_Alignment_Left); UI_SetNext(ChildAlignment, UI_Alignment_Left);
UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_Interactable); UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_Interactable);
UI_PushCP(UI_BuildRow(btn_key)); UI_PushCP(UI_BuildRowEx(btn_key));
{ {
/* Begin spacer */ /* Begin spacer */
UI_BuildSpacer(UI_PIX(20, 1)); UI_BuildSpacer(UI_PIX(20, 1), Axis_X);
/* Command label */ /* Command label */
UI_BuildLabel(item->name); UI_BuildLabel(item->name);
/* Middle spacer */ /* Middle spacer */
UI_BuildSpacer(UI_GROW(1, 0)); UI_BuildSpacer(UI_GROW(1, 0), Axis_X);
/* Command hotkey button */ /* Command hotkey button */
UI_SetNext(Text, UI_StringF("Test")); UI_SetNext(Text, UI_StringF("Test"));
@ -182,14 +182,14 @@ void PP_EndCommandsWidget(PP_CommandsWidget *widget)
UI_SetNext(BackgroundColor, Color_Cyan); UI_SetNext(BackgroundColor, Color_Cyan);
UI_SetNext(ChildAlignment, UI_Alignment_Center); UI_SetNext(ChildAlignment, UI_Alignment_Center);
UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_Interactable); UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_Interactable);
UI_PushCP(UI_BuildRow(UI_NilKey)); UI_PushCP(UI_BuildRow());
{ {
} }
UI_PopCP(UI_TopCP()); UI_PopCP(UI_TopCP());
/* End spacer */ /* End spacer */
UI_BuildSpacer(UI_PIX(20, 1)); UI_BuildSpacer(UI_PIX(20, 1), Axis_X);
} }
UI_PopCP(UI_TopCP()); UI_PopCP(UI_TopCP());
} }
@ -198,18 +198,18 @@ void PP_EndCommandsWidget(PP_CommandsWidget *widget)
} }
UI_PopCP(UI_TopCP()); UI_PopCP(UI_TopCP());
} }
UI_BuildSpacer(UI_PIX(padding, 1)); UI_BuildSpacer(UI_PIX(padding, 1), Axis_X);
} }
UI_PopCP(UI_TopCP()); UI_PopCP(UI_TopCP());
UI_BuildSpacer(UI_PIX(padding, 1)); UI_BuildSpacer(UI_PIX(padding, 1), Axis_Y);
UI_PopCP(UI_TopCP()); UI_PopCP(UI_TopCP());
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Console widget //~ Console widget
UI_Box *PP_BuildConsoleWidget(b32 minimized) UI_Key PP_BuildConsoleWidget(b32 minimized)
{ {
/* TODO: Remove this whole thing */ /* TODO: Remove this whole thing */
__prof; __prof;
@ -246,7 +246,7 @@ UI_Box *PP_BuildConsoleWidget(b32 minimized)
f32 fade_curve = 0.5; f32 fade_curve = 0.5;
i64 now_ns = TimeNs(); i64 now_ns = TimeNs();
UI_Box *console_box = 0; UI_Key console_box = ZI;
{ {
UI_SetNext(Border, 0); UI_SetNext(Border, 0);
if (minimized) if (minimized)
@ -261,7 +261,7 @@ UI_Box *PP_BuildConsoleWidget(b32 minimized)
UI_SetNext(Width, UI_GROW(1, 0)); UI_SetNext(Width, UI_GROW(1, 0));
UI_SetNext(Height, UI_SHRINK(0, 1)); UI_SetNext(Height, UI_SHRINK(0, 1));
} }
console_box = UI_BuildColumn(UI_KeyF("Console box")); console_box = UI_BuildColumnEx(UI_KeyF("Console box"));
UI_PushCP(console_box); UI_PushCP(console_box);
{ {
/* Gather display logs */ /* Gather display logs */
@ -312,7 +312,7 @@ UI_Box *PP_BuildConsoleWidget(b32 minimized)
FmtUintZ(datetime.milliseconds, 3), FmtUintZ(datetime.milliseconds, 3),
FmtString(text)); FmtString(text));
} }
UI_PushCP(0); UI_PushCP(UI_NilKey);
{ {
Vec4 tint = VEC4(1, 1, 1, opacity); Vec4 tint = VEC4(1, 1, 1, opacity);
UI_Push(Tint, tint); UI_Push(Tint, tint);
@ -325,17 +325,17 @@ UI_Box *PP_BuildConsoleWidget(b32 minimized)
UI_Push(Rounding, UI_RPIX(0)); UI_Push(Rounding, UI_RPIX(0));
UI_Push(Border, 1); UI_Push(Border, 1);
UI_Push(ChildAlignment, UI_Alignment_Left); UI_Push(ChildAlignment, UI_Alignment_Left);
UI_PushCP(UI_BuildRow(UI_NilKey)); UI_PushCP(UI_BuildRow());
{ {
// UI_SetNext(Height, UI_PIX(100, 0)); // UI_SetNext(Height, UI_PIX(100, 0));
UI_BuildSpacer(UI_PIX(10, 0)); UI_BuildSpacer(UI_PIX(10, 0), Axis_X);
UI_Push(BackgroundColor, 0); UI_Push(BackgroundColor, 0);
UI_Push(Border, 0); UI_Push(Border, 0);
UI_Push(Text, text); UI_Push(Text, text);
UI_Push(Width, UI_GROW(1, 0)); UI_Push(Width, UI_GROW(1, 0));
UI_Push(Height, UI_SHRINK(0, 1)); UI_Push(Height, UI_SHRINK(0, 1));
UI_Push(Flags, UI_BoxFlag_DrawText); UI_Push(Flags, UI_BoxFlag_DrawText);
UI_BuildBox(UI_NilKey); UI_BuildBox();
} }
UI_PopCP(UI_TopCP()); UI_PopCP(UI_TopCP());
} }

View File

@ -60,4 +60,4 @@ void PP_EndCommandsWidget(PP_CommandsWidget *widget);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Console widget //~ Console widget
UI_Box *PP_BuildConsoleWidget(b32 minimized); UI_Key PP_BuildConsoleWidget(b32 minimized);

View File

@ -1,15 +1,15 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Label helpers //~ Label helpers
UI_Box *UI_BuildLabel(String text) UI_Key UI_BuildLabel(String text)
{ {
UI_Box *parent = UI_UseTop(Parent); UI_Key parent = UI_UseTop(Parent);
ResourceKey font = UI_UseTop(Font); ResourceKey font = UI_UseTop(Font);
f32 font_size = UI_UseTop(FontSize); f32 font_size = UI_UseTop(FontSize);
Vec4 tint = UI_UseTop(Tint); Vec4 tint = UI_UseTop(Tint);
UI_Box *box = 0; UI_Key key = ZI;
UI_PushCP(0); UI_PushCP(UI_NilKey);
{ {
UI_PushDefaults(); UI_PushDefaults();
UI_Push(Parent, parent); UI_Push(Parent, parent);
@ -20,13 +20,13 @@ UI_Box *UI_BuildLabel(String text)
UI_SetNext(Height, UI_SHRINK(0, 1)); UI_SetNext(Height, UI_SHRINK(0, 1));
UI_SetNext(Text, text); UI_SetNext(Text, text);
UI_SetNext(Flags, UI_BoxFlag_DrawText); UI_SetNext(Flags, UI_BoxFlag_DrawText);
box = UI_BuildBox(UI_NilKey); key = UI_BuildBox();
} }
UI_PopCP(UI_TopCP()); UI_PopCP(UI_TopCP());
return box; return key;
} }
UI_Box *UI_BuildLabelF_(char *fmt_cstr, ...) UI_Key UI_BuildLabelF_(char *fmt_cstr, ...)
{ {
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
String str = ZI; String str = ZI;
@ -36,39 +36,37 @@ UI_Box *UI_BuildLabelF_(char *fmt_cstr, ...)
str = FormatStringV(scratch.arena, StringFromCstrNoLimit(fmt_cstr), va); str = FormatStringV(scratch.arena, StringFromCstrNoLimit(fmt_cstr), va);
va_end(va); va_end(va);
} }
UI_Box *box = UI_BuildLabel(str); UI_Key key = UI_BuildLabel(str);
EndScratch(scratch); EndScratch(scratch);
return box; return key;
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Spacing helpers //~ Spacing helpers
UI_Box *UI_BuildSpacer(UI_Size size) UI_Key UI_BuildSpacer(UI_Size size, Axis axis)
{ {
UI_Box *box = 0; UI_Key parent = UI_UseTop(Parent);
UI_Box *parent = UI_UseTop(Parent); UI_Key key = ZI;
Axis axis = parent->child_layout_axis; UI_PushCP(UI_NilKey);
UI_PushCP(0);
{ {
UI_PushDefaults(); UI_PushDefaults();
UI_Push(Parent, parent); UI_Push(Parent, parent);
UI_Push(Tint, 0); UI_Push(Tint, 0);
UI_Push(AxisSize, UI_GROW(1, 0), .axis = !axis); UI_Push(AxisSize, UI_GROW(1, 0), .axis = !axis);
UI_Push(AxisSize, size, .axis = axis); UI_Push(AxisSize, size, .axis = axis);
box = UI_BuildBox(UI_NilKey); key = UI_BuildBox();
} }
UI_PopCP(UI_TopCP()); UI_PopCP(UI_TopCP());
return box; return key;
} }
UI_Box *UI_BuildDivider(UI_Size size, Vec4 color) UI_Key UI_BuildDivider(UI_Size size, Vec4 color, Axis axis)
{ {
UI_Box *box = 0; UI_Key key = ZI;
UI_Box *parent = UI_UseTop(Parent); UI_Key parent = UI_UseTop(Parent);
Vec4 tint = UI_UseTop(Tint); Vec4 tint = UI_UseTop(Tint);
Axis axis = parent->child_layout_axis; UI_PushCP(UI_NilKey);
UI_PushCP(0);
{ {
UI_PushDefaults(); UI_PushDefaults();
UI_Push(Parent, parent); UI_Push(Parent, parent);
@ -76,25 +74,23 @@ UI_Box *UI_BuildDivider(UI_Size size, Vec4 color)
UI_Push(BackgroundColor, color); UI_Push(BackgroundColor, color);
UI_Push(AxisSize, UI_GROW(1, 0), .axis = !axis); UI_Push(AxisSize, UI_GROW(1, 0), .axis = !axis);
UI_Push(AxisSize, size, .axis = axis); UI_Push(AxisSize, size, .axis = axis);
box = UI_BuildBox(UI_NilKey); key = UI_BuildBox();
} }
UI_PopCP(UI_TopCP()); UI_PopCP(UI_TopCP());
return box; return key;
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Layout helpers //~ Layout helpers
UI_Box *UI_BuildColumn(UI_Key key) UI_Key UI_BuildColumnEx(UI_Key key)
{ {
UI_SetNext(ChildLayoutAxis, Axis_Y); UI_SetNext(ChildLayoutAxis, Axis_Y);
UI_Box *box = UI_BuildBox(key); return UI_BuildBoxEx(key);
return box;
} }
UI_Box *UI_BuildRow(UI_Key key) UI_Key UI_BuildRowEx(UI_Key key)
{ {
UI_SetNext(ChildLayoutAxis, Axis_X); UI_SetNext(ChildLayoutAxis, Axis_X);
UI_Box *box = UI_BuildBox(key); return UI_BuildBoxEx(key);
return box;
} }

View File

@ -1,18 +1,21 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Label helpers //~ Label helpers
UI_Box *UI_BuildLabel(String text); UI_Key UI_BuildLabel(String text);
#define UI_BuildLabelF(fmt_cstr, ...) UI_BuildLabelF_(fmt_cstr, __VA_ARGS__, FmtEnd) #define UI_BuildLabelF(fmt_cstr, ...) UI_BuildLabelF_(fmt_cstr, __VA_ARGS__, FmtEnd)
UI_Box *UI_BuildLabelF_(char *fmt_cstr, ...); UI_Key UI_BuildLabelF_(char *fmt_cstr, ...);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Spacing helpers //~ Spacing helpers
UI_Box *UI_BuildSpacer(UI_Size size); UI_Key UI_BuildSpacer(UI_Size size, Axis axis);
UI_Box *UI_BuildDivider(UI_Size size, Vec4 color); UI_Key UI_BuildDivider(UI_Size size, Vec4 color, Axis axis);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Layout helpers //~ Layout helpers
UI_Box *UI_BuildColumn(UI_Key key); UI_Key UI_BuildColumnEx(UI_Key key);
UI_Box *UI_BuildRow(UI_Key key); UI_Key UI_BuildRowEx(UI_Key key);
#define UI_BuildColumn() UI_BuildColumnEx(UI_TransKey())
#define UI_BuildRow() UI_BuildRowEx(UI_TransKey())

File diff suppressed because it is too large Load Diff

View File

@ -90,32 +90,35 @@ Enum(UI_BoxFlag)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Style types //~ Style types
#define UI_StyleKindsXMacro(x) \ #define UI_StyleKindsXMacro(X) \
x(Flags, UI_BoxFlag) \ X(Flags, UI_BoxFlag) \
x(Parent, struct UI_Box *) \ X(Parent, UI_Key) \
x(Tag, u64) \ X(Tag, u64) \
x(ChildLayoutAxis, Axis) \ X(ChildLayoutAxis, Axis) \
x(ChildAlignmentX, UI_AxisAlignment) \ X(ChildAlignmentX, UI_AxisAlignment) \
x(ChildAlignmentY, UI_AxisAlignment) \ X(ChildAlignmentY, UI_AxisAlignment) \
x(Width, UI_Size) \ X(Width, UI_Size) \
x(Height, UI_Size) \ X(Height, UI_Size) \
x(BackgroundColor, Vec4) \ X(BackgroundColor, Vec4) \
x(BorderColor, Vec4) \ X(BorderColor, Vec4) \
x(DebugColor, Vec4) \ X(DebugColor, Vec4) \
x(Tint, Vec4) \ X(Tint, Vec4) \
x(Border, f32) \ X(Border, f32) \
x(FloatingPos, Vec2) \ X(FloatingPos, Vec2) \
x(Rounding, UI_Round) \ X(Rounding, UI_Round) \
x(Font, ResourceKey) \ X(Font, ResourceKey) \
x(FontSize, u32) \ X(FontSize, u32) \
x(Text, String) \ X(Text, String) \
/* ----------------------------------- */ \ X(BackgroundTexture, GPU_Resource *) \
/* --------- Virtual styles --------- */ \ X(BackgroundTextureUv0, Vec2) \
/* ----------------------------------- */ \ X(BackgroundTextureUv1, Vec2) \
x(BeginVirtualStyles_, i8) \ /* --------------------------------------- */ \
x(ChildAlignment, UI_Alignment) \ /* ----------- Virtual styles ----------- */ \
x(AxisSize, UI_Size) \ /* --------------------------------------- */ \
/* ------------------------------------------- */ X(BeginVirtualStyles_, i8) \
X(ChildAlignment, UI_Alignment) \
X(AxisSize, UI_Size) \
/* -------------------------------------------------- */
Enum(UI_StyleKind) Enum(UI_StyleKind)
{ {
@ -189,29 +192,15 @@ Struct(UI_Report)
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Box types //~ Command types
Struct(UI_Box) Struct(UI_Cmd)
{ {
//- 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;
UI_Report report;
//- Per-build data
UI_BoxFlag flags; UI_BoxFlag flags;
UI_Key key;
UI_Key parent;
GPU_Resource *background_texture; GPU_Resource *background_texture;
Vec2 background_texture_uv0; Vec2 background_texture_uv0;
Vec2 background_texture_uv1; Vec2 background_texture_uv1;
@ -229,6 +218,37 @@ Struct(UI_Box)
f32 font_size; f32 font_size;
Axis child_layout_axis; Axis child_layout_axis;
UI_AxisAlignment child_alignment[Axis_CountXY]; UI_AxisAlignment child_alignment[Axis_CountXY];
};
Struct(UI_CmdNode)
{
UI_CmdNode *next;
UI_Cmd cmd;
};
////////////////////////////////////////////////////////////
//~ Box types
Struct(UI_Box)
{
UI_Key key;
//- Persistent data
UI_Box *next_in_bin;
UI_Box *prev_in_bin;
UI_Report report;
u64 last_updated_tick;
//- Tree links
UI_Box *parent;
UI_Box *first;
UI_Box *last;
UI_Box *next;
UI_Box *prev;
u64 count;
//- Cmd data
UI_Cmd cmd;
//- Pre-layout data //- Pre-layout data
u64 pre_index; u64 pre_index;
@ -241,7 +261,7 @@ Struct(UI_Box)
f32 solved_dims[Axis_CountXY]; f32 solved_dims[Axis_CountXY];
f32 final_children_size_accum[Axis_CountXY]; f32 final_children_size_accum[Axis_CountXY];
//- Post-layout data //- Layout results
Vec2 p0; Vec2 p0;
Vec2 p1; Vec2 p1;
f32 rounding_tl; f32 rounding_tl;
@ -277,47 +297,71 @@ Struct(UI_Frame)
#define UI_NumBoxLookupBins 16384 #define UI_NumBoxLookupBins 16384
Struct(UI_SharedState) Struct(UI_BFrameState);
Struct(UI_EFrameState);
Struct(UI_State)
{ {
//- Control state //////////////////////////////
i64 last_frame_begin_ns; //- Persistent sate
Arena *box_arena;
UI_BoxBin *box_bins;
u64 boxes_count;
UI_Box *first_free_box;
//////////////////////////////
//- Frame-begin state
struct UI_BFrameState
{
Arena *cmds_arena;
WND_Frame window_frame;
u64 transient_key_seed;
/* Time */
u64 tick;
i64 time_ns;
i64 dt_ns;
/* Control */
Vec2 cursor_pos; Vec2 cursor_pos;
UI_Key hovered_box; UI_Key hovered_box;
UI_Key active_box; UI_Key active_box;
//- Build state /* Cmds */
Arena *build_arena;
Arena *back_build_arena;
UI_FrameFlag frame_flags; UI_FrameFlag frame_flags;
UI_FrameFlag back_frame_flags; UI_CmdNode *first_cmd_node;
UI_CmdNode *last_cmd_node;
UI_BoxBin *box_bins; u64 cmds_count;
UI_BoxBin *back_box_bins;
UI_Box *root_box;
UI_Box *back_root_box;
u64 boxes_count;
u64 back_boxes_count;
/* Style stack */
UI_Stack *top_stack; UI_Stack *top_stack;
UI_StyleNode *first_free_style_node; UI_StyleNode *first_free_style_node;
} bframe;
//- Layout state //////////////////////////////
UI_Box **boxes_pre; //- Frame-end state
UI_Box **boxes_post;
UI_Box **back_boxes_pre;
UI_Box **back_boxes_post;
//- Render state struct UI_EFrameState
{
Arena *layout_arena;
Arena *rects_arena;
u64 tick;
/* Render */
GPU_Resource *render_target; GPU_Resource *render_target;
GPU_Swapchain *swapchain; GPU_Swapchain *swapchain;
i64 gpu_submit_fence_target; i64 gpu_submit_fence_target;
GPU_TransientBuffer draw_rects_tbuff; GPU_TransientBuffer draw_rects_tbuff;
Arena *draw_rects_arena;
} extern UI_shared_state; /* Layout */
UI_Box *root_box;
UI_Box **boxes_pre;
UI_Box **boxes_post;
} eframe;
} extern UI_state;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Startup //~ Startup
@ -336,8 +380,9 @@ UI_Key UI_KeyFromString(String str);
UI_Key UI_KeyF_(String fmt, ...); UI_Key UI_KeyF_(String fmt, ...);
#define UI_KeyF(fmt_cstr, ...) UI_KeyF_(StringFromCstrNoLimit(fmt_cstr), __VA_ARGS__, FmtEnd) #define UI_KeyF(fmt_cstr, ...) UI_KeyF_(StringFromCstrNoLimit(fmt_cstr), __VA_ARGS__, FmtEnd)
UI_Box *UI_BackBoxFromKey(UI_Key key); UI_Key UI_TransKey(void);
UI_Box *UI_FrontBoxFromKey(UI_Key key);
UI_Box *UI_BoxFromKey(UI_Key key);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ String helpers //~ String helpers
@ -348,7 +393,7 @@ String UI_StringF_(String fmt, ...);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Checkpoint helpers //~ Checkpoint helpers
UI_Checkpoint UI_PushCP(UI_Box *parent); UI_Checkpoint UI_PushCP(UI_Key parent);
void UI_PopCP(UI_Checkpoint pop_to); void UI_PopCP(UI_Checkpoint pop_to);
UI_Checkpoint UI_TopCP(void); UI_Checkpoint UI_TopCP(void);
@ -397,12 +442,10 @@ UI_Style UI_PopStyle(UI_StyleDesc desc);
#define UI_RGROW(_v) UI_ROUND(UI_RoundKind_Fill, (_v)) #define UI_RGROW(_v) UI_ROUND(UI_RoundKind_Fill, (_v))
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Box //~ Command helpers
UI_Box *UI_BuildBox(UI_Key key); UI_Key UI_BuildBoxEx(UI_Key key);
#define UI_BuildBox() UI_BuildBoxEx(UI_TransKey())
void UI_SetBackgroundTexture(UI_Box *box, GPU_Resource *texture, Vec2 uv0, Vec2 uv1);
b32 UI_IsPointInBox(UI_Box *box, Vec2 point);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Report //~ Report
@ -417,8 +460,8 @@ UI_Frame UI_BeginFrame(UI_FrameFlag frame_flags);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Frame helpers //~ Frame helpers
Arena *UI_GetFrameArena(void); Arena *UI_FrameArena(void);
Vec2 UI_GetCursorPos(void); Vec2 UI_CursorPos(void);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ End frame //~ End frame