explicit checkpoint push/pop

This commit is contained in:
jacob 2025-11-07 17:10:10 -06:00
parent 54861e0935
commit 9c8f585bf4
6 changed files with 106 additions and 170 deletions

View File

@ -111,7 +111,7 @@ JobDef(PP_VisWorker, sig, job_id)
Struct(VisPersist) Struct(VisPersist)
{ {
PP_ListerWidget lister; PP_CommandsWidget commands_widget;
b32 ui_debug; b32 ui_debug;
}; };
VisPersist persist = ZI; VisPersist persist = ZI;
@ -173,36 +173,36 @@ JobDef(PP_VisWorker, sig, job_id)
{ {
b32 minimized = 1; b32 minimized = 1;
PP_BuildDebugConsoleWidget(minimized); PP_BuildConsoleWidget(minimized);
} }
////////////////////////////// //////////////////////////////
//- Build lister //- Build commands widget
PP_BeginListerWidget(&persist.lister); PP_BeginCommandsWidget(&persist.commands_widget);
{ {
if (PP_BuildListerButton(&persist.lister, Lit("Debug UI")).m1_presses > 0) if (PP_PushItemToCommandsWidget(&persist.commands_widget, Lit("Debug UI")).m1_presses > 0)
{ {
persist.ui_debug = !persist.ui_debug; persist.ui_debug = !persist.ui_debug;
} }
if (PP_BuildListerButton(&persist.lister, Lit("Fullscreen")).m1_presses > 0) if (PP_PushItemToCommandsWidget(&persist.commands_widget, Lit("Fullscreen")).m1_presses > 0)
{ {
b32 new = !window_frame.fullscreen; b32 new = !window_frame.fullscreen;
WND_PushCmd(window_frame, .kind = WND_CmdKind_SetFullscreen, .v = new); WND_PushCmd(window_frame, .kind = WND_CmdKind_SetFullscreen, .v = new);
LogInfoF("Toggled fullscreen: %F", FmtSint(new)); LogInfoF("Toggled fullscreen: %F", FmtSint(new));
} }
if (PP_BuildListerButton(&persist.lister, Lit("Topmost")).m1_presses > 0) if (PP_PushItemToCommandsWidget(&persist.commands_widget, Lit("Topmost")).m1_presses > 0)
{ {
b32 new = !window_frame.forced_top; b32 new = !window_frame.forced_top;
WND_PushCmd(window_frame, .kind = WND_CmdKind_SetForcedTop, .v = new); WND_PushCmd(window_frame, .kind = WND_CmdKind_SetForcedTop, .v = new);
LogInfoF("Toggled topmost: %F", FmtSint(new)); LogInfoF("Toggled topmost: %F", FmtSint(new));
} }
if (PP_BuildListerButton(&persist.lister, Lit("Spawn")).m1_presses > 0) if (PP_PushItemToCommandsWidget(&persist.commands_widget, Lit("Spawn")).m1_presses > 0)
{ {
LogErrorF("RAAAAH"); LogErrorF("RAAAAH");
} }
} }
PP_EndListerWidget(&persist.lister); PP_EndCommandsWidget(&persist.commands_widget);
////////////////////////////// //////////////////////////////
//- Submit sim commands //- Submit sim commands

View File

