From e8b5edb3710ee76b1a59b170975e72b0ea0cde0f Mon Sep 17 00:00:00 2001 From: jacob Date: Mon, 29 Dec 2025 22:53:04 -0600 Subject: [PATCH] working tweak vars --- src/base/base.cgh | 2 +- src/base/base_state.h | 2 +- src/base/base_tweak.c | 84 +++-- src/base/base_tweak.h | 33 +- src/base/base_win32/base_win32.c | 3 + src/config.h | 2 +- src/glyph_cache/glyph_cache.c | 2 +- src/pp/pp_vis/pp_vis_core.c | 581 ++++++++++++++++++------------- src/pp/pp_vis/pp_vis_core.h | 46 +-- 9 files changed, 438 insertions(+), 317 deletions(-) diff --git a/src/base/base.cgh b/src/base/base.cgh index 0c779f88..296e30b6 100644 --- a/src/base/base.cgh +++ b/src/base/base.cgh @@ -431,7 +431,7 @@ #define IsFixedArray(a) (IsIndexable(a) && (((void *)&a) == ((void *)a))) //- offsetof -#if !IsCompilerMsvc +#if IsCompilerMsvc #ifdef _CRT_USE_BUILTIN_OFFSETOF #define offsetof(type, field) __builtin_offsetof(type, field) #else diff --git a/src/base/base_state.h b/src/base/base_state.h index da676b05..d77d3a2b 100644 --- a/src/base/base_state.h +++ b/src/base/base_state.h @@ -3,11 +3,11 @@ Struct(BaseCtx) { + TweakVarsCtx tweak; CmdLineCtx cmdline; ResourceCtx resource; GstatCtx gstat; AsyncCtx async; - TweakVarsCtx tweak; }; extern BaseCtx Base; diff --git a/src/base/base_tweak.c b/src/base/base_tweak.c index 21210484..20b332b6 100644 --- a/src/base/base_tweak.c +++ b/src/base/base_tweak.c @@ -1,39 +1,81 @@ +//////////////////////////////////////////////////////////// +//~ Bootstrap + +void BootstrapTweakVars(void) +{ + // TODO: Swap in/out for persistence + #define X(name, type, default_value) Base.tweak.shared_vars.##name = default_value; + TweakVarsXMacro(X); + #undef X +} + //////////////////////////////////////////////////////////// //~ Tweak var get/set //- Auto-generated functions -#define X(name, type, default_value) \ - type GetTweak_##name(void) \ - { \ - type result = Zi; \ - LockTicketMutex(&Base.tweak.mutex); \ - { \ - result = Base.tweak.shared_vars.##name; \ - } \ - UnlockTicketMutex(&Base.tweak.mutex); \ - return result; \ - } \ - void SetTweak_##name(type v) \ - { \ - LockTicketMutex(&Base.tweak.mutex); \ - { \ - Base.tweak.shared_vars.name = v; \ - } \ - UnlockTicketMutex(&Base.tweak.mutex); \ +#define X(name, type, default_value) \ + type GetGlobalTweakVar_TweakVarKind_##name(void) \ + { \ + type result = Zi; \ + LockTicketMutex(&Base.tweak.tm); \ + { \ + result = Base.tweak.shared_vars.##name; \ + } \ + UnlockTicketMutex(&Base.tweak.tm); \ + return result; \ + } \ + void SetGlobalTweakVar_TweakVarKind_##name(type v) \ + { \ + LockTicketMutex(&Base.tweak.tm); \ + { \ + Base.tweak.shared_vars.name = v; \ + } \ + UnlockTicketMutex(&Base.tweak.tm); \ } TweakVarsXMacro(X); #undef X //- Helpers -TweakVars GetAllTweakVars(void) +TweakVarDesc TweakVarDescFromKind(TweakVarKind kind) +{ + Readonly PERSIST TweakVarDesc descs[TweakVarKind_COUNT] = { +#define X(_name, _type, _default_value) \ + { \ + .name = CompLit(#_name), \ + .type = TweakVarType_##_type, \ + .offset = offsetof(TweakVars, _name), \ + .default_##_type = (_default_value), \ + }, + TweakVarsXMacro(X) +#undef X + }; + + TweakVarDesc result = Zi; + if (kind >= 0 && kind < countof(descs)) + { + result = descs[kind]; + } + return result; +} + +TweakVars GetAllGlobalTweakVars(void) { TweakVars result; - LockTicketMutex(&Base.tweak.mutex); + LockTicketMutex(&Base.tweak.tm); { result = Base.tweak.shared_vars; } - UnlockTicketMutex(&Base.tweak.mutex); + UnlockTicketMutex(&Base.tweak.tm); return result; } + +void SetAllGlobalTweakVars(TweakVars *v) +{ + LockTicketMutex(&Base.tweak.tm); + { + CopyStruct(&Base.tweak.shared_vars, v); + } + UnlockTicketMutex(&Base.tweak.tm); +} diff --git a/src/base/base_tweak.h b/src/base/base_tweak.h index 682c923c..dd40d2ff 100644 --- a/src/base/base_tweak.h +++ b/src/base/base_tweak.h @@ -22,22 +22,43 @@ Struct(TweakVars) i32 __; // Prevent empty struct }; +Struct(TweakVarDesc) +{ + String name; + TweakVarType type; + i32 offset; + union + { + b32 default_b32; + }; +}; + +//////////////////////////////////////////////////////////// +//~ State types + Struct(TweakVarsCtx) { - TicketMutex mutex; + TicketMutex tm; TweakVars shared_vars; }; +//////////////////////////////////////////////////////////// +//~ Bootstrap + +void BootstrapTweakVars(void); + //////////////////////////////////////////////////////////// //~ Tweak var operations //- Auto-generated functions #define X(name, type, ...) \ - type GetTweak_##name(void); \ - void SetTweak_##name(type v); + type GetGlobalTweakVar_##name(void); \ + void SetGlobalTweakVar_##name(type v); #undef X //- Helpers -TweakVars GetAllTweakVars(void); -#define GetTweak(name) GetTweak_##name() -#define SetTweak(name, v) SetTweak_##name((v)) +TweakVarDesc TweakVarDescFromKind(TweakVarKind kind); +TweakVars GetAllGlobalTweakVars(void); +void SetAllGlobalTweakVars(TweakVars *v); +#define GetGlobalTweakVar(name) GetGlobalTweakVar_TweakVarKind_##name() +#define SetGlobalTweakVar(name, v) SetGlobalTweakVar_TweakVarKind_##name((v)) diff --git a/src/base/base_win32/base_win32.c b/src/base/base_win32/base_win32.c index 2f32f76a..8e925ee6 100644 --- a/src/base/base_win32/base_win32.c +++ b/src/base/base_win32/base_win32.c @@ -451,6 +451,9 @@ i32 W32_Main(void) ////////////////////////////// //- Bootstrap + // Bootstrap tweak vars + BootstrapTweakVars(); + // Bootstrap command line BootstrapCmdline(); diff --git a/src/config.h b/src/config.h index b9f87b49..9e77fc1c 100644 --- a/src/config.h +++ b/src/config.h @@ -2,7 +2,7 @@ //~ Debug tweak vars #define TweakVarsXMacro(X) \ - X(CeilGlyphAdvances, b32, 1) \ + X(CeilGlyphAdvances, b32, 0) \ /* --------------------------------- */ //////////////////////////////////////////////////////////// diff --git a/src/glyph_cache/glyph_cache.c b/src/glyph_cache/glyph_cache.c index 5cdba8f0..cdda1130 100644 --- a/src/glyph_cache/glyph_cache.c +++ b/src/glyph_cache/glyph_cache.c @@ -180,7 +180,7 @@ GC_Run GC_RunFromString(Arena *arena, String str, GC_FontKey font, f32 font_size GC_RunRect *rect = &result.rects[glyph_idx]; f32 advance = 0; - if (GetTweak(CeilGlyphAdvances)) + if (GetGlobalTweakVar(CeilGlyphAdvances)) { advance = CeilF32(glyph->advance * scale); } diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index 10fc612d..0e7f7ae1 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -28,6 +28,19 @@ V_Frame *V_LastFrame(void) return &V.frames[(V.current_frame_tick - 1) % countof(V.frames)]; } +V_Cmd *V_PushVisCmd(String name) +{ + V_Frame *frame = V_CurrentFrame(); + V_CmdNode *cmd_node = PushStruct(frame->arena, V_CmdNode); + V_Cmd *cmd = &cmd_node->cmd; + { + cmd->name = name; + } + ++frame->cmds_count; + SllQueuePush(frame->first_cmd_node, frame->last_cmd_node, cmd_node); + return cmd; +} + S_Cmd *V_PushSimCmd(S_CmdKind kind) { V_Frame *frame = V_CurrentFrame(); @@ -87,6 +100,9 @@ V_WidgetTheme V_GetWidgetTheme(void) theme.button_hot_color = Rgb32(0x103c4c); theme.button_selected_color = Rgb32(0x00668D); + theme.color_positive = VEC4(0.25, 0.5, 0.25, 1); + theme.color_negative = VEC4(0.5, 0.25, 0.25, 1); + theme.window_title_font_size = 16; theme.text_padding_x = 5; theme.text_padding_y = 5; @@ -100,227 +116,6 @@ void V_PushWidgetThemeStyles(V_WidgetTheme theme) UI_Push(FontSize, theme.font_size); } -//////////////////////////////////////////////////////////// -//~ Palette - -void V_BeginPalette(V_Palette *widget) -{ - ZeroStruct(&widget->build); - widget->build.cp = UI_PushCP(UI_NilKey); - widget->key = UI_KeyF("commands palette"); - UI_Push(Tag, widget->key.hash); -} - -V_PaletteItemReport V_PushPaletteItem(V_Palette *widget, V_PaletteItemDesc desc) -{ - Arena *frame_arena = UI_FrameArena(); - - UI_Key key = UI_KeyF("btn%F", FmtSint(widget->build.num_items)); - { - V_PaletteItem *item = PushStruct(frame_arena, V_PaletteItem); - item->key = key; - item->desc = desc; - SllQueuePush(widget->build.first_item, widget->build.last_item, item); - ++widget->build.num_items; - } - - V_PaletteItemReport result = Zi; - UI_Report rep = UI_ReportFromKey(key); - result.ui_report = rep; - result.pressed = rep.m1.presses > 0; - CopyStructs(result.new_hotkeys, desc.hotkeys, MinU32(countof(result.new_hotkeys), countof(desc.hotkeys))); - return result; -} - -void V_EndPalette(V_Palette *widget) -{ - V_Frame *frame = V_CurrentFrame(); - V_WidgetTheme theme = V_GetWidgetTheme(); - Vec2 cursor_pos = UI_CursorPos(); - - UI_Key titlebar_key = UI_KeyF("title bar"); - UI_Report titlebar_rep = UI_ReportFromKey(titlebar_key); - UI_Report widget_rep = UI_ReportFromKey(widget->key); - Vec2 widget_half_dims = MulVec2(DimsFromRng2(widget_rep.screen_rect), 0.5); - - Vec4 window_background_color = theme.window_background_color; - // Vec4 window_background_color = VEC4(0, 0, 0, 0); - Vec4 window_border_color = theme.window_border_color; - Vec4 titlebar_color = Zi; - Vec4 titlebar_border_color = Zi; - Vec4 divider_color = theme.divider_color; - if (titlebar_rep.m1.held) - { - widget->pos = AddVec2(SubVec2(cursor_pos, titlebar_rep.last_mouse_down_cursor_offset), widget_half_dims); - } - window_border_color = LerpSrgb(window_border_color, Rgb32(0x0078a6), titlebar_rep.hot); - - UI_Push(Scale, LerpF32(0.75, 1, widget_rep.selected)); - UI_Push(Tint, VEC4(1, 1, 1, widget_rep.selected)); - if (widget_rep.selected < 0.25) - { - UI_Push(OmitFlags, UI_UseTop(OmitFlags) | UI_BoxFlag_Interactable); - } - - UI_Push(BackgroundColor, window_background_color); - UI_Push(BorderColor, window_border_color); - UI_Push(Border, theme.window_border); - UI_Push(Rounding, UI_RPIX(15)); - UI_Push(Width, UI_PIX(theme.window_width, 0)); - UI_Push(Height, UI_SHRINK(0, 0)); - UI_Push(ChildLayoutAxis, Axis_Y); - UI_Push(FloatingPos, SubVec2(widget->pos, widget_half_dims)); - UI_SetNext(Flags, UI_BoxFlag_Floating | (UI_BoxFlag_Selected * frame->show_palette)); - UI_PushCP(UI_BuildBoxEx(widget->key)); - { - // Title bar - UI_PushCP(UI_NilKey); - { - UI_Push(BackgroundColor, titlebar_color); - UI_Push(BorderColor, titlebar_border_color); - UI_Push(Rounding, UI_RPIX(0)); - UI_Push(ChildLayoutAxis, Axis_X); - UI_Push(Width, UI_GROW(1, 0)); - UI_Push(Height, UI_FNT(2, 1)); - UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_Interactable); - UI_PushCP(UI_BuildBoxEx(titlebar_key)); - { - UI_Push(Width, UI_GROW(1, 0)); - UI_Push(BorderColor, 0); - - // Left title box - UI_BuildRow(); - - // Title box - UI_SetNext(FontSize, theme.window_title_font_size); - UI_SetNext(ChildAlignment, UI_Alignment_Center); - UI_SetNext(Width, UI_SHRINK(0, 1)); - UI_SetNext(Text, Lit("Command Palette")); - UI_SetNext(Flags, UI_BoxFlag_DrawText); - UI_BuildBox(); - - // Right title box - UI_BuildRow(); - } - UI_PopCP(UI_TopCP()); - } - UI_PopCP(UI_TopCP()); - } - - f32 padding = theme.window_border; - UI_SetNext(Tint, 0); - UI_SetNext(Rounding, 0); - UI_PushCP(UI_BuildRow()); - { - UI_BuildSpacer(UI_PIX(padding, 1), Axis_X); - { - UI_SetNext(Tint, 0); - UI_SetNext(Rounding, 0); - UI_SetNext(Width, UI_GROW(1, 0)); - UI_PushCP(UI_BuildColumn()); - { - for (V_PaletteItem *item = widget->build.first_item; item; item = item->next) - { - UI_BuildDivider(UI_PIX(1, 1), theme.divider_color, Axis_Y); - - UI_Key btn_key = item->key; - UI_Report btn_rep = UI_ReportFromKey(btn_key); - - Vec4 btn_color = theme.window_background_color; - btn_color = LerpSrgb(btn_color, theme.button_hot_color, btn_rep.hot); - btn_color = LerpSrgb(btn_color, theme.button_active_color, btn_rep.active); - Vec4 btn_border_color = LerpSrgb(VEC4(0, 0, 0, 0), theme.button_active_color, btn_rep.hot); - - UI_SetNext(Rounding, 0); - UI_SetNext(Tint, 0); - UI_PushCP(UI_BuildRow()); - { - UI_SetNext(BorderColor, btn_border_color); - UI_SetNext(BackgroundColor, btn_color); - UI_SetNext(Rounding, UI_RPIX(5)); - UI_SetNext(Width, UI_GROW(1, 0)); - UI_SetNext(Height, UI_FNT(1.5, 1)); - UI_SetNext(ChildAlignment, UI_Alignment_Left); - UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_Interactable); - UI_PushCP(UI_BuildRowEx(btn_key)); - { - UI_Push(Tag, btn_key.hash); - - // Begin spacer - UI_BuildSpacer(UI_PIX(20, 1), Axis_X); - - // Command label - // UI_SetNext(ChildAlignment, UI_Alignment_Center); - UI_SetNext(ChildAlignment, UI_Alignment_Left); - UI_BuildLabel(item->desc.display_name); - - // Middle spacer - UI_BuildSpacer(UI_GROW(1, 0), Axis_X); - - // Command hotkey buttons - for (u64 i = 0; i < countof(item->desc.hotkeys); ++i) - { - UI_Key hotkey_key = UI_KeyF("hotkey%F", FmtUint(i)); - UI_Report hotkey_rep = UI_ReportFromKey(hotkey_key); - - Vec4 hotkey_color = Zi; - Vec4 hotkey_border_color = Zi; - { - Vec4 hovered_color = Rgb32(0x103c4c); - Vec4 pressed_color = hovered_color; - pressed_color.w = 0.2; - f32 hotkey_hot = hotkey_rep.hot; - f32 hotkey_active = hotkey_rep.active; - f32 hotkey_hovered = hotkey_rep.hovered; - hotkey_color = LerpSrgb(hotkey_color, hovered_color, hotkey_hot); - hotkey_color = LerpSrgb(hotkey_color, pressed_color, hotkey_active * hotkey_hovered); - hotkey_border_color = LerpSrgb(hotkey_border_color, Rgb32(0x0078a6), hotkey_hot); - } - - V_Hotkey hotkey = item->desc.hotkeys[i]; - if (hotkey.button == Button_None) - { - break; - } - else - { - UI_BuildSpacer(UI_PIX(10, 1), Axis_X); - - String hotkey_name = V_StringFromHotkey(UI_FrameArena(), hotkey); - UI_SetNext(BackgroundColor, hotkey_color); - UI_SetNext(BorderColor, hotkey_border_color); - UI_SetNext(Text, hotkey_name); - UI_SetNext(Width, UI_SHRINK(theme.text_padding_x, 1)); - UI_SetNext(Height, UI_GROW(1, 0)); - UI_SetNext(Rounding, UI_RPIX(5)); - UI_SetNext(Border, 1); - UI_SetNext(ChildAlignment, UI_Alignment_Center); - UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_Interactable); - UI_PushCP(UI_BuildRowEx(hotkey_key)); - { - } - UI_PopCP(UI_TopCP()); - } - } - - // End spacer - UI_BuildSpacer(UI_PIX(20, 1), Axis_X); - } - UI_PopCP(UI_TopCP()); - } - UI_PopCP(UI_TopCP()); - } - } - UI_PopCP(UI_TopCP()); - } - UI_BuildSpacer(UI_PIX(padding, 1), Axis_X); - } - UI_PopCP(UI_TopCP()); - - UI_BuildSpacer(UI_PIX(padding, 1), Axis_Y); - UI_PopCP(widget->build.cp); -} - //////////////////////////////////////////////////////////// //~ Vis tick @@ -610,10 +405,6 @@ void V_TickForever(WaveLaneCtx *lane) ////////////////////////////// //- Process controller events into vis cmds - u64 cmds_count = 0; - V_CmdNode *first_cmd_node = 0; - V_CmdNode *last_cmd_node = 0; - b32 has_mouse_focus = UI_IsKeyNil(ui_frame->hot_box) || UI_MatchKey(ui_frame->hot_box, vis_box); b32 has_keyboard_focus = 1; if (!window_frame.has_focus) @@ -685,10 +476,7 @@ void V_TickForever(WaveLaneCtx *lane) } if (shortcut != 0 && down) { - V_CmdNode *cmd_node = PushStruct(frame->arena, V_CmdNode); - cmd_node->cmd.name = shortcut->cmd_name; - SllQueuePush(first_cmd_node, last_cmd_node, cmd_node); - ++cmds_count; + V_PushVisCmd(shortcut->cmd_name); } } frame->held_buttons[hotkey.button] = down; @@ -1496,30 +1284,324 @@ void V_TickForever(WaveLaneCtx *lane) ////////////////////////////// //- Build command palette + V_Palette *palette = &frame->palette; { - V_BeginPalette(&frame->palette); + palette->key = UI_KeyF("command palette"); + UI_Checkpoint palette_cp = UI_PushCP(UI_NilKey); { - // Push cmd items to palette - for (u64 i = 0; i < countof(V_cmd_descs); ++i) + UI_Push(Tag, palette->key.hash); + UI_Key titlebar_key = UI_KeyF("title bar"); + UI_Report titlebar_rep = UI_ReportFromKey(titlebar_key); + UI_Report widget_rep = UI_ReportFromKey(palette->key); + Vec2 widget_half_dims = MulVec2(DimsFromRng2(widget_rep.screen_rect), 0.5); + + Vec4 window_background_color = theme.window_background_color; + // Vec4 window_background_color = VEC4(0, 0, 0, 0); + Vec4 window_border_color = theme.window_border_color; + Vec4 titlebar_color = Zi; + Vec4 titlebar_border_color = Zi; + Vec4 divider_color = theme.divider_color; + if (titlebar_rep.m1.held) { - V_CmdDesc cmd_desc = V_cmd_descs[i]; - if (!cmd_desc.flags & V_CmdDescFlag_HideFromPalette) - { - V_PaletteItemDesc item_desc = Zi; - item_desc.display_name = cmd_desc.display_name; - // FIXME: Attach active shortcuts instead of default hotkeys - CopyStructs(item_desc.hotkeys, cmd_desc.default_hotkeys, MinU32(countof(item_desc.hotkeys), countof(cmd_desc.default_hotkeys))); - if (V_PushPaletteItem(&frame->palette, item_desc).pressed > 0) - { - V_CmdNode *cmd_node = PushStruct(frame->arena, V_CmdNode); - cmd_node->cmd.name = cmd_desc.name; - SllQueuePush(first_cmd_node, last_cmd_node, cmd_node); - ++cmds_count; - } - } + palette->pos = AddVec2(SubVec2(frame->ui_cursor, titlebar_rep.last_mouse_down_cursor_offset), widget_half_dims); } + window_border_color = LerpSrgb(window_border_color, Rgb32(0x0078a6), titlebar_rep.hot); + + UI_Push(Scale, LerpF32(0.75, 1, widget_rep.selected)); + UI_Push(Tint, VEC4(1, 1, 1, widget_rep.selected)); + if (widget_rep.selected < 0.25) + { + UI_Push(OmitFlags, UI_UseTop(OmitFlags) | UI_BoxFlag_Interactable); + } + + UI_Push(BackgroundColor, window_background_color); + UI_Push(BorderColor, window_border_color); + UI_Push(Border, theme.window_border); + UI_Push(Rounding, UI_RPIX(15)); + UI_Push(Width, UI_PIX(theme.window_width, 0)); + UI_Push(Height, UI_SHRINK(0, 0)); + UI_Push(ChildLayoutAxis, Axis_Y); + UI_Push(FloatingPos, SubVec2(palette->pos, widget_half_dims)); + UI_SetNext(Flags, UI_BoxFlag_Floating | (UI_BoxFlag_Selected * frame->show_palette)); + UI_PushCP(UI_BuildBoxEx(palette->key)); + { + // Title bar + UI_PushCP(UI_NilKey); + { + UI_Push(BackgroundColor, titlebar_color); + UI_Push(BorderColor, titlebar_border_color); + UI_Push(Rounding, UI_RPIX(0)); + UI_Push(ChildLayoutAxis, Axis_X); + UI_Push(Width, UI_GROW(1, 0)); + UI_Push(Height, UI_FNT(2, 1)); + UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_Interactable); + UI_PushCP(UI_BuildBoxEx(titlebar_key)); + { + UI_Push(Width, UI_GROW(1, 0)); + UI_Push(BorderColor, 0); + + // Left title box + UI_BuildRow(); + + // Title box + UI_SetNext(FontSize, theme.window_title_font_size); + UI_SetNext(ChildAlignment, UI_Alignment_Center); + UI_SetNext(Width, UI_SHRINK(0, 1)); + UI_SetNext(Text, Lit("Command Palette")); + UI_SetNext(Flags, UI_BoxFlag_DrawText); + UI_BuildBox(); + + // Right title box + UI_BuildRow(); + } + UI_PopCP(UI_TopCP()); + } + UI_PopCP(UI_TopCP()); + } + + ////////////////////////////// + //- Build palette items list + + f32 padding = theme.window_border; + UI_SetNext(Tint, 0); + UI_SetNext(Rounding, 0); + UI_PushCP(UI_BuildRow()); + { + UI_BuildSpacer(UI_PIX(padding, 1), Axis_X); + { + UI_SetNext(Tint, 0); + UI_SetNext(Rounding, 0); + UI_SetNext(Width, UI_GROW(1, 0)); + UI_PushCP(UI_BuildColumn()); + { + Enum(PaletteItemFlag) + { + PaletteItemFlag_None = 0, + PaletteItemFlag_IsCmd = (1 << 0), + PaletteItemFlag_IsTweakVar = (2 << 0), + }; + + Struct(PaletteItem) + { + PaletteItem *next; + PaletteItem *prev; + + UI_Key key; + PaletteItemFlag flags; + + V_Hotkey hotkeys[8]; + String display_name; + + V_CmdDesc cmd_desc; + TweakVarDesc tweak_desc; + }; + PaletteItem *first_item = 0; + PaletteItem *last_item = 0; + + ////////////////////////////// + //- Push command items + + { + for (u64 cmd_desc_idx = 0; cmd_desc_idx < countof(V_cmd_descs); ++cmd_desc_idx) + { + V_CmdDesc cmd_desc = V_cmd_descs[cmd_desc_idx]; + if (!cmd_desc.flags & V_CmdDescFlag_HideFromPalette) + { + PaletteItem *item = PushStruct(frame->arena, PaletteItem); + { + item->key = UI_KeyF("cmd palette item %F", FmtString(cmd_desc.name)); + item->display_name = cmd_desc.display_name; + item->flags |= PaletteItemFlag_IsCmd; + item->cmd_desc = cmd_desc; + // FIXME: Attach active shortcuts instead of default hotkeys + CopyStructs(item->hotkeys, cmd_desc.default_hotkeys, MinU32(countof(item->hotkeys), countof(cmd_desc.default_hotkeys))); + } + DllQueuePush(first_item, last_item, item); + } + } + } + + ////////////////////////////// + //- Push tweak variables + + { + for (TweakVarKind tweak_var_kind = 0; tweak_var_kind < TweakVarKind_COUNT; ++tweak_var_kind) + { + TweakVarDesc tweak_desc = TweakVarDescFromKind(tweak_var_kind); + PaletteItem *item = PushStruct(frame->arena, PaletteItem); + { + item->key = UI_KeyF("tweak var palette item %F", FmtString(tweak_desc.name)); + item->display_name = tweak_desc.name; + item->flags |= PaletteItemFlag_IsTweakVar; + item->tweak_desc = tweak_desc; + } + DllQueuePush(first_item, last_item, item); + } + } + + ////////////////////////////// + //- Build items + + TweakVars tweak_vars = GetAllGlobalTweakVars(); + + for (PaletteItem *item = first_item; item; item = item->next) + { + UI_BuildDivider(UI_PIX(1, 1), theme.divider_color, Axis_Y); + + UI_Report item_rep = UI_ReportFromKey(item->key); + if (item_rep.m1.presses) + { + if (item->flags & PaletteItemFlag_IsCmd) + { + String cmd_name = item->cmd_desc.name; + V_PushVisCmd(cmd_name); + } + } + + Vec4 item_color = theme.window_background_color; + item_color = LerpSrgb(item_color, theme.button_hot_color, item_rep.hot); + item_color = LerpSrgb(item_color, theme.button_active_color, item_rep.active); + Vec4 item_border_color = LerpSrgb(VEC4(0, 0, 0, 0), theme.button_active_color, item_rep.hot); + + UI_SetNext(BorderColor, 0); + UI_SetNext(Rounding, UI_RPIX(0)); + UI_PushCP(UI_BuildRow()); + { + UI_SetNext(BorderColor, item_border_color); + UI_SetNext(BackgroundColor, item_color); + UI_SetNext(Rounding, UI_RPIX(5)); + UI_SetNext(Width, UI_GROW(1, 0)); + UI_SetNext(Height, UI_FNT(1.5, 1)); + UI_SetNext(ChildAlignment, UI_Alignment_Left); + UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_Interactable); + UI_PushCP(UI_BuildRowEx(item->key)); + { + UI_Push(Tag, item->key.hash); + + // Begin spacer + UI_BuildSpacer(UI_PIX(20, 1), Axis_X); + + // Command label + UI_SetNext(ChildAlignment, UI_Alignment_Left); + UI_BuildLabel(item->display_name); + + // Middle spacer + UI_BuildSpacer(UI_GROW(1, 0), Axis_X); + + // Tweak + if (item->flags & PaletteItemFlag_IsTweakVar) + { + TweakVarDesc tweak_desc = item->tweak_desc; + UI_Key tweak_key = UI_KeyF("tweak"); + UI_Report tweak_rep = UI_ReportFromKey(tweak_key); + + switch (tweak_desc.type) + { + // Tweak checkbox + case TweakVarType_b32: + { + b32 *tweak_val = (b32 *)(&tweak_vars + tweak_desc.offset); + + Vec4 tweak_bg_color = Zi; + if (*tweak_val) + { + tweak_bg_color = theme.color_positive; + } + else + { + tweak_bg_color = theme.color_negative; + } + + Vec4 tweak_border_color = Zi; + tweak_border_color = LerpSrgb(tweak_border_color, theme.button_hot_color, tweak_rep.hot); + tweak_border_color = LerpSrgb(tweak_border_color, theme.button_active_color, tweak_rep.active); + + if (tweak_rep.m1.downs) + { + *tweak_val = !*tweak_val; + } + + UI_SetNext(BackgroundColor, tweak_bg_color); + UI_SetNext(BorderColor, tweak_border_color); + UI_SetNext(Rounding, UI_RGROW(0.5)); + UI_SetNext(Border, 2); + UI_SetNext(Width, UI_FNT(1.25, 1)); + UI_SetNext(Height, UI_FNT(1.25, 1)); + UI_SetNext(Flags, UI_BoxFlag_Interactable); + UI_PushCP(UI_BuildRowEx(tweak_key)); + { + } + UI_PopCP(UI_TopCP()); + } break; + } + } + + // Command hotkey buttons + for (u64 i = 0; i < countof(item->hotkeys); ++i) + { + UI_Key hotkey_key = UI_KeyF("hotkey%F", FmtUint(i)); + UI_Report hotkey_rep = UI_ReportFromKey(hotkey_key); + + Vec4 hotkey_color = Zi; + Vec4 hotkey_border_color = Zi; + { + Vec4 hovered_color = Rgb32(0x103c4c); + Vec4 pressed_color = hovered_color; + pressed_color.w = 0.2; + f32 hotkey_hot = hotkey_rep.hot; + f32 hotkey_active = hotkey_rep.active; + f32 hotkey_hovered = hotkey_rep.hovered; + hotkey_color = LerpSrgb(hotkey_color, hovered_color, hotkey_hot); + hotkey_color = LerpSrgb(hotkey_color, pressed_color, hotkey_active * hotkey_hovered); + hotkey_border_color = LerpSrgb(hotkey_border_color, Rgb32(0x0078a6), hotkey_hot); + } + + V_Hotkey hotkey = item->hotkeys[i]; + if (hotkey.button == Button_None) + { + break; + } + else + { + UI_BuildSpacer(UI_PIX(10, 1), Axis_X); + + String hotkey_name = V_StringFromHotkey(UI_FrameArena(), hotkey); + UI_SetNext(BackgroundColor, hotkey_color); + UI_SetNext(BorderColor, hotkey_border_color); + UI_SetNext(Text, hotkey_name); + UI_SetNext(Width, UI_SHRINK(theme.text_padding_x, 1)); + UI_SetNext(Height, UI_GROW(1, 0)); + UI_SetNext(Rounding, UI_RPIX(5)); + UI_SetNext(Border, 1); + UI_SetNext(ChildAlignment, UI_Alignment_Center); + UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_Interactable); + UI_PushCP(UI_BuildRowEx(hotkey_key)); + { + } + UI_PopCP(UI_TopCP()); + } + } + + // End spacer + UI_BuildSpacer(UI_PIX(20, 1), Axis_X); + } + UI_PopCP(UI_TopCP()); + } + UI_PopCP(UI_TopCP()); + } + + SetAllGlobalTweakVars(&tweak_vars); + } + UI_PopCP(UI_TopCP()); + } + UI_BuildSpacer(UI_PIX(padding, 1), Axis_X); + } + UI_PopCP(UI_TopCP()); + + UI_BuildSpacer(UI_PIX(padding, 1), Axis_Y); } - V_EndPalette(&frame->palette); + // UI_PopCP(UI_TopCP()); + UI_PopCP(palette_cp); } ////////////////////////////// @@ -1559,6 +1641,7 @@ void V_TickForever(WaveLaneCtx *lane) Vec2I32 tile_pos = S_TilePosFromWorldPos(frame->world_cursor); i32 tile_idx = S_TileIdxFromTilePos(tile_pos); { + UI_BuildLabelF("Camera pos: %F", FmtFloat2(frame->camera_pos)); UI_BuildLabelF("Cursor world pos: %F", FmtFloat2(frame->world_cursor)); UI_BuildLabelF("Cursor tile pos: %F", FmtSint2(tile_pos)); UI_BuildLabelF("Cursor tile idx: %F", FmtSint(tile_idx)); @@ -1740,7 +1823,7 @@ void V_TickForever(WaveLaneCtx *lane) ////////////////////////////// //- Process vis commands - for (V_CmdNode *cmd_node = first_cmd_node; cmd_node; cmd_node = cmd_node->next) + for (V_CmdNode *cmd_node = frame->first_cmd_node; cmd_node; cmd_node = cmd_node->next) { String cmd_name = cmd_node->cmd.name; V_CmdKind kind = V_CmdKind_nop; diff --git a/src/pp/pp_vis/pp_vis_core.h b/src/pp/pp_vis/pp_vis_core.h index dc534c37..90454f70 100644 --- a/src/pp/pp_vis/pp_vis_core.h +++ b/src/pp/pp_vis/pp_vis_core.h @@ -36,6 +36,9 @@ Struct(V_WidgetTheme) Vec4 button_active_color; Vec4 button_selected_color; + Vec4 color_positive; + Vec4 color_negative; + f32 text_padding_x; f32 text_padding_y; }; @@ -112,41 +115,11 @@ Global Readonly V_CmdDesc V_cmd_descs[V_CmdKind_COUNT] = { //////////////////////////////////////////////////////////// //~ Palette types -Struct(V_PaletteItemReport) -{ - b32 pressed; - b32 hotkey_changed; - UI_Report ui_report; - V_Hotkey new_hotkeys[8]; -}; - -Struct(V_PaletteItemDesc) -{ - String display_name; - V_Hotkey hotkeys[8]; -}; - -Struct(V_PaletteItem) -{ - V_PaletteItem *next; - UI_Key key; - V_PaletteItemDesc desc; -}; - Struct(V_Palette) { // Persistent state Vec2 pos; UI_Key key; - - // Per-build state - struct - { - UI_Checkpoint cp; - V_PaletteItem *first_item; - V_PaletteItem *last_item; - u64 num_items; - } build; }; //////////////////////////////////////////////////////////// @@ -264,6 +237,11 @@ Struct(V_Frame) Rng2 draw_selection; Rng2 world_selection; + // Commands + i64 cmds_count; + V_CmdNode *first_cmd_node; + V_CmdNode *last_cmd_node; + // Control Vec2 move; Vec2 look; @@ -306,6 +284,7 @@ void V_Shutdown(void); V_Frame *V_CurrentFrame(void); V_Frame *V_LastFrame(void); +V_Cmd *V_PushVisCmd(String name); S_Cmd *V_PushSimCmd(S_CmdKind kind); String V_StringFromHotkey(Arena *arena, V_Hotkey hotkey); @@ -315,13 +294,6 @@ String V_StringFromHotkey(Arena *arena, V_Hotkey hotkey); V_WidgetTheme V_GetWidgetTheme(void); void V_PushWidgetThemeStyles(V_WidgetTheme theme); -//////////////////////////////////////////////////////////// -//~ Palette - -void V_BeginPalette(V_Palette *widget); -V_PaletteItemReport V_PushPaletteItem(V_Palette *widget, V_PaletteItemDesc desc); -void V_EndPalette(V_Palette *widget); - //////////////////////////////////////////////////////////// //~ Vis tick