Addded scrollable boxes.
parent
c9f125cc56
commit
4dd7703810
|
@ -507,6 +507,12 @@ inline r32 DimOfRange(range1_r32 Range)
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline range1_r32 Intersection(range1_r32 A, range1_r32 B)
|
||||||
|
{
|
||||||
|
range1_r32 Result = {Max(A.Min, B.Min), Min(A.Max, B.Max)};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
inline range1_s32 Range1S32(s32 Min, s32 Max)
|
inline range1_s32 Range1S32(s32 Min, s32 Max)
|
||||||
{
|
{
|
||||||
range1_s32 Result = {Min, Max};
|
range1_s32 Result = {Min, Max};
|
||||||
|
@ -525,6 +531,12 @@ inline s32 DimOfRange(range1_s32 Range)
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline range1_s32 Intersection(range1_s32 A, range1_s32 B)
|
||||||
|
{
|
||||||
|
range1_s32 Result = {Max(A.Min, B.Min), Min(A.Max, B.Max)};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
inline range1_s64 Range1S64(s64 Min, s64 Max)
|
inline range1_s64 Range1S64(s64 Min, s64 Max)
|
||||||
{
|
{
|
||||||
range1_s64 Result = {Min, Max};
|
range1_s64 Result = {Min, Max};
|
||||||
|
@ -543,6 +555,12 @@ inline s64 DimOfRange(range1_s64 Range)
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline range1_s64 Intersection(range1_s64 A, range1_s64 B)
|
||||||
|
{
|
||||||
|
range1_s64 Result = {Max(A.Min, B.Min), Min(A.Max, B.Max)};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
inline range2_r32 Range2R32(v2_r32 Min, v2_r32 Max)
|
inline range2_r32 Range2R32(v2_r32 Min, v2_r32 Max)
|
||||||
{
|
{
|
||||||
range2_r32 Result = {Min, Max};
|
range2_r32 Result = {Min, Max};
|
||||||
|
@ -562,6 +580,12 @@ inline v2_r32 DimOfRange(range2_r32 Range)
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline range2_r32 Intersection(range2_r32 A, range2_r32 B)
|
||||||
|
{
|
||||||
|
range2_r32 Result = {Max(A.Min, B.Min), Min(A.Max, B.Max)};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
inline range2_s32 Range2S32(v2_s32 Min, v2_s32 Max)
|
inline range2_s32 Range2S32(v2_s32 Min, v2_s32 Max)
|
||||||
{
|
{
|
||||||
range2_s32 Result = {Min, Max};
|
range2_s32 Result = {Min, Max};
|
||||||
|
@ -581,6 +605,12 @@ inline v2_s32 DimOfRange(range2_s32 Range)
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline range2_s32 Intersection(range2_s32 A, range2_s32 B)
|
||||||
|
{
|
||||||
|
range2_s32 Result = {Max(A.Min, B.Min), Min(A.Max, B.Max)};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
inline range2_s64 Range2S64(v2_s64 Min, v2_s64 Max)
|
inline range2_s64 Range2S64(v2_s64 Min, v2_s64 Max)
|
||||||
{
|
{
|
||||||
range2_s64 Result = {Min, Max};
|
range2_s64 Result = {Min, Max};
|
||||||
|
@ -599,3 +629,9 @@ inline v2_s64 DimOfRange(range2_s64 Range)
|
||||||
v2_s64 Result = Range.Max - Range.Min;
|
v2_s64 Result = Range.Max - Range.Min;
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline range2_s64 Intersection(range2_s64 A, range2_s64 B)
|
||||||
|
{
|
||||||
|
range2_s64 Result = {Max(A.Min, B.Min), Min(A.Max, B.Max)};
|
||||||
|
return(Result);
|
||||||
|
}
|
|
@ -209,6 +209,12 @@ inline r32 LinearBlend(r32 a, r32 b, r32 x) { r32 Result = a + (b-a)*x; return(R
|
||||||
inline r32 Min(r32 A, r32 B) { r32 Result = Minimum(A, B); return(Result); }
|
inline r32 Min(r32 A, r32 B) { r32 Result = Minimum(A, B); return(Result); }
|
||||||
inline r32 Max(r32 A, r32 B) { r32 Result = Maximum(A, B); return(Result); }
|
inline r32 Max(r32 A, r32 B) { r32 Result = Maximum(A, B); return(Result); }
|
||||||
|
|
||||||
|
inline s32 Min(s32 A, s32 B) { s32 Result = Minimum(A, B); return(Result); }
|
||||||
|
inline s32 Max(s32 A, s32 B) { s32 Result = Maximum(A, B); return(Result); }
|
||||||
|
|
||||||
|
inline s64 Min(s64 A, s64 B) { s64 Result = Minimum(A, B); return(Result); }
|
||||||
|
inline s64 Max(s64 A, s64 B) { s64 Result = Maximum(A, B); return(Result); }
|
||||||
|
|
||||||
//- sixten: Vector functions
|
//- sixten: Vector functions
|
||||||
|
|
||||||
inline v2_r32 V2R32(r32 x, r32 y);
|
inline v2_r32 V2R32(r32 x, r32 y);
|
||||||
|
@ -322,26 +328,32 @@ inline v4_s64 Max(v4_s64 A, v4_s64 B);
|
||||||
inline range1_r32 Range1R32(r32 Min, r32 Max);
|
inline range1_r32 Range1R32(r32 Min, r32 Max);
|
||||||
inline b32 InRange(range1_r32 Range, r32 Value);
|
inline b32 InRange(range1_r32 Range, r32 Value);
|
||||||
inline r32 DimOfRange(range1_r32 Range);
|
inline r32 DimOfRange(range1_r32 Range);
|
||||||
|
inline range1_r32 Intersection(range1_r32 A, range1_r32 B);
|
||||||
|
|
||||||
inline range1_s32 Range1S32(s32 Min, s32 Max);
|
inline range1_s32 Range1S32(s32 Min, s32 Max);
|
||||||
inline b32 InRange(range1_s32 Range, s32 Value);
|
inline b32 InRange(range1_s32 Range, s32 Value);
|
||||||
inline s32 DimOfRange(range1_s32 Range);
|
inline s32 DimOfRange(range1_s32 Range);
|
||||||
|
inline range1_s32 Intersection(range1_s32 A, range1_s32 B);
|
||||||
|
|
||||||
inline range1_s64 Range1S64(s64 Min, s64 Max);
|
inline range1_s64 Range1S64(s64 Min, s64 Max);
|
||||||
inline b32 InRange(range1_s64 Range, s64 Value);
|
inline b32 InRange(range1_s64 Range, s64 Value);
|
||||||
inline s64 DimOfRange(range1_s64 Range);
|
inline s64 DimOfRange(range1_s64 Range);
|
||||||
|
inline range1_s64 Intersection(range1_s64 A, range1_s64 B);
|
||||||
|
|
||||||
inline range2_r32 Range2R32(v2_r32 Min, v2_r32 Max);
|
inline range2_r32 Range2R32(v2_r32 Min, v2_r32 Max);
|
||||||
inline b32 InRange(range2_r32 Range, v2_r32 Value);
|
inline b32 InRange(range2_r32 Range, v2_r32 Value);
|
||||||
inline v2_r32 DimOfRange(range2_r32 Range);
|
inline v2_r32 DimOfRange(range2_r32 Range);
|
||||||
|
inline range2_r32 Intersection(range2_r32 A, range2_r32 B);
|
||||||
|
|
||||||
inline range2_s32 Range2S32(v2_s32 Min, v2_s32 Max);
|
inline range2_s32 Range2S32(v2_s32 Min, v2_s32 Max);
|
||||||
inline b32 InRange(range2_s32 Range, v2_s32 Value);
|
inline b32 InRange(range2_s32 Range, v2_s32 Value);
|
||||||
inline v2_s32 DimOfRange(range2_s32 Range);
|
inline v2_s32 DimOfRange(range2_s32 Range);
|
||||||
|
inline range2_s32 Intersection(range2_s32 A, range2_s32 B);
|
||||||
|
|
||||||
inline range2_s64 Range2S64(v2_s64 Min, v2_s64 Max);
|
inline range2_s64 Range2S64(v2_s64 Min, v2_s64 Max);
|
||||||
inline b32 InRange(range2_s64 Range, v2_s64 Value);
|
inline b32 InRange(range2_s64 Range, v2_s64 Value);
|
||||||
inline v2_s64 DimOfRange(range2_s64 Range);
|
inline v2_s64 DimOfRange(range2_s64 Range);
|
||||||
|
inline range2_s64 Intersection(range2_s64 A, range2_s64 B);
|
||||||
|
|
||||||
//- sixten: Shorthand base types
|
//- sixten: Shorthand base types
|
||||||
|
|
||||||
|
|
|
@ -262,7 +262,7 @@ static string ConvertS64ToString(memory_arena *Arena, s64 Value)
|
||||||
Value = -Value;
|
Value = -Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
s64 DigitCount = (s64)Floor(Log(Max(Value, 1)) / Log(10)) + 1;
|
s64 DigitCount = (s64)Floor(Log(Max(Value, 1LL)) / Log(10)) + 1;
|
||||||
|
|
||||||
s64 TotalBufferCount = DigitCount + IsNegative;
|
s64 TotalBufferCount = DigitCount + IsNegative;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "vn_core.h"
|
#include "core/core.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#define ArrayCount(Array) (sizeof(Array)/sizeof((Array)[0]))
|
#define ArrayCount(Array) (sizeof(Array)/sizeof((Array)[0]))
|
||||||
|
|
|
@ -20,6 +20,8 @@ ui_style_stack UIStyleStacks[] =
|
||||||
{ "CornerRadius", "r32", "CornerRadius" },
|
{ "CornerRadius", "r32", "CornerRadius" },
|
||||||
{ "Font", "font_id", "Font" },
|
{ "Font", "font_id", "Font" },
|
||||||
{ "FontSize", "r32", "FontSize" },
|
{ "FontSize", "r32", "FontSize" },
|
||||||
|
{ "OffsetX", "r32", "Offset.x" },
|
||||||
|
{ "OffsetY", "r32", "Offset.y" },
|
||||||
};
|
};
|
||||||
|
|
||||||
static void GenUI(void)
|
static void GenUI(void)
|
||||||
|
|
|
@ -453,6 +453,76 @@ inline r32 UI_TopFontSize(void)
|
||||||
|
|
||||||
#define UI_FontSize(Element) DeferLoop(UI_PushFontSize(Element), UI_PopFontSize())
|
#define UI_FontSize(Element) DeferLoop(UI_PushFontSize(Element), UI_PopFontSize())
|
||||||
|
|
||||||
|
inline void UI_PushOffsetX(r32 Element)
|
||||||
|
{
|
||||||
|
ui *UI = UI_GetState();
|
||||||
|
Assert(UI->Stacks.OffsetXStackUsed + 1 < ArrayCount(UI->Stacks.OffsetXStack));
|
||||||
|
UI->Stacks.OffsetXStack[UI->Stacks.OffsetXStackUsed++] = Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void UI_PopOffsetX(void)
|
||||||
|
{
|
||||||
|
ui *UI = UI_GetState();
|
||||||
|
Assert(UI->Stacks.OffsetXStackUsed > 0);
|
||||||
|
--UI->Stacks.OffsetXStackUsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void UI_SetNextOffsetX(r32 Element)
|
||||||
|
{
|
||||||
|
ui *UI = UI_GetState();
|
||||||
|
UI_PushOffsetX(Element);
|
||||||
|
UI->Stacks.AutoPopOffsetX = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline r32 UI_FirstOffsetX(void)
|
||||||
|
{
|
||||||
|
ui *UI = UI_GetState();
|
||||||
|
return(UI->Stacks.OffsetXStack[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline r32 UI_TopOffsetX(void)
|
||||||
|
{
|
||||||
|
ui *UI = UI_GetState();
|
||||||
|
return(UI->Stacks.OffsetXStack[UI->Stacks.OffsetXStackUsed - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define UI_OffsetX(Element) DeferLoop(UI_PushOffsetX(Element), UI_PopOffsetX())
|
||||||
|
|
||||||
|
inline void UI_PushOffsetY(r32 Element)
|
||||||
|
{
|
||||||
|
ui *UI = UI_GetState();
|
||||||
|
Assert(UI->Stacks.OffsetYStackUsed + 1 < ArrayCount(UI->Stacks.OffsetYStack));
|
||||||
|
UI->Stacks.OffsetYStack[UI->Stacks.OffsetYStackUsed++] = Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void UI_PopOffsetY(void)
|
||||||
|
{
|
||||||
|
ui *UI = UI_GetState();
|
||||||
|
Assert(UI->Stacks.OffsetYStackUsed > 0);
|
||||||
|
--UI->Stacks.OffsetYStackUsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void UI_SetNextOffsetY(r32 Element)
|
||||||
|
{
|
||||||
|
ui *UI = UI_GetState();
|
||||||
|
UI_PushOffsetY(Element);
|
||||||
|
UI->Stacks.AutoPopOffsetY = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline r32 UI_FirstOffsetY(void)
|
||||||
|
{
|
||||||
|
ui *UI = UI_GetState();
|
||||||
|
return(UI->Stacks.OffsetYStack[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline r32 UI_TopOffsetY(void)
|
||||||
|
{
|
||||||
|
ui *UI = UI_GetState();
|
||||||
|
return(UI->Stacks.OffsetYStack[UI->Stacks.OffsetYStackUsed - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define UI_OffsetY(Element) DeferLoop(UI_PushOffsetY(Element), UI_PopOffsetY())
|
||||||
|
|
||||||
|
|
||||||
inline void UI_ApplyStyles(ui_box *Box)
|
inline void UI_ApplyStyles(ui_box *Box)
|
||||||
{
|
{
|
||||||
|
@ -561,4 +631,20 @@ inline void UI_ApplyStyles(ui_box *Box)
|
||||||
UI->Stacks.AutoPopFontSize = false;
|
UI->Stacks.AutoPopFontSize = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Assert(UI->Stacks.OffsetXStackUsed > 0);
|
||||||
|
Box->Offset.x = UI->Stacks.OffsetXStack[UI->Stacks.OffsetXStackUsed - 1];
|
||||||
|
if(UI->Stacks.AutoPopOffsetX)
|
||||||
|
{
|
||||||
|
UI_PopOffsetX();
|
||||||
|
UI->Stacks.AutoPopOffsetX = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert(UI->Stacks.OffsetYStackUsed > 0);
|
||||||
|
Box->Offset.y = UI->Stacks.OffsetYStack[UI->Stacks.OffsetYStackUsed - 1];
|
||||||
|
if(UI->Stacks.AutoPopOffsetY)
|
||||||
|
{
|
||||||
|
UI_PopOffsetY();
|
||||||
|
UI->Stacks.AutoPopOffsetY = false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,4 +39,10 @@ struct ui_style_stacks
|
||||||
r32 FontSizeStack[64];
|
r32 FontSizeStack[64];
|
||||||
s32 FontSizeStackUsed;
|
s32 FontSizeStackUsed;
|
||||||
b32 AutoPopFontSize;
|
b32 AutoPopFontSize;
|
||||||
|
r32 OffsetXStack[64];
|
||||||
|
s32 OffsetXStackUsed;
|
||||||
|
b32 AutoPopOffsetX;
|
||||||
|
r32 OffsetYStack[64];
|
||||||
|
s32 OffsetYStackUsed;
|
||||||
|
b32 AutoPopOffsetY;
|
||||||
};
|
};
|
||||||
|
|
15
code/vn.cpp
15
code/vn.cpp
|
@ -7,6 +7,7 @@ struct debug_settings
|
||||||
{
|
{
|
||||||
b32 RenderUIDebugRects;
|
b32 RenderUIDebugRects;
|
||||||
b32 RenderFPSCounter;
|
b32 RenderFPSCounter;
|
||||||
|
b32 ListHotAndActive;
|
||||||
};
|
};
|
||||||
|
|
||||||
per_thread debug_settings *DEBUG_DebugSettings = 0;
|
per_thread debug_settings *DEBUG_DebugSettings = 0;
|
||||||
|
@ -18,6 +19,7 @@ per_thread debug_settings *DEBUG_DebugSettings = 0;
|
||||||
#include "vn_font.h"
|
#include "vn_font.h"
|
||||||
#include "vn_text_op.h"
|
#include "vn_text_op.h"
|
||||||
#include "vn_ui.h"
|
#include "vn_ui.h"
|
||||||
|
#include "vn_ui_utils.h"
|
||||||
#include "vn_workspace.h"
|
#include "vn_workspace.h"
|
||||||
#include "vn_theme_dark.h"
|
#include "vn_theme_dark.h"
|
||||||
#include "vn_animation_curve.h"
|
#include "vn_animation_curve.h"
|
||||||
|
@ -66,6 +68,7 @@ VN_UPDATE_AND_RENDER(VN_UpdateAndRender)
|
||||||
#if VN_INTERNAL
|
#if VN_INTERNAL
|
||||||
Config_BindB32(State->Config, StrLit("Dev/RenderUIDebugRects"), &State->DebugSettings.RenderUIDebugRects, 0);
|
Config_BindB32(State->Config, StrLit("Dev/RenderUIDebugRects"), &State->DebugSettings.RenderUIDebugRects, 0);
|
||||||
Config_BindB32(State->Config, StrLit("Dev/RenderFPSCounter"), &State->DebugSettings.RenderFPSCounter, 0);
|
Config_BindB32(State->Config, StrLit("Dev/RenderFPSCounter"), &State->DebugSettings.RenderFPSCounter, 0);
|
||||||
|
Config_BindB32(State->Config, StrLit("Dev/ListHotAndActive"), &State->DebugSettings.ListHotAndActive, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Config_ReadFile(State->Config, StrLit("config.vn"));
|
Config_ReadFile(State->Config, StrLit("config.vn"));
|
||||||
|
@ -79,13 +82,13 @@ VN_UPDATE_AND_RENDER(VN_UpdateAndRender)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
AnimationCurve_NewFrame(&State->AnimationCurveState, Input->dtForFrame);
|
AnimationCurve_NewFrame(&State->AnimationCurveState, Input->dtForFrame);
|
||||||
UI_NewFrame(&State->UI, Input->EventList, Input->MouseP);
|
UI_NewFrame(&State->UI, Input->EventList, Input->MouseP, State->GlyphAtlas);
|
||||||
|
|
||||||
UI_BeginBuild(RenderCommands->RenderDim);
|
UI_BeginBuild(RenderCommands->RenderDim);
|
||||||
{
|
{
|
||||||
Workspace_Update(&State->Workspace, RenderCommands, Input, State->GlyphAtlas);
|
Workspace_Update(&State->Workspace, RenderCommands, Input, State->GlyphAtlas);
|
||||||
}
|
}
|
||||||
UI_EndBuild(State->GlyphAtlas);
|
UI_EndBuild();
|
||||||
|
|
||||||
|
|
||||||
for(platform_event *Event = Input->EventList->First;
|
for(platform_event *Event = Input->EventList->First;
|
||||||
|
@ -105,4 +108,12 @@ VN_UPDATE_AND_RENDER(VN_UpdateAndRender)
|
||||||
PushClear(&Group, V3(0.1, 0.1, 0.1));
|
PushClear(&Group, V3(0.1, 0.1, 0.1));
|
||||||
|
|
||||||
UI_RenderFrame(&Group, State->GlyphAtlas);
|
UI_RenderFrame(&Group, State->GlyphAtlas);
|
||||||
|
|
||||||
|
if(DEBUG_DebugSettings->ListHotAndActive)
|
||||||
|
{
|
||||||
|
PushText(&Group, State->GlyphAtlas, Font_Regular, V2(5, RenderCommands->RenderDim.y - 20), 15, Color_Grey,
|
||||||
|
PushFormat(&State->UI.FrameArena, "Hot: %S:%llu", UI_GetBoxNameByKey(UI_GetHot()), UI_GetHot()));
|
||||||
|
PushText(&Group, State->GlyphAtlas, Font_Regular, V2(5, RenderCommands->RenderDim.y - 40), 15, Color_Grey,
|
||||||
|
PushFormat(&State->UI.FrameArena, "Active: %S:%llu", UI_GetBoxNameByKey(UI_GetActive()), UI_GetActive()));
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -116,6 +116,7 @@ static glyph_atlas *CreateGlyphAtlas(vn_render_commands *RenderCommands,
|
||||||
Atlas->Fonts[Font_Regular].Data = Platform_ReadEntireFile(&Atlas->Arena, StrLit("fonts/Roboto-Regular.ttf"));
|
Atlas->Fonts[Font_Regular].Data = Platform_ReadEntireFile(&Atlas->Arena, StrLit("fonts/Roboto-Regular.ttf"));
|
||||||
Atlas->Fonts[Font_Bold].Data = Platform_ReadEntireFile(&Atlas->Arena, StrLit("fonts/Roboto-Bold.ttf"));
|
Atlas->Fonts[Font_Bold].Data = Platform_ReadEntireFile(&Atlas->Arena, StrLit("fonts/Roboto-Bold.ttf"));
|
||||||
Atlas->Fonts[Font_Monospace].Data = Platform_ReadEntireFile(&Atlas->Arena, StrLit("fonts/Liberation-Mono.ttf"));
|
Atlas->Fonts[Font_Monospace].Data = Platform_ReadEntireFile(&Atlas->Arena, StrLit("fonts/Liberation-Mono.ttf"));
|
||||||
|
Atlas->Fonts[Font_Hand].Data = Platform_ReadEntireFile(&Atlas->Arena, StrLit("fonts/PatrickHand-Regular.ttf"));
|
||||||
Atlas->Fonts[Font_Icons].Data = Platform_ReadEntireFile(&Atlas->Arena, StrLit("fonts/icons.ttf"));
|
Atlas->Fonts[Font_Icons].Data = Platform_ReadEntireFile(&Atlas->Arena, StrLit("fonts/icons.ttf"));
|
||||||
|
|
||||||
for(s32 FontIndex = 0;
|
for(s32 FontIndex = 0;
|
||||||
|
|
|
@ -8,6 +8,7 @@ enum font_id
|
||||||
Font_Regular,
|
Font_Regular,
|
||||||
Font_Bold,
|
Font_Bold,
|
||||||
Font_Monospace,
|
Font_Monospace,
|
||||||
|
Font_Hand,
|
||||||
Font_Icons,
|
Font_Icons,
|
||||||
|
|
||||||
Font_Count,
|
Font_Count,
|
||||||
|
|
|
@ -127,7 +127,7 @@ inline void PushTexturedQuad(render_group *Group,
|
||||||
v2 DestMin = Max(Dest.Min, Clip.Min);
|
v2 DestMin = Max(Dest.Min, Clip.Min);
|
||||||
v2 DestMax = Min(Dest.Max, Clip.Max);
|
v2 DestMax = Min(Dest.Max, Clip.Max);
|
||||||
|
|
||||||
//if(InRange(Clip, P) || InRange(Clip, P + Dim))
|
if(InRange(Clip, P) || InRange(Clip, P + Dim))
|
||||||
{
|
{
|
||||||
v2 HalfSize = Dim*0.5;
|
v2 HalfSize = Dim*0.5;
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
|
|
||||||
#define ColorFromHex(Value) V4((((Value) >> 24) & 0xFF) / 255.0, (((Value) >> 16) & 0xFF) / 255.0, (((Value) >> 8) & 0xFF) / 255.0, (((Value) >> 0) & 0xFF) / 255.0)
|
#define ColorFromHex(Value) V4((((Value) >> 24) & 0xFF) / 255.0, (((Value) >> 16) & 0xFF) / 255.0, (((Value) >> 8) & 0xFF) / 255.0, (((Value) >> 0) & 0xFF) / 255.0)
|
||||||
|
|
||||||
|
#define Brighten(Color, Amount) (Color*(Amount))
|
||||||
|
#define Darken(Color, Amount) (Color*(1.0/(Amount)))
|
||||||
|
|
||||||
read_only v4 Color_Black = V4(0, 0, 0, 1);
|
read_only v4 Color_Black = V4(0, 0, 0, 1);
|
||||||
read_only v4 Color_White = V4(1, 1, 1, 1);
|
read_only v4 Color_White = V4(1, 1, 1, 1);
|
||||||
read_only v4 Color_Grey = V4(0.5, 0.5, 0.5, 1);
|
read_only v4 Color_Grey = V4(0.5, 0.5, 0.5, 1);
|
||||||
|
|
105
code/vn_ui.cpp
105
code/vn_ui.cpp
|
@ -30,7 +30,6 @@ inline ui_size UI_ChildrenSum(r32 Value, r32 Strictness)
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
per_thread ui *ThreadLocal_UI;
|
per_thread ui *ThreadLocal_UI;
|
||||||
|
|
||||||
inline void UI_SetState(ui *UI)
|
inline void UI_SetState(ui *UI)
|
||||||
|
@ -304,26 +303,36 @@ inline void UI_SetNextHot(ui_key Key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline b32 UI_ChildrenContainsP(ui_box *Box, v2 P)
|
// sixten(NOTE): ClippingRect = Intersection(TrueClippingRect, Parent->Rect);
|
||||||
|
static b32 UI_ChildrenContainsP(ui_box *Parent, v2 P, range2_r32 Clip)
|
||||||
{
|
{
|
||||||
b32 Result = false;
|
b32 Result = false;
|
||||||
|
|
||||||
if(Box->Flags & UI_BoxFlag_Clickable && InRange(Box->Rect, P))
|
for(ui_box *Child = Parent->First;
|
||||||
|
Child != 0;
|
||||||
|
Child = Child->Next)
|
||||||
{
|
{
|
||||||
Result = true;
|
range2_r32 IntersectionRect = Intersection(Clip, Child->Rect);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(Box->First)
|
|
||||||
{
|
|
||||||
Result = UI_ChildrenContainsP(Box->First, P);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!Result)
|
if(Child->Flags & UI_BoxFlag_Clickable && InRange(IntersectionRect, P))
|
||||||
{
|
{
|
||||||
if(Box->Next)
|
Result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(Child->Flags & UI_BoxFlag_Clip)
|
||||||
{
|
{
|
||||||
Result = UI_ChildrenContainsP(Box->Next, P);
|
Result = UI_ChildrenContainsP(Child, P, IntersectionRect);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Result = UI_ChildrenContainsP(Child, P, Clip);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Result)
|
||||||
|
{
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -337,9 +346,19 @@ static ui_signal UI_SignalFromBox(ui_box *Box)
|
||||||
|
|
||||||
ui_signal Signal = {};
|
ui_signal Signal = {};
|
||||||
|
|
||||||
Signal.Hovering = InRange(Box->Rect, UI->MouseP) &&
|
// sixten: Gather the clipping rects of all the parents.
|
||||||
!(Box->First && UI_ChildrenContainsP(Box->First, UI->MouseP)) &&
|
range2_r32 ClippedRect = Box->Rect;
|
||||||
!(Box->Next && UI_ChildrenContainsP(Box->Next, UI->MouseP));
|
for(ui_box *Parent = Box->Parent;
|
||||||
|
Parent != 0;
|
||||||
|
Parent = Parent->Parent)
|
||||||
|
{
|
||||||
|
if(Parent->Flags & UI_BoxFlag_Clip)
|
||||||
|
{
|
||||||
|
ClippedRect = Intersection(ClippedRect, Parent->Rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Signal.Hovering = InRange(ClippedRect, UI->MouseP) && !UI_ChildrenContainsP(Box, UI->MouseP, ClippedRect);
|
||||||
|
|
||||||
// sixten: Make sure the tooltip is not overlapping.
|
// sixten: Make sure the tooltip is not overlapping.
|
||||||
{
|
{
|
||||||
|
@ -356,9 +375,10 @@ static ui_signal UI_SignalFromBox(ui_box *Box)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!FoundTooltip && UI->TooltipNode->First)
|
if(!FoundTooltip)
|
||||||
{
|
{
|
||||||
Signal.Hovering &= ~UI_ChildrenContainsP(UI->TooltipNode->First, UI->MouseP);
|
Signal.Hovering &= ~UI_ChildrenContainsP(UI->TooltipNode, UI->MouseP,
|
||||||
|
Range2R32(V2(0, 0), V2(InfinityR32, InfinityR32)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -585,7 +605,8 @@ static void UI_DrawBox(ui_box *Box, render_group *Group, glyph_atlas *GlyphAtlas
|
||||||
|
|
||||||
if(Box->Flags & UI_BoxFlag_Clip)
|
if(Box->Flags & UI_BoxFlag_Clip)
|
||||||
{
|
{
|
||||||
PushClip(Group, Box->Rect);
|
range2_r32 Rect = Intersection(Group->ClipStack[Group->ClipStackUsed], Box->Rect);
|
||||||
|
PushClip(Group, Rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(ui_box *Child = Box->First;
|
for(ui_box *Child = Box->First;
|
||||||
|
@ -622,12 +643,13 @@ 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_CalculateChildrenSum(ui_box *Box, axis2 Axis);
|
||||||
|
|
||||||
static r32 UI_CalculateBoxSize(ui_box *Box, axis2 Axis, glyph_atlas *Atlas)
|
static r32 UI_CalculateBoxSize(ui_box *Box, axis2 Axis)
|
||||||
{
|
{
|
||||||
r32 Result = 0;
|
r32 Result = 0;
|
||||||
|
|
||||||
|
ui *UI = UI_GetState();
|
||||||
ui_box *Parent = Box->Parent;
|
ui_box *Parent = Box->Parent;
|
||||||
|
|
||||||
switch(Box->SemanticSize[Axis].Type)
|
switch(Box->SemanticSize[Axis].Type)
|
||||||
|
@ -639,6 +661,8 @@ static r32 UI_CalculateBoxSize(ui_box *Box, axis2 Axis, glyph_atlas *Atlas)
|
||||||
|
|
||||||
case UI_SizeType_TextContent:
|
case UI_SizeType_TextContent:
|
||||||
{
|
{
|
||||||
|
glyph_atlas *Atlas = UI->GlyphAtlas;
|
||||||
|
|
||||||
Result = ((Axis == Axis2_X) ?
|
Result = ((Axis == Axis2_X) ?
|
||||||
CalculateRasterizedTextWidth(Atlas, Box->Font, Box->FontSize, Box->String) :
|
CalculateRasterizedTextWidth(Atlas, Box->Font, Box->FontSize, Box->String) :
|
||||||
CalculateRasterizedTextHeight(Atlas, Box->Font, Box->FontSize, Box->String)) +
|
CalculateRasterizedTextHeight(Atlas, Box->Font, Box->FontSize, Box->String)) +
|
||||||
|
@ -661,7 +685,7 @@ static r32 UI_CalculateBoxSize(ui_box *Box, axis2 Axis, glyph_atlas *Atlas)
|
||||||
|
|
||||||
case UI_SizeType_ChildrenSum:
|
case UI_SizeType_ChildrenSum:
|
||||||
{
|
{
|
||||||
Result = UI_CalculateChildrenSum(Box, Axis, Atlas)*Box->SemanticSize[Axis].Value;
|
Result = UI_CalculateChildrenSum(Box, Axis)*Box->SemanticSize[Axis].Value;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
InvalidDefaultCase;
|
InvalidDefaultCase;
|
||||||
|
@ -670,7 +694,7 @@ static r32 UI_CalculateBoxSize(ui_box *Box, axis2 Axis, glyph_atlas *Atlas)
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static r32 UI_CalculateChildrenSum(ui_box *Box, axis2 Axis, glyph_atlas *Atlas)
|
static r32 UI_CalculateChildrenSum(ui_box *Box, axis2 Axis)
|
||||||
{
|
{
|
||||||
r32 Result = 0;
|
r32 Result = 0;
|
||||||
|
|
||||||
|
@ -680,7 +704,7 @@ static r32 UI_CalculateChildrenSum(ui_box *Box, axis2 Axis, glyph_atlas *Atlas)
|
||||||
Child != 0;
|
Child != 0;
|
||||||
Child = Child->Next)
|
Child = Child->Next)
|
||||||
{
|
{
|
||||||
Result += UI_CalculateBoxSize(Child, Axis, Atlas);
|
Result += UI_CalculateBoxSize(Child, Axis);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -689,31 +713,33 @@ static r32 UI_CalculateChildrenSum(ui_box *Box, axis2 Axis, glyph_atlas *Atlas)
|
||||||
Child != 0;
|
Child != 0;
|
||||||
Child = Child->Next)
|
Child = Child->Next)
|
||||||
{
|
{
|
||||||
Result = Max(Result, UI_CalculateBoxSize(Child, Axis, Atlas));
|
Result = Max(Result, UI_CalculateBoxSize(Child, Axis));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UI_LayoutBox(ui_box *Box, axis2 Axis, glyph_atlas *Atlas)
|
static void UI_LayoutBox(ui_box *Box)
|
||||||
{
|
{
|
||||||
for(ui_box *Child = Box->First;
|
for(ui_box *Child = Box->First;
|
||||||
Child != 0;
|
Child != 0;
|
||||||
Child = Child->Next)
|
Child = Child->Next)
|
||||||
{
|
{
|
||||||
Child->ComputedDim.E[Axis] = UI_CalculateBoxSize(Child, Axis, Atlas);
|
Child->ComputedDim.E[Axis2_X] = UI_CalculateBoxSize(Child, Axis2_X);
|
||||||
|
Child->ComputedDim.E[Axis2_Y] = UI_CalculateBoxSize(Child, Axis2_Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
UI_SolveSizeViolations(Box, Axis);
|
UI_SolveSizeViolations(Box, Axis2_X);
|
||||||
|
UI_SolveSizeViolations(Box, Axis2_Y);
|
||||||
|
|
||||||
for(ui_box *Child = Box->First;
|
for(ui_box *Child = Box->First;
|
||||||
Child;
|
Child != 0;
|
||||||
Child = Child->Next)
|
Child = Child->Next)
|
||||||
{
|
{
|
||||||
Child->Rect.Min.E[Axis] = Box->Rect.Min.E[Axis] + Child->ComputedRelativeP.E[Axis];
|
Child->Rect.Min = Box->Rect.Min + Child->ComputedRelativeP + Box->Offset;
|
||||||
Child->Rect.Max.E[Axis] = Child->Rect.Min.E[Axis] + Child->ComputedDim.E[Axis];
|
Child->Rect.Max = Child->Rect.Min + Child->ComputedDim;
|
||||||
|
|
||||||
UI_LayoutBox(Child, Axis, Atlas);
|
UI_LayoutBox(Child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -734,6 +760,8 @@ static void UI_BeginBuild(v2 ScreenDim)
|
||||||
UI_PushCornerRadius(0);
|
UI_PushCornerRadius(0);
|
||||||
UI_PushFont(Font_Regular);
|
UI_PushFont(Font_Regular);
|
||||||
UI_PushFontSize(15.0f);
|
UI_PushFontSize(15.0f);
|
||||||
|
UI_PushOffsetX(0);
|
||||||
|
UI_PushOffsetY(0);
|
||||||
|
|
||||||
UI->RootNode = UI_MakeBox(UI_BoxFlag_DrawBackground, StrLit("UI Root Node"));
|
UI->RootNode = UI_MakeBox(UI_BoxFlag_DrawBackground, StrLit("UI Root Node"));
|
||||||
UI->Stacks.ParentStack[0] = UI->RootNode;
|
UI->Stacks.ParentStack[0] = UI->RootNode;
|
||||||
|
@ -746,7 +774,7 @@ static void UI_BeginBuild(v2 ScreenDim)
|
||||||
UI->NextHotSet = false;
|
UI->NextHotSet = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UI_EndBuild(glyph_atlas *GlyphAtlas)
|
static void UI_EndBuild(void)
|
||||||
{
|
{
|
||||||
ui *UI = UI_GetState();
|
ui *UI = UI_GetState();
|
||||||
|
|
||||||
|
@ -770,9 +798,10 @@ static void UI_EndBuild(glyph_atlas *GlyphAtlas)
|
||||||
UI_PopCornerRadius();
|
UI_PopCornerRadius();
|
||||||
UI_PopFont();
|
UI_PopFont();
|
||||||
UI_PopFontSize();
|
UI_PopFontSize();
|
||||||
|
UI_PopOffsetX();
|
||||||
|
UI_PopOffsetY();
|
||||||
|
|
||||||
UI_LayoutBox(UI->RootNode, Axis2_X, GlyphAtlas);
|
UI_LayoutBox(UI->RootNode);
|
||||||
UI_LayoutBox(UI->RootNode, Axis2_Y, GlyphAtlas);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UI_RenderFrame(render_group *Group, glyph_atlas *GlyphAtlas)
|
static void UI_RenderFrame(render_group *Group, glyph_atlas *GlyphAtlas)
|
||||||
|
@ -804,7 +833,7 @@ inline void UI_ScanForHotAndActive(ui_box *Box, b32 *FoundHot, b32 *FoundActive)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UI_NewFrame(ui *UI, platform_event_list *EventList, v2 MouseP)
|
static void UI_NewFrame(ui *UI, platform_event_list *EventList, v2 MouseP, glyph_atlas *GlyphAtlas)
|
||||||
{
|
{
|
||||||
UI_SetState(UI);
|
UI_SetState(UI);
|
||||||
|
|
||||||
|
@ -818,6 +847,8 @@ static void UI_NewFrame(ui *UI, platform_event_list *EventList, v2 MouseP)
|
||||||
UI->EventList = EventList;
|
UI->EventList = EventList;
|
||||||
UI->MouseP = MouseP;
|
UI->MouseP = MouseP;
|
||||||
|
|
||||||
|
UI->GlyphAtlas = GlyphAtlas;
|
||||||
|
|
||||||
// sixten: Make sure that the hot and active boxes are valid.
|
// sixten: Make sure that the hot and active boxes are valid.
|
||||||
if(UI->RootNode)
|
if(UI->RootNode)
|
||||||
{
|
{
|
||||||
|
|
67
code/vn_ui.h
67
code/vn_ui.h
|
@ -3,6 +3,7 @@
|
||||||
#ifndef VN_UI_H
|
#ifndef VN_UI_H
|
||||||
#define VN_UI_H
|
#define VN_UI_H
|
||||||
|
|
||||||
|
//- sixten: Keying
|
||||||
struct ui_key
|
struct ui_key
|
||||||
{
|
{
|
||||||
u64 Value;
|
u64 Value;
|
||||||
|
@ -14,23 +15,7 @@ inline b32 AreEqual(ui_key A, ui_key B)
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum
|
//- sixten: Semantic sizing
|
||||||
{
|
|
||||||
UI_BoxFlag_Clickable = (1 << 0),
|
|
||||||
UI_BoxFlag_DrawText = (1 << 1),
|
|
||||||
UI_BoxFlag_DrawBorder = (1 << 2),
|
|
||||||
UI_BoxFlag_DrawBackground = (1 << 3),
|
|
||||||
UI_BoxFlag_DrawDropShadow = (1 << 4),
|
|
||||||
UI_BoxFlag_Clip = (1 << 5),
|
|
||||||
UI_BoxFlag_HotAnimation = (1 << 6),
|
|
||||||
UI_BoxFlag_ActiveAnimation = (1 << 7),
|
|
||||||
UI_BoxFlag_OverflowX = (1 << 8),
|
|
||||||
UI_BoxFlag_OverflowY = (1 << 9),
|
|
||||||
UI_BoxFlag_FloatingX = (1 << 10),
|
|
||||||
UI_BoxFlag_FloatingY = (1 << 11),
|
|
||||||
};
|
|
||||||
typedef u32 ui_box_flags;
|
|
||||||
|
|
||||||
enum ui_size_type
|
enum ui_size_type
|
||||||
{
|
{
|
||||||
UI_SizeType_Pixels,
|
UI_SizeType_Pixels,
|
||||||
|
@ -52,6 +37,24 @@ inline ui_size UI_TextContent(r32 Value, r32 Strictness);
|
||||||
inline ui_size UI_Percent(r32 Value, r32 Strictness);
|
inline ui_size UI_Percent(r32 Value, r32 Strictness);
|
||||||
inline ui_size UI_ChildrenSum(r32 Value, r32 Strictness);
|
inline ui_size UI_ChildrenSum(r32 Value, r32 Strictness);
|
||||||
|
|
||||||
|
//- sixten: UI core
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
UI_BoxFlag_Clickable = (1 << 0),
|
||||||
|
UI_BoxFlag_DrawText = (1 << 1),
|
||||||
|
UI_BoxFlag_DrawBorder = (1 << 2),
|
||||||
|
UI_BoxFlag_DrawBackground = (1 << 3),
|
||||||
|
UI_BoxFlag_DrawDropShadow = (1 << 4),
|
||||||
|
UI_BoxFlag_Clip = (1 << 5),
|
||||||
|
UI_BoxFlag_HotAnimation = (1 << 6),
|
||||||
|
UI_BoxFlag_ActiveAnimation = (1 << 7),
|
||||||
|
UI_BoxFlag_OverflowX = (1 << 8),
|
||||||
|
UI_BoxFlag_OverflowY = (1 << 9),
|
||||||
|
UI_BoxFlag_FloatingX = (1 << 10),
|
||||||
|
UI_BoxFlag_FloatingY = (1 << 11),
|
||||||
|
};
|
||||||
|
typedef u32 ui_box_flags;
|
||||||
|
|
||||||
typedef void ui_draw_callback(render_group *Group, glyph_atlas *Atlas, struct ui_box *Box, void *Data);
|
typedef void ui_draw_callback(render_group *Group, glyph_atlas *Atlas, struct ui_box *Box, void *Data);
|
||||||
|
|
||||||
struct ui_box
|
struct ui_box
|
||||||
|
@ -81,6 +84,7 @@ struct ui_box
|
||||||
r32 CornerRadius;
|
r32 CornerRadius;
|
||||||
font_id Font;
|
font_id Font;
|
||||||
r32 FontSize;
|
r32 FontSize;
|
||||||
|
v2 Offset;
|
||||||
|
|
||||||
ui_draw_callback *DrawCallback;
|
ui_draw_callback *DrawCallback;
|
||||||
void *DrawCallbackData;
|
void *DrawCallbackData;
|
||||||
|
@ -136,13 +140,15 @@ struct ui
|
||||||
ui_key NextHot;
|
ui_key NextHot;
|
||||||
b32 NextHotSet;
|
b32 NextHotSet;
|
||||||
|
|
||||||
platform_event_list *EventList;
|
|
||||||
v2 MouseP;
|
|
||||||
|
|
||||||
u64 DragData[8];
|
u64 DragData[8];
|
||||||
v2 DragStartP;
|
v2 DragStartP;
|
||||||
|
|
||||||
ui_style_stacks Stacks;
|
ui_style_stacks Stacks;
|
||||||
|
|
||||||
|
platform_event_list *EventList;
|
||||||
|
v2 MouseP;
|
||||||
|
|
||||||
|
glyph_atlas *GlyphAtlas;
|
||||||
};
|
};
|
||||||
|
|
||||||
//- sixten: State management
|
//- sixten: State management
|
||||||
|
@ -166,20 +172,23 @@ inline void UI_StoreDragPointer(void *Data);
|
||||||
inline void *UI_GetDragDataPointer(void);
|
inline void *UI_GetDragDataPointer(void);
|
||||||
|
|
||||||
//- sixten: Key functions
|
//- sixten: Key functions
|
||||||
inline ui_key UI_EmptyKey(void);
|
static ui_key UI_EmptyKey(void);
|
||||||
inline ui_key UI_SeedKey(ui_key Key, ui_key Seed);
|
static ui_key UI_SeedKey(ui_key Key, ui_key Seed);
|
||||||
inline ui_key UI_GenerateKeyFromString(string String);
|
static ui_key UI_GenerateKeyFromString(string String);
|
||||||
static string UI_GetBoxNameByKey(ui_key Key);
|
static string UI_GetBoxNameByKey(ui_key Key);
|
||||||
inline ui_box *UI_GetBoxByKey(ui *UI, ui_key Key);
|
static ui_box *UI_GetBoxByKey(ui *UI, ui_key Key);
|
||||||
|
|
||||||
//- sixten: Box creation
|
//- sixten: Box creation
|
||||||
inline ui_box *UI_MakeBox(ui_box_flags Flags, string String);
|
static ui_box *UI_MakeBox(ui_box_flags Flags, string String);
|
||||||
inline ui_box *UI_MakeBoxF(ui_box_flags Flags, char *Format, ...);
|
static ui_box *UI_MakeBoxF(ui_box_flags Flags, char *Format, ...);
|
||||||
|
|
||||||
|
//- sixten: User interaction
|
||||||
|
static ui_signal UI_SignalFromBox(ui_box *Box);
|
||||||
|
|
||||||
//- sixten: Building and rendering
|
//- sixten: Building and rendering
|
||||||
static void UI_BeginBuild(ui *UI, v2 ScreenDim);
|
static void UI_BeginBuild(ui *UI, v2 ScreenDim);
|
||||||
static void UI_EndBuild(glyph_atlas *GlyphAtlas);
|
static void UI_EndBuild(void);
|
||||||
static void UI_RenderFrame(render_group *RenderGroup, glyph_atlas *GlyphAtlas);
|
static void UI_RenderFrame(render_group *RenderGroup);
|
||||||
static void UI_NewFrame(ui *UI, platform_event_list *EventList, v2 MouseP);
|
static void UI_NewFrame(ui *UI, platform_event_list *EventList, v2 MouseP, glyph_atlas *GlyphAtlas);
|
||||||
|
|
||||||
#endif //VN_UI_H
|
#endif //VN_UI_H
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
// sixten: Rows and columns.
|
//- sixten: Rows and columns.
|
||||||
inline void UI_RowBegin(void)
|
inline void UI_RowBegin(u32 Flags, string Name)
|
||||||
{
|
{
|
||||||
UI_SetNextLayoutAxis(Axis2_X);
|
UI_SetNextLayoutAxis(Axis2_X);
|
||||||
ui_box *Box = UI_MakeBox(0, StrLit(""));
|
ui_box *Box = UI_MakeBox(Flags, Name);
|
||||||
UI_PushParent(Box);
|
UI_PushParent(Box);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,10 +11,10 @@ inline void UI_RowEnd(void)
|
||||||
UI_PopParent();
|
UI_PopParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void UI_ColumnBegin(void)
|
inline void UI_ColumnBegin(u32 Flags, string Name)
|
||||||
{
|
{
|
||||||
UI_SetNextLayoutAxis(Axis2_Y);
|
UI_SetNextLayoutAxis(Axis2_Y);
|
||||||
ui_box *Box = UI_MakeBox(0, StrLit(""));
|
ui_box *Box = UI_MakeBox(Flags, Name);
|
||||||
UI_PushParent(Box);
|
UI_PushParent(Box);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,10 +23,7 @@ inline void UI_ColumnEnd(void)
|
||||||
UI_PopParent();
|
UI_PopParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
#define UI_Row DeferLoop(UI_RowBegin(), UI_RowEnd())
|
//- sixten: Compositions
|
||||||
#define UI_Column DeferLoop(UI_ColumnBegin(), UI_ColumnEnd())
|
|
||||||
|
|
||||||
// sixten: Compositions
|
|
||||||
inline void UI_PushAxisSize(axis2 Axis, ui_size Size)
|
inline void UI_PushAxisSize(axis2 Axis, ui_size Size)
|
||||||
{
|
{
|
||||||
if(Axis == Axis2_X)
|
if(Axis == Axis2_X)
|
||||||
|
@ -63,17 +60,7 @@ inline void UI_SetNextAxisSize(axis2 Axis, ui_size Size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define UI_AxisSize(Axis, Size) DeferLoop(UI_PushAxisSize(Axis, Size), UI_PopAxisSize(Axis))
|
//- sixten: Spacing
|
||||||
|
|
||||||
#define UI_Size(Width, Height) UI_Width(Width) UI_Height(Height)
|
|
||||||
#define UI_PushSize(Width, Height) UI_PushWidth(Width); UI_PushHeight(Height)
|
|
||||||
#define UI_PopSize() UI_PopWidth(); UI_PopHeight()
|
|
||||||
#define UI_SetNextSize(Width, Height) UI_SetNextWidth(Width); UI_SetNextHeight(Height)
|
|
||||||
|
|
||||||
#define UI_FixedP(Value) UI_FixedX(Value.x) UI_FixedY(Value.y)
|
|
||||||
#define UI_SetNextFixedP(Value) UI_SetNextFixedX(Value.x); UI_SetNextFixedY(Value.y)
|
|
||||||
|
|
||||||
// sixten: Spacing
|
|
||||||
static ui_box *UI_NamedSpacer(ui_size Size, string String)
|
static ui_box *UI_NamedSpacer(ui_size Size, string String)
|
||||||
{
|
{
|
||||||
ui_box *Parent = UI_TopParent();
|
ui_box *Parent = UI_TopParent();
|
||||||
|
@ -104,9 +91,10 @@ static void UI_Spacer(ui_size Size)
|
||||||
UI_NamedSpacer(Size, StrLit(""));
|
UI_NamedSpacer(Size, StrLit(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define UI_Padding(Size) DeferLoop(UI_Spacer(Size), UI_Spacer(Size))
|
//- sixten: Scrollable regions
|
||||||
|
|
||||||
// sixten: Common widgets
|
|
||||||
|
//- sixten: Common widgets
|
||||||
static ui_box *UI_Label(string String)
|
static ui_box *UI_Label(string String)
|
||||||
{
|
{
|
||||||
ui_box *Box = UI_MakeBox(UI_BoxFlag_DrawText, String);
|
ui_box *Box = UI_MakeBox(UI_BoxFlag_DrawText, String);
|
||||||
|
@ -165,7 +153,7 @@ static ui_signal UI_ButtonF(char *Format, ...)
|
||||||
return(Signal);
|
return(Signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ui_signal UI_Checkbox(string String, b32 *Checked)
|
static ui_signal UI_Checkbox(b32 *Checked, string String)
|
||||||
{
|
{
|
||||||
UI_SetNextSize(UI_ChildrenSum(1, 1), UI_ChildrenSum(1, 1));
|
UI_SetNextSize(UI_ChildrenSum(1, 1), UI_ChildrenSum(1, 1));
|
||||||
UI_SetNextLayoutAxis(Axis2_X);
|
UI_SetNextLayoutAxis(Axis2_X);
|
||||||
|
@ -197,3 +185,173 @@ static ui_signal UI_Checkbox(string String, b32 *Checked)
|
||||||
|
|
||||||
return(Signal);
|
return(Signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//- sixten: Scrollable regions
|
||||||
|
static ui_signal UI_Scrollbar(axis2 Axis, string Name, r32 Size, r32 Offset)
|
||||||
|
{
|
||||||
|
ui_signal Signal;
|
||||||
|
|
||||||
|
UI_SetNextAxisSize(Axis, UI_Percent(1, 0));
|
||||||
|
UI_SetNextAxisSize(Opposite(Axis), UI_Em(1, 1));
|
||||||
|
UI_SetNextBackgroundColor(Darken(UI_TopBackgroundColor(), 2));
|
||||||
|
UI_SetNextLayoutAxis(Axis);
|
||||||
|
UI_Parent(UI_MakeBox(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground, Name))
|
||||||
|
{
|
||||||
|
UI_SetNextSize(UI_Em(1, 1), UI_Em(1, 1));
|
||||||
|
UI_SetNextFont(Font_Icons);
|
||||||
|
UI_MakeBoxF(UI_BoxFlag_DrawText, "%U", Axis?FontIcon_UpDir:FontIcon_LeftDir);
|
||||||
|
|
||||||
|
UI_Spacer(UI_Pixels(Offset, 1));
|
||||||
|
|
||||||
|
UI_SetNextAxisSize(Axis, UI_Pixels(Size, 1));
|
||||||
|
UI_SetNextAxisSize(Opposite(Axis), UI_Percent(1, 1));
|
||||||
|
|
||||||
|
Signal = UI_SignalFromBox(UI_MakeBox(UI_BoxFlag_DrawBorder |
|
||||||
|
UI_BoxFlag_DrawBackground |
|
||||||
|
UI_BoxFlag_Clickable |
|
||||||
|
UI_BoxFlag_HotAnimation |
|
||||||
|
UI_BoxFlag_ActiveAnimation,
|
||||||
|
StrLit("Slider")));
|
||||||
|
|
||||||
|
UI_Spacer(UI_Percent(1, 0));
|
||||||
|
|
||||||
|
UI_SetNextSize(UI_Em(1, 1), UI_Em(1, 1));
|
||||||
|
UI_SetNextFont(Font_Icons);
|
||||||
|
UI_MakeBoxF(UI_BoxFlag_DrawText, "%U", Axis?FontIcon_DownDir:FontIcon_RightDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(Signal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Goal for next week: Be able to make basic dialog trees.
|
||||||
|
Goal for tomorrow: Scrollable regions and basic text editing (with line wrapping).
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void UI_ScrollBegin(r32 *X, r32 *Y, string Name)
|
||||||
|
{
|
||||||
|
u32 Flags = 0;
|
||||||
|
|
||||||
|
b32 AllowOnX = (X != 0);
|
||||||
|
b32 AllowOnY = (Y != 0);
|
||||||
|
|
||||||
|
UI_RowBegin(UI_BoxFlag_Clip|UI_BoxFlag_DrawBorder, Name);
|
||||||
|
{
|
||||||
|
UI_SetNextSize(UI_Percent(1, 0), UI_Percent(1, 0));
|
||||||
|
UI_ColumnBegin();
|
||||||
|
{
|
||||||
|
if(AllowOnX)
|
||||||
|
{
|
||||||
|
Flags |= UI_BoxFlag_OverflowX;
|
||||||
|
UI_SetNextOffsetX(-(*X));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(AllowOnY)
|
||||||
|
{
|
||||||
|
Flags |= UI_BoxFlag_OverflowY;
|
||||||
|
UI_SetNextOffsetY(-(*Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
UI_SetNextSize(AllowOnX?UI_ChildrenSum(1, 1):UI_Percent(1, 0),
|
||||||
|
AllowOnY?UI_ChildrenSum(1, 1):UI_Percent(1, 0));
|
||||||
|
|
||||||
|
ui_box *ScrollableBox = UI_MakeBox(Flags, StrLit("Scrollable Box"));
|
||||||
|
|
||||||
|
UI_PushParent(ScrollableBox);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UI_ScrollEnd(r32 *X, r32 *Y)
|
||||||
|
{
|
||||||
|
b32 AllowOnX = (X != 0);
|
||||||
|
b32 AllowOnY = (Y != 0);
|
||||||
|
|
||||||
|
ui_box *ScrollableBox = UI_TopParent();
|
||||||
|
{
|
||||||
|
{
|
||||||
|
UI_PopParent();
|
||||||
|
|
||||||
|
if(AllowOnX)
|
||||||
|
{
|
||||||
|
r32 TotalWidth = UI_CalculateBoxSize(ScrollableBox, Axis2_X);
|
||||||
|
r32 ViewWidth = UI_CalculateBoxSize(ScrollableBox->Parent->Parent, Axis2_X);
|
||||||
|
|
||||||
|
if(ViewWidth / TotalWidth < 1)
|
||||||
|
{
|
||||||
|
r32 TotalScrollWidth = ViewWidth - ScrollableBox->FontSize*2;
|
||||||
|
r32 ScrollScale = TotalScrollWidth / TotalWidth;
|
||||||
|
|
||||||
|
// sixten(TODO): Add a max of 1 em, and figure out the associated algebra.
|
||||||
|
r32 ScrollWidth = ViewWidth*ScrollScale;
|
||||||
|
r32 ScrollOffset = (*X)*ScrollScale;
|
||||||
|
|
||||||
|
ui_signal Signal = UI_Scrollbar(Axis2_X, StrLit("Scroll X"), ScrollWidth, ScrollOffset);
|
||||||
|
{
|
||||||
|
if(Signal.Dragging)
|
||||||
|
{
|
||||||
|
if(Signal.Pressed)
|
||||||
|
{
|
||||||
|
UI_StoreDragR32(*X);
|
||||||
|
}
|
||||||
|
|
||||||
|
r32 StartOffset = UI_GetDragR32();
|
||||||
|
r32 EndOffset = StartOffset + Signal.DragDelta.x/ScrollScale;
|
||||||
|
|
||||||
|
AnimationCurve_AnimateValueDirect(EndOffset, 0.2, X);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*X = Clamp(*X, 0, Max(0.0, TotalWidth - ViewWidth));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UI_ColumnEnd();
|
||||||
|
|
||||||
|
if(AllowOnY)
|
||||||
|
{
|
||||||
|
UI_SetNextSize(UI_ChildrenSum(1, 1), UI_Percent(1, 0));
|
||||||
|
UI_Column()
|
||||||
|
{
|
||||||
|
r32 TotalHeight = UI_CalculateBoxSize(ScrollableBox, Axis2_Y);
|
||||||
|
r32 ViewHeight = UI_CalculateBoxSize(ScrollableBox->Parent->Parent, Axis2_Y);
|
||||||
|
|
||||||
|
if(ViewHeight / TotalHeight < 1)
|
||||||
|
{
|
||||||
|
r32 TotalScrollHeight = ViewHeight - ScrollableBox->FontSize*2;
|
||||||
|
r32 ScrollScale = TotalScrollHeight / TotalHeight;
|
||||||
|
|
||||||
|
// sixten(TODO): Add a max of 1 em, and figure out the associated algebra.
|
||||||
|
r32 ScrollHeight = ViewHeight*ScrollScale;
|
||||||
|
r32 ScrollOffset = (*Y)*ScrollScale;
|
||||||
|
|
||||||
|
ui_signal Signal = UI_Scrollbar(Axis2_Y, StrLit("Scroll Y"), ScrollHeight, ScrollOffset);
|
||||||
|
{
|
||||||
|
if(Signal.Dragging)
|
||||||
|
{
|
||||||
|
if(Signal.Pressed)
|
||||||
|
{
|
||||||
|
UI_StoreDragR32(*Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
r32 StartOffset = UI_GetDragR32();
|
||||||
|
r32 EndOffset = StartOffset + Signal.DragDelta.y/ScrollScale;
|
||||||
|
|
||||||
|
AnimationCurve_AnimateValueDirect(EndOffset, 0.2, Y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*Y = Clamp(*Y, 0, Max(0.0, TotalHeight - ViewHeight));
|
||||||
|
}
|
||||||
|
// sixten: Add padding
|
||||||
|
if(AllowOnX && AllowOnY)
|
||||||
|
{
|
||||||
|
UI_SetNextSize(UI_Em(1, 1), UI_Em(1, 1));
|
||||||
|
UI_SetNextBackgroundColor(Darken(UI_TopBackgroundColor(), 2));
|
||||||
|
UI_MakeBox(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground, StrLit("Padding"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UI_RowEnd();
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
/* date = June 24th 2023 9:43 pm */
|
||||||
|
|
||||||
|
#ifndef VN_UI_UTILS_H
|
||||||
|
#define VN_UI_UTILS_H
|
||||||
|
|
||||||
|
//- sixten: Rows and columns.
|
||||||
|
inline void UI_RowBegin(u32 Flags = 0, string Name = StrLit(""));
|
||||||
|
inline void UI_RowEnd(void);
|
||||||
|
inline void UI_ColumnBegin(u32 Flags = 0, string Name = StrLit(""));
|
||||||
|
inline void UI_ColumnEnd(void);
|
||||||
|
|
||||||
|
#define UI_Row(...) DeferLoop(UI_RowBegin(__VA_ARGS__), UI_RowEnd())
|
||||||
|
#define UI_Column(...) DeferLoop(UI_ColumnBegin(__VA_ARGS__), UI_ColumnEnd())
|
||||||
|
|
||||||
|
//- sixten: Compositions
|
||||||
|
inline void UI_PushAxisSize(axis2 Axis, ui_size Size);
|
||||||
|
inline void UI_PopAxisSize(axis2 Axis);
|
||||||
|
inline void UI_SetNextAxisSize(axis2 Axis, ui_size Size);
|
||||||
|
|
||||||
|
#define UI_AxisSize(Axis, Size) DeferLoop(UI_PushAxisSize(Axis, Size), UI_PopAxisSize(Axis))
|
||||||
|
|
||||||
|
#define UI_Size(Width, Height) UI_Width(Width) UI_Height(Height)
|
||||||
|
#define UI_PushSize(Width, Height) UI_PushWidth(Width); UI_PushHeight(Height)
|
||||||
|
#define UI_PopSize() UI_PopWidth(); UI_PopHeight()
|
||||||
|
#define UI_SetNextSize(Width, Height) UI_SetNextWidth(Width); UI_SetNextHeight(Height)
|
||||||
|
|
||||||
|
#define UI_Offset(x, y) UI_OffsetX(x) UI_OffsetY(y)
|
||||||
|
#define UI_PushOffset(x, y) UI_PushOffsetX(x); UI_PushOffsetY(y)
|
||||||
|
#define UI_PopOffset() UI_PopOffsetX(); UI_PopOffsetY()
|
||||||
|
#define UI_SetNextOffset(x, y) UI_SetNextOffsetX(x); UI_SetNextOffsetY(y)
|
||||||
|
|
||||||
|
#define UI_FixedP(Value) UI_FixedX(Value.x) UI_FixedY(Value.y)
|
||||||
|
#define UI_SetNextFixedP(Value) UI_SetNextFixedX(Value.x); UI_SetNextFixedY(Value.y)
|
||||||
|
|
||||||
|
//- sixten: Spacing
|
||||||
|
static ui_box *UI_NamedSpacer(ui_size Size, string String);
|
||||||
|
static ui_box *UI_NamedSpacerF(ui_size Size, char *Format, ...);
|
||||||
|
|
||||||
|
#define UI_Padding(Size) DeferLoop(UI_Spacer(Size), UI_Spacer(Size))
|
||||||
|
|
||||||
|
//- sixten: Scrollable regions
|
||||||
|
static void UI_ScrollBegin(r32 *X, r32 *Y, string Name = StrLit("Scrollable Region Container"));
|
||||||
|
static void UI_ScrollEnd(r32 *X, r32 *Y, string Name);
|
||||||
|
|
||||||
|
#define UI_Scroll(...) DeferLoop(UI_ScrollBegin(__VA_ARGS__), UI_ScrollEnd(__VA_ARGS__))
|
||||||
|
|
||||||
|
//- sixten: Common widgets
|
||||||
|
static ui_box *UI_Label(string String);
|
||||||
|
static ui_box *UI_LabelF(char *Format, ...);
|
||||||
|
|
||||||
|
static ui_signal UI_Button(string String);
|
||||||
|
static ui_signal UI_ButtonF(char *Format, ...);
|
||||||
|
|
||||||
|
static ui_signal UI_Checkbox(b32 *Checked, string String);
|
||||||
|
|
||||||
|
#endif //VN_UI_UTILS_H
|
|
@ -205,6 +205,12 @@ static void Workspace_BuildToolbar(workspace *Workspace, r32 dtForFrame)
|
||||||
|
|
||||||
Workspace->Menu = ToolbarMenu_None;
|
Workspace->Menu = ToolbarMenu_None;
|
||||||
}
|
}
|
||||||
|
if(Workspace_BuildMenuItem(FontIcon_None, "Command Palette", "").Clicked)
|
||||||
|
{
|
||||||
|
Workspace_CreateNewView(Workspace_View_CommandPalette, CurrentPanel);
|
||||||
|
|
||||||
|
Workspace->Menu = ToolbarMenu_None;
|
||||||
|
}
|
||||||
if(Workspace_BuildMenuItem(FontIcon_Wrench, "Settings", "").Clicked)
|
if(Workspace_BuildMenuItem(FontIcon_Wrench, "Settings", "").Clicked)
|
||||||
{
|
{
|
||||||
Workspace_CreateNewView(Workspace_View_Settings, CurrentPanel);
|
Workspace_CreateNewView(Workspace_View_Settings, CurrentPanel);
|
||||||
|
@ -419,6 +425,8 @@ static void Workspace_BuildPanelHeader(workspace *Workspace, workspace_panel *Pa
|
||||||
Workspace_BuildTabItem(Workspace, Panel, View);
|
Workspace_BuildTabItem(Workspace, Panel, View);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UI_Spacer(UI_Percent(1, 0));
|
||||||
|
|
||||||
// sixten: Panel Close Button
|
// sixten: Panel Close Button
|
||||||
if(Panel != Workspace->RootPanel)
|
if(Panel != Workspace->RootPanel)
|
||||||
{
|
{
|
||||||
|
@ -500,8 +508,8 @@ static void Workspace_BuildPanel(workspace *Workspace, workspace_panel *Panel)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UI_Column UI_Padding(UI_Percent(1, 0))
|
UI_Column() UI_Padding(UI_Percent(1, 0))
|
||||||
UI_Height(UI_ChildrenSum(1, 1)) UI_Row UI_Padding(UI_Percent(1, 0))
|
UI_Height(UI_ChildrenSum(1, 1)) UI_Row() UI_Padding(UI_Percent(1, 0))
|
||||||
{
|
{
|
||||||
UI_Size(UI_TextContent(0, 1), UI_TextContent(10, 1))
|
UI_Size(UI_TextContent(0, 1), UI_TextContent(10, 1))
|
||||||
{
|
{
|
||||||
|
|
|
@ -146,7 +146,7 @@ static void Workspace_BuildViewTypeLister(workspace *Workspace, workspace_view *
|
||||||
ui_box *InputTextBox = UI_MakeBox(UI_BoxFlag_DrawText, StrLit("Workspace View Lister"));
|
ui_box *InputTextBox = UI_MakeBox(UI_BoxFlag_DrawText, StrLit("Workspace View Lister"));
|
||||||
InputTextBox->String = MakeString(CommandPalette->ListerInput, CommandPalette->ListerInputUsed);
|
InputTextBox->String = MakeString(CommandPalette->ListerInput, CommandPalette->ListerInputUsed);
|
||||||
InputTextBox->DrawCallback = Workspace_ViewListerInputCallback;
|
InputTextBox->DrawCallback = Workspace_ViewListerInputCallback;
|
||||||
InputTextBox->DrawCallbackData = View;
|
InputTextBox->DrawCallbackData = CommandPalette;
|
||||||
}
|
}
|
||||||
|
|
||||||
UI_Spacer(UI_Pixels(4, 1));
|
UI_Spacer(UI_Pixels(4, 1));
|
||||||
|
@ -338,8 +338,8 @@ static void Workspace_BuildSettings(workspace *Workspace, workspace_view *View)
|
||||||
workspace_view_settings *Settings = (workspace_view_settings *)View->Data;
|
workspace_view_settings *Settings = (workspace_view_settings *)View->Data;
|
||||||
|
|
||||||
UI_Height(UI_ChildrenSum(1, 1))
|
UI_Height(UI_ChildrenSum(1, 1))
|
||||||
UI_Column UI_Padding(UI_Pixels(50, 0))
|
UI_Column() UI_Padding(UI_Pixels(50, 0))
|
||||||
UI_Row UI_Padding(UI_Pixels(50, 0))
|
UI_Row() UI_Padding(UI_Pixels(50, 0))
|
||||||
{
|
{
|
||||||
UI_Size(UI_TextContent(0, 1), UI_TextContent(10, 1))
|
UI_Size(UI_TextContent(0, 1), UI_TextContent(10, 1))
|
||||||
UI_Font(Font_Bold) UI_FontSize(36)
|
UI_Font(Font_Bold) UI_FontSize(36)
|
||||||
|
@ -353,8 +353,8 @@ static void Workspace_BuildSettings(workspace *Workspace, workspace_view *View)
|
||||||
UI_Width(UI_Pixels(300, 1))
|
UI_Width(UI_Pixels(300, 1))
|
||||||
UI_Parent(UI_MakeBoxF(0, "Navigation"))
|
UI_Parent(UI_MakeBoxF(0, "Navigation"))
|
||||||
{
|
{
|
||||||
UI_Row UI_Padding(UI_Pixels(50, 1))
|
UI_Row() UI_Padding(UI_Pixels(50, 1))
|
||||||
UI_Width(UI_Percent(1, 0)) UI_Column UI_Padding(UI_Percent(1, 0))
|
UI_Width(UI_Percent(1, 0)) UI_Column() UI_Padding(UI_Percent(1, 0))
|
||||||
UI_Height(UI_ChildrenSum(1, 1)) UI_LayoutAxis(Axis2_Y) UI_Parent(UI_MakeBoxF(0, ""))
|
UI_Height(UI_ChildrenSum(1, 1)) UI_LayoutAxis(Axis2_Y) UI_Parent(UI_MakeBoxF(0, ""))
|
||||||
{
|
{
|
||||||
Workspace_BuildSettingsTabButton(Settings, "All", Workspace_Settings_All);
|
Workspace_BuildSettingsTabButton(Settings, "All", Workspace_Settings_All);
|
||||||
|
@ -391,12 +391,11 @@ static void Workspace_BuildSettings(workspace *Workspace, workspace_view *View)
|
||||||
s32 DropdownSelected;
|
s32 DropdownSelected;
|
||||||
FindIndexOfElement(DropdownSelected, AlternativeMapping, 0, Workspace->Input->RefreshRate);
|
FindIndexOfElement(DropdownSelected, AlternativeMapping, 0, Workspace->Input->RefreshRate);
|
||||||
|
|
||||||
persist b32 DropdownOpen = false;
|
if(UI_DropdownSelection(Alternatives, ArrayCount(Alternatives),
|
||||||
|
&Settings->GeneralDropdownOpen, &DropdownSelected))
|
||||||
if(UI_DropdownSelection(Alternatives, ArrayCount(Alternatives), &DropdownOpen, &DropdownSelected))
|
|
||||||
{
|
{
|
||||||
Workspace->Input->RefreshRate = AlternativeMapping[DropdownSelected];
|
Workspace->Input->RefreshRate = AlternativeMapping[DropdownSelected];
|
||||||
DropdownOpen = false;
|
Settings->GeneralDropdownOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
UI_Spacer(UI_Pixels(50, 1));
|
UI_Spacer(UI_Pixels(50, 1));
|
||||||
|
@ -406,19 +405,25 @@ static void Workspace_BuildSettings(workspace *Workspace, workspace_view *View)
|
||||||
{
|
{
|
||||||
UI_Font(Font_Bold) UI_FontSize(36) UI_LabelF("Theme");
|
UI_Font(Font_Bold) UI_FontSize(36) UI_LabelF("Theme");
|
||||||
|
|
||||||
UI_SetNextSize(UI_Percent(1, 1), UI_ChildrenSum(1, 1));
|
UI_SetNextSize(UI_Percent(1, 1), UI_Em(13, 1));
|
||||||
UI_SetNextCornerRadius(3);
|
|
||||||
|
|
||||||
UI_Parent(UI_MakeBoxF(UI_BoxFlag_DrawBorder, "Theme Lister"))
|
UI_Scroll(0, &Settings->ThemeScroll)
|
||||||
UI_Size(UI_Percent(1, 1), UI_Em(2, 1))
|
|
||||||
{
|
{
|
||||||
UI_ButtonF("Hello");
|
UI_Size(UI_Percent(1, 1), UI_Em(2, 1))
|
||||||
UI_ButtonF("Line");
|
{
|
||||||
UI_ButtonF("Paint");
|
for(s32 Index = 0;
|
||||||
UI_ButtonF("Color");
|
Index < 2;
|
||||||
UI_ButtonF("Design");
|
++Index)
|
||||||
UI_ButtonF("Address");
|
{
|
||||||
UI_ButtonF("Brightness");
|
UI_ButtonF("Hello#%i", Index);
|
||||||
|
UI_ButtonF("Line#%i", Index);
|
||||||
|
UI_ButtonF("Paint#%i", Index);
|
||||||
|
UI_ButtonF("Color#%i", Index);
|
||||||
|
UI_ButtonF("Design#%i", Index);
|
||||||
|
UI_ButtonF("Address#%i", Index);
|
||||||
|
UI_ButtonF("Brightness#%i", Index);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UI_Spacer(UI_Pixels(50, 1));
|
UI_Spacer(UI_Pixels(50, 1));
|
||||||
|
@ -427,9 +432,11 @@ static void Workspace_BuildSettings(workspace *Workspace, workspace_view *View)
|
||||||
if(!Category || (Category == Workspace_Settings_Developer))
|
if(!Category || (Category == Workspace_Settings_Developer))
|
||||||
{
|
{
|
||||||
UI_Font(Font_Bold) UI_FontSize(36) UI_LabelF("Developer");
|
UI_Font(Font_Bold) UI_FontSize(36) UI_LabelF("Developer");
|
||||||
UI_Checkbox(StrLit("Render UI Debug Rects"), &DEBUG_DebugSettings->RenderUIDebugRects);
|
UI_Checkbox(&DEBUG_DebugSettings->RenderUIDebugRects, StrLit("Render UI Debug Rects"));
|
||||||
UI_Spacer(UI_Pixels(5, 1));
|
UI_Spacer(UI_Pixels(5, 1));
|
||||||
UI_Checkbox(StrLit("Render FPS Counter"), &DEBUG_DebugSettings->RenderFPSCounter);
|
UI_Checkbox(&DEBUG_DebugSettings->RenderFPSCounter, StrLit("Render FPS Counter"));
|
||||||
|
UI_Spacer(UI_Pixels(5, 1));
|
||||||
|
UI_Checkbox(&DEBUG_DebugSettings->ListHotAndActive, StrLit("List Hot & Active"));
|
||||||
|
|
||||||
UI_Spacer(UI_Pixels(50, 1));
|
UI_Spacer(UI_Pixels(50, 1));
|
||||||
}
|
}
|
||||||
|
@ -459,8 +466,8 @@ static void Workspace_BuildView(workspace *Workspace, workspace_view *View)
|
||||||
{
|
{
|
||||||
if(View->Type == Workspace_View_Startup)
|
if(View->Type == Workspace_View_Startup)
|
||||||
{
|
{
|
||||||
UI_Row UI_Padding(UI_Pixels(50, 0))
|
UI_Row() UI_Padding(UI_Pixels(50, 0))
|
||||||
UI_Width(UI_ChildrenSum(1, 1)) UI_Column UI_Padding(UI_Pixels(50, 0))
|
UI_Width(UI_ChildrenSum(1, 1)) UI_Column() UI_Padding(UI_Pixels(50, 0))
|
||||||
{
|
{
|
||||||
UI_Size(UI_TextContent(0, 1), UI_TextContent(10, 1))
|
UI_Size(UI_TextContent(0, 1), UI_TextContent(10, 1))
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,6 +53,12 @@ enum workspace_settings_category
|
||||||
struct workspace_view_settings
|
struct workspace_view_settings
|
||||||
{
|
{
|
||||||
workspace_settings_category Category;
|
workspace_settings_category Category;
|
||||||
|
|
||||||
|
// sixten: General
|
||||||
|
b32 GeneralDropdownOpen;
|
||||||
|
|
||||||
|
// sixten: Theme
|
||||||
|
r32 ThemeScroll;
|
||||||
};
|
};
|
||||||
|
|
||||||
//- sixten: Views
|
//- sixten: Views
|
||||||
|
|
|
@ -7,4 +7,5 @@ Dev
|
||||||
{
|
{
|
||||||
RenderUIDebugRects = false;
|
RenderUIDebugRects = false;
|
||||||
RenderFPSCounter = false;
|
RenderFPSCounter = false;
|
||||||
|
ListHotAndActive = true;
|
||||||
}
|
}
|
Binary file not shown.
5
todo.txt
5
todo.txt
|
@ -1,9 +1,12 @@
|
||||||
This is a list of things that needs doing in a SUGGESTED order.
|
This is a list of things that needs doing in a SUGGESTED order.
|
||||||
|
|
||||||
* UI
|
* UI
|
||||||
- Settings / Preferences view. (Including saving and loading of these settings/preferences)
|
- Incorrect behaviour when closing panels in a certain order, most likely some things are not being copied over properly.
|
||||||
|
|
||||||
* Rendering
|
* Rendering
|
||||||
- Fix texture clipping
|
- Fix texture clipping
|
||||||
- Control over each corner when rounding
|
- Control over each corner when rounding
|
||||||
|
|
||||||
|
Completed
|
||||||
|
* UI
|
||||||
|
- Settings / Preferences view. (Including saving and loading of these settings/preferences)
|
Loading…
Reference in New Issue