@ -23,17 +23,19 @@ void PP_PushWidgetThemeStyles(PP_WidgetTheme theme)
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Lister widgets //~ Commands widget
void PP_BeginListerWidget(PP_ListerWidget *lister) void PP_BeginCommandsWidget(PP_CommandsWidget *widget)
{ {
widget->window_cp = UI_PushCP(0);
PP_WidgetTheme theme = PP_GetWidgetTheme(); PP_WidgetTheme theme = PP_GetWidgetTheme();
Vec2 cursor_pos = UI_GetCursorPos(); Vec2 cursor_pos = UI_GetCursorPos();
lister->num_buttons = 0; widget->num_items = 0;
UI_Push(Tag, HashF("commands widget"));
UI_Push(Tag, HashF("lister")); UI_Key titlebar_key = UI_KeyF("title bar");
UI_Key titlebar_key = UI_KeyF("lister title bar");
Vec4 window_background_color = theme.window_background_color; Vec4 window_background_color = theme.window_background_color;
Vec4 window_border_color = theme.window_border_color; Vec4 window_border_color = theme.window_border_color;
@ -44,7 +46,7 @@ void PP_BeginListerWidget(PP_ListerWidget *lister)
UI_Report rep = UI_ReportFromKey(titlebar_key); UI_Report rep = UI_ReportFromKey(titlebar_key);
if (rep.m1_held) if (rep.m1_held)
{ {
lister->pos = SubVec2(cursor_pos, rep.last_m1_offset); widget->pos = SubVec2(cursor_pos, rep.last_m1_offset);
} }
window_border_color = BlendSrgb(window_border_color, Rgb(0.5, 0.5, 0.5), rep.hot); window_border_color = BlendSrgb(window_border_color, Rgb(0.5, 0.5, 0.5), rep.hot);
} }
@ -57,9 +59,9 @@ void PP_BeginListerWidget(PP_ListerWidget *lister)
UI_Push(Width, UI_PIX(theme.window_width, 0)); UI_Push(Width, UI_PIX(theme.window_width, 0));
UI_Push(Height, UI_FIT(0)); UI_Push(Height, UI_FIT(0));
UI_Push(ChildLayoutAxis, Axis_Y); UI_Push(ChildLayoutAxis, Axis_Y);
UI_Push(FloatingPos, lister->pos); UI_Push(FloatingPos, widget->pos);
UI_SetNext(Flags, UI_BoxFlag_Floating); UI_SetNext(Flags, UI_BoxFlag_Floating);
UI_PushCP(UI_BuildBox(UI_KeyF("lister"))); UI_PushCP(UI_BuildBox(UI_KeyF("titlebar")));
{ {
/* Title bar */ /* Title bar */
UI_PushCP(0); UI_PushCP(0);
@ -83,16 +85,16 @@ void PP_BeginListerWidget(PP_ListerWidget *lister)
UI_SetNext(FontSize, theme.window_title_font_size); UI_SetNext(FontSize, theme.window_title_font_size);
UI_SetNext(ChildAlignment, UI_Alignment_Center); UI_SetNext(ChildAlignment, UI_Alignment_Center);
UI_SetNext(Width, UI_FIT(1)); UI_SetNext(Width, UI_FIT(1));
UI_SetNext(Text, Lit("Lister")); UI_SetNext(Text, Lit("Commands"));
UI_SetNext(Flags, UI_BoxFlag_DrawText); UI_SetNext(Flags, UI_BoxFlag_DrawText);
UI_BuildBox(UI_NilKey); UI_BuildBox(UI_NilKey);
/* Right title box */ /* Right title box */
UI_BuildRow(UI_NilKey); UI_BuildRow(UI_NilKey);
} }
UI_PopCP(); UI_PopCP(UI_TopCP());
} }
UI_PopCP(); UI_PopCP(UI_TopCP());
} }
UI_SetNext(Tint, 0); UI_SetNext(Tint, 0);
@ -110,12 +112,12 @@ void PP_BeginListerWidget(PP_ListerWidget *lister)
} }
} }
UI_Report PP_BuildListerButton(PP_ListerWidget *lister, String text) UI_Report PP_PushItemToCommandsWidget(PP_CommandsWidget *widget, String text)
{ {
PP_WidgetTheme theme = PP_GetWidgetTheme(); PP_WidgetTheme theme = PP_GetWidgetTheme();
UI_BuildDivider(UI_PIX(1, 1), theme.divider_color); UI_BuildDivider(UI_PIX(1, 1), theme.divider_color);
UI_Key btn_key = UI_KeyF("btn%F", FmtSint(lister->num_buttons)); UI_Key btn_key = UI_KeyF("btn%F", FmtSint(widget->num_items));
UI_Report rep = UI_ReportFromKey(btn_key); UI_Report rep = UI_ReportFromKey(btn_key);
Vec4 hovered_color = Rgb32(0x103c4c); Vec4 hovered_color = Rgb32(0x103c4c);
@ -149,30 +151,29 @@ UI_Report PP_BuildListerButton(PP_ListerWidget *lister, String text)
UI_BuildSpacer(UI_PIX(20, 1)); UI_BuildSpacer(UI_PIX(20, 1));
UI_BuildLabel(text); UI_BuildLabel(text);
} }
UI_PopCP(); UI_PopCP(UI_TopCP());
} }
UI_PopCP(); UI_PopCP(UI_TopCP());
++lister->num_buttons; ++widget->num_items;
return rep; return rep;
} }
void PP_EndListerWidget(PP_ListerWidget *lister) void PP_EndCommandsWidget(PP_CommandsWidget *widget)
{ {
PP_WidgetTheme theme = PP_GetWidgetTheme(); PP_WidgetTheme theme = PP_GetWidgetTheme();
f32 padding = theme.window_border; f32 padding = theme.window_border;
UI_BuildSpacer(UI_PIX(padding, 1)); UI_BuildSpacer(UI_PIX(padding, 1));
UI_PopCP(); UI_PopCP(UI_TopCP());
UI_BuildSpacer(UI_PIX(padding, 1)); UI_BuildSpacer(UI_PIX(padding, 1));
UI_PopCP(); UI_PopCP(widget->window_cp);
UI_PopCP();
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Debug console widgets //~ Console widget
UI_Box *PP_BuildDebugConsoleWidget(b32 minimized) UI_Box *PP_BuildConsoleWidget(b32 minimized)
{ {
/* TODO: Remove this whole thing */ /* TODO: Remove this whole thing */
__prof; __prof;
@ -300,13 +301,13 @@ UI_Box *PP_BuildDebugConsoleWidget(b32 minimized)
UI_Push(Flags, UI_BoxFlag_DrawText); UI_Push(Flags, UI_BoxFlag_DrawText);
UI_BuildBox(UI_NilKey); UI_BuildBox(UI_NilKey);
} }
UI_PopCP(); UI_PopCP(UI_TopCP());
} }
} }
UI_PopCP(); UI_PopCP(UI_TopCP());
} }
} }
UI_PopCP(); UI_PopCP(UI_TopCP());
} }
EndScratch(scratch); EndScratch(scratch);

