From 296472a5881968ba1a4c901bd64575c3ac89add9 Mon Sep 17 00:00:00 2001 From: PS Date: Sun, 15 Nov 2020 14:48:04 -0800 Subject: [PATCH] Implemented variable sized row specifications --- src/app/editor/foldhaus_editor.cpp | 98 +++- .../foldhaus_panel_animation_timeline.h | 4 +- .../editor/panels/foldhaus_panel_hierarchy.h | 1 - .../editor/panels/foldhaus_panel_profiler.h | 17 +- src/app/foldhaus_app.cpp | 2 +- src/app/interface.h | 463 ++++++++++++------ 6 files changed, 410 insertions(+), 175 deletions(-) diff --git a/src/app/editor/foldhaus_editor.cpp b/src/app/editor/foldhaus_editor.cpp index 39460fd..6fda7e6 100644 --- a/src/app/editor/foldhaus_editor.cpp +++ b/src/app/editor/foldhaus_editor.cpp @@ -200,39 +200,86 @@ TestRender(app_state* State, context* Context, render_command_buffer* RenderBuff { ui_InterfaceReset(&State->Interface); State->Interface.RenderBuffer = RenderBuffer; + State->Interface.WindowBounds = Context->WindowBounds; - ui_PushLayout(&State->Interface, Context->WindowBounds, LayoutDirection_TopDown, MakeString("TestRender Layout")); + gs_string A = MakeString("TestRender Layout"); - ui_widget_id Ids[2]; - - gs_string String = MakeString("Select"); - ui_StartRow(&State->Interface, 2); - for (u32 j = 0; j < 2; j++) + ui_PushLayout(&State->Interface, A); { - if (ui_BeginDropdown(&State->Interface, String)) +#if 1 + ui_column_spec ColumnRules[] = { + { UIColumnSize_Fixed, 128 }, + { UIColumnSize_Fill, 0 }, + { UIColumnSize_Percent, .5f } + }; + ui_BeginRow(&State->Interface, 3, ColumnRules); + { - for (u32 i = 0; i < State->PanelSystem.PanelDefsCount; i++) + ui_Button(&State->Interface, MakeString("B")); + ui_Button(&State->Interface, MakeString("B")); + ui_Button(&State->Interface, MakeString("B")); + } + ui_EndRow(&State->Interface); + ui_Button(&State->Interface, MakeString("B")); + ui_Button(&State->Interface, MakeString("C")); +#elif 0 + ui_PushLayout(&State->Interface, MakeString("Outer")); + { + for (u32 i = 0; i < 3; i++) { - panel_definition Def = State->PanelSystem.PanelDefs[i]; - gs_string DefName = MakeString(Def.PanelName, Def.PanelNameLength); - if (ui_Button(&State->Interface, DefName)) - { - - } + ui_Button(&State->Interface, MakeString("A")); } } - ui_EndDropdown(&State->Interface); + ui_PopLayout(&State->Interface); + + ui_BeginRow(&State->Interface, 2); + { + ui_PushLayout(&State->Interface, MakeString("TestLayout")); + { + for (u32 i = 0; i < 5; i++) + { + ui_Button(&State->Interface, MakeString("TestButon")); + } + } + ui_PopLayout(&State->Interface); + + ui_PushLayout(&State->Interface, MakeString("TestLayout")); + { + ui_Button(&State->Interface, MakeString("TestButon")); + TestToggle = ui_Toggle(&State->Interface, MakeString("Toggle"), TestToggle); + TestSlider_Value = ui_RangeSlider(&State->Interface, MakeString("TestSlider"), TestSlider_Value, TestSlider_Min, TestSlider_Max); + if (ui_BeginDropdown(&State->Interface, MakeString("TestDropdown"))) + { + ui_Button(&State->Interface, MakeString("TestButon")); + ui_Button(&State->Interface, MakeString("TestButon")); + ui_Button(&State->Interface, MakeString("TestButon")); + } + ui_EndDropdown(&State->Interface); + } + ui_PopLayout(&State->Interface); + } + ui_EndRow(&State->Interface); + + ui_PushLayout(&State->Interface, MakeString("Outer")); + { + for (u32 i = 0; i < 3; i++) + { + ui_Button(&State->Interface, MakeString("B")); + } + } + ui_PopLayout(&State->Interface); +#else + ui_BeginList(&State->Interface, MakeString("Test List"), 10); + { + for (u32 i = 0; i < 32; i++) + { + ui_Button(&State->Interface, MakeString("Option")); + } + } + ui_EndList(&State->Interface); +#endif } - ui_EndRow(&State->Interface); - TestSlider_Value = ui_RangeSlider(&State->Interface, MakeString("Test Slider"), TestSlider_Value, TestSlider_Min, TestSlider_Max); - - TestToggle = ui_Toggle(&State->Interface, MakeString("test toggle"), TestToggle); - - ui_Button(&State->Interface, MakeString("Hello")); - ui_PopLayout(&State->Interface); - - Assert(!ui_WidgetIdsEqual(Ids[0], Ids[1])); } internal void @@ -243,9 +290,6 @@ Editor_Render(app_state* State, context* Context, render_command_buffer* RenderB #if 0 TestRender(State, Context, RenderBuffer); - //ui_widget_id IdTwo = TestRender(State, Context, RenderBuffer); - //Assert(ui_WidgetIdsEqual(IdOne, IdTwo)); - #else ui_InterfaceReset(&State->Interface); State->Interface.RenderBuffer = RenderBuffer; diff --git a/src/app/editor/panels/foldhaus_panel_animation_timeline.h b/src/app/editor/panels/foldhaus_panel_animation_timeline.h index e9ec1c8..d66b36a 100644 --- a/src/app/editor/panels/foldhaus_panel_animation_timeline.h +++ b/src/app/editor/panels/foldhaus_panel_animation_timeline.h @@ -608,7 +608,7 @@ PlayBar_Render(animation_timeline_state* TimelineState, rect2 Bounds, panel* Pan ui_PushLayout(Interface, Bounds, LayoutDirection_TopDown, MakeString("PlayBar Layout")); ui_FillRect(Interface, Bounds, Interface->Style.PanelBGColors[0]); - ui_StartRow(&State->Interface, 4); + ui_BeginRow(&State->Interface, 4); { if (ui_Button(Interface, MakeString("Pause"))) { @@ -796,7 +796,7 @@ AnimInfoView_Render(animation_timeline_state* TimelineState, rect2 Bounds, rende ui_FillRect(&State->Interface, Bounds, Interface->Style.PanelBGColors[0]); - ui_StartRow(&State->Interface, 2); + ui_BeginRow(&State->Interface, 2); { ui_Label(Interface, MakeString("Active Animation")); if (ui_BeginDropdown(Interface, ActiveAnim->Name)) diff --git a/src/app/editor/panels/foldhaus_panel_hierarchy.h b/src/app/editor/panels/foldhaus_panel_hierarchy.h index 12c9fc2..ec6ca55 100644 --- a/src/app/editor/panels/foldhaus_panel_hierarchy.h +++ b/src/app/editor/panels/foldhaus_panel_hierarchy.h @@ -52,7 +52,6 @@ HierarchyView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* Ren // Fill in alternating color rows for the backgrounds for (u32 Line = 0; Line < LineCount; Line++) { - //LineBounds[Line] = ui_ReserveElementBounds(Layout); v4 ListItemBGColor = ui_GetListItemBGColor(State->Interface.Style, Line); ui_FillRect(&State->Interface, LineBounds[Line], ListItemBGColor); } diff --git a/src/app/editor/panels/foldhaus_panel_profiler.h b/src/app/editor/panels/foldhaus_panel_profiler.h index 80b7890..f6d1ce8 100644 --- a/src/app/editor/panels/foldhaus_panel_profiler.h +++ b/src/app/editor/panels/foldhaus_panel_profiler.h @@ -94,8 +94,13 @@ RenderProfiler_ListVisualization(ui_interface* Interface, ui_widget* Layout, deb char Backbuffer[256]; gs_string String = MakeString(Backbuffer, 0, 256); - r32 ColumnWidths[] = {256, 128, 128, 128, 128}; - ui_StartRow(Interface, 5, &ColumnWidths[0]); + ui_column_spec ColumnWidths[] = { + { UIColumnSize_Fixed, 256 }, + { UIColumnSize_Fixed, 128 }, + { UIColumnSize_Fixed, 128 }, + { UIColumnSize_Fixed, 128 }, + { UIColumnSize_Fixed, 128 }}; + ui_BeginRow(Interface, 5, &ColumnWidths[0]); { ui_Label(Interface, MakeString("Procedure")); ui_Label(Interface, MakeString("% Frame")); @@ -112,7 +117,7 @@ RenderProfiler_ListVisualization(ui_interface* Interface, ui_widget* Layout, deb { collated_scope_record* CollatedRecord = VisibleFrame->CollatedScopes + n; - ui_StartRow(Interface, 5, &ColumnWidths[0]); + ui_BeginRow(Interface, 5, &ColumnWidths[0]); { PrintF(&String, "%S", NameEntry.Name); ui_Label(Interface, String); @@ -181,7 +186,7 @@ ProfilerView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* Rend ui_widget* Layout = ui_PushLayout(&State->Interface, ProcListBounds, LayoutDirection_TopDown, MakeString("Profiler Layout")); - ui_StartRow(&State->Interface, 4); + ui_BeginRow(&State->Interface, 4); { s64 FrameStartCycles = VisibleFrame->FrameStartCycles; s64 FrameTotalCycles = VisibleFrame->FrameEndCycles - VisibleFrame->FrameStartCycles; @@ -194,7 +199,7 @@ ProfilerView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* Rend // NOTE(NAME): Skipping a space for aesthetic reasons, not functional, and could // be removed, or used for something else - ui_ReserveElementBounds(Layout); + ui_ReserveBounds(Layout, true); if (ui_Button(&State->Interface, MakeString("Resume Recording"))) { @@ -203,7 +208,7 @@ ProfilerView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* Rend } ui_EndRow(&State->Interface); - ui_StartRow(&State->Interface, 8); + ui_BeginRow(&State->Interface, 8); { if (ui_Button(&State->Interface, MakeString("Scope View"))) { diff --git a/src/app/foldhaus_app.cpp b/src/app/foldhaus_app.cpp index 90ce10b..c56bcaf 100644 --- a/src/app/foldhaus_app.cpp +++ b/src/app/foldhaus_app.cpp @@ -106,7 +106,7 @@ INITIALIZE_APPLICATION(InitializeApplication) State->Interface.Style.ListBGHover = v4{ .22f, .22f, .22f, 1.f }; State->Interface.Style.ListBGSelected = v4{.44f, .44f, .44f, 1.f }; State->Interface.Style.Margin = v2{5, 5}; - State->Interface.Style.RowHeight = ui_GetTextLineHeight(State->Interface); + State->Interface.Style.RowHeight = ui_GetTextLineHeight(State->Interface) + (2 * State->Interface.Style.Margin.y); State->Interface.WidgetsCountMax = 4096; State->Interface.Widgets = PushArray(&State->Permanent, ui_widget, State->Interface.WidgetsCountMax); diff --git a/src/app/interface.h b/src/app/interface.h index c2c0b22..cc20c18 100644 --- a/src/app/interface.h +++ b/src/app/interface.h @@ -199,6 +199,13 @@ enum ui_layout_direction { LayoutDirection_TopDown, LayoutDirection_BottomUp, + LayoutDirection_Inherit, +}; + +struct ui_column +{ + r32 XMin; + r32 XMax; }; struct ui_widget @@ -225,10 +232,9 @@ struct ui_widget ui_layout_direction FillDirection; - b32 DrawHorizontal; - u32 ColumnsMax; - r32* ColumnWidths; + ui_column* Columns; u32 ColumnsCount; + u32 ColumnsFilled; // NOTE(pjs): I'm not sure this will stay but // its here so that when we end things like a dropdown, @@ -278,7 +284,10 @@ struct ui_widget_retained_state struct ui_interface { interface_config Style; + mouse_state Mouse; + rect2 WindowBounds; + render_command_buffer* RenderBuffer; ui_widget* Widgets; @@ -325,6 +334,28 @@ ui_WidgetIdsEqual(ui_widget_id A, ui_widget_id B) return Result; } +internal void +ui_WidgetSetFlag(ui_widget* Widget, u64 Flag) +{ + u64 Value = ((u64)1 << Flag); + Widget->Flags = Widget->Flags | Value; +} + +internal void +ui_WidgetClearFlag(ui_widget* Widget, u64 Flag) +{ + u64 Value = ((u64)1 << Flag); + Widget->Flags = Widget->Flags & ~Value; +} + +internal bool +ui_WidgetIsFlagSet(ui_widget Widget, u64 Flag) +{ + u64 Value = ((u64)1 << Flag); + bool Result = (Widget.Flags & Value); + return Result; +} + internal ui_widget_retained_state* ui_GetRetainedState(ui_interface* Interface, ui_widget_id Id) { @@ -374,21 +405,7 @@ ui_CreateWidget(ui_interface* Interface, gs_string String) Result->ChildrenRoot = 0; Result->ChildrenHead = 0; Result->Flags = 0; - return Result; -} - -internal void -ui_WidgetSetFlag(ui_widget* Widget, u64 Flag) -{ - u64 Value = ((u64)1 << Flag); - Widget->Flags = Widget->Flags | Value; -} - -internal bool -ui_WidgetIsFlagSet(ui_widget Widget, u64 Flag) -{ - u64 Value = ((u64)1 << Flag); - bool Result = (Widget.Flags & Value); + return Result; } @@ -406,37 +423,146 @@ ui_MouseClickedRect(ui_interface Interface, rect2 Rect) // Layout +static rect2 +ui_ReserveBounds(ui_widget* Widget, bool Inset) +{ + Assert(Widget->ColumnsCount > 0); + rect2 Bounds = {0}; + u32 ColumnIndex = Widget->ChildCount % Widget->ColumnsCount; + + ui_column Column = Widget->Columns[ColumnIndex]; + Bounds.Min.x = Column.XMin; + Bounds.Min.y = Widget->RowYAt; + Bounds.Max.x = Column.XMax; + Bounds.Max.y = Bounds.Min.y + Widget->RowHeight; + + if (Inset) + { + Bounds.Min.x += Widget->Margin.x; + Bounds.Min.y += Widget->Margin.y; + Bounds.Max.x -= Widget->Margin.x; + Bounds.Max.y -= Widget->Margin.y; + } + + return Bounds; +} + +internal void +ui_CommitBounds(ui_widget* Parent, rect2 Bounds) +{ + u32 ColumnIndex = Parent->ChildCount % Parent->ColumnsCount; + if (ColumnIndex == 0) + { + switch (Parent->FillDirection) + { + case LayoutDirection_BottomUp: + { + Parent->RowYAt = Bounds.Max.y; + }break; + + case LayoutDirection_TopDown: + { + Parent->RowYAt = Bounds.Min.y - Parent->RowHeight; + }break; + } + } +} + +internal void +ui_ExpandParentToFit(ui_widget* Widget) +{ + ui_widget* Parent = Widget->Parent; + switch (Widget->FillDirection) + { + case LayoutDirection_TopDown: + { + Parent->Bounds.Min.y = Min(Parent->Bounds.Min.y, Widget->Bounds.Min.y - Parent->Margin.y); + }break; + + case LayoutDirection_BottomUp: + { + Parent->Bounds.Max.y = Max(Parent->Bounds.Max.y, Widget->Bounds.Max.y + Parent->Margin.y); + }break; + + InvalidDefaultCase; + } +} + +internal void +ui_WidgetCreateColumns(ui_widget* Widget, u32 ColumnsCount, ui_interface* Interface) +{ + Widget->Columns = PushArray(Interface->PerFrameMemory, ui_column, ColumnsCount); + Widget->ColumnsCount = ColumnsCount; + Widget->ColumnsFilled = 0; +} + +internal void +ui_WidgetInitUniformColumns(ui_widget* Widget) +{ + r32 CurrentRowWidth = Rect2Width(Widget->Bounds); + r32 ColumnWidth = CurrentRowWidth / Widget->ColumnsCount; + for (u32 i = 0; i < Widget->ColumnsCount; i++) + { + ui_column* Column = Widget->Columns + i; + Column->XMin = Widget->Bounds.Min.x + (ColumnWidth * i); + Column->XMax = Column->XMin + ColumnWidth; + } +} + internal ui_widget* -ui_CreateLayoutWidget(ui_interface* Interface, rect2 Bounds, ui_layout_direction FillDir, gs_string Name) +ui_CreateLayoutWidget(ui_interface* Interface, rect2 Bounds, gs_string Name, ui_layout_direction FillDir = LayoutDirection_Inherit) { ui_widget* Result = ui_CreateWidget(Interface, Name); - //ui_WidgetSetFlag(Result, UIWidgetFlag_DrawOutline); + ui_WidgetSetFlag(Result, UIWidgetFlag_DrawOutline); Result->Bounds = Bounds; Result->Margin = Interface->Style.Margin; Result->RowHeight = Interface->Style.RowHeight; - Result->FillDirection = FillDir; - switch(FillDir) + // Single Column Layout + ui_WidgetCreateColumns(Result, 1, Interface); + ui_WidgetInitUniformColumns(Result); + + if (FillDir == LayoutDirection_Inherit && Result->Parent != 0) + { + Result->FillDirection = Result->Parent->FillDirection; + } + else + { + Result->FillDirection = FillDir; + } + + switch(Result->FillDirection) { case LayoutDirection_BottomUp: { - Result->RowYAt = Bounds.Min.y + Result->Margin.y; + Result->RowYAt = Bounds.Min.y; }break; case LayoutDirection_TopDown: { - Result->RowYAt = Bounds.Max.y - (Result->RowHeight + Result->Margin.y); + Result->RowYAt = Bounds.Max.y - Result->RowHeight; }break; + + InvalidDefaultCase; } return Result; } +static ui_widget* +ui_PushOverlayLayout(ui_interface* Interface, rect2 Bounds, ui_layout_direction FillDir, gs_string Name) +{ + ui_widget* Result = ui_CreateLayoutWidget(Interface, Bounds, Name, FillDir); + SLLPushOrInit(Interface->DrawOrderRoot, Interface->DrawOrderHead, Result); + Interface->ActiveLayout = Result; + return Result; +} + static ui_widget* ui_PushLayout(ui_interface* Interface, rect2 Bounds, ui_layout_direction FillDir, gs_string Name) { - ui_widget* Result = ui_CreateLayoutWidget(Interface, Bounds, FillDir, Name); + ui_widget* Result = ui_CreateLayoutWidget(Interface, Bounds, Name, FillDir); if (Interface->DrawOrderRoot) { @@ -453,124 +579,178 @@ ui_PushLayout(ui_interface* Interface, rect2 Bounds, ui_layout_direction FillDir } static ui_widget* -ui_PushOverlayLayout(ui_interface* Interface, rect2 Bounds, ui_layout_direction FillDir, gs_string Name) +ui_PushLayout(ui_interface* Interface, gs_string Name, bool Inset = true) { - ui_widget* Result = ui_CreateLayoutWidget(Interface, Bounds, FillDir, Name); - SLLPushOrInit(Interface->DrawOrderRoot, Interface->DrawOrderHead, Result); - Interface->ActiveLayout = Result; - return Result; + rect2 Bounds = {}; + ui_layout_direction Direction = LayoutDirection_TopDown; + if (Interface->ActiveLayout) + { + Bounds = ui_ReserveBounds(Interface->ActiveLayout, Inset); + Direction = Interface->ActiveLayout->FillDirection; + } + else + { + Bounds.Min.x = Interface->WindowBounds.Min.x; + Bounds.Min.y = Interface->WindowBounds.Max.y; + Bounds.Max.x = Interface->WindowBounds.Max.x; + Bounds.Max.y = Interface->WindowBounds.Max.y; + + if (Inset) + { + Bounds.Min.x += Interface->Style.Margin.x; + Bounds.Max.x -= Interface->Style.Margin.x; + } + + Direction = LayoutDirection_TopDown; + } + return ui_PushLayout(Interface, Bounds, Direction, Name); +} + +internal void +ui_ExpandToFitChildren(ui_widget* Parent) +{ + v2 Extents = { Parent->Bounds.Max.y, Parent->Bounds.Min.y }; + for (ui_widget* Child = Parent->ChildrenRoot; Child != 0; Child = Child->Next) + { + Extents.x = Min(Extents.x, Child->Bounds.Min.y); + Extents.y = Max(Extents.y, Child->Bounds.Max.y); + } + + switch(Parent->FillDirection) + { + case LayoutDirection_BottomUp: + { + Parent->Bounds.Max.y = Extents.y + Parent->Margin.y; + }break; + + case LayoutDirection_TopDown: + { + Parent->Bounds.Min.y = Extents.x - Parent->Margin.y; + }break; + + InvalidDefaultCase; + } } static void ui_PopLayout(ui_interface* Interface) { Assert(Interface->ActiveLayout != 0); + + ui_widget* Layout = Interface->ActiveLayout; + ui_ExpandToFitChildren(Layout); + Interface->ActiveLayout = Interface->ActiveLayout->Parent; + + // NOTE(pjs): This indicates that the parent layout should + // expand to fit the layout that we just popped + if (Interface->ActiveLayout != 0 && + Interface->ActiveLayout->ChildrenHead == Layout) + { + ui_CommitBounds(Interface->ActiveLayout, Layout->Bounds); + } } static void -ui_StartRow(ui_interface* Interface, u32 ColumnsMax = 0) +ui_BeginRow(ui_interface* Interface, u32 ColumnsMax) { - Interface->ActiveLayout->DrawHorizontal = true; - Interface->ActiveLayout->ColumnsMax = ColumnsMax; - Interface->ActiveLayout->ColumnWidths = 0; - Interface->ActiveLayout->ColumnsCount = 0; + ui_widget* Layout = ui_PushLayout(Interface, MakeString("Row"), false); + ui_WidgetCreateColumns(Layout, ColumnsMax, Interface); + ui_WidgetInitUniformColumns(Layout); } -static void -ui_StartRow(ui_interface* Interface, u32 ColumnsMax, r32* ColumnWidths) +enum ui_column_size_rule { - Interface->ActiveLayout->DrawHorizontal = true; - Interface->ActiveLayout->ColumnsMax = ColumnsMax; - Interface->ActiveLayout->ColumnWidths = ColumnWidths; - Interface->ActiveLayout->ColumnsCount = 0; + UIColumnSize_Fixed, + UIColumnSize_Percent, + UIColumnSize_Fill, +}; + +struct ui_column_spec +{ + ui_column_size_rule Rule; + union + { + r32 Width; + r32 Percent; + }; +}; + +static void +ui_BeginRow(ui_interface* Interface, u32 ColumnsMax, ui_column_spec* ColumnRules) +{ + ui_widget* Layout = ui_PushLayout(Interface, MakeString("Row"), false); + ui_WidgetCreateColumns(Layout, ColumnsMax, Interface); + + // First Pass, determine widths of each column, and how much space is left to be divided by the fill columns + r32 RowWidth = Rect2Width(Layout->Bounds); + r32 RemainingSpace = RowWidth; + u32 FillColumnsCount = 0; + for (u32 i = 0; i < Layout->ColumnsCount; i++) + { + ui_column_spec Spec = ColumnRules[i]; + ui_column* Column = Layout->Columns + i; + + switch (Spec.Rule) + { + case UIColumnSize_Fixed: + { + Column->XMax = Spec.Width; + RemainingSpace -= Column->XMax; + }break; + + case UIColumnSize_Percent: + { + Column->XMax = Spec.Percent * RowWidth; + RemainingSpace -= Column->XMax; + }break; + + case UIColumnSize_Fill: + { + FillColumnsCount += 1; + }break; + InvalidDefaultCase; + } + } + + r32 FillColumnWidth = RemainingSpace / FillColumnsCount; + + // Second Pass, specify the actual XMin and XMax of each column + r32 ColumnStartX = Layout->Bounds.Min.x; + for (u32 i = 0; i < Layout->ColumnsCount; i++) + { + ui_column_spec Spec = ColumnRules[i]; + ui_column* Column = Layout->Columns + i; + + r32 ColumnWidth = 0; + switch (Spec.Rule) + { + case UIColumnSize_Fixed: + case UIColumnSize_Percent: + { + ColumnWidth = Column->XMax; + }break; + + case UIColumnSize_Fill: + { + ColumnWidth = FillColumnWidth; + }break; + } + + Column->XMin = ColumnStartX ; + Column->XMax = Column->XMin + Max(0, ColumnWidth); + ColumnStartX = Column->XMax; + } } static void ui_EndRow(ui_interface* Interface) { - Interface->ActiveLayout->DrawHorizontal = false; - Interface->ActiveLayout->ColumnWidths = 0; - Interface->ActiveLayout->RowYAt -= (Interface->ActiveLayout->RowHeight + Interface->ActiveLayout->Margin.y); -} - -static b32 -ui_TryReserveElementBounds(ui_widget* Widget, rect2* Bounds) -{ - b32 Result = true; - if (!Widget->DrawHorizontal) - { - Bounds->Min = { Widget->Bounds.Min.x + Widget->Margin.x, Widget->RowYAt }; - Bounds->Max = { Widget->Bounds.Max.x - Widget->Margin.x, Bounds->Min.y + Widget->RowHeight }; - - r32 RowOffset = Widget->RowHeight + Widget->Margin.y; - switch (Widget->FillDirection) - { - case LayoutDirection_BottomUp: - { - Widget->RowYAt += RowOffset; - }break; - - case LayoutDirection_TopDown: - { - Widget->RowYAt -= RowOffset; - }break; - - InvalidDefaultCase; - } - } - else - { - if (Widget->ColumnsMax > 0) - { - Assert(Widget->ColumnsCount < Widget->ColumnsMax); - if (Widget->ColumnWidths != 0) - { - v2 Min = { - Widget->Bounds.Min.x + Widget->Margin.x, - Widget->RowYAt - }; - for (u32 i = 0; i < Widget->ColumnsCount; i++) - { - Min.x += Widget->ColumnWidths[i]; - } - Bounds->Min = Min; - Bounds->Max = Bounds->Min + v2{ - Widget->ColumnWidths[Widget->ColumnsCount] - Widget->Margin.x, - Widget->RowHeight - }; - } - else - { - r32 ElementWidth = Rect2Width(Widget->Bounds) / Widget->ColumnsMax; - Bounds->Min = { - Widget->Bounds.Min.x + (ElementWidth * Widget->ColumnsCount) + Widget->Margin.x, - Widget->RowYAt - }; - Bounds->Max = { - Bounds->Min.x + ElementWidth - (Widget->Margin.x * 2), - Bounds->Min.y + Widget->RowHeight - }; - } - Widget->ColumnsCount++; - } - else - { - Result = false; - } - } - return Result; -} - -static rect2 -ui_ReserveElementBounds(ui_widget* Layout) -{ - rect2 Bounds = {0}; - if (!ui_TryReserveElementBounds(Layout, &Bounds)) - { - InvalidCodePath; - } - return Bounds; + ui_PopLayout(Interface); + //ui_widget* Layout = Interface->ActiveLayout; + //Layout->DrawHorizontal = false; + //Layout->RowYAt -= (Layout->RowHeight + Layout->Margin.y); + } static rect2 @@ -578,10 +758,6 @@ ui_LayoutRemaining(ui_widget Layout) { rect2 Result = Layout.Bounds; Result.Max.y = Layout.RowYAt; - if (Layout.DrawHorizontal) - { - Result.Max.y -= Layout.RowHeight; - } return Result; } @@ -625,20 +801,17 @@ ui_EvaluateWidget(ui_interface* Interface, ui_widget* Widget, rect2 Bounds) } + Assert(Widget->Parent != 0); + ui_CommitBounds(Widget->Parent, Widget->Bounds); + return Result; } internal ui_eval_result ui_EvaluateWidget(ui_interface* Interface, ui_widget* Widget) { - rect2 Bounds = {0}; ui_widget* Layout = Interface->ActiveLayout; - if (!ui_TryReserveElementBounds(Layout, &Bounds)) - { - // TODO(pjs): This isn't invalid, but Idk when we'd hit this case yet - InvalidCodePath; - } - + rect2 Bounds = ui_ReserveBounds(Layout, true); return ui_EvaluateWidget(Interface, Widget, Bounds); } @@ -781,8 +954,8 @@ ui_EvaluateDropdown(ui_interface* Interface, ui_widget* Widget, ui_eval_result E r32 ParentLayoutMaxY = ParentLayout.Bounds.Max.y; Direction = LayoutDirection_BottomUp; MenuBounds = rect2{ - v2{ Widget->Bounds.Min.x, Widget->Bounds.Max.y }, - v2{ Widget->Bounds.Max.x, ParentLayoutMaxY } + v2{ Widget->Bounds.Min.x - ParentLayout.Margin.x, Widget->Bounds.Max.y }, + v2{ Widget->Bounds.Max.x + ParentLayout.Margin.x, ParentLayoutMaxY } }; } else @@ -790,14 +963,15 @@ ui_EvaluateDropdown(ui_interface* Interface, ui_widget* Widget, ui_eval_result E r32 ParentLayoutMinY = ParentLayout.Bounds.Min.y; Direction = LayoutDirection_TopDown; MenuBounds = rect2{ - v2{ Widget->Bounds.Min.x, ParentLayoutMinY }, - v2{ Widget->Bounds.Max.x, Widget->Bounds.Min.y } + v2{ Widget->Bounds.Min.x - ParentLayout.Margin.x, ParentLayoutMinY }, + v2{ Widget->Bounds.Max.x + ParentLayout.Margin.x, Widget->Bounds.Min.y } }; } ui_widget* Layout = ui_PushOverlayLayout(Interface, MenuBounds, Direction, MakeString("WidgetLayout")); Layout->Margin.y = 0; Layout->WidgetReference = Widget->Id; + ui_WidgetClearFlag(Layout, UIWidgetFlag_DrawOutline); } return State->Value; @@ -913,6 +1087,19 @@ ui_Toggle(ui_interface* Interface, gs_string Text, bool Value) return Result; } +internal void +ui_BeginList(ui_interface* Interface, gs_string Text, u32 ViewportRows) +{ + ui_widget* Layout = ui_PushLayout(Interface, Text); + +} + +internal void +ui_EndList(ui_interface* Interface) +{ + +} + // // OLD