diff --git a/src/meta/meta.c b/src/meta/meta.c index b0bdaff8..2bca3dfa 100644 --- a/src/meta/meta.c +++ b/src/meta/meta.c @@ -916,7 +916,7 @@ JobDef(Build, _, __) PushStringToList(arena, &cp.compiler_only_flags_msvc, Lit("-Z7")); /* Enable warnings */ - PushStringToList(arena, &cp.warnings_msvc, Lit("-Wall")); + PushStringToList(arena, &cp.warnings_msvc, Lit("-W4")); PushStringToList(arena, &cp.warnings_msvc, Lit("-WX")); // PushStringToList(arena, &cp.warnings_msvc, Lit("-we4013")); /* function undefined; assuming extern returning int */ @@ -929,14 +929,15 @@ JobDef(Build, _, __) PushStringToList(arena, &cp.warnings_msvc, Lit("-wd4189")); /* local variable is initialized but not referenced */ PushStringToList(arena, &cp.warnings_msvc, Lit("-wd4200")); /* nonstandard extension used: zero-sized array in struct/union */ PushStringToList(arena, &cp.warnings_msvc, Lit("-wd4702")); /* unreachable code */ - PushStringToList(arena, &cp.warnings_msvc, Lit("-wd4127")); /* conditional expression is constant */ - PushStringToList(arena, &cp.warnings_msvc, Lit("-wd4305")); /* 'initializing': truncation from 'double' to 'f32' */ - PushStringToList(arena, &cp.warnings_msvc, Lit("-wd4820")); /* bytes padding added after data member */ - PushStringToList(arena, &cp.warnings_msvc, Lit("-wd4464")); /* relative include path contains '..' */ - PushStringToList(arena, &cp.warnings_msvc, Lit("-wd4061")); /* enumerator is not explicitly handled by a case label */ - PushStringToList(arena, &cp.warnings_msvc, Lit("-wd4242")); /* conversion from X to Y, possible loss of data */ - PushStringToList(arena, &cp.warnings_msvc, Lit("-wd4388")); /* signed/unsigned mismatch */ - PushStringToList(arena, &cp.warnings_msvc, Lit("-wd5045")); /* Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified */ + + // PushStringToList(arena, &cp.warnings_msvc, Lit("-wd4127")); /* conditional expression is constant */ + // PushStringToList(arena, &cp.warnings_msvc, Lit("-wd4305")); /* 'initializing': truncation from 'double' to 'f32' */ + // PushStringToList(arena, &cp.warnings_msvc, Lit("-wd4820")); /* bytes padding added after data member */ + // PushStringToList(arena, &cp.warnings_msvc, Lit("-wd4464")); /* relative include path contains '..' */ + // PushStringToList(arena, &cp.warnings_msvc, Lit("-wd4061")); /* enumerator is not explicitly handled by a case label */ + // PushStringToList(arena, &cp.warnings_msvc, Lit("-wd4242")); /* conversion from X to Y, possible loss of data */ + // PushStringToList(arena, &cp.warnings_msvc, Lit("-wd4388")); /* signed/unsigned mismatch */ + // PushStringToList(arena, &cp.warnings_msvc, Lit("-wd5045")); /* Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified */ } //- Clang diff --git a/src/pp/pp.c b/src/pp/pp.c index ecda8471..3ef02e4e 100644 --- a/src/pp/pp.c +++ b/src/pp/pp.c @@ -2001,16 +2001,17 @@ void PP_UpdateUser(void) { UI_Push(Width, UI_FILL(1, 0)); - /* Left title box */ + // /* Left title box */ UI_BuildRow(Zstr); /* Title box */ + UI_SetNext(ChildAlignment, UI_Alignment_Center); UI_SetNext(Width, UI_FIT(1)); UI_SetNext(Text, Lit("Titleeee")); UI_SetNext(Flags, UI_BoxFlag_DrawText); UI_BuildBox(Zstr); - /* Right title box */ + // /* Right title box */ UI_BuildBox(Zstr); } UI_PopCP(); diff --git a/src/pp/pp_widgets.c b/src/pp/pp_widgets.c index 2a609fed..0e3ba59a 100644 --- a/src/pp/pp_widgets.c +++ b/src/pp/pp_widgets.c @@ -116,6 +116,7 @@ UI_Box *PP_BuildDebugConsole(b32 minimized) UI_Push(BorderColor, Rgba32F(0.25, 0.25, 0.25, 1)); UI_Push(Rounding, UI_RPIX(0)); UI_Push(Border, 1); + UI_Push(ChildAlignment, UI_Alignment_Left); UI_PushCP(UI_BuildRow(Zstr)); { // UI_SetNext(Height, UI_PIX(100, 0)); @@ -123,7 +124,7 @@ UI_Box *PP_BuildDebugConsole(b32 minimized) UI_Push(BackgroundColor, 0); UI_Push(Border, 0); UI_Push(Text, text); - UI_Push(TextAlignment, UI_Alignment_Left); + // UI_Push(ChildAlignment, UI_Alignment_Left); UI_Push(Width, UI_FILL(1, 0)); UI_Push(Height, UI_FIT(1)); UI_Push(Flags, UI_BoxFlag_DrawText); diff --git a/src/ui/ui_common.c b/src/ui/ui_common.c index 9fa0ceda..e524f7ab 100644 --- a/src/ui/ui_common.c +++ b/src/ui/ui_common.c @@ -33,15 +33,14 @@ UI_Box *UI_BuildSpacer(UI_Size size) UI_Box *box = 0; UI_Box *old_parent = UI_UseTop(Parent); - UI_Size old_axis_sizes[Axis_CountXY] = { UI_UseTop(Width), UI_UseTop(Height) }; Axis axis = old_parent->child_layout_axis; UI_PushEmptyStack(); { UI_Push(Tint, 0); UI_Push(Parent, old_parent); - UI_Push(AxisSize, UI_AXSIZE(!axis, old_axis_sizes[axis])); - UI_Push(AxisSize, UI_AXSIZE(axis, size)); + UI_Push(AxisSize, UI_FILL(1, 0), .axis = !axis); + UI_Push(AxisSize, size, .axis = axis); box = UI_BuildBox(Zstr); } UI_PopStack(); @@ -53,7 +52,6 @@ UI_Box *UI_BuildDivider(UI_Size size) UI_Box *box = 0; UI_Box *old_parent = UI_UseTop(Parent); - UI_Size old_axis_sizes[Axis_CountXY] = { UI_UseTop(Width), UI_UseTop(Height) }; u32 old_tint = UI_UseTop(Tint); f32 old_border = UI_UseTop(Border); u32 old_border_color = UI_UseTop(BorderColor); @@ -64,8 +62,8 @@ UI_Box *UI_BuildDivider(UI_Size size) UI_Push(Parent, old_parent); UI_Push(Tint, old_tint); UI_Push(BackgroundColor, old_border_color); - UI_Push(AxisSize, UI_AXSIZE(!axis, old_axis_sizes[axis])); - UI_Push(AxisSize, UI_AXSIZE(axis, size)); + UI_Push(AxisSize, UI_FILL(1, 0), .axis = !axis); + UI_Push(AxisSize, size, .axis = axis); box = UI_BuildBox(Zstr); } UI_PopStack(); diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index f1d50318..721ae42e 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -200,37 +200,88 @@ void UI_PopStack(void) g->first_free_stack = stack; } -void UI_PushStyle(UI_Style desc) +void UI_PushStyle(UI_StyleDesc desc) { UI_SharedState *g = &UI_shared_state; UI_Stack *stack = g->top_stack; - - if (desc.kind >= UI_StyleKind_BeginVirtualStyles_) + UI_StyleKind kind = desc.style.kind; + if (kind >= UI_StyleKind_BeginVirtualStyles_) { - switch(desc.kind) + switch(kind) { default: break; case UI_StyleKind_AxisSize: { - if (desc.AxisSize.axis == Axis_X) + if (desc.axis == Axis_X) { - UI_PushCopy(Width, desc, desc.AxisSize.size); + UI_PushCopy(Width, desc, desc.style.AxisSize); } else { - UI_PushCopy(Height, desc, desc.AxisSize.size); + UI_PushCopy(Height, desc, desc.style.AxisSize); + } + } break; + + case UI_StyleKind_ChildAlignment: + { + UI_Alignment alignment = desc.style.ChildAlignment; + /* Alignment -> horizontal alignment */ + switch(alignment) + { + default: break; + case UI_Alignment_TopLeft: + case UI_Alignment_Left: + case UI_Alignment_BottomLeft: + { + UI_PushCopy(ChildAlignmentX, desc, UI_AxisAlignment_Start); + } break; + case UI_Alignment_Top: + case UI_Alignment_Center: + case UI_Alignment_Bottom: + { + UI_PushCopy(ChildAlignmentX, desc, UI_AxisAlignment_Center); + } break; + case UI_Alignment_TopRight: + case UI_Alignment_Right: + case UI_Alignment_BottomRight: + { + UI_PushCopy(ChildAlignmentX, desc, UI_AxisAlignment_End); + } break; + } + /* Alignment -> vertical alignment */ + switch(alignment) + { + default: break; + case UI_Alignment_TopLeft: + case UI_Alignment_Top: + case UI_Alignment_TopRight: + { + UI_PushCopy(ChildAlignmentY, desc, UI_AxisAlignment_Start); + } break; + case UI_Alignment_Left: + case UI_Alignment_Center: + case UI_Alignment_Right: + { + UI_PushCopy(ChildAlignmentY, desc, UI_AxisAlignment_Center); + } break; + case UI_Alignment_BottomLeft: + case UI_Alignment_Bottom: + case UI_Alignment_BottomRight: + { + UI_PushCopy(ChildAlignmentY, desc, UI_AxisAlignment_End); + } break; } } break; } } else { - UI_StyleNode *n = stack->style_tops[desc.kind]; - if (!n->style.forced) + UI_StyleNode *n = stack->style_tops[kind]; + if (!n->override) { { - if (n->style.pop_when_used) + if (n->pop_when_used) { UI_StyleNode *next = n->next; ZeroStruct(n); @@ -248,29 +299,31 @@ void UI_PushStyle(UI_Style desc) { n = PushStruct(g->build_arena, UI_StyleNode); } - n->next = stack->style_tops[desc.kind]; - stack->style_tops[desc.kind] = n; + n->next = stack->style_tops[kind]; + stack->style_tops[kind] = n; } - n->style = desc; + n->style = desc.style; + n->pop_when_used = desc.pop_when_used; + n->override = desc.override; n->checkpoint = stack->top_checkpoint->v; } /* Initialize style data from desc */ - switch (desc.kind) + switch (kind) { default: break; case UI_StyleKind_Text: { - n->style.Text = PushString(g->build_arena, desc.Text); + n->style.Text = PushString(g->build_arena, desc.style.Text); } break; case UI_StyleKind_Tag: { - n->style.Tag.name = PushString(g->build_arena, desc.Tag.name); + n->style.Tag.name = PushString(g->build_arena, desc.style.Tag.name); if (n->style.Tag.hash == 0) { - n->style.Tag.hash = HashFnv64(stack->style_tops[desc.kind]->style.Tag.hash, n->style.Tag.name); + n->style.Tag.hash = HashFnv64(stack->style_tops[kind]->style.Tag.hash, n->style.Tag.name); } } break; } @@ -278,33 +331,39 @@ void UI_PushStyle(UI_Style desc) } } -UI_Style UI_PopStyle(UI_StyleKind kind) -{ - UI_SharedState *g = &UI_shared_state; - UI_Stack *stack = g->top_stack; - UI_StyleNode *n = stack->style_tops[kind]; - UI_Style style = n->style; - stack->style_tops[kind] = n->next; - n->next = g->first_free_style_node; - g->first_free_style_node = n; - return style; -} - -UI_Style UI_FetchStyle(UI_StyleKind kind, b32 use) +UI_Style UI_PopStyle(UI_StyleDesc desc) { UI_SharedState *g = &UI_shared_state; UI_Stack *stack = g->top_stack; UI_Style result = ZI; + UI_StyleKind kind = desc.style.kind; result.kind = kind; if (kind >= UI_StyleKind_BeginVirtualStyles_) { - /* Do nothing */ + switch(kind) + { + default: break; + + case UI_StyleKind_AxisSize: + { + if (desc.axis == Axis_X) + { + desc.style.kind = UI_StyleKind_Width; + result = UI_PopStyle(desc); + } + else + { + desc.style.kind = UI_StyleKind_Height; + result = UI_PopStyle(desc); + } + }; + } } else { UI_StyleNode *n = stack->style_tops[kind]; result = n->style; - if (use && n->style.pop_when_used) + if (desc.use && n->pop_when_used) { stack->style_tops[kind] = n->next; n->next = g->first_free_style_node; @@ -371,21 +430,22 @@ UI_Box *UI_BuildBox(String seed) } /* Pull from style stack */ - box->flags = UI_UseTop(Flags); - box->pref_size[Axis_X] = UI_UseTop(Width); - box->pref_size[Axis_Y] = UI_UseTop(Height); - box->child_layout_axis = UI_UseTop(ChildLayoutAxis); - box->text_alignment = UI_UseTop(TextAlignment); - box->background_color = UI_UseTop(BackgroundColor); - box->border_color = UI_UseTop(BorderColor); - box->debug_color = UI_UseTop(DebugColor); - box->tint = UI_UseTop(Tint); - box->border = UI_UseTop(Border); - box->font_resource = UI_UseTop(Font); - box->font_size = UI_UseTop(FontSize); - box->rounding = UI_UseTop(Rounding); - box->text = UI_UseTop(Text); - box->floating_pos = UI_UseTop(FloatingPos); + box->flags = UI_UseTop(Flags); + box->pref_size[Axis_X] = UI_UseTop(Width); + box->pref_size[Axis_Y] = UI_UseTop(Height); + box->child_alignment[Axis_X] = UI_UseTop(ChildAlignmentX); + box->child_alignment[Axis_Y] = UI_UseTop(ChildAlignmentY); + box->child_layout_axis = UI_UseTop(ChildLayoutAxis); + box->background_color = UI_UseTop(BackgroundColor); + box->border_color = UI_UseTop(BorderColor); + box->debug_color = UI_UseTop(DebugColor); + box->tint = UI_UseTop(Tint); + box->border = UI_UseTop(Border); + box->font_resource = UI_UseTop(Font); + box->font_size = UI_UseTop(FontSize); + box->rounding = UI_UseTop(Rounding); + box->text = UI_UseTop(Text); + box->floating_pos = UI_UseTop(FloatingPos); /* Prefetch font */ if (box->text.len > 0) @@ -840,6 +900,7 @@ i64 UI_EndFrame(UI_Frame frame) f32 violation = size_accum - box_size; if (violation > 0 && flex_accum > 0) { + f32 adjusted_size_accum = 0; for (UI_Box *child = box->first; child; child = child->next) { if (!AnyBit(child->flags, UI_BoxFlag_Floating)) @@ -860,9 +921,28 @@ i64 UI_EndFrame(UI_Frame frame) new_size = MaxF32(size - flex, box_size); } } + adjusted_size_accum += new_size; child->solved_dims[axis] = new_size; } } + size_accum = adjusted_size_accum; + } + /* Initialize layout cursor based on alignment */ + if (axis == box->child_layout_axis) + { + UI_AxisAlignment alignment = box->child_alignment[axis]; + switch(alignment) + { + default: break; + case UI_AxisAlignment_Center: + { + box->layout_cursor = box_size / 2 - size_accum / 2; + } break; + case UI_AxisAlignment_End: + { + box->layout_cursor = box_size - size_accum; + } break; + } } } /* Solve floating violations */ @@ -890,7 +970,8 @@ i64 UI_EndFrame(UI_Frame frame) /* Position */ { - Vec2 dims = VEC2(box->solved_dims[0], box->solved_dims[1]); + f32 *dims_arr = box->solved_dims; + Vec2 dims_vec = VEC2(dims_arr[0], dims_arr[1]); Vec2 final_pos = ZI; /* Floating box position */ @@ -901,11 +982,11 @@ i64 UI_EndFrame(UI_Frame frame) if (!AnyBit(box->flags, UI_BoxFlag_NoFloatingClamp)) { { - f32 overshoot = MaxF32(0, (final_pos.x + dims.x) - parent->p1.x); + f32 overshoot = MaxF32(0, (final_pos.x + dims_vec.x) - parent->p1.x); final_pos.x = MaxF32(parent->p0.x, final_pos.x - overshoot); } { - f32 overshoot = MaxF32((final_pos.y + dims.y) - parent->p1.y, 0); + f32 overshoot = MaxF32((final_pos.y + dims_vec.y) - parent->p1.y, 0); final_pos.y = MaxF32(parent->p0.y, final_pos.y - overshoot); } } @@ -913,16 +994,42 @@ i64 UI_EndFrame(UI_Frame frame) /* Non-floating box position */ else if (parent) { - b32 is_layout_x = parent->child_layout_axis == Axis_X; f32 layout_cursor = parent->layout_cursor; - Vec2 offset = VEC2(layout_cursor * is_layout_x, layout_cursor * !is_layout_x); - parent->layout_cursor += dims.x * is_layout_x + dims.y * !is_layout_x; - final_pos = AddVec2(parent->p0, offset); + f32 offset[2] = ZI; + /* Calculate offset in layout direction */ + { + Axis axis = parent->child_layout_axis; + offset[axis] = layout_cursor; + } + /* Calculate offset in non-layout direction (based on alignment) */ + { + Axis axis = !parent->child_layout_axis; + UI_AxisAlignment alignment = parent->child_alignment[axis]; + switch(alignment) + { + default: break; + case UI_AxisAlignment_Center: + { + f32 parent_size = parent->solved_dims[axis]; + f32 box_size = dims_arr[axis]; + offset[axis] = parent_size / 2 - box_size / 2; + } break; + case UI_AxisAlignment_End: + { + f32 parent_size = parent->solved_dims[axis]; + f32 box_size = dims_arr[axis]; + offset[axis] = parent_size - box_size; + } break; + } + } + final_pos.x = parent->p0.x + offset[0]; + final_pos.y = parent->p0.y + offset[1]; + parent->layout_cursor += dims_arr[parent->child_layout_axis]; } /* Submit position */ box->p0 = RoundVec2(final_pos); - box->p1 = RoundVec2(AddVec2(final_pos, dims)); + box->p1 = RoundVec2(AddVec2(final_pos, dims_vec)); box->report.screen_p0 = box->p0; box->report.screen_p1 = box->p1; } @@ -1076,10 +1183,11 @@ i64 UI_EndFrame(UI_Frame frame) run.rects = new_rects; } - UI_Alignment alignment = box->text_alignment; + UI_AxisAlignment x_alignment = box->child_alignment[Axis_X]; + UI_AxisAlignment y_alignment = box->child_alignment[Axis_Y]; if (should_truncate) { - alignment = UI_Alignment_Left; + x_alignment = UI_AxisAlignment_Start; } /* Calculate baseline */ @@ -1090,26 +1198,42 @@ i64 UI_EndFrame(UI_Frame frame) f32 box_width = box->p1.x - box->p0.x; f32 box_height = box->p1.y - box->p0.y; Vec2 baseline = ZI; - switch (alignment) + switch (x_alignment) { - case UI_Alignment_Left: + case UI_AxisAlignment_Start: { baseline.x = box->p0.x; } break; - case UI_Alignment_Right: + case UI_AxisAlignment_End: { baseline.x = box->p1.x; baseline.x -= baseline_width; } break; - case UI_Alignment_Center: + case UI_AxisAlignment_Center: { baseline.x = box->p0.x; baseline.x += (box_width - baseline_width) / 2; } break; } - baseline.y = box->p0.y; - baseline.y += box_height / 2; - baseline.y += baseline_height / 4; + switch (y_alignment) + { + case UI_AxisAlignment_Start: + { + baseline.y = box->p0.y; + baseline.y += ascent; + } break; + case UI_AxisAlignment_End: + { + baseline.y = box->p1.y; + baseline.y -= descent; + } break; + case UI_AxisAlignment_Center: + { + baseline.y = box->p0.y; + baseline.y += box_height / 2; + baseline.y += baseline_height / 4; + } break; + } baseline = RoundVec2(baseline); diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index f6489df7..ced12891 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -46,9 +46,24 @@ Struct(UI_Round) Enum(UI_Alignment) { - UI_Alignment_Center, + UI_Alignment_TopLeft, + UI_Alignment_Top, + UI_Alignment_TopRight, + UI_Alignment_Left, + UI_Alignment_Center, UI_Alignment_Right, + + UI_Alignment_BottomLeft, + UI_Alignment_Bottom, + UI_Alignment_BottomRight, +}; + +Enum(UI_AxisAlignment) +{ + UI_AxisAlignment_Start, + UI_AxisAlignment_Center, + UI_AxisAlignment_End, }; //////////////////////////////////////////////////////////// @@ -80,12 +95,13 @@ Enum(UI_BoxFlag) x(Parent, struct UI_Box *) \ x(Tag, UI_Tag) \ x(ChildLayoutAxis, Axis) \ + x(ChildAlignmentX, UI_AxisAlignment) \ + x(ChildAlignmentY, UI_AxisAlignment) \ x(Width, UI_Size) \ x(Height, UI_Size) \ - x(Size, UI_Size) \ x(BackgroundColor, u32) \ x(BorderColor, u32) \ - x(DebugColor, u32) \ + x(DebugColor, u32) \ x(Tint, u32) \ x(Border, f32) \ x(FloatingPos, Vec2) \ @@ -93,12 +109,12 @@ Enum(UI_BoxFlag) x(Font, ResourceKey) \ x(FontSize, u32) \ x(Text, String) \ - x(TextAlignment, UI_Alignment) \ /* ----------------------------------- */ \ /* --------- Virtual styles --------- */ \ /* ----------------------------------- */ \ x(BeginVirtualStyles_, i8) \ - x(AxisSize, UI_AxisSize) \ + x(ChildAlignment, UI_Alignment) \ + x(AxisSize, UI_Size) \ /* ------------------------------------------- */ Struct(UI_Tag) @@ -107,12 +123,6 @@ Struct(UI_Tag) u64 hash; }; -Struct(UI_AxisSize) -{ - Axis axis; - UI_Size size; -}; - Enum(UI_StyleKind) { #define X(name, type) UI_StyleKind_##name, @@ -125,8 +135,6 @@ Enum(UI_StyleKind) Struct(UI_Style) { UI_StyleKind kind; - b32 pop_when_used; - b32 forced; /* Union of all style fields */ union { @@ -136,11 +144,27 @@ Struct(UI_Style) }; }; +Struct(UI_StyleDesc) +{ + Axis axis; + UI_Style style; + + /* Push */ + b32 pop_when_used; + b32 override; + + /* Pop */ + b32 force_pop; + b32 use; +}; + Struct(UI_StyleNode) { UI_StyleNode *next; - u64 checkpoint; UI_Style style; + b32 pop_when_used; + b32 override; + u64 checkpoint; }; Struct(UI_Stack) @@ -208,10 +232,10 @@ Struct(UI_Box) f32 border; Vec2 floating_pos; String text; - UI_Alignment text_alignment; ResourceKey font_resource; f32 font_size; Axis child_layout_axis; + UI_AxisAlignment child_alignment[Axis_CountXY]; //- Pre-layout data u64 pre_index; @@ -326,31 +350,30 @@ void UI_PopCP(void); void UI_PushEmptyStack(void); void UI_PopStack(void); -void UI_PushStyle(UI_Style desc); -UI_Style UI_PopStyle(UI_StyleKind kind); -UI_Style UI_FetchStyle(UI_StyleKind kind, b32 use); +void UI_PushStyle(UI_StyleDesc desc); +UI_Style UI_PopStyle(UI_StyleDesc desc); -#define UI_SetNext(name, ...) UI_PushStyle((UI_Style) { .kind = UI_StyleKind_##name, .name = __VA_ARGS__, .pop_when_used = 1 }) -#define UI_Push(name, ...) UI_PushStyle((UI_Style) { .kind = UI_StyleKind_##name, .name = __VA_ARGS__ }) -#define UI_ForceNext(name, ...) UI_PushStyle((UI_Style) { .kind = UI_StyleKind_##name, .name = __VA_ARGS__, .pop_when_used = 1, .forced = 1 }) -#define UI_ForcePush(name, ...) UI_PushStyle((UI_Style) { .kind = UI_StyleKind_##name, .name = __VA_ARGS__, .forced = 1 }) -#define UI_Pop(name) UI_PopStyle(UI_StyleKind_##name).name -#define UI_FetchTop(name, use) UI_FetchStyle(UI_StyleKind_##name, use).name -#define UI_PeekTop(name) UI_FetchTop(name, 0) -#define UI_UseTop(name) UI_FetchTop(name, 1) +#define UI_STYLEDESC(name, ...) (UI_StyleDesc) { .style.kind = UI_StyleKind_##name, __VA_ARGS__ } -#define UI_PushCopy(name, src, ...) do { \ - UI_Style _new = src; \ - _new.kind = UI_StyleKind_##name; \ - _new.name = __VA_ARGS__; \ - UI_PushStyle(_new); \ +#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_ForceNext(name, ...) UI_PushStyle(UI_STYLEDESC(name, .pop_when_used = 1, .forced = 1, .style.name = __VA_ARGS__)) +#define UI_ForcePush(name, ...) UI_PushStyle(UI_STYLEDESC(name, .forced = 1, .style.name = __VA_ARGS__)) +#define UI_Pop(name, ...) UI_PopStyle(UI_STYLEDESC(name, .forced_pop = 1, __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_PushCopy(name, src, ...) do { \ + UI_StyleDesc _new = src; \ + _new.style.kind = UI_StyleKind_##name; \ + _new.style.name = __VA_ARGS__; \ + UI_PushStyle(_new); \ } while (0) //////////////////////////////////////////////////////////// //~ Size helpers #define UI_SIZE(_kind, _v, _s) (UI_Size) { .kind = (_kind), .v = (_v), .strictness = (_s) } -#define UI_AXSIZE(_axis, _size) (UI_AxisSize) { .axis = (_axis), .size = (_size) } #define UI_PIX(_v, _s) UI_SIZE(UI_SizeKind_Pixel, (_v), (_s)) #define UI_FIT(_s) UI_SIZE(UI_SizeKind_Fit, 0, (_s))