View File

@ -16,15 +16,16 @@ Struct(PP_WidgetTheme)
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Lister types //~ Commands widget types
Struct(PP_ListerWidget) Struct(PP_CommandsWidget)
{ {
/* Persistent state */ /* Persistent state */
Vec2 pos; Vec2 pos;
/* Per-build state */ /* Per-build state */
i64 num_buttons; UI_Checkpoint window_cp;
i64 num_items;
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -34,11 +35,13 @@ PP_WidgetTheme PP_GetWidgetThemeStyles(void);
void PP_PushWidgetTheme(PP_WidgetTheme theme); void PP_PushWidgetTheme(PP_WidgetTheme theme);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Lister widgets //~ Commands widget
/* FIXME */ void PP_BeginCommandsWidget(PP_CommandsWidget *widget);
UI_Report PP_PushItemToCommandsWidget(PP_CommandsWidget *widget, String text);
void PP_EndCommandsWidget(PP_CommandsWidget *widget);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Debug console widgets //~ Console widget
UI_Box *PP_BuildDebugConsoleWidget(b32 minimized); UI_Box *PP_BuildConsoleWidget(b32 minimized);

View File

@ -8,10 +8,11 @@ UI_Box *UI_BuildLabel(String text)
Vec4 tint = UI_UseTop(Tint); Vec4 tint = UI_UseTop(Tint);
UI_Box *box = 0; UI_Box *box = 0;
UI_PushEmptyStack(); UI_PushCP(0);
{ {
UI_PushDefaults();
UI_Push(Parent, parent);
UI_SetNext(Tint, tint); UI_SetNext(Tint, tint);
UI_SetNext(Parent, parent);
UI_SetNext(Font, font); UI_SetNext(Font, font);
UI_SetNext(FontSize, font_size); UI_SetNext(FontSize, font_size);
UI_SetNext(Width, UI_FIT(0)); UI_SetNext(Width, UI_FIT(0));
@ -20,7 +21,7 @@ UI_Box *UI_BuildLabel(String text)
UI_SetNext(Flags, UI_BoxFlag_DrawText); UI_SetNext(Flags, UI_BoxFlag_DrawText);
box = UI_BuildBox(UI_NilKey); box = UI_BuildBox(UI_NilKey);
} }
UI_PopStack(); UI_PopCP(UI_TopCP());
return box; return box;
} }
@ -47,15 +48,16 @@ UI_Box *UI_BuildSpacer(UI_Size size)
UI_Box *box = 0; UI_Box *box = 0;
UI_Box *parent = UI_UseTop(Parent); UI_Box *parent = UI_UseTop(Parent);
Axis axis = parent->child_layout_axis; Axis axis = parent->child_layout_axis;
UI_PushEmptyStack(); UI_PushCP(0);
{ {
UI_Push(Tint, 0); UI_PushDefaults();
UI_Push(Parent, parent); UI_Push(Parent, parent);
UI_Push(Tint, 0);
UI_Push(AxisSize, UI_FILL(1, 0), .axis = !axis); UI_Push(AxisSize, UI_FILL(1, 0), .axis = !axis);
UI_Push(AxisSize, size, .axis = axis); UI_Push(AxisSize, size, .axis = axis);
box = UI_BuildBox(UI_NilKey); box = UI_BuildBox(UI_NilKey);
} }
UI_PopStack(); UI_PopCP(UI_TopCP());
return box; return box;
} }
@ -65,8 +67,9 @@ UI_Box *UI_BuildDivider(UI_Size size, Vec4 color)
UI_Box *parent = UI_UseTop(Parent); UI_Box *parent = UI_UseTop(Parent);
Vec4 tint = UI_UseTop(Tint); Vec4 tint = UI_UseTop(Tint);
Axis axis = parent->child_layout_axis; Axis axis = parent->child_layout_axis;
UI_PushEmptyStack(); UI_PushCP(0);
{ {
UI_PushDefaults();
UI_Push(Parent, parent); UI_Push(Parent, parent);
UI_Push(Tint, tint); UI_Push(Tint, tint);
UI_Push(BackgroundColor, color); UI_Push(BackgroundColor, color);
@ -74,7 +77,7 @@ UI_Box *UI_BuildDivider(UI_Size size, Vec4 color)
UI_Push(AxisSize, size, .axis = axis); UI_Push(AxisSize, size, .axis = axis);
box = UI_BuildBox(UI_NilKey); box = UI_BuildBox(UI_NilKey);
} }
UI_PopStack(); UI_PopCP(UI_TopCP());
return box; return box;
} }

