diff --git a/code/core/core.h b/code/core/core.h index 9ab81a9..858d1ed 100644 --- a/code/core/core.h +++ b/code/core/core.h @@ -80,6 +80,16 @@ typedef intptr_t smm; #define PointerToU64(x) ((u64)(void *)x) #define U64ToPointer(x) ((void *)(u64)x) +#define FindIndexOfElement(Index, Array, Default, ToFind)\ +Index = Default;\ +for(s64 ___ = 0; ___ < ArrayCount(Array); ++___)\ +{\ +if(Array[___] == ToFind)\ +{\ +Index = ___; break;\ +}\ +}\ + //- sixten: Min, max & clamp #define Minimum(A, B) (((A)<(B))?(A):(B)) diff --git a/code/vn.cpp b/code/vn.cpp index 4899866..be0cd34 100644 --- a/code/vn.cpp +++ b/code/vn.cpp @@ -81,8 +81,12 @@ VN_UPDATE_AND_RENDER(VN_UpdateAndRender) AnimationCurve_NewFrame(&State->AnimationCurveState, Input->dtForFrame); UI_NewFrame(&State->UI, Input->EventList, Input->MouseP); - Workspace_Update(&State->Workspace, RenderCommands, Input, State->GlyphAtlas); - UI_SignalFromBox(UI_GetState()->ContainerNode); // sixten(TODO): Move elsewhere. + UI_BeginBuild(RenderCommands->RenderDim); + { + Workspace_Update(&State->Workspace, RenderCommands, Input, State->GlyphAtlas); + } + UI_EndBuild(State->GlyphAtlas); + for(platform_event *Event = Input->EventList->First; Event != 0; @@ -90,7 +94,7 @@ VN_UPDATE_AND_RENDER(VN_UpdateAndRender) { if(Event->Type == PlatformEvent_WindowClose) { - Config_WriteFile(State->Config); + Config_WriteFile(State->Config, StrLit("config.vn")); Input->ExitRequested = true; } diff --git a/code/vn_config.cpp b/code/vn_config.cpp index cc01489..1c3bd5d 100644 --- a/code/vn_config.cpp +++ b/code/vn_config.cpp @@ -207,7 +207,7 @@ static void Config_ReadFile(config *Config, string Path) ReleaseScratch(Scratch); } -static void Config_WriteFile(config *Config) +static void Config_WriteFile(config *Config, string Path) { string_list Out = {}; temporary_memory Scratch = GetScratch(); @@ -276,7 +276,7 @@ static void Config_WriteFile(config *Config) string FinalOut = JoinStringList(&Out, Scratch.Arena); - platform_file_handle Handle = Platform.OpenFile(StrLit("config.vn"), PlatformAccess_Write); + platform_file_handle Handle = Platform.OpenFile(Path, PlatformAccess_Write); if(Handle.IsValid) { Platform.WriteFile(Handle, FinalOut.Data, 0, FinalOut.Count); diff --git a/code/vn_ui.cpp b/code/vn_ui.cpp index cabb02f..aad2251 100644 --- a/code/vn_ui.cpp +++ b/code/vn_ui.cpp @@ -422,82 +422,6 @@ static ui_signal UI_SignalFromBox(ui_box *Box) return(Signal); } -static void UI_CalculateStandaloneSize(ui_box *Box, axis2 Axis, glyph_atlas *Atlas) -{ - for(ui_box *Child = Box->First; - Child != 0; - Child = Child->Next) - { - UI_CalculateStandaloneSize(Child, Axis, Atlas); - } - - if(Box->SemanticSize[Axis].Type == UI_SizeType_Pixels) - { - Box->ComputedDim.E[Axis] = Box->SemanticSize[Axis].Value; - } - else if(Box->SemanticSize[Axis].Type == UI_SizeType_TextContent) - { - if(Axis == Axis2_X) - { - Box->ComputedDim.E[Axis] = CalculateRasterizedTextWidth(Atlas, Box->Font, Box->FontSize, Box->String); - } - else if(Axis == Axis2_Y) - { - Box->ComputedDim.E[Axis] = CalculateRasterizedTextHeight(Atlas, Box->Font, Box->FontSize, Box->String); - } - else - { - InvalidCodepath; - } - - Box->ComputedDim.E[Axis] += Box->SemanticSize[Axis].Value; - } -} - -static void UI_CalculateUpwardsDependentSize(ui_box *Box, axis2 Axis) -{ - if(Box->SemanticSize[Axis].Type == UI_SizeType_PercentOfParent) - { - Box->ComputedDim.E[Axis] = Box->Parent->ComputedDim.E[Axis]*Box->SemanticSize[Axis].Value; - } - - for(ui_box *Child = Box->First; - Child != 0; - Child = Child->Next) - { - UI_CalculateUpwardsDependentSize(Child, Axis); - } -} - -static void UI_CalculateDownwardsDependentSize(ui_box *Box, axis2 Axis) -{ - for(ui_box *Child = Box->First; - Child != 0; - Child = Child->Next) - { - UI_CalculateDownwardsDependentSize(Child, Axis); - } - - if(Box->SemanticSize[Axis].Type == UI_SizeType_ChildrenSum) - { - for(ui_box *Child = Box->First; - Child; - Child = Child->Next) - { - if(Box->LayoutAxis == Axis) - { - Box->ComputedDim.E[Axis] += Child->ComputedDim.E[Axis]; - } - else - { - Box->ComputedDim.E[Axis] = Maximum(Box->ComputedDim.E[Axis], Child->ComputedDim.E[Axis]); - } - - Box->ComputedDim.E[Axis] *= Box->SemanticSize[Axis].Value; - } - } -} - static void UI_SolveSizeViolations(ui_box *Box, axis2 Axis) { r32 TotalSpace = 0; @@ -584,16 +508,6 @@ static void UI_SolveSizeViolations(ui_box *Box, axis2 Axis) } } } - - for(ui_box *Child = Box->First; - Child; - Child = Child->Next) - { - Child->Rect.Min.E[Axis] = Box->Rect.Min.E[Axis] + Child->ComputedRelativeP.E[Axis]; - Child->Rect.Max.E[Axis] = Child->Rect.Min.E[Axis] + Child->ComputedDim.E[Axis]; - - UI_SolveSizeViolations(Child, Axis); - } } inline void UI_BeginTooltip(void) @@ -708,6 +622,101 @@ static void UI_DrawBox(ui_box *Box, render_group *Group, glyph_atlas *GlyphAtlas } } +static r32 UI_CalculateChildrenSum(ui_box *Box, axis2 Axis, glyph_atlas *Atlas); + +static r32 UI_CalculateBoxSize(ui_box *Box, axis2 Axis, glyph_atlas *Atlas) +{ + r32 Result = 0; + + ui_box *Parent = Box->Parent; + + switch(Box->SemanticSize[Axis].Type) + { + case UI_SizeType_Pixels: + { + Result = Box->SemanticSize[Axis].Value; + } break; + + case UI_SizeType_TextContent: + { + Result = ((Axis == Axis2_X) ? + CalculateRasterizedTextWidth(Atlas, Box->Font, Box->FontSize, Box->String) : + CalculateRasterizedTextHeight(Atlas, Box->Font, Box->FontSize, Box->String)) + + Box->SemanticSize[Axis].Value; + } break; + + case UI_SizeType_PercentOfParent: + { + if(Parent && Parent->SemanticSize[Axis].Type != UI_SizeType_ChildrenSum) + { + Result = Parent->ComputedDim.E[Axis]*Box->SemanticSize[Axis].Value; + } + else + { + // sixten(NOTE): A box that depends on the size of the parent can not be allowed if the parent depends + // on the children sum. + InvalidCodepath; + } + } break; + + case UI_SizeType_ChildrenSum: + { + Result = UI_CalculateChildrenSum(Box, Axis, Atlas)*Box->SemanticSize[Axis].Value; + } break; + + InvalidDefaultCase; + } + + return(Result); +} + +static r32 UI_CalculateChildrenSum(ui_box *Box, axis2 Axis, glyph_atlas *Atlas) +{ + r32 Result = 0; + + if(Box->LayoutAxis == Axis) + { + for(ui_box *Child = Box->First; + Child != 0; + Child = Child->Next) + { + Result += UI_CalculateBoxSize(Child, Axis, Atlas); + } + } + else + { + for(ui_box *Child = Box->First; + Child != 0; + Child = Child->Next) + { + Result = Max(Result, UI_CalculateBoxSize(Child, Axis, Atlas)); + } + } + return(Result); +} + +static void UI_LayoutBox(ui_box *Box, axis2 Axis, glyph_atlas *Atlas) +{ + for(ui_box *Child = Box->First; + Child != 0; + Child = Child->Next) + { + Child->ComputedDim.E[Axis] = UI_CalculateBoxSize(Child, Axis, Atlas); + } + + UI_SolveSizeViolations(Box, Axis); + + for(ui_box *Child = Box->First; + Child; + Child = Child->Next) + { + Child->Rect.Min.E[Axis] = Box->Rect.Min.E[Axis] + Child->ComputedRelativeP.E[Axis]; + Child->Rect.Max.E[Axis] = Child->Rect.Min.E[Axis] + Child->ComputedDim.E[Axis]; + + UI_LayoutBox(Child, Axis, Atlas); + } +} + static void UI_BeginBuild(v2 ScreenDim) { ui *UI = UI_GetState(); @@ -741,6 +750,8 @@ static void UI_EndBuild(glyph_atlas *GlyphAtlas) { ui *UI = UI_GetState(); + UI_SignalFromBox(UI_GetState()->ContainerNode); + if(UI->NextHotSet) { UI->Hot = UI->NextHot; @@ -760,17 +771,8 @@ static void UI_EndBuild(glyph_atlas *GlyphAtlas) UI_PopFont(); UI_PopFontSize(); - UI_CalculateStandaloneSize(UI->RootNode, Axis2_X, GlyphAtlas); - UI_CalculateStandaloneSize(UI->RootNode, Axis2_Y, GlyphAtlas); - - UI_CalculateUpwardsDependentSize(UI->RootNode, Axis2_X); - UI_CalculateUpwardsDependentSize(UI->RootNode, Axis2_Y); - - UI_CalculateDownwardsDependentSize(UI->RootNode, Axis2_X); - UI_CalculateDownwardsDependentSize(UI->RootNode, Axis2_Y); - - UI_SolveSizeViolations(UI->RootNode, Axis2_X); - UI_SolveSizeViolations(UI->RootNode, Axis2_Y); + UI_LayoutBox(UI->RootNode, Axis2_X, GlyphAtlas); + UI_LayoutBox(UI->RootNode, Axis2_Y, GlyphAtlas); } static void UI_RenderFrame(render_group *Group, glyph_atlas *GlyphAtlas) diff --git a/code/vn_ui_utils.cpp b/code/vn_ui_utils.cpp index b5f1290..620de29 100644 --- a/code/vn_ui_utils.cpp +++ b/code/vn_ui_utils.cpp @@ -178,7 +178,7 @@ static ui_signal UI_Checkbox(string String, b32 *Checked) v4 TextColor = UI_TopTextColor(); TextColor.a = OpacityTransition; - UI_Size(UI_Em(1, 1), UI_Em(1, 1)) UI_Font(Font_Icons) UI_TextColor(TextColor) + UI_CornerRadius(2) UI_Size(UI_Em(1, 1), UI_Em(1, 1)) UI_Font(Font_Icons) UI_TextColor(TextColor) UI_MakeBoxF(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawText, "%U", FontIcon_Cancel); UI_Size(UI_TextContent(15, 1), UI_Em(1, 1)) UI_Label(String); @@ -189,9 +189,11 @@ static ui_signal UI_Checkbox(string String, b32 *Checked) { Platform.SetCursor(PlatformCursor_Hand); } + if(Signal.Pressed) { *Checked = !*Checked; } + return(Signal); } \ No newline at end of file diff --git a/code/vn_workspace.cpp b/code/vn_workspace.cpp index 07cb4ea..c0057e8 100644 --- a/code/vn_workspace.cpp +++ b/code/vn_workspace.cpp @@ -419,8 +419,6 @@ static void Workspace_BuildPanelHeader(workspace *Workspace, workspace_panel *Pa Workspace_BuildTabItem(Workspace, Panel, View); } - UI_Spacer(UI_Percent(1, 0)); - // sixten: Panel Close Button if(Panel != Workspace->RootPanel) { @@ -705,10 +703,7 @@ static void Workspace_Init(workspace *Workspace) { Workspace->RootPanel = Workspace->CurrentPanel = Workspace_CreateNewPanel(Workspace, 0); - // sixten(TEMP): Add mock views. - { - Workspace_CreateNewView(Workspace_View_Startup, Workspace->RootPanel); - } + Workspace_CreateNewView(Workspace_View_Startup, Workspace->RootPanel); // sixten: Setup keybinds { @@ -739,7 +734,6 @@ static void Workspace_Update(workspace *Workspace, vn_render_commands *RenderCom } // sixten: Build the UI. - UI_BeginBuild(RenderCommands->RenderDim); { Workspace_BuildToolbar(Workspace, Input->dtForFrame); @@ -749,5 +743,4 @@ static void Workspace_Update(workspace *Workspace, vn_render_commands *RenderCom Workspace_BuildDragPayload(Workspace, Input); } - UI_EndBuild(GlyphAtlas); } \ No newline at end of file diff --git a/code/vn_workspace_view.cpp b/code/vn_workspace_view.cpp index 4007c06..f6852a0 100644 --- a/code/vn_workspace_view.cpp +++ b/code/vn_workspace_view.cpp @@ -361,6 +361,8 @@ static void Workspace_BuildSettings(workspace *Workspace, workspace_view *View) UI_Spacer(UI_Pixels(30, 1)); Workspace_BuildSettingsTabButton(Settings, "General", Workspace_Settings_General); UI_Spacer(UI_Pixels(30, 1)); + Workspace_BuildSettingsTabButton(Settings, "Theme", Workspace_Settings_Theme); + UI_Spacer(UI_Pixels(30, 1)); Workspace_BuildSettingsTabButton(Settings, "Developer", Workspace_Settings_Developer); UI_Spacer(UI_Pixels(150, 1)); @@ -384,38 +386,44 @@ static void Workspace_BuildSettings(workspace *Workspace, workspace_view *View) UI_Font(Font_Bold) UI_FontSize(36) UI_LabelF("General"); char *Alternatives[] = {"60 Hz", "120 Hz", "144 Hz", "Uncapped", "V-Sync"}; + s64 AlternativeMapping[] = {60, 120, 144, -1, 0}; + + s32 DropdownSelected; + FindIndexOfElement(DropdownSelected, AlternativeMapping, 0, Workspace->Input->RefreshRate); persist b32 DropdownOpen = false; - s32 DropdownSelected; - switch(Workspace->Input->RefreshRate) - { - case 60: { DropdownSelected = 0; } break; - case 120:{ DropdownSelected = 1; } break; - case 144:{ DropdownSelected = 2; } break; - case -1: { DropdownSelected = 3; } break; - case 0: { DropdownSelected = 4; } break; - default: { DropdownSelected = 0; } break; - } - if(UI_DropdownSelection(Alternatives, ArrayCount(Alternatives), &DropdownOpen, &DropdownSelected)) { - switch(DropdownSelected) - { - case 0: { Workspace->Input->RefreshRate = 60; } break; - case 1: { Workspace->Input->RefreshRate = 120; } break; - case 2: { Workspace->Input->RefreshRate = 144; } break; - case 3: { Workspace->Input->RefreshRate = -1; } break; - case 4: { Workspace->Input->RefreshRate = 0; } break; - InvalidDefaultCase; - } - + Workspace->Input->RefreshRate = AlternativeMapping[DropdownSelected]; DropdownOpen = false; } UI_Spacer(UI_Pixels(50, 1)); } + if(!Category || (Category == Workspace_Settings_Theme)) + { + UI_Font(Font_Bold) UI_FontSize(36) UI_LabelF("Theme"); + + UI_SetNextSize(UI_Percent(1, 1), UI_ChildrenSum(1, 1)); + UI_SetNextCornerRadius(3); + + UI_Parent(UI_MakeBoxF(UI_BoxFlag_DrawBorder, "Theme Lister")) + UI_Size(UI_Percent(1, 1), UI_Em(2, 1)) + { + UI_ButtonF("Hello"); + UI_ButtonF("Line"); + UI_ButtonF("Paint"); + UI_ButtonF("Color"); + UI_ButtonF("Design"); + UI_ButtonF("Address"); + UI_ButtonF("Brightness"); + } + + UI_Spacer(UI_Pixels(50, 1)); + } + if(!Category || (Category == Workspace_Settings_Developer)) { UI_Font(Font_Bold) UI_FontSize(36) UI_LabelF("Developer"); @@ -437,7 +445,7 @@ static void Workspace_BuildView(workspace *Workspace, workspace_view *View) r32 ViewHighlightTransition = AnimationCurve_AnimateValueF(Workspace_ViewIsCurrent(Workspace, View), 0, 0.25, "Workspace View Highlight %p", View); UI_SetNextBorderColor(LinearBlend(Theme_BorderColor, Theme_HighlightBorderColor, ViewHighlightTransition)); - UI_SetNextBackgroundColor(Theme_BackgroundColor); + UI_PushBackgroundColor(Theme_BackgroundColor); UI_SetNextCornerRadius(3); ui_box *ViewBox = UI_MakeBoxF(UI_BoxFlag_Clickable | @@ -476,5 +484,7 @@ static void Workspace_BuildView(workspace *Workspace, workspace_view *View) } } + UI_PopBackgroundColor(); + UI_SignalFromBox(ViewBox); } diff --git a/code/vn_workspace_view.h b/code/vn_workspace_view.h index 7893282..d0c031b 100644 --- a/code/vn_workspace_view.h +++ b/code/vn_workspace_view.h @@ -46,6 +46,7 @@ enum workspace_settings_category { Workspace_Settings_All, Workspace_Settings_General, + Workspace_Settings_Theme, Workspace_Settings_Developer, };