View File

@ -98,41 +98,26 @@ String UI_StringF_(String fmt, ...)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Checkpoint helpers //~ Checkpoint helpers
UI_Box *UI_PushCP(UI_Box *parent) UI_Checkpoint UI_PushCP(UI_Box *parent)
{ {
UI_SharedState *g = &UI_shared_state; UI_SharedState *g = &UI_shared_state;
UI_Stack *stack = g->top_stack; UI_Stack *stack = g->top_stack;
UI_Checkpoint *cp = g->first_free_checkpoint; stack->top_checkpoint.v += 1;
if (cp)
{
g->first_free_checkpoint = cp->next;
ZeroStruct(cp);
}
else
{
cp = PushStruct(g->build_arena, UI_Checkpoint);
}
cp->next = stack->top_checkpoint;
cp->v = stack->top_checkpoint->v + 1;
stack->top_checkpoint = cp;
if (parent != 0) if (parent != 0)
{ {
UI_Push(Parent, parent); UI_Push(Parent, parent);
} }
return parent; return stack->top_checkpoint;
} }
void UI_PopCP(void) void UI_PopCP(UI_Checkpoint cp)
{ {
UI_SharedState *g = &UI_shared_state; UI_SharedState *g = &UI_shared_state;
UI_Stack *stack = g->top_stack; UI_Stack *stack = g->top_stack;
UI_Checkpoint *cp = stack->top_checkpoint;
u64 v = cp->v;
/* Pop styles */
for (UI_StyleKind kind = UI_StyleKind_None; kind < UI_StyleKind_Count; ++kind) for (UI_StyleKind kind = UI_StyleKind_None; kind < UI_StyleKind_Count; ++kind)
{ {
UI_StyleNode *n = stack->style_tops[kind]; UI_StyleNode *n = stack->style_tops[kind];
while (n && n->checkpoint >= v) while (n && n->checkpoint.v >= cp.v)
{ {
UI_StyleNode *next = n->next; UI_StyleNode *next = n->next;
n->next = g->first_free_style_node; n->next = g->first_free_style_node;
@ -141,98 +126,44 @@ void UI_PopCP(void)
n = next; n = next;
} }
} }
stack->top_checkpoint = cp->next; stack->top_checkpoint.v = cp.v - 1;
cp->next = g->first_free_checkpoint; }
g->first_free_checkpoint = cp;
UI_Checkpoint UI_TopCP(void)
{
UI_SharedState *g = &UI_shared_state;
UI_Stack *stack = g->top_stack;
return stack->top_checkpoint;
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Style stack helpers //~ Style stack helpers
void UI_PushEmptyStack(void) void UI_PushDefaults(void)
{
UI_SharedState *g = &UI_shared_state;
UI_Stack *stack = PushStruct(g->build_arena, UI_Stack);
/* Init checkpoint */
{
UI_Checkpoint *cp = g->first_free_checkpoint;
if (cp)
{
g->first_free_checkpoint = cp->next;
ZeroStruct(cp);
}
else
{
cp = PushStruct(g->build_arena, UI_Checkpoint);
}
stack->top_checkpoint = cp;
}
/* Init styles */
{
for (UI_StyleKind kind = UI_StyleKind_None; kind < UI_StyleKind_Count; ++kind)
{
UI_StyleNode *n = g->first_free_style_node;
if (n)
{
g->first_free_style_node = n->next;
ZeroStruct(n);
}
else
{
n = PushStruct(g->build_arena, UI_StyleNode);
}
n->style.kind = kind;
stack->style_tops[kind] = n;
}
stack->style_tops[UI_StyleKind_Parent]->style.Parent = g->root_box;
stack->style_tops[UI_StyleKind_Width]->style.Width = UI_FILL(1, 0);
stack->style_tops[UI_StyleKind_Height]->style.Height = UI_FILL(1, 0);
stack->style_tops[UI_StyleKind_Font]->style.Font = UI_GetDefaultFontResource();
stack->style_tops[UI_StyleKind_FontSize]->style.FontSize = 16.0f;
stack->style_tops[UI_StyleKind_Tint]->style.Tint = Color_White;
stack->style_tops[UI_StyleKind_Tag]->style.Tag = HashFnv64(Fnv64Basis, Lit("root"));
stack->style_tops[UI_StyleKind_DebugColor]->style.DebugColor = Rgba(1, 0, 1, 0.5);
}
stack->next = g->top_stack;
g->top_stack = stack;
}
void UI_PopStack(void)
{ {
UI_SharedState *g = &UI_shared_state; UI_SharedState *g = &UI_shared_state;
UI_Stack *stack = g->top_stack; UI_Stack *stack = g->top_stack;
UI_Checkpoint checkpoint = stack->top_checkpoint;
/* Free checkpoints */
{ {
UI_Checkpoint *cp = stack->top_checkpoint; for (UI_StyleKind kind = UI_StyleKind_None; kind < UI_StyleKind_Count; ++kind)
while (cp)
{ {
UI_Checkpoint *next = cp->next; UI_StyleDesc desc = ZI;
cp->next = g->first_free_checkpoint; desc.style.kind = kind;
g->first_free_checkpoint = cp; switch (kind)
cp = next; {
default: break;
case UI_StyleKind_Parent: { desc.style.Parent = g->root_box; } break;
case UI_StyleKind_Width: { desc.style.Width = UI_FILL(1, 0); } break;
case UI_StyleKind_Height: { desc.style.Height = UI_FILL(1, 0); } break;
case UI_StyleKind_Font: { desc.style.Font = UI_GetDefaultFontResource(); } break;
case UI_StyleKind_FontSize: { desc.style.FontSize = 16.0f; } break;
case UI_StyleKind_Tint: { desc.style.Tint = Color_White; } break;
case UI_StyleKind_Tag: { desc.style.Tag = HashFnv64(Fnv64Basis, Lit("root")); } break;
case UI_StyleKind_DebugColor: { desc.style.DebugColor = Rgba(1, 0, 1, 0.5); } break;
};
UI_PushStyle(desc);
} }
} }
/* Free style nodes */
for (UI_StyleKind kind = UI_StyleKind_None; kind < UI_StyleKind_Count; ++kind)
{
UI_StyleNode *n = stack->style_tops[kind];
while (n)
{
UI_StyleNode *next = n->next;
n->next = g->first_free_style_node;
g->first_free_style_node = n;
n = next;
}
}
g->top_stack = stack->next;
stack->next = g->first_free_stack;
g->first_free_stack = stack;
} }
void UI_PushStyle(UI_StyleDesc desc) void UI_PushStyle(UI_StyleDesc desc)
@ -313,10 +244,10 @@ void UI_PushStyle(UI_StyleDesc desc)
else else
{ {
UI_StyleNode *n = stack->style_tops[kind]; UI_StyleNode *n = stack->style_tops[kind];
if (!n->override) if (!(n && n->override))
{ {
{ {
if (n->pop_when_used) if (n && n->pop_when_used)
{ {
UI_StyleNode *next = n->next; UI_StyleNode *next = n->next;
ZeroStruct(n); ZeroStruct(n);
@ -340,7 +271,7 @@ void UI_PushStyle(UI_StyleDesc desc)
n->style = desc.style; n->style = desc.style;
n->pop_when_used = desc.pop_when_used; n->pop_when_used = desc.pop_when_used;
n->override = desc.override; n->override = desc.override;
n->checkpoint = stack->top_checkpoint->v; n->checkpoint = stack->top_checkpoint;
} }
/* Initialize style data from desc */ /* Initialize style data from desc */
@ -355,7 +286,10 @@ void UI_PushStyle(UI_StyleDesc desc)
case UI_StyleKind_Tag: case UI_StyleKind_Tag:
{ {
n->style.Tag = RandU64FromSeeds(n->next->style.Tag, n->style.Tag); if (n->next != 0)
{
n->style.Tag = RandU64FromSeeds(n->next->style.Tag, n->style.Tag);
}
} break; } break;
} }
} }
@ -686,8 +620,6 @@ UI_Frame UI_BeginFrame(UI_FrameFlag frame_flags)
ResetArena(g->build_arena); ResetArena(g->build_arena);
g->boxes_count = 0; g->boxes_count = 0;
g->first_free_style_node = 0; g->first_free_style_node = 0;
g->first_free_checkpoint = 0;
g->first_free_stack = 0;
g->frame_flags = frame_flags; g->frame_flags = frame_flags;
@ -711,7 +643,8 @@ UI_Frame UI_BeginFrame(UI_FrameFlag frame_flags)
////////////////////////////// //////////////////////////////
//- Init style stack //- Init style stack
UI_PushEmptyStack(); g->top_stack = PushStruct(g->build_arena, UI_Stack);
UI_PushDefaults();
frame.cursor_pos = g->cursor_pos; frame.cursor_pos = g->cursor_pos;
return frame; return frame;

View File

@ -71,7 +71,6 @@ Enum(UI_AxisAlignment)
Struct(UI_Checkpoint) Struct(UI_Checkpoint)
{ {
UI_Checkpoint *next;
u64 v; u64 v;
}; };
@ -157,17 +156,15 @@ Struct(UI_StyleNode)
{ {
UI_StyleNode *next; UI_StyleNode *next;
UI_Style style; UI_Style style;
UI_Checkpoint checkpoint;
b32 pop_when_used; b32 pop_when_used;
b32 override; b32 override;
u64 checkpoint;
}; };
Struct(UI_Stack) Struct(UI_Stack)
{ {
UI_Stack *next;
UI_Checkpoint *top_checkpoint;
UI_StyleNode *style_tops[UI_StyleKind_Count]; UI_StyleNode *style_tops[UI_StyleKind_Count];
UI_Checkpoint top_checkpoint;
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -305,8 +302,6 @@ Struct(UI_SharedState)
u64 back_boxes_count; u64 back_boxes_count;
UI_Stack *top_stack; UI_Stack *top_stack;
UI_Stack *first_free_stack;
UI_Checkpoint *first_free_checkpoint;
UI_StyleNode *first_free_style_node; UI_StyleNode *first_free_style_node;
//- Layout state //- Layout state
@ -353,14 +348,15 @@ String UI_StringF_(String fmt, ...);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Checkpoint helpers //~ Checkpoint helpers
UI_Box *UI_PushCP(UI_Box *parent); UI_Checkpoint UI_PushCP(UI_Box *parent);
void UI_PopCP(void); void UI_PopCP(UI_Checkpoint pop_to);
UI_Checkpoint UI_TopCP(void);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Style stack helpers //~ Style stack helpers
void UI_PushEmptyStack(void); void UI_PushDefaults(void);
void UI_PopStack(void);
void UI_PushStyle(UI_StyleDesc desc); void UI_PushStyle(UI_StyleDesc desc);
UI_Style UI_PopStyle(UI_StyleDesc desc); UI_Style UI_PopStyle(UI_StyleDesc desc);
@ -369,9 +365,9 @@ UI_Style UI_PopStyle(UI_StyleDesc desc);
#define UI_SetNext(name, ...) UI_PushStyle(UI_STYLEDESC(name, .pop_when_used = 1, .style.name = __VA_ARGS__)) #define UI_SetNext(name, ...) UI_PushStyle(UI_STYLEDESC(name, .pop_when_used = 1, .style.name = __VA_ARGS__))
#define UI_Push(name, ...) UI_PushStyle(UI_STYLEDESC(name, .style.name = __VA_ARGS__)) #define UI_Push(name, ...) UI_PushStyle(UI_STYLEDESC(name, .style.name = __VA_ARGS__))
#define UI_ForceNext(name, ...) UI_PushStyle(UI_STYLEDESC(name, .pop_when_used = 1, .forced = 1, .style.name = __VA_ARGS__)) #define UI_ForceNext(name, ...) UI_PushStyle(UI_STYLEDESC(name, .pop_when_used = 1, .override = 1, .style.name = __VA_ARGS__))
#define UI_ForcePush(name, ...) UI_PushStyle(UI_STYLEDESC(name, .forced = 1, .style.name = __VA_ARGS__)) #define UI_ForcePush(name, ...) UI_PushStyle(UI_STYLEDESC(name, .override = 1, .style.name = __VA_ARGS__))
#define UI_Pop(name, ...) UI_PopStyle(UI_STYLEDESC(name, .forced_pop = 1, __VA_ARGS__)).name #define UI_Pop(name, ...) UI_PopStyle(UI_STYLEDESC(name, .force_pop = 1, __VA_ARGS__)).name
#define UI_PeekTop(name, ...) UI_PopStyle(UI_STYLEDESC(name, __VA_ARGS__)).name #define UI_PeekTop(name, ...) UI_PopStyle(UI_STYLEDESC(name, __VA_ARGS__)).name
#define UI_UseTop(name, ...) UI_PopStyle(UI_STYLEDESC(name, .use = 1, __VA_ARGS__)).name #define UI_UseTop(name, ...) UI_PopStyle(UI_STYLEDESC(name, .use = 1, __VA_ARGS__)).name