From c530ec16c059901d738da98e9941328afa1344d0 Mon Sep 17 00:00:00 2001 From: jacob Date: Sun, 29 Mar 2026 18:41:22 -0500 Subject: [PATCH] lister & profiler experimentation --- src/pp/pp_vis/pp_vis.lay | 10 + src/pp/pp_vis/pp_vis_core.c | 2335 ++++++++++++++++++++++--------- src/pp/pp_vis/pp_vis_gpu.g | 129 ++ src/pp/pp_vis/pp_vis_shared.cgh | 49 + 4 files changed, 1876 insertions(+), 647 deletions(-) diff --git a/src/pp/pp_vis/pp_vis.lay b/src/pp/pp_vis/pp_vis.lay index ff82e313..e1774ae4 100644 --- a/src/pp/pp_vis/pp_vis.lay +++ b/src/pp/pp_vis/pp_vis.lay @@ -15,6 +15,16 @@ ////////////////////////////// //- Resources + + + +// FIXME: Remove this +@ComputeShader V_BlaCS (128, 1) + + + + + @ComputeShader V_PrepareShadeCS (16, 16) @ComputeShader V_PrepareCellsCS (16, 16) @ComputeShader V_BackdropDownCS (16, 16) diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index b7dec5fe..755094f6 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -290,7 +290,6 @@ void V_ApplyTextboxDeltas(V_TextboxState *tb, V_TextboxDeltaList deltas) navigated = 1; if (delta.flags & V_TextboxDeltaFlag_NavLine) { - // TODO: Real line start tb->end = 0; } else if (delta.flags & V_TextboxDeltaFlag_NavWord) @@ -317,7 +316,6 @@ void V_ApplyTextboxDeltas(V_TextboxState *tb, V_TextboxDeltaList deltas) navigated = 1; if (delta.flags & V_TextboxDeltaFlag_NavLine) { - // TODO: Real line end tb->end = I64Max; } else if (delta.flags & V_TextboxDeltaFlag_NavWord) @@ -4348,748 +4346,1791 @@ void V_TickForever(WaveLaneCtx *lane) } } + + + + + + + + + + + + + + + + + + + ////////////////////////////// //- Build command palette V_Palette *palette = &frame->palette; - { - f32 ease_rate = TweakFloat("Debug palette ease rate", 20, 1, 100) * frame->dt; - f32 ease_in_target = TweakFloat("Debug palette ease-in target", 1.3, 0, 2); - f32 pref_show = palette->is_showing ? ease_in_target : 0; - palette->show = SaturateF32(LerpF32(palette->show, pref_show, ease_rate)); - } + UI_Size total_width = UI_FNT(40, 1); + UI_Size total_height = UI_FNT(40, 1); + UI_Size header_height = UI_FNT(1.25, 1); + UI_Size window_padding = UI_FNT(0.5, 1); + UI_Size col0_width = UI_FNT(1.75, 1); + UI_Size col1_width = UI_FNT(30, 1); + UI_Size col2_width = UI_FNT(10, 1); - if (palette->is_showing || palette->show > 0.001) - { - f32 item_size_px = UI_FNT(1.5, 1).v; - f32 tweak_size_px = UI_FNT(1.25, 1).v; - - palette->key = UI_KeyF("command palette"); - UI_Checkpoint palette_cp = UI_PushCP(UI_NilKey); { - UI_Push(Tag, palette->key.v); - UI_Key titlebar_key = UI_KeyF("title bar"); - UI_BoxReports titlebar_reps = UI_ReportsFromKey(titlebar_key); - UI_BoxReports palette_reps = UI_ReportsFromKey(palette->key); + f32 ease_rate = TweakFloat("Debug palette ease rate", 20, 1, 100) * frame->dt; + f32 ease_in_target = TweakFloat("Debug palette ease-in target", 1.3, 0, 2); + f32 pref_show = palette->is_showing ? ease_in_target : 0; + palette->show = SaturateF32(LerpF32(palette->show, pref_show, ease_rate)); + } - Vec4 window_background_color = theme.col.window_bg; - Vec4 window_border_color = theme.col.window_bd; - Vec4 titlebar_color = Zi; - Vec4 titlebar_border_color = Zi; - Vec4 divider_color = theme.col.divider; - if (titlebar_reps.draw.m1.held) + if (palette->is_showing || palette->show > 0.001) + { + f32 item_size_px = UI_FNT(1.5, 1).v; + f32 tweak_size_px = UI_FNT(1.25, 1).v; + + palette->key = UI_KeyF("command palette"); + UI_Checkpoint palette_cp = UI_PushCP(UI_NilKey); { - Vec2 drag_offset = SubVec2(ui_frame->drag_cursor_pos, palette_reps.drag.screen_anchor); - palette->pos = SubVec2(frame->screen_cursor, drag_offset); - } - window_border_color = LerpSrgb(window_border_color, theme.col.button_active, titlebar_reps.draw.hot); + UI_Push(Tag, palette->key.v); + UI_Key titlebar_key = UI_KeyF("title bar"); + UI_BoxReports titlebar_reps = UI_ReportsFromKey(titlebar_key); + UI_BoxReports palette_reps = UI_ReportsFromKey(palette->key); - f32 scale = LerpF32(0.85, 1, palette->show); - UI_Push(Tint, VEC4(1, 1, 1, palette->show)); - UI_SetNext(Scale, VEC2(scale, scale)); - - UI_Push(BackgroundColor, window_background_color); - UI_Push(BorderColor, window_border_color); - // UI_Push(BorderSize, theme.window_bd_sz); - UI_Push(BorderSize, 1); - UI_Push(Rounding, UI_RGROW(0.06 * theme.rounding)); - UI_Push(Width, UI_FNT(40, 0)); - UI_Push(Height, UI_SHRINK(0, 0)); - UI_Push(ChildLayoutAxis, Axis_Y); - UI_Push(FloatingPos, palette->pos); - UI_SetNext(Anchor, UI_Region_Center); - UI_SetNext(Flags, UI_BoxFlag_Floating | (UI_BoxFlag_CaptureMouse * !!palette->is_showing)); - UI_PushCP(UI_BuildBoxEx(palette->key)); - { - // Title bar - UI_PushCP(UI_NilKey); + Vec4 window_background_color = theme.col.window_bg; + Vec4 window_border_color = theme.col.window_bd; + Vec4 titlebar_color = Zi; + Vec4 titlebar_border_color = Zi; + Vec4 divider_color = theme.col.divider; + if (titlebar_reps.draw.m1.held) { - 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_CaptureMouse * !!palette->is_showing)); - 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, UI_Top(FontSize) * theme.h3); - UI_SetNext(ChildAlignment, UI_Region_Center); - UI_SetNext(Width, UI_SHRINK(0, 1)); - UI_SetNext(Text, Lit("Debug Palette")); - UI_SetNext(Flags, UI_BoxFlag_DrawText); - UI_BuildBox(); - - // Right title box - UI_BuildRow(); - } - UI_PopCP(UI_TopCP()); + Vec2 drag_offset = SubVec2(ui_frame->drag_cursor_pos, palette_reps.drag.screen_anchor); + palette->pos = SubVec2(frame->screen_cursor, drag_offset); } - UI_PopCP(UI_TopCP()); - } + window_border_color = LerpSrgb(window_border_color, theme.col.button_active, titlebar_reps.draw.hot); - ////////////////////////////// - //- Build searchbox + f32 scale = LerpF32(0.85, 1, palette->show); + UI_Push(Tint, VEC4(1, 1, 1, palette->show)); + UI_SetNext(Scale, VEC2(scale, scale)); - b32 is_searching = 0; - String search_text = Zi; - { - UI_Size search_height = UI_PIX(item_size_px * 1.25, 1); - - UI_SetNext(ChildAlignment, UI_Region_Left); - UI_PushCP(UI_BuildRow()); + UI_SetNext(BackgroundColor, window_background_color); + UI_SetNext(BorderColor, window_border_color); + // UI_SetNext(BorderSize, theme.window_bd_sz); + UI_SetNext(BorderSize, 1); + UI_SetNext(Rounding, UI_RGROW(0.06 * theme.rounding)); + UI_SetNext(Width, total_width); + UI_SetNext(Height, total_height); + UI_SetNext(FloatingPos, palette->pos); + UI_SetNext(ChildLayoutAxis, Axis_Y); + UI_SetNext(Anchor, UI_Region_Center); + UI_SetNext(Flags, UI_BoxFlag_Floating | (UI_BoxFlag_CaptureMouse * !!palette->is_showing)); + UI_PushCP(UI_BuildBoxEx(palette->key)); { - //- Search icon + ////////////////////////////// + //- Build header + + UI_PushCP(UI_NilKey); { - f32 size_px = UI_Top(FontSize) * 1.25; - - UI_SetNext(Rounding, UI_RGROW(0.75 * theme.rounding)); - UI_SetNext(ChildAlignment, UI_Region_Center); - UI_SetNext(BackgroundColor, 0); - // UI_SetNext(BorderColor, reset_bd); - UI_SetNext(BorderSize, 0); - UI_SetNext(Rounding, 0); - UI_SetNext(TextColor, theme.col.hint); - UI_SetNext(Width, UI_PIX(size_px * 1.5, 1)); - UI_SetNext(Height, UI_PIX(size_px * 1.5, 1)); - // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); - UI_SetNext(FontSize, size_px * theme.h6); - UI_BuildIcon(theme.icon_font, UI_Icon_Search); - // UI_BuildRow(); - } - - //- Search box - { - UI_Key search_box = UI_KeyF("search box"); - UI_BoxReport search_report = UI_ReportsFromKey(search_box).draw; - V_TextboxState *search_state = &palette->search_state; - - b32 has_focus = UI_MatchKey(search_box, prev_frame->keyboard_focus_box); - - // FIXME: Remove this - has_focus = 1; - - // if (search_report.m1.downs) - if (search_report.m1.downs) + 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, header_height); + UI_SetNext(Flags, UI_BoxFlag_DrawText | (UI_BoxFlag_CaptureMouse * !!palette->is_showing)); + UI_PushCP(UI_BuildBoxEx(titlebar_key)); { - has_focus = 1; - V.text_input_ns = frame->time_ns; - } - - if (search_report.is_hot) - { - WND_SetCursor(window_frame, WND_CursorKind_Text); - } - - if (has_focus) - { - frame->keyboard_focus_box = search_box; - if (text_input_deltas.first) - { - V.text_input_ns = frame->time_ns; - V_ApplyTextboxDeltas(search_state, text_input_deltas); - } - } - - - - - - // // FIXME: Remove this - // if (frame->held_buttons[Button_B] && !prev_frame->held_buttons[Button_B]) - // { - // V_TextboxDelta delta = Zi; - // // delta.kind = V_DeltaKind_ - // delta.text = Lit("Hi"); - // // delta.range = RNGI64(I64Max, I64Max); - - // // delta.start = search_state->start; - // // delta.end = search_state->end; - - // // delta.start = 0; - // // delta.end = 1; - - // delta.flags |= V_TextboxDeltaFlag_UpdateText; - - // V_ApplyTextboxDelta(search_state, delta); - // } - - - - - - search_text = V_StringFromTextbox(frame->arena, search_state); - is_searching = search_text.len != 0; - - - String display_text = search_text; - Vec4 display_text_color = Color_White; - if (!is_searching) - { - display_text_color = theme.col.hint; - display_text = Lit(" Search..."); - } - - // Vec4 raah_color = Color_Black; - Vec4 raah_color = Zi; - - UI_SetNext(Height, search_height); - UI_SetNext(Width, UI_GROW(1, 0)); - UI_SetNext(BackgroundColor, raah_color); - // UI_SetNext(BorderColor, item_border_color); - UI_SetNext(BorderSize, 0); - // UI_SetNext(Rounding, UI_RPIX(5)); - UI_SetNext(ChildAlignment, UI_Region_Left); - UI_SetNext(TextColor, display_text_color); - UI_SetNext(Text, display_text); - UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_CaptureMouse); - UI_PushCP(UI_BuildRowEx(search_box)); - { - f32 font_size = UI_Top(FontSize); - GC_FontKey font = UI_Top(Font); - - //- Text caret/selection - if (has_focus) - { - UI_Key caret_box = UI_KeyF("search caret"); - UI_Key selection_box = UI_KeyF("search selection"); - - - UI_Size caret_width = UI_PIX(1, 1); - UI_Size caret_height = UI_PIX(search_height.v, 1); - - - Vec4 selection_color = VEC4(0, 0.25, 0.75, 0.5); - - Vec4 caret_color = VEC4(1, 1, 1, 0.75); - // caret_color.a = AbsF32(SinF32(SecondsFromNs(frame->time_ns - V.text_input_ns) * 4)); - // caret_color.a = SinF32(SecondsFromNs(frame->time_ns - V.text_input_ns)) > 0.5 ? 1 : 0; - // caret_color.a = (CosF32(SecondsFromNs(frame->time_ns - V.text_input_ns) * 5) + 1) * 0.5; - caret_color.a *= AbsF32(CosF32(SecondsFromNs(frame->time_ns - V.text_input_ns) * 3)); - - f32 start_offset_px = 0; - f32 end_offset_px = 0; - - // caret_offset_px = TweakFloat("RAAAAAAAAAAAAAAAAAAAH", 0, 0, 100); - - // caret_offset_px = - - - - - // FIXME: Remove this, use UI computed run - if (search_text.len > 0) - { - String32 codepoints = String32FromString(frame->arena, search_text); - GC_Run run = GC_RunFromString32(frame->arena, codepoints, font, font_size); - - // FIXME: Don't use rect idx - // FIXME: Selection - // FIXME: Offset & scissor - for (i64 rect_idx = 0; rect_idx < (i64)run.rects_count; ++rect_idx) - { - if (rect_idx < search_state->start) - { - GC_RunRect rect = run.rects[rect_idx]; - start_offset_px = rect.baseline_pos + rect.advance; - } - if (rect_idx < search_state->end) - { - GC_RunRect rect = run.rects[rect_idx]; - end_offset_px = rect.baseline_pos + rect.advance; - } - if (rect_idx >= search_state->start && rect_idx >= search_state->end) - { - break; - } - } - } - - - - - - - - - // { - // i64 offset_ - // } - - // Selection - { - f32 min = MinF32(start_offset_px, end_offset_px); - f32 max = MaxF32(start_offset_px, end_offset_px); - - UI_SetNext(Width, UI_PIX(max - min, 1)); - UI_SetNext(Height, caret_height); - UI_SetNext(FloatingPos, VEC2(min, 0)); - UI_SetNext(Anchor, UI_Region_Left); - UI_SetNext(Flags, UI_BoxFlag_Floating, UI_BoxFlag_CaptureMouse); - UI_SetNext(BorderSize, 0); - UI_SetNext(BackgroundColor, selection_color); - UI_SetNext(FontSize, font_size); - UI_BuildBoxEx(selection_box); - } - - // Caret - { - UI_SetNext(Width, caret_width); - UI_SetNext(Height, caret_height); - UI_SetNext(FloatingPos, VEC2(end_offset_px, 0)); - UI_SetNext(Anchor, UI_Region_Left); - UI_SetNext(Flags, UI_BoxFlag_Floating, UI_BoxFlag_CaptureMouse); - UI_SetNext(BorderSize, 0); - UI_SetNext(BackgroundColor, caret_color); - UI_SetNext(FontSize, font_size); - UI_BuildBoxEx(caret_box); - } - } + UI_Push(Width, UI_GROW(1, 0)); + UI_Push(BorderColor, 0); + // Left title box + UI_BuildRow(); + // Title box + // UI_SetNext(FontSize, UI_Top(FontSize) * theme.h3); + UI_SetNext(FontSize, UI_Top(FontSize) * theme.h5); + UI_SetNext(TextColor, theme.col.hint); + UI_SetNext(ChildAlignment, UI_Region_Center); + UI_SetNext(Width, UI_SHRINK(0, 1)); + UI_SetNext(Text, Lit("Developer Palette")); + UI_SetNext(Flags, UI_BoxFlag_DrawText); + UI_BuildBox(); + // Right title box + UI_BuildRow(); } UI_PopCP(UI_TopCP()); } - } - UI_PopCP(UI_TopCP()); - } + UI_PopCP(UI_TopCP()); - ////////////////////////////// - //- Build palette items list - - f32 window_padding = theme.window_padding; - UI_SetNext(Tint, 0); - UI_SetNext(Rounding, 0); - UI_PushCP(UI_BuildRow()); - { - UI_BuildSpacer(UI_PIX(window_padding, 1), Axis_X); - { - UI_SetNext(Tint, 0); + UI_SetNext(BackgroundColor, 0); UI_SetNext(Rounding, 0); UI_SetNext(Width, UI_GROW(1, 0)); - UI_PushCP(UI_BuildColumn()); + UI_SetNext(Height, UI_GROW(1, 0)); + UI_PushCP(UI_BuildRow()); { - Enum(PaletteItemFlag) + UI_BuildSpacer(window_padding, Axis_X); + + UI_SetNext(BackgroundColor, 0); + UI_SetNext(Rounding, 0); + UI_SetNext(Width, UI_GROW(1, 0)); + UI_SetNext(Height, UI_GROW(1, 0)); + UI_PushCP(UI_BuildColumn()); { - PaletteItemFlag_None = 0, - PaletteItemFlag_IsCmd = (1 << 0), - PaletteItemFlag_IsTweakVar = (2 << 0), - }; + ////////////////////////////// + //- Build searchbox - Struct(PaletteItem) - { - PaletteItem *next; - PaletteItem *prev; - - UI_Key key; - PaletteItemFlag flags; - - V_Hotkey hotkeys[8]; - String display_name; - - V_CmdDesc cmd_desc; - TweakVar tweak_var; - }; - 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) + b32 is_searching = 0; + String search_text = Zi; { - 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); - } - } - } + UI_Size search_height = UI_PIX(item_size_px * 1.25, 1); - ////////////////////////////// - //- Push tweak variables - - TweakVarArray tweak_vars = GetAllTweakVars(frame->arena); - - { - for (i64 tweak_idx = 0; tweak_idx < tweak_vars.count; ++tweak_idx) - { - TweakVar tweak_var = tweak_vars.v[tweak_idx]; - PaletteItem *item = PushStruct(frame->arena, PaletteItem); - { - item->key = UI_KeyF("tweak var palette item %F", FmtString(tweak_var.name)); - item->display_name = tweak_var.name; - item->flags |= PaletteItemFlag_IsTweakVar; - item->tweak_var = tweak_var; - } - DllQueuePush(first_item, last_item, item); - } - } - - ////////////////////////////// - //- Build items - - for (PaletteItem *item = first_item; item; item = item->next) - { - f32 spacing = 20; - - // Divider - UI_BuildDivider(UI_PIX(1, 1), divider_color, Axis_Y); - - UI_BoxReport item_rep = UI_ReportsFromKey(item->key).draw; - 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.col.window_bg; - Vec4 item_color = Zi; - // Vec4 item_color = theme.col.hint; - Vec4 item_border_color = Zi; - if (item->flags & PaletteItemFlag_IsCmd) - { - item_color = LerpSrgb(item_color, theme.col.button_hot, item_rep.hot); - item_color = LerpSrgb(item_color, theme.col.button_active, item_rep.active); - item_border_color = LerpSrgb(item_border_color, theme.col.button_active, item_rep.hot); - } - else - { - item_border_color = LerpSrgb(item_border_color, theme.col.button_active, item_rep.hot); - } - - UI_SetNext(Tint, 0); - UI_PushCP(UI_BuildRow()); - { - UI_SetNext(BackgroundColor, item_color); - UI_SetNext(BorderColor, item_border_color); - UI_SetNext(BorderSize, 1); - UI_SetNext(Rounding, UI_RPIX(5)); - UI_SetNext(Width, UI_GROW(1, 0)); - UI_SetNext(Height, UI_PIX(item_size_px, 1)); + UI_SetNext(BackgroundColor, 0); UI_SetNext(ChildAlignment, UI_Region_Left); - UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_CaptureMouse); - UI_PushCP(UI_BuildRowEx(item->key)); + UI_SetNext(Width, UI_GROW(1, 0)); + UI_SetNext(Height, search_height); + UI_PushCP(UI_BuildRow()); { - UI_Push(Tag, item->key.v); - - // Begin spacer - UI_BuildSpacer(UI_PIX(spacing, 1), Axis_X); - - // Command label - UI_SetNext(ChildAlignment, UI_Region_Left); - UI_BuildLabel(item->display_name); - - // Middle spacer - UI_BuildSpacer(UI_GROW(1, 0), Axis_X); - - // Tweak - if (item->flags & PaletteItemFlag_IsTweakVar) + //- Search icon { - TweakVar tweak_var = item->tweak_var; - String old_tweak_str = tweak_var.value; - String new_tweak_str = tweak_var.value; - b32 is_default = MatchString(new_tweak_str, tweak_var.initial); + f32 size_px = UI_Top(FontSize) * 1.25; - // Reset button - if (!is_default) + UI_SetNext(Rounding, UI_RGROW(0.75 * theme.rounding)); + UI_SetNext(ChildAlignment, UI_Region_Center); + UI_SetNext(BackgroundColor, 0); + // UI_SetNext(BorderColor, reset_bd); + UI_SetNext(BorderSize, 0); + UI_SetNext(Rounding, 0); + UI_SetNext(TextColor, theme.col.hint); + UI_SetNext(Width, col0_width); + UI_SetNext(Height, UI_PIX(size_px * 1.5, 1)); + // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + UI_SetNext(FontSize, size_px * theme.h6); + UI_BuildIcon(theme.icon_font, UI_Icon_Search); + // UI_BuildRow(); + } + + //- Search box + { + UI_Key search_box = UI_KeyF("search box"); + UI_BoxReport search_report = UI_ReportsFromKey(search_box).draw; + V_TextboxState *search_state = &palette->search_state; + + b32 has_focus = UI_MatchKey(search_box, prev_frame->keyboard_focus_box); + + // FIXME: Remove this + has_focus = 1; + + // if (search_report.m1.downs) + if (search_report.m1.downs) { - UI_BuildSpacer(UI_PIX(spacing * 0.5, 1), Axis_X); - UI_Key reset_key = UI_KeyF("reset"); - UI_BoxReport reset_rep = UI_ReportsFromKey(reset_key).draw; - - if (reset_rep.m1.downs > 0) - { - new_tweak_str = tweak_var.initial; - } - if (reset_rep.is_hot) - { - WND_SetCursor(window_frame, WND_CursorKind_Hand); - } - - Vec4 reset_bg = Zi; - // reset_bg = LerpSrgb(reset_bg, theme.col.button_hot, reset_rep.hot); - // reset_bg = LerpSrgb(reset_bg, theme.col.button_active, reset_rep.active); - - Vec4 reset_bd = Zi; - // reset_bd = LerpSrgb(reset_bd, theme.col.button_active, reset_rep.hot); - // reset_bd = LerpSrgb(reset_bd, theme.col.text, reset_rep.hot); - - Vec4 reset_text_col = theme.col.hint; - reset_text_col = LerpSrgb(reset_text_col, theme.col.text, reset_rep.hot); - - UI_SetNext(Rounding, UI_RGROW(0.75 * theme.rounding)); - UI_SetNext(ChildAlignment, UI_Region_Bottom); - UI_SetNext(BackgroundColor, reset_bg); - UI_SetNext(BorderColor, reset_bd); - UI_SetNext(BorderSize, 0); - UI_SetNext(TextColor, reset_text_col); - UI_SetNext(Width, UI_SHRINK(0, 1)); - UI_SetNext(Height, UI_SHRINK(0, 1)); - UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); - UI_SetNext(FontSize, UI_Top(FontSize) * theme.h6); - UI_BuildIconEx(reset_key, theme.icon_font, UI_Icon_Loop2); + has_focus = 1; + V.text_input_ns = frame->time_ns; } - // Tweak label + if (search_report.is_hot) { - UI_BuildSpacer(UI_PIX(spacing, 1), Axis_X); - if (is_default) - { - UI_SetNext(TextColor, theme.col.hint); - } - else - { - UI_SetNext(TextColor, Color_White); - } - UI_SetNext(FontSize, UI_Top(FontSize) * theme.h5); - UI_SetNext(ChildAlignment, UI_Region_Left); - UI_SetNext(Width, UI_SHRINK(0, 1)); - UI_SetNext(Height, UI_SHRINK(0, 1)); - UI_SetNext(Text, new_tweak_str); - UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_NoTextTruncation); - UI_SetNext(BackgroundColor, 0); - UI_SetNext(BorderColor, 0); - UI_BuildBox(); + WND_SetCursor(window_frame, WND_CursorKind_Text); } - UI_BuildSpacer(UI_PIX(spacing, 1), Axis_X); - - switch (tweak_var.kind) + if (has_focus) { - // Boolean tweak - case TweakKind_Bool: + frame->keyboard_focus_box = search_box; + if (text_input_deltas.first) { - UI_Key cb_key = UI_KeyF("tweak checkbox"); - UI_BoxReport cb_rep = UI_ReportsFromKey(cb_key).draw; + V.text_input_ns = frame->time_ns; + V_ApplyTextboxDeltas(search_state, text_input_deltas); + } + } - b32 tweak_bool = CR_BoolFromString(new_tweak_str); - if (cb_rep.m1.downs) - { - tweak_bool = !tweak_bool; - new_tweak_str = StringFromBool(frame->arena, tweak_bool); - } - // Tweak checkbox - Vec4 cb_bg_color = Zi; - Vec4 cb_border_color = theme.col.window_bd; - cb_bg_color = LerpSrgb(cb_bg_color, theme.col.positive, tweak_bool); - cb_border_color = LerpSrgb(cb_border_color, theme.col.button_active, cb_rep.hot); - UI_SetNext(BackgroundColor, cb_bg_color); - UI_SetNext(BorderColor, cb_border_color); - UI_SetNext(Rounding, UI_RGROW(theme.rounding)); - UI_SetNext(BorderSize, 1); - UI_SetNext(Width, UI_FNT(1.25, 1)); - UI_SetNext(Height, UI_FNT(1.25, 1)); - UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); - UI_PushCP(UI_BuildRowEx(cb_key)); - { - } - UI_PopCP(UI_TopCP()); - } break; - // Float tweak - case TweakKind_Float: + + // // FIXME: Remove this + // if (frame->held_buttons[Button_B] && !prev_frame->held_buttons[Button_B]) + // { + // V_TextboxDelta delta = Zi; + // // delta.kind = V_DeltaKind_ + // delta.text = Lit("Hi"); + // // delta.range = RNGI64(I64Max, I64Max); + + // // delta.start = search_state->start; + // // delta.end = search_state->end; + + // // delta.start = 0; + // // delta.end = 1; + + // delta.flags |= V_TextboxDeltaFlag_UpdateText; + + // V_ApplyTextboxDelta(search_state, delta); + // } + + + + + + search_text = V_StringFromTextbox(frame->arena, search_state); + is_searching = search_text.len != 0; + + + String display_text = search_text; + Vec4 display_text_color = Color_White; + if (!is_searching) + { + display_text_color = theme.col.hint; + display_text = Lit(" Search..."); + } + + // Vec4 raah_color = Color_Black; + Vec4 raah_color = Zi; + + UI_SetNext(Width, UI_GROW(1, 0)); + UI_SetNext(Height, search_height); + UI_SetNext(BackgroundColor, raah_color); + // UI_SetNext(BorderColor, item_border_color); + UI_SetNext(BorderSize, 0); + // UI_SetNext(Rounding, UI_RPIX(5)); + UI_SetNext(ChildAlignment, UI_Region_Left); + UI_SetNext(TextColor, display_text_color); + UI_SetNext(Text, display_text); + UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_CaptureMouse); + UI_PushCP(UI_BuildRowEx(search_box)); + { + f32 font_size = UI_Top(FontSize); + GC_FontKey font = UI_Top(Font); + + //- Text caret/selection + if (has_focus) { - UI_Key slider_key = UI_KeyF("tweak slider"); - UI_Key marker_key = UI_KeyF("tweak slider marker"); + UI_Key caret_box = UI_KeyF("search caret"); + UI_Key selection_box = UI_KeyF("search selection"); - UI_BoxReports slider_reps = UI_ReportsFromKey(slider_key); - UI_BoxReports marker_reps = UI_ReportsFromKey(marker_key); - b32 is_hot = slider_reps.draw.is_hot || marker_reps.draw.is_hot; - b32 is_active = slider_reps.draw.m1.held || marker_reps.draw.m1.held; - f32 hot = MaxF32(slider_reps.draw.hot, marker_reps.draw.hot); + UI_Size caret_width = UI_PIX(1, 1); + UI_Size caret_height = UI_PIX(search_height.v, 1); - Vec2 slider_pos = slider_reps.draw.screen_rect.p0; - Vec2 slider_dims = DimsFromRng2(slider_reps.draw.screen_rect); - Vec2 marker_dims = DimsFromRng2(marker_reps.draw.screen_rect); - Vec2 half_marker_dims = MulVec2(marker_dims, 0.5); - f64 range_min = tweak_var.range.min; - f64 range_max = tweak_var.range.max; - if (range_max <= range_min) + Vec4 selection_color = VEC4(0, 0.25, 0.75, 0.5); + + Vec4 caret_color = VEC4(1, 1, 1, 0.75); + // caret_color.a = AbsF32(SinF32(SecondsFromNs(frame->time_ns - V.text_input_ns) * 4)); + // caret_color.a = SinF32(SecondsFromNs(frame->time_ns - V.text_input_ns)) > 0.5 ? 1 : 0; + // caret_color.a = (CosF32(SecondsFromNs(frame->time_ns - V.text_input_ns) * 5) + 1) * 0.5; + caret_color.a *= AbsF32(CosF32(SecondsFromNs(frame->time_ns - V.text_input_ns) * 3)); + + f32 start_offset_px = 0; + f32 end_offset_px = 0; + + // caret_offset_px = TweakFloat("RAAAAAAAAAAAAAAAAAAAH", 0, 0, 100); + + // caret_offset_px = + + + + + // FIXME: Remove this, use UI computed run + if (search_text.len > 0) { - range_max = range_min + 1; - } + String32 codepoints = String32FromString(frame->arena, search_text); + GC_Run run = GC_RunFromString32(frame->arena, codepoints, font, font_size); - f64 tweak_float = CR_FloatFromString(new_tweak_str); - { - if (is_active) + // FIXME: Don't use rect idx + // FIXME: Selection + // FIXME: Offset & scissor + for (i64 rect_idx = 0; rect_idx < (i64)run.rects_count; ++rect_idx) { - f64 initial_slider_pos = slider_reps.drag.screen_rect.p0.x; - f64 initial_marker_width = DimsFromRng2(marker_reps.drag.screen_rect).x; - f64 initial_slider_width = DimsFromRng2(slider_reps.drag.screen_rect).x - initial_marker_width; - f64 initial_cursor = ui_frame->drag_cursor_pos.x; - f64 initial_ratio = slider_reps.drag.misc; - - f64 virtual_slider_start = initial_cursor - (initial_slider_width * initial_ratio); - f64 virtual_slider_end = virtual_slider_start + initial_slider_width; - f64 virtual_cursor_ratio = (frame->screen_cursor.x - virtual_slider_start) / (virtual_slider_end - virtual_slider_start); - - tweak_float = LerpF64(range_min, range_max, virtual_cursor_ratio); - tweak_float = ClampF64(tweak_float, range_min, range_max); - if (frame->screen_cursor.x != prev_frame->screen_cursor.x) + if (rect_idx < search_state->start) { - new_tweak_str = StringFromFloat(frame->arena, tweak_float, tweak_var.precision); + GC_RunRect rect = run.rects[rect_idx]; + start_offset_px = rect.baseline_pos + rect.advance; + } + if (rect_idx < search_state->end) + { + GC_RunRect rect = run.rects[rect_idx]; + end_offset_px = rect.baseline_pos + rect.advance; + } + if (rect_idx >= search_state->start && rect_idx >= search_state->end) + { + break; } } - if (is_hot) - { - WND_SetCursor(window_frame, WND_CursorKind_HorizontalResize); - } } - f32 ratio = 0; - ratio = (tweak_float - range_min) / (range_max - range_min); - ratio = ClampF32(ratio, 0, 1); - Vec4 slider_bg_color = theme.col.window_bg; - Vec4 slider_border_color = theme.col.window_bd; - Vec4 slider_progress_color = theme.col.positive; - Vec4 marker_bg_color = slider_progress_color; - slider_border_color = LerpSrgb(slider_border_color, theme.col.button_active, hot); - marker_bg_color = LerpSrgb(marker_bg_color, theme.col.text, hot); - UI_SetNext(BackgroundColor, slider_bg_color); - UI_SetNext(BorderColor, slider_border_color); - UI_SetNext(Rounding, UI_RGROW(theme.rounding)); - UI_SetNext(BorderSize, 1); - UI_SetNext(Width, UI_FNT(10, 1)); - UI_SetNext(Height, UI_PIX(tweak_size_px * 0.75, 1)); - UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); - UI_SetNext(Misc, ratio); - UI_PushCP(UI_BuildRowEx(slider_key)); + + + + + + + // { + // i64 offset_ + // } + + // Selection { - f32 marker_pos = ratio * (slider_dims.x - marker_dims.x); + f32 min = MinF32(start_offset_px, end_offset_px); + f32 max = MaxF32(start_offset_px, end_offset_px); - // Slider progress - { - UI_SetNext(BackgroundColor, slider_progress_color); - // UI_SetNext(Rounding, UI_RGROW(theme.rounding)); - UI_SetNext(Rounding, 0); - UI_SetNext(BorderColor, 0); - UI_SetNext(BorderSize, 1); - UI_SetNext(Width, UI_PIX(marker_pos + half_marker_dims.x, 0)); - UI_SetNext(Height, UI_PIX(tweak_size_px * 0.75, 1)); - UI_BuildBox(); - } - - // Slider marker - { - UI_SetNext(BackgroundColor, marker_bg_color); - UI_SetNext(BorderColor, slider_border_color); - UI_SetNext(Rounding, UI_RGROW(theme.rounding)); - UI_SetNext(BorderSize, 1); - UI_SetNext(Width, UI_PIX(tweak_size_px, 1)); - UI_SetNext(Height, UI_PIX(tweak_size_px, 1)); - // UI_SetNext(Anchor, UI_Region_Center); - // UI_SetNext(FloatingPos, VEC2(marker_pos, (marker_size_px * 0.5))); - UI_SetNext(FloatingPos, VEC2(marker_pos, -marker_dims.y * 0.125)); - UI_SetNext(Flags, UI_BoxFlag_Floating | UI_BoxFlag_NoFloatingClamp | UI_BoxFlag_CaptureMouse); - UI_BuildBoxEx(marker_key); - } + UI_SetNext(Width, UI_PIX(max - min, 1)); + UI_SetNext(Height, caret_height); + UI_SetNext(FloatingPos, VEC2(min, 0)); + UI_SetNext(Anchor, UI_Region_Left); + UI_SetNext(Flags, UI_BoxFlag_Floating, UI_BoxFlag_CaptureMouse); + UI_SetNext(BorderSize, 0); + UI_SetNext(BackgroundColor, selection_color); + UI_SetNext(FontSize, font_size); + UI_BuildBoxEx(selection_box); } - UI_PopCP(UI_TopCP()); - } break; - } - if (!MatchString(old_tweak_str, new_tweak_str)) + // Caret + { + UI_SetNext(Width, caret_width); + UI_SetNext(Height, caret_height); + UI_SetNext(FloatingPos, VEC2(end_offset_px, 0)); + UI_SetNext(Anchor, UI_Region_Left); + UI_SetNext(Flags, UI_BoxFlag_Floating, UI_BoxFlag_CaptureMouse); + UI_SetNext(BorderSize, 0); + UI_SetNext(BackgroundColor, caret_color); + UI_SetNext(FontSize, font_size); + UI_BuildBoxEx(caret_box); + } + } + + + + } + UI_PopCP(UI_TopCP()); + } + } + UI_PopCP(UI_TopCP()); + } + + ////////////////////////////// + //- Build palette items list + + UI_SetNext(Tint, 0); + UI_SetNext(Rounding, 0); + UI_PushCP(UI_BuildRow()); + { + 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; + TweakVar tweak_var; + }; + 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) { - TweakVar new_tweak_var = tweak_var; - new_tweak_var.value = new_tweak_str; - TweakEx(frame->arena, new_tweak_var, 1); + 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); + } } } - // Command hotkey buttons - for (u64 i = 0; i < countof(item->hotkeys); ++i) - { - UI_Key hotkey_key = UI_KeyF("hotkey%F", FmtUint(i)); - UI_BoxReport hotkey_rep = UI_ReportsFromKey(hotkey_key).draw; + ////////////////////////////// + //- Push tweak variables - Vec4 hotkey_color = Zi; - Vec4 hotkey_border_color = Zi; + TweakVarArray tweak_vars = GetAllTweakVars(frame->arena); + + { + for (i64 tweak_idx = 0; tweak_idx < tweak_vars.count; ++tweak_idx) { - 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); + TweakVar tweak_var = tweak_vars.v[tweak_idx]; + PaletteItem *item = PushStruct(frame->arena, PaletteItem); + { + item->key = UI_KeyF("tweak var palette item %F", FmtString(tweak_var.name)); + item->display_name = tweak_var.name; + item->flags |= PaletteItemFlag_IsTweakVar; + item->tweak_var = tweak_var; + } + DllQueuePush(first_item, last_item, item); + } + } + + ////////////////////////////// + //- Build items + + for (PaletteItem *item = first_item; item; item = item->next) + { + // Divider + UI_BuildDivider(UI_PIX(1, 1), divider_color, Axis_Y); + + UI_BoxReport item_rep = UI_ReportsFromKey(item->key).draw; + if (item_rep.m1.presses) + { + if (item->flags & PaletteItemFlag_IsCmd) + { + String cmd_name = item->cmd_desc.name; + V_PushVisCmd(cmd_name); + } } - V_Hotkey hotkey = item->hotkeys[i]; - if (hotkey.button == Button_None) + // Vec4 item_color = theme.col.window_bg; + Vec4 item_color = Zi; + // Vec4 item_color = theme.col.hint; + Vec4 item_border_color = Zi; + if (item->flags & PaletteItemFlag_IsCmd) { - break; + item_color = LerpSrgb(item_color, theme.col.button_hot, item_rep.hot); + item_color = LerpSrgb(item_color, theme.col.button_active, item_rep.active); + item_border_color = LerpSrgb(item_border_color, theme.col.button_active, item_rep.hot); } else { - UI_BuildSpacer(UI_PIX(10, 1), Axis_X); + item_border_color = LerpSrgb(item_border_color, theme.col.button_active, item_rep.hot); + } - 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(Tint, 0); + // UI_SetNext(Width, UI_PIX(total_width.v - window_padding.v * 2, 1)); + UI_SetNext(Width, UI_GROW(1, 0)); + UI_SetNext(Height, UI_FNT(1.5, 1)); + UI_PushCP(UI_BuildRow()); + { + UI_SetNext(BackgroundColor, item_color); + UI_SetNext(BorderColor, item_border_color); UI_SetNext(BorderSize, 1); - UI_SetNext(ChildAlignment, UI_Region_Center); + UI_SetNext(Rounding, UI_RPIX(5)); + // UI_SetNext(Width, col1_width); + UI_SetNext(Width, UI_GROW(1, 0)); + // UI_SetNext(Height, UI_PIX(item_size_px, 1)); + // UI_SetNext(Height, UI_FNT(1, 0)); + UI_SetNext(ChildAlignment, UI_Region_Left); UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_CaptureMouse); - UI_PushCP(UI_BuildRowEx(hotkey_key)); + UI_PushCP(UI_BuildRowEx(item->key)); { + UI_Push(Tag, item->key.v); + + // Begin spacer + UI_BuildSpacer(col0_width, Axis_X); + // UI_BuildSpacer(window_padding, Axis_X); + + // Command label + UI_SetNext(ChildAlignment, UI_Region_Left); + UI_BuildLabel(item->display_name); + + // Middle spacer + UI_BuildSpacer(UI_GROW(1, 0), Axis_X); + + // Tweak + if (item->flags & PaletteItemFlag_IsTweakVar) + { + TweakVar tweak_var = item->tweak_var; + String old_tweak_str = tweak_var.value; + String new_tweak_str = tweak_var.value; + b32 is_default = MatchString(new_tweak_str, tweak_var.initial); + + // Reset button + if (!is_default) + { + // UI_BuildSpacer(UI_PIX(spacing * 0.5, 1), Axis_X); + UI_Key reset_key = UI_KeyF("reset"); + UI_BoxReport reset_rep = UI_ReportsFromKey(reset_key).draw; + + if (reset_rep.m1.downs > 0) + { + new_tweak_str = tweak_var.initial; + } + if (reset_rep.is_hot) + { + WND_SetCursor(window_frame, WND_CursorKind_Hand); + } + + Vec4 reset_bg = Zi; + // reset_bg = LerpSrgb(reset_bg, theme.col.button_hot, reset_rep.hot); + // reset_bg = LerpSrgb(reset_bg, theme.col.button_active, reset_rep.active); + + Vec4 reset_bd = Zi; + // reset_bd = LerpSrgb(reset_bd, theme.col.button_active, reset_rep.hot); + // reset_bd = LerpSrgb(reset_bd, theme.col.text, reset_rep.hot); + + Vec4 reset_text_col = theme.col.hint; + reset_text_col = LerpSrgb(reset_text_col, theme.col.text, reset_rep.hot); + + UI_SetNext(Rounding, UI_RGROW(0.75 * theme.rounding)); + UI_SetNext(ChildAlignment, UI_Region_Bottom); + UI_SetNext(BackgroundColor, reset_bg); + UI_SetNext(BorderColor, reset_bd); + UI_SetNext(BorderSize, 0); + UI_SetNext(TextColor, reset_text_col); + UI_SetNext(Width, UI_SHRINK(0, 1)); + UI_SetNext(Height, UI_SHRINK(0, 1)); + UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + UI_SetNext(FontSize, UI_Top(FontSize) * theme.h6); + UI_BuildIconEx(reset_key, theme.icon_font, UI_Icon_Loop2); + } + + // Tweak label + { + UI_BuildSpacer(col0_width, Axis_X); + if (is_default) + { + UI_SetNext(TextColor, theme.col.hint); + } + else + { + UI_SetNext(TextColor, Color_White); + } + UI_SetNext(FontSize, UI_Top(FontSize) * theme.h5); + UI_SetNext(ChildAlignment, UI_Region_Left); + UI_SetNext(Width, UI_SHRINK(0, 1)); + UI_SetNext(Height, UI_SHRINK(0, 1)); + UI_SetNext(Text, new_tweak_str); + UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_NoTextTruncation); + UI_SetNext(BackgroundColor, 0); + UI_SetNext(BorderColor, 0); + UI_BuildBox(); + } + + UI_BuildSpacer(col0_width, Axis_X); + + switch (tweak_var.kind) + { + // Boolean tweak + case TweakKind_Bool: + { + UI_Key cb_key = UI_KeyF("tweak checkbox"); + UI_BoxReport cb_rep = UI_ReportsFromKey(cb_key).draw; + + b32 tweak_bool = CR_BoolFromString(new_tweak_str); + if (cb_rep.m1.downs) + { + tweak_bool = !tweak_bool; + new_tweak_str = StringFromBool(frame->arena, tweak_bool); + } + + // Tweak checkbox + Vec4 cb_bg_color = Zi; + Vec4 cb_border_color = theme.col.window_bd; + cb_bg_color = LerpSrgb(cb_bg_color, theme.col.positive, tweak_bool); + cb_border_color = LerpSrgb(cb_border_color, theme.col.button_active, cb_rep.hot); + + UI_SetNext(BackgroundColor, cb_bg_color); + UI_SetNext(BorderColor, cb_border_color); + UI_SetNext(Rounding, UI_RGROW(theme.rounding)); + UI_SetNext(BorderSize, 1); + UI_SetNext(Width, UI_FNT(1.25, 1)); + UI_SetNext(Height, UI_FNT(1.25, 1)); + UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + UI_PushCP(UI_BuildRowEx(cb_key)); + { + } + UI_PopCP(UI_TopCP()); + } break; + + // Float tweak + case TweakKind_Float: + { + UI_Key slider_key = UI_KeyF("tweak slider"); + UI_Key marker_key = UI_KeyF("tweak slider marker"); + + UI_BoxReports slider_reps = UI_ReportsFromKey(slider_key); + UI_BoxReports marker_reps = UI_ReportsFromKey(marker_key); + + b32 is_hot = slider_reps.draw.is_hot || marker_reps.draw.is_hot; + b32 is_active = slider_reps.draw.m1.held || marker_reps.draw.m1.held; + f32 hot = MaxF32(slider_reps.draw.hot, marker_reps.draw.hot); + + Vec2 slider_pos = slider_reps.draw.screen_rect.p0; + Vec2 slider_dims = DimsFromRng2(slider_reps.draw.screen_rect); + Vec2 marker_dims = DimsFromRng2(marker_reps.draw.screen_rect); + Vec2 half_marker_dims = MulVec2(marker_dims, 0.5); + + f64 range_min = tweak_var.range.min; + f64 range_max = tweak_var.range.max; + if (range_max <= range_min) + { + range_max = range_min + 1; + } + + f64 tweak_float = CR_FloatFromString(new_tweak_str); + { + if (is_active) + { + f64 initial_slider_pos = slider_reps.drag.screen_rect.p0.x; + f64 initial_marker_width = DimsFromRng2(marker_reps.drag.screen_rect).x; + f64 initial_slider_width = DimsFromRng2(slider_reps.drag.screen_rect).x - initial_marker_width; + f64 initial_cursor = ui_frame->drag_cursor_pos.x; + f64 initial_ratio = slider_reps.drag.misc; + + f64 virtual_slider_start = initial_cursor - (initial_slider_width * initial_ratio); + f64 virtual_slider_end = virtual_slider_start + initial_slider_width; + f64 virtual_cursor_ratio = (frame->screen_cursor.x - virtual_slider_start) / (virtual_slider_end - virtual_slider_start); + + tweak_float = LerpF64(range_min, range_max, virtual_cursor_ratio); + tweak_float = ClampF64(tweak_float, range_min, range_max); + if (frame->screen_cursor.x != prev_frame->screen_cursor.x) + { + new_tweak_str = StringFromFloat(frame->arena, tweak_float, tweak_var.precision); + } + } + if (is_hot) + { + WND_SetCursor(window_frame, WND_CursorKind_HorizontalResize); + } + } + f32 ratio = 0; + ratio = (tweak_float - range_min) / (range_max - range_min); + ratio = ClampF32(ratio, 0, 1); + + Vec4 slider_bg_color = theme.col.window_bg; + Vec4 slider_border_color = theme.col.window_bd; + Vec4 slider_progress_color = theme.col.positive; + Vec4 marker_bg_color = slider_progress_color; + slider_border_color = LerpSrgb(slider_border_color, theme.col.button_active, hot); + marker_bg_color = LerpSrgb(marker_bg_color, theme.col.text, hot); + + UI_SetNext(BackgroundColor, slider_bg_color); + UI_SetNext(BorderColor, slider_border_color); + UI_SetNext(Rounding, UI_RGROW(theme.rounding)); + UI_SetNext(BorderSize, 1); + UI_SetNext(Width, UI_FNT(10, 1)); + UI_SetNext(Height, UI_PIX(tweak_size_px * 0.75, 1)); + UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + UI_SetNext(Misc, ratio); + UI_PushCP(UI_BuildRowEx(slider_key)); + { + f32 marker_pos = ratio * (slider_dims.x - marker_dims.x); + + // Slider progress + { + UI_SetNext(BackgroundColor, slider_progress_color); + // UI_SetNext(Rounding, UI_RGROW(theme.rounding)); + UI_SetNext(Rounding, 0); + UI_SetNext(BorderColor, 0); + UI_SetNext(BorderSize, 1); + UI_SetNext(Width, UI_PIX(marker_pos + half_marker_dims.x, 0)); + UI_SetNext(Height, UI_PIX(tweak_size_px * 0.75, 1)); + UI_BuildBox(); + } + + // Slider marker + { + UI_SetNext(BackgroundColor, marker_bg_color); + UI_SetNext(BorderColor, slider_border_color); + UI_SetNext(Rounding, UI_RGROW(theme.rounding)); + UI_SetNext(BorderSize, 1); + UI_SetNext(Width, UI_PIX(tweak_size_px, 1)); + UI_SetNext(Height, UI_PIX(tweak_size_px, 1)); + // UI_SetNext(Anchor, UI_Region_Center); + // UI_SetNext(FloatingPos, VEC2(marker_pos, (marker_size_px * 0.5))); + UI_SetNext(FloatingPos, VEC2(marker_pos, -marker_dims.y * 0.125)); + UI_SetNext(Flags, UI_BoxFlag_Floating | UI_BoxFlag_NoFloatingClamp | UI_BoxFlag_CaptureMouse); + UI_BuildBoxEx(marker_key); + } + } + UI_PopCP(UI_TopCP()); + } break; + } + + if (!MatchString(old_tweak_str, new_tweak_str)) + { + TweakVar new_tweak_var = tweak_var; + new_tweak_var.value = new_tweak_str; + TweakEx(frame->arena, new_tweak_var, 1); + } + } + + // Command hotkey buttons + for (u64 i = 0; i < countof(item->hotkeys); ++i) + { + UI_Key hotkey_key = UI_KeyF("hotkey%F", FmtUint(i)); + UI_BoxReport hotkey_rep = UI_ReportsFromKey(hotkey_key).draw; + + 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(BorderSize, 1); + UI_SetNext(ChildAlignment, UI_Region_Center); + UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_CaptureMouse); + UI_PushCP(UI_BuildRowEx(hotkey_key)); + { + } + UI_PopCP(UI_TopCP()); + } + } + + // End spacer + UI_BuildSpacer(col0_width, Axis_X); } UI_PopCP(UI_TopCP()); } + UI_PopCP(UI_TopCP()); } - - // End spacer - UI_BuildSpacer(UI_PIX(spacing, 1), Axis_X); } UI_PopCP(UI_TopCP()); } UI_PopCP(UI_TopCP()); } + UI_PopCP(UI_TopCP()); + + UI_BuildSpacer(window_padding, Axis_X); + // UI_BuildSpacer(UI_FNT(100, 1), Axis_Y); } UI_PopCP(UI_TopCP()); + // UI_BuildSpacer(window_padding, Axis_Y); } - UI_BuildSpacer(UI_PIX(window_padding, 1), Axis_X); + UI_PopCP(UI_TopCP()); } - UI_PopCP(UI_TopCP()); - - UI_BuildSpacer(UI_PIX(window_padding, 1), Axis_Y); + // UI_PopCP(UI_TopCP()); + UI_PopCP(palette_cp); } - // UI_PopCP(UI_TopCP()); - UI_PopCP(palette_cp); } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + // ////////////////////////////// + // //- Build command palette + + // V_Palette *palette = &frame->palette; + + // { + // f32 ease_rate = TweakFloat("Debug palette ease rate", 20, 1, 100) * frame->dt; + // f32 ease_in_target = TweakFloat("Debug palette ease-in target", 1.3, 0, 2); + // f32 pref_show = palette->is_showing ? ease_in_target : 0; + // palette->show = SaturateF32(LerpF32(palette->show, pref_show, ease_rate)); + // } + + // if (palette->is_showing || palette->show > 0.001) + // { + // f32 item_size_px = UI_FNT(1.5, 1).v; + // f32 tweak_size_px = UI_FNT(1.25, 1).v; + + // palette->key = UI_KeyF("command palette"); + // UI_Checkpoint palette_cp = UI_PushCP(UI_NilKey); + // { + // UI_Push(Tag, palette->key.v); + // UI_Key titlebar_key = UI_KeyF("title bar"); + // UI_BoxReports titlebar_reps = UI_ReportsFromKey(titlebar_key); + // UI_BoxReports palette_reps = UI_ReportsFromKey(palette->key); + + // Vec4 window_background_color = theme.col.window_bg; + // Vec4 window_border_color = theme.col.window_bd; + // Vec4 titlebar_color = Zi; + // Vec4 titlebar_border_color = Zi; + // Vec4 divider_color = theme.col.divider; + // if (titlebar_reps.draw.m1.held) + // { + // Vec2 drag_offset = SubVec2(ui_frame->drag_cursor_pos, palette_reps.drag.screen_anchor); + // palette->pos = SubVec2(frame->screen_cursor, drag_offset); + // } + // window_border_color = LerpSrgb(window_border_color, theme.col.button_active, titlebar_reps.draw.hot); + + // f32 scale = LerpF32(0.85, 1, palette->show); + // UI_Push(Tint, VEC4(1, 1, 1, palette->show)); + // UI_SetNext(Scale, VEC2(scale, scale)); + + // UI_Push(BackgroundColor, window_background_color); + // UI_Push(BorderColor, window_border_color); + // // UI_Push(BorderSize, theme.window_bd_sz); + // UI_Push(BorderSize, 1); + // UI_Push(Rounding, UI_RGROW(0.06 * theme.rounding)); + // UI_Push(Width, UI_FNT(40, 0)); + // UI_Push(Height, UI_SHRINK(0, 0)); + // UI_Push(ChildLayoutAxis, Axis_Y); + // UI_Push(FloatingPos, palette->pos); + // UI_SetNext(Anchor, UI_Region_Center); + // UI_SetNext(Flags, UI_BoxFlag_Floating | (UI_BoxFlag_CaptureMouse * !!palette->is_showing)); + // 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_CaptureMouse * !!palette->is_showing)); + // 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, UI_Top(FontSize) * theme.h3); + // UI_SetNext(ChildAlignment, UI_Region_Center); + // UI_SetNext(Width, UI_SHRINK(0, 1)); + // UI_SetNext(Text, Lit("Debug Palette")); + // UI_SetNext(Flags, UI_BoxFlag_DrawText); + // UI_BuildBox(); + + // // Right title box + // UI_BuildRow(); + // } + // UI_PopCP(UI_TopCP()); + // } + // UI_PopCP(UI_TopCP()); + // } + + // ////////////////////////////// + // //- Build searchbox + + // b32 is_searching = 0; + // String search_text = Zi; + // { + // UI_Size search_height = UI_PIX(item_size_px * 1.25, 1); + + // UI_SetNext(ChildAlignment, UI_Region_Left); + // UI_PushCP(UI_BuildRow()); + // { + // //- Search icon + // { + // f32 size_px = UI_Top(FontSize) * 1.25; + + // UI_SetNext(Rounding, UI_RGROW(0.75 * theme.rounding)); + // UI_SetNext(ChildAlignment, UI_Region_Center); + // UI_SetNext(BackgroundColor, 0); + // // UI_SetNext(BorderColor, reset_bd); + // UI_SetNext(BorderSize, 0); + // UI_SetNext(Rounding, 0); + // UI_SetNext(TextColor, theme.col.hint); + // UI_SetNext(Width, UI_PIX(size_px * 1.5, 1)); + // UI_SetNext(Height, UI_PIX(size_px * 1.5, 1)); + // // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + // UI_SetNext(FontSize, size_px * theme.h6); + // UI_BuildIcon(theme.icon_font, UI_Icon_Search); + // // UI_BuildRow(); + // } + + // //- Search box + // { + // UI_Key search_box = UI_KeyF("search box"); + // UI_BoxReport search_report = UI_ReportsFromKey(search_box).draw; + // V_TextboxState *search_state = &palette->search_state; + + // b32 has_focus = UI_MatchKey(search_box, prev_frame->keyboard_focus_box); + + // // FIXME: Remove this + // has_focus = 1; + + // // if (search_report.m1.downs) + // if (search_report.m1.downs) + // { + // has_focus = 1; + // V.text_input_ns = frame->time_ns; + // } + + // if (search_report.is_hot) + // { + // WND_SetCursor(window_frame, WND_CursorKind_Text); + // } + + // if (has_focus) + // { + // frame->keyboard_focus_box = search_box; + // if (text_input_deltas.first) + // { + // V.text_input_ns = frame->time_ns; + // V_ApplyTextboxDeltas(search_state, text_input_deltas); + // } + // } + + + + + + // // // FIXME: Remove this + // // if (frame->held_buttons[Button_B] && !prev_frame->held_buttons[Button_B]) + // // { + // // V_TextboxDelta delta = Zi; + // // // delta.kind = V_DeltaKind_ + // // delta.text = Lit("Hi"); + // // // delta.range = RNGI64(I64Max, I64Max); + + // // // delta.start = search_state->start; + // // // delta.end = search_state->end; + + // // // delta.start = 0; + // // // delta.end = 1; + + // // delta.flags |= V_TextboxDeltaFlag_UpdateText; + + // // V_ApplyTextboxDelta(search_state, delta); + // // } + + + + + + // search_text = V_StringFromTextbox(frame->arena, search_state); + // is_searching = search_text.len != 0; + + + // String display_text = search_text; + // Vec4 display_text_color = Color_White; + // if (!is_searching) + // { + // display_text_color = theme.col.hint; + // display_text = Lit(" Search..."); + // } + + // // Vec4 raah_color = Color_Black; + // Vec4 raah_color = Zi; + + // UI_SetNext(Height, search_height); + // UI_SetNext(Width, UI_GROW(1, 0)); + // UI_SetNext(BackgroundColor, raah_color); + // // UI_SetNext(BorderColor, item_border_color); + // UI_SetNext(BorderSize, 0); + // // UI_SetNext(Rounding, UI_RPIX(5)); + // UI_SetNext(ChildAlignment, UI_Region_Left); + // UI_SetNext(TextColor, display_text_color); + // UI_SetNext(Text, display_text); + // UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_CaptureMouse); + // UI_PushCP(UI_BuildRowEx(search_box)); + // { + // f32 font_size = UI_Top(FontSize); + // GC_FontKey font = UI_Top(Font); + + // //- Text caret/selection + // if (has_focus) + // { + // UI_Key caret_box = UI_KeyF("search caret"); + // UI_Key selection_box = UI_KeyF("search selection"); + + + // UI_Size caret_width = UI_PIX(1, 1); + // UI_Size caret_height = UI_PIX(search_height.v, 1); + + + // Vec4 selection_color = VEC4(0, 0.25, 0.75, 0.5); + + // Vec4 caret_color = VEC4(1, 1, 1, 0.75); + // // caret_color.a = AbsF32(SinF32(SecondsFromNs(frame->time_ns - V.text_input_ns) * 4)); + // // caret_color.a = SinF32(SecondsFromNs(frame->time_ns - V.text_input_ns)) > 0.5 ? 1 : 0; + // // caret_color.a = (CosF32(SecondsFromNs(frame->time_ns - V.text_input_ns) * 5) + 1) * 0.5; + // caret_color.a *= AbsF32(CosF32(SecondsFromNs(frame->time_ns - V.text_input_ns) * 3)); + + // f32 start_offset_px = 0; + // f32 end_offset_px = 0; + + // // caret_offset_px = TweakFloat("RAAAAAAAAAAAAAAAAAAAH", 0, 0, 100); + + // // caret_offset_px = + + + + + // // FIXME: Remove this, use UI computed run + // if (search_text.len > 0) + // { + // String32 codepoints = String32FromString(frame->arena, search_text); + // GC_Run run = GC_RunFromString32(frame->arena, codepoints, font, font_size); + + // // FIXME: Don't use rect idx + // // FIXME: Selection + // // FIXME: Offset & scissor + // for (i64 rect_idx = 0; rect_idx < (i64)run.rects_count; ++rect_idx) + // { + // if (rect_idx < search_state->start) + // { + // GC_RunRect rect = run.rects[rect_idx]; + // start_offset_px = rect.baseline_pos + rect.advance; + // } + // if (rect_idx < search_state->end) + // { + // GC_RunRect rect = run.rects[rect_idx]; + // end_offset_px = rect.baseline_pos + rect.advance; + // } + // if (rect_idx >= search_state->start && rect_idx >= search_state->end) + // { + // break; + // } + // } + // } + + + + + + + + + // // { + // // i64 offset_ + // // } + + // // Selection + // { + // f32 min = MinF32(start_offset_px, end_offset_px); + // f32 max = MaxF32(start_offset_px, end_offset_px); + + // UI_SetNext(Width, UI_PIX(max - min, 1)); + // UI_SetNext(Height, caret_height); + // UI_SetNext(FloatingPos, VEC2(min, 0)); + // UI_SetNext(Anchor, UI_Region_Left); + // UI_SetNext(Flags, UI_BoxFlag_Floating, UI_BoxFlag_CaptureMouse); + // UI_SetNext(BorderSize, 0); + // UI_SetNext(BackgroundColor, selection_color); + // UI_SetNext(FontSize, font_size); + // UI_BuildBoxEx(selection_box); + // } + + // // Caret + // { + // UI_SetNext(Width, caret_width); + // UI_SetNext(Height, caret_height); + // UI_SetNext(FloatingPos, VEC2(end_offset_px, 0)); + // UI_SetNext(Anchor, UI_Region_Left); + // UI_SetNext(Flags, UI_BoxFlag_Floating, UI_BoxFlag_CaptureMouse); + // UI_SetNext(BorderSize, 0); + // UI_SetNext(BackgroundColor, caret_color); + // UI_SetNext(FontSize, font_size); + // UI_BuildBoxEx(caret_box); + // } + // } + + + + // } + // UI_PopCP(UI_TopCP()); + // } + // } + // UI_PopCP(UI_TopCP()); + // } + + // ////////////////////////////// + // //- Build palette items list + + // f32 window_padding = theme.window_padding; + // UI_SetNext(Tint, 0); + // UI_SetNext(Rounding, 0); + // UI_PushCP(UI_BuildRow()); + // { + // UI_BuildSpacer(UI_PIX(window_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; + // TweakVar tweak_var; + // }; + // 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 + + // TweakVarArray tweak_vars = GetAllTweakVars(frame->arena); + + // { + // for (i64 tweak_idx = 0; tweak_idx < tweak_vars.count; ++tweak_idx) + // { + // TweakVar tweak_var = tweak_vars.v[tweak_idx]; + // PaletteItem *item = PushStruct(frame->arena, PaletteItem); + // { + // item->key = UI_KeyF("tweak var palette item %F", FmtString(tweak_var.name)); + // item->display_name = tweak_var.name; + // item->flags |= PaletteItemFlag_IsTweakVar; + // item->tweak_var = tweak_var; + // } + // DllQueuePush(first_item, last_item, item); + // } + // } + + // ////////////////////////////// + // //- Build items + + // for (PaletteItem *item = first_item; item; item = item->next) + // { + // f32 spacing = 20; + + // // Divider + // UI_BuildDivider(UI_PIX(1, 1), divider_color, Axis_Y); + + // UI_BoxReport item_rep = UI_ReportsFromKey(item->key).draw; + // 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.col.window_bg; + // Vec4 item_color = Zi; + // // Vec4 item_color = theme.col.hint; + // Vec4 item_border_color = Zi; + // if (item->flags & PaletteItemFlag_IsCmd) + // { + // item_color = LerpSrgb(item_color, theme.col.button_hot, item_rep.hot); + // item_color = LerpSrgb(item_color, theme.col.button_active, item_rep.active); + // item_border_color = LerpSrgb(item_border_color, theme.col.button_active, item_rep.hot); + // } + // else + // { + // item_border_color = LerpSrgb(item_border_color, theme.col.button_active, item_rep.hot); + // } + + // UI_SetNext(Tint, 0); + // UI_PushCP(UI_BuildRow()); + // { + // UI_SetNext(BackgroundColor, item_color); + // UI_SetNext(BorderColor, item_border_color); + // UI_SetNext(BorderSize, 1); + // UI_SetNext(Rounding, UI_RPIX(5)); + // UI_SetNext(Width, UI_GROW(1, 0)); + // UI_SetNext(Height, UI_PIX(item_size_px, 1)); + // UI_SetNext(ChildAlignment, UI_Region_Left); + // UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_CaptureMouse); + // UI_PushCP(UI_BuildRowEx(item->key)); + // { + // UI_Push(Tag, item->key.v); + + // // Begin spacer + // UI_BuildSpacer(col0_width, Axis_X); + + // // Command label + // UI_SetNext(ChildAlignment, UI_Region_Left); + // UI_BuildLabel(item->display_name); + + // // Middle spacer + // UI_BuildSpacer(UI_GROW(1, 0), Axis_X); + + // // Tweak + // if (item->flags & PaletteItemFlag_IsTweakVar) + // { + // TweakVar tweak_var = item->tweak_var; + // String old_tweak_str = tweak_var.value; + // String new_tweak_str = tweak_var.value; + // b32 is_default = MatchString(new_tweak_str, tweak_var.initial); + + // // Reset button + // if (!is_default) + // { + // UI_BuildSpacer(UI_PIX(spacing * 0.5, 1), Axis_X); + // UI_Key reset_key = UI_KeyF("reset"); + // UI_BoxReport reset_rep = UI_ReportsFromKey(reset_key).draw; + + // if (reset_rep.m1.downs > 0) + // { + // new_tweak_str = tweak_var.initial; + // } + // if (reset_rep.is_hot) + // { + // WND_SetCursor(window_frame, WND_CursorKind_Hand); + // } + + // Vec4 reset_bg = Zi; + // // reset_bg = LerpSrgb(reset_bg, theme.col.button_hot, reset_rep.hot); + // // reset_bg = LerpSrgb(reset_bg, theme.col.button_active, reset_rep.active); + + // Vec4 reset_bd = Zi; + // // reset_bd = LerpSrgb(reset_bd, theme.col.button_active, reset_rep.hot); + // // reset_bd = LerpSrgb(reset_bd, theme.col.text, reset_rep.hot); + + // Vec4 reset_text_col = theme.col.hint; + // reset_text_col = LerpSrgb(reset_text_col, theme.col.text, reset_rep.hot); + + // UI_SetNext(Rounding, UI_RGROW(0.75 * theme.rounding)); + // UI_SetNext(ChildAlignment, UI_Region_Bottom); + // UI_SetNext(BackgroundColor, reset_bg); + // UI_SetNext(BorderColor, reset_bd); + // UI_SetNext(BorderSize, 0); + // UI_SetNext(TextColor, reset_text_col); + // UI_SetNext(Width, UI_SHRINK(0, 1)); + // UI_SetNext(Height, UI_SHRINK(0, 1)); + // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + // UI_SetNext(FontSize, UI_Top(FontSize) * theme.h6); + // UI_BuildIconEx(reset_key, theme.icon_font, UI_Icon_Loop2); + // } + + // // Tweak label + // { + // UI_BuildSpacer(col0_width, Axis_X); + // if (is_default) + // { + // UI_SetNext(TextColor, theme.col.hint); + // } + // else + // { + // UI_SetNext(TextColor, Color_White); + // } + // UI_SetNext(FontSize, UI_Top(FontSize) * theme.h5); + // UI_SetNext(ChildAlignment, UI_Region_Left); + // UI_SetNext(Width, UI_SHRINK(0, 1)); + // UI_SetNext(Height, UI_SHRINK(0, 1)); + // UI_SetNext(Text, new_tweak_str); + // UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_NoTextTruncation); + // UI_SetNext(BackgroundColor, 0); + // UI_SetNext(BorderColor, 0); + // UI_BuildBox(); + // } + + // UI_BuildSpacer(col0_width, Axis_X); + + // switch (tweak_var.kind) + // { + // // Boolean tweak + // case TweakKind_Bool: + // { + // UI_Key cb_key = UI_KeyF("tweak checkbox"); + // UI_BoxReport cb_rep = UI_ReportsFromKey(cb_key).draw; + + // b32 tweak_bool = CR_BoolFromString(new_tweak_str); + // if (cb_rep.m1.downs) + // { + // tweak_bool = !tweak_bool; + // new_tweak_str = StringFromBool(frame->arena, tweak_bool); + // } + + // // Tweak checkbox + // Vec4 cb_bg_color = Zi; + // Vec4 cb_border_color = theme.col.window_bd; + // cb_bg_color = LerpSrgb(cb_bg_color, theme.col.positive, tweak_bool); + // cb_border_color = LerpSrgb(cb_border_color, theme.col.button_active, cb_rep.hot); + + // UI_SetNext(BackgroundColor, cb_bg_color); + // UI_SetNext(BorderColor, cb_border_color); + // UI_SetNext(Rounding, UI_RGROW(theme.rounding)); + // UI_SetNext(BorderSize, 1); + // UI_SetNext(Width, UI_FNT(1.25, 1)); + // UI_SetNext(Height, UI_FNT(1.25, 1)); + // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + // UI_PushCP(UI_BuildRowEx(cb_key)); + // { + // } + // UI_PopCP(UI_TopCP()); + // } break; + + // // Float tweak + // case TweakKind_Float: + // { + // UI_Key slider_key = UI_KeyF("tweak slider"); + // UI_Key marker_key = UI_KeyF("tweak slider marker"); + + // UI_BoxReports slider_reps = UI_ReportsFromKey(slider_key); + // UI_BoxReports marker_reps = UI_ReportsFromKey(marker_key); + + // b32 is_hot = slider_reps.draw.is_hot || marker_reps.draw.is_hot; + // b32 is_active = slider_reps.draw.m1.held || marker_reps.draw.m1.held; + // f32 hot = MaxF32(slider_reps.draw.hot, marker_reps.draw.hot); + + // Vec2 slider_pos = slider_reps.draw.screen_rect.p0; + // Vec2 slider_dims = DimsFromRng2(slider_reps.draw.screen_rect); + // Vec2 marker_dims = DimsFromRng2(marker_reps.draw.screen_rect); + // Vec2 half_marker_dims = MulVec2(marker_dims, 0.5); + + // f64 range_min = tweak_var.range.min; + // f64 range_max = tweak_var.range.max; + // if (range_max <= range_min) + // { + // range_max = range_min + 1; + // } + + // f64 tweak_float = CR_FloatFromString(new_tweak_str); + // { + // if (is_active) + // { + // f64 initial_slider_pos = slider_reps.drag.screen_rect.p0.x; + // f64 initial_marker_width = DimsFromRng2(marker_reps.drag.screen_rect).x; + // f64 initial_slider_width = DimsFromRng2(slider_reps.drag.screen_rect).x - initial_marker_width; + // f64 initial_cursor = ui_frame->drag_cursor_pos.x; + // f64 initial_ratio = slider_reps.drag.misc; + + // f64 virtual_slider_start = initial_cursor - (initial_slider_width * initial_ratio); + // f64 virtual_slider_end = virtual_slider_start + initial_slider_width; + // f64 virtual_cursor_ratio = (frame->screen_cursor.x - virtual_slider_start) / (virtual_slider_end - virtual_slider_start); + + // tweak_float = LerpF64(range_min, range_max, virtual_cursor_ratio); + // tweak_float = ClampF64(tweak_float, range_min, range_max); + // if (frame->screen_cursor.x != prev_frame->screen_cursor.x) + // { + // new_tweak_str = StringFromFloat(frame->arena, tweak_float, tweak_var.precision); + // } + // } + // if (is_hot) + // { + // WND_SetCursor(window_frame, WND_CursorKind_HorizontalResize); + // } + // } + // f32 ratio = 0; + // ratio = (tweak_float - range_min) / (range_max - range_min); + // ratio = ClampF32(ratio, 0, 1); + + // Vec4 slider_bg_color = theme.col.window_bg; + // Vec4 slider_border_color = theme.col.window_bd; + // Vec4 slider_progress_color = theme.col.positive; + // Vec4 marker_bg_color = slider_progress_color; + // slider_border_color = LerpSrgb(slider_border_color, theme.col.button_active, hot); + // marker_bg_color = LerpSrgb(marker_bg_color, theme.col.text, hot); + + // UI_SetNext(BackgroundColor, slider_bg_color); + // UI_SetNext(BorderColor, slider_border_color); + // UI_SetNext(Rounding, UI_RGROW(theme.rounding)); + // UI_SetNext(BorderSize, 1); + // UI_SetNext(Width, UI_FNT(10, 1)); + // UI_SetNext(Height, UI_PIX(tweak_size_px * 0.75, 1)); + // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + // UI_SetNext(Misc, ratio); + // UI_PushCP(UI_BuildRowEx(slider_key)); + // { + // f32 marker_pos = ratio * (slider_dims.x - marker_dims.x); + + // // Slider progress + // { + // UI_SetNext(BackgroundColor, slider_progress_color); + // // UI_SetNext(Rounding, UI_RGROW(theme.rounding)); + // UI_SetNext(Rounding, 0); + // UI_SetNext(BorderColor, 0); + // UI_SetNext(BorderSize, 1); + // UI_SetNext(Width, UI_PIX(marker_pos + half_marker_dims.x, 0)); + // UI_SetNext(Height, UI_PIX(tweak_size_px * 0.75, 1)); + // UI_BuildBox(); + // } + + // // Slider marker + // { + // UI_SetNext(BackgroundColor, marker_bg_color); + // UI_SetNext(BorderColor, slider_border_color); + // UI_SetNext(Rounding, UI_RGROW(theme.rounding)); + // UI_SetNext(BorderSize, 1); + // UI_SetNext(Width, UI_PIX(tweak_size_px, 1)); + // UI_SetNext(Height, UI_PIX(tweak_size_px, 1)); + // // UI_SetNext(Anchor, UI_Region_Center); + // // UI_SetNext(FloatingPos, VEC2(marker_pos, (marker_size_px * 0.5))); + // UI_SetNext(FloatingPos, VEC2(marker_pos, -marker_dims.y * 0.125)); + // UI_SetNext(Flags, UI_BoxFlag_Floating | UI_BoxFlag_NoFloatingClamp | UI_BoxFlag_CaptureMouse); + // UI_BuildBoxEx(marker_key); + // } + // } + // UI_PopCP(UI_TopCP()); + // } break; + // } + + // if (!MatchString(old_tweak_str, new_tweak_str)) + // { + // TweakVar new_tweak_var = tweak_var; + // new_tweak_var.value = new_tweak_str; + // TweakEx(frame->arena, new_tweak_var, 1); + // } + // } + + // // Command hotkey buttons + // for (u64 i = 0; i < countof(item->hotkeys); ++i) + // { + // UI_Key hotkey_key = UI_KeyF("hotkey%F", FmtUint(i)); + // UI_BoxReport hotkey_rep = UI_ReportsFromKey(hotkey_key).draw; + + // 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(BorderSize, 1); + // UI_SetNext(ChildAlignment, UI_Region_Center); + // UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_CaptureMouse); + // UI_PushCP(UI_BuildRowEx(hotkey_key)); + // { + // } + // UI_PopCP(UI_TopCP()); + // } + // } + + // // End spacer + // UI_BuildSpacer(col0_width, Axis_X); + // } + // UI_PopCP(UI_TopCP()); + // } + // UI_PopCP(UI_TopCP()); + // } + // } + // UI_PopCP(UI_TopCP()); + // } + // UI_BuildSpacer(UI_PIX(window_padding, 1), Axis_X); + // } + // UI_PopCP(UI_TopCP()); + + // UI_BuildSpacer(UI_PIX(window_padding, 1), Axis_Y); + // } + // // UI_PopCP(UI_TopCP()); + // UI_PopCP(palette_cp); + // } + + + + + + + + + + + + + + ////////////////////////////// + //- Build test profiler + + + + + + // TODO: Remove this + + // FIXME: remove this (samples testing) + + + + + + // { + // BlaParams params = Zi; + // params.cursor = frame->screen_cursor; + + // //- Sample GPU work + // G_ZoneDF(cl, "BLAAAAAAAAA") + // { + // params.bla_dims = VEC2(1000, 200); + // // params.bla_samples_count = Mebi(1); + // params.bla_samples_count = 1000; + // BlaSample *bla_samples = PushStructsNoZero(frame->arena, BlaSample, params.bla_samples_count); + // { + // for (i64 sample_idx = 0; sample_idx < params.bla_samples_count; ++sample_idx) + // { + // BlaSample *sample = &bla_samples[sample_idx]; + // // sample->bla0 = sample_idx; + // // sample->bla1 = params.bla_samples_count - sample_idx; + + + + + // // sample->r0 = Norm24(MixU64(sample_idx)); + // sample->r0 = 0.5 + ((Norm24(MixU64(sample_idx + frame->tick)) - 0.5) * 0.01); + // // sample->r0 += SinF32(SecondsFromNs(frame->time_ns)) * 0.1; + + // // sample->r0 += SinF32(SecondsFromNs(frame->time_ns)) * 0.1; + + // sample->r1 = (1.0 - sample->r0) * 0.5; + // } + // } + + + + // params.bla_samples = G_PushStructsFromCpu( + // cl, gpu_frame_arena, + // bla_samples, params.bla_samples_count, + // .name = StringF(frame->arena, "bla samples [%F]", FmtSint(frame->tick)) + // ); + // params.bla_tex = G_PushTexture2D( + // cl, gpu_frame_arena, + // G_TextureLayout_Family, + // G_Format_R16G16B16A16_Float, + // params.bla_dims, + // .flags = G_MemoryFlag_AllowTextureRW, + // .name = StringF(frame->arena, "Shade target [%F]", FmtSint(frame->tick)) + // ); + + + + + + + + + + // G_BufferRef gpu_bla_params = G_PushStructFromCpu( + // cl, gpu_frame_arena, + // ¶ms, + // .name = StringF(frame->arena, "Bla params [%F]", FmtSint(frame->tick)) + // ); + + // // Set initial constants + // // FIXME: Don't use frame slot + // G_SetConstant(cl, V_GpuConst_Frame, gpu_bla_params); + + + // // Compute + // { + // G_Sync(cl); + // G_Compute2D(cl, V_BlaCS, params.bla_dims); + // G_Sync(cl); + // } + // } + + // //- Sample UI + // { + // UI_Key bla_box = UI_KeyF("blaaaa samples"); + // UI_Key bla_tex_box = UI_KeyF("blaaaa samples tex"); + // b32 is_showing = 1; + + // { + // Rng2 uv = RNG2(VEC2(0, 0), VEC2(1, 1)); + // UI_SetRawTexture(bla_tex_box, params.bla_tex, uv); + // } + + + // UI_Push(Tag, HashF("BLAAA")); + // { + + + // Vec4 bg = Color_Black; + // Vec4 bd = Color_White; + // UI_Size width = UI_PIX(params.bla_dims.x, 1); + // UI_Size height = UI_PIX(params.bla_dims.y, 1); + // Vec2 pos = VEC2(frame->screen_dims.x / 2, 100); + + + // UI_SetNext(Tint, Color_White); + // // UI_SetNext(BackgroundColor, bg); + // // UI_SetNext(BorderColor, bd); + // // UI_SetNext(BorderSize, 1); + // UI_SetNext(Rounding, UI_RPIX(20)); + // // UI_SetNext(BorderColor, window_border_color); + // // // UI_SetNext(BorderSize, theme.window_bd_sz); + // // UI_SetNext(BorderSize, 1); + // // UI_SetNext(Rounding, UI_RGROW(0.06 * theme.rounding)); + // UI_SetNext(Width, width); + // UI_SetNext(Height, height); + // // UI_SetNext(ChildLayoutAxis, Axis_Y); + // UI_SetNext(FloatingPos, pos); + // UI_SetNext(Anchor, UI_Region_Top); + // // UI_SetNext(Flags, UI_BoxFlag_Floating | (UI_BoxFlag_CaptureMouse * !!is_showing)); + // UI_SetNext(Flags, UI_BoxFlag_Floating); + // UI_PushCP(UI_BuildBoxEx(bla_box)); + // { + // UI_PushCP(UI_BuildBoxEx(bla_tex_box)); + // { + // } + // UI_PopCP(UI_TopCP()); + // } + // UI_PopCP(UI_TopCP()); + // } + // UI_Pop(Tag); + + + + + + // // f32 item_size_px = UI_FNT(1.5, 1).v; + // // f32 tweak_size_px = UI_FNT(1.25, 1).v; + + // // palette->key = UI_KeyF("command palette"); + // // UI_Checkpoint palette_cp = UI_PushCP(UI_NilKey); + // // { + // // UI_Push(Tag, palette->key.v); + // // UI_Key titlebar_key = UI_KeyF("title bar"); + // // UI_BoxReports titlebar_reps = UI_ReportsFromKey(titlebar_key); + // // UI_BoxReports palette_reps = UI_ReportsFromKey(palette->key); + + // // Vec4 window_background_color = theme.col.window_bg; + // // Vec4 window_border_color = theme.col.window_bd; + // // Vec4 titlebar_color = Zi; + // // Vec4 titlebar_border_color = Zi; + // // Vec4 divider_color = theme.col.divider; + // // if (titlebar_reps.draw.m1.held) + // // { + // // Vec2 drag_offset = SubVec2(ui_frame->drag_cursor_pos, palette_reps.drag.screen_anchor); + // // palette->pos = SubVec2(frame->screen_cursor, drag_offset); + // // } + // // window_border_color = LerpSrgb(window_border_color, theme.col.button_active, titlebar_reps.draw.hot); + + // // f32 scale = LerpF32(0.85, 1, palette->show); + // // UI_Push(Tint, VEC4(1, 1, 1, palette->show)); + // // UI_SetNext(Scale, VEC2(scale, scale)); + + // // UI_Push(BackgroundColor, window_background_color); + // // UI_Push(BorderColor, window_border_color); + // // // UI_Push(BorderSize, theme.window_bd_sz); + // // UI_Push(BorderSize, 1); + // // UI_Push(Rounding, UI_RGROW(0.06 * theme.rounding)); + // // UI_Push(Width, UI_FNT(40, 0)); + // // UI_Push(Height, UI_SHRINK(0, 0)); + // // UI_Push(ChildLayoutAxis, Axis_Y); + // // UI_Push(FloatingPos, palette->pos); + // // UI_SetNext(Anchor, UI_Region_Center); + // // UI_SetNext(Flags, UI_BoxFlag_Floating | (UI_BoxFlag_CaptureMouse * !!palette->is_showing)); + // // UI_PushCP(UI_BuildBoxEx(palette->key)); + // // } + // } + // } + + + + + + + + + + + + + + + ////////////////////////////// //- Build debug info UI diff --git a/src/pp/pp_vis/pp_vis_gpu.g b/src/pp/pp_vis/pp_vis_gpu.g index 182b0884..4014afeb 100644 --- a/src/pp/pp_vis/pp_vis_gpu.g +++ b/src/pp/pp_vis/pp_vis_gpu.g @@ -1,3 +1,132 @@ + +//////////////////////////////////////////////////////////// +//~ Bla samples test + + + +// FIXME: Remove this + + + + + + + +// FIXME: Header + + + + + + + +// TODO: Make use of the fact that x is always scalar? + + + + + + + + +ComputeShader(V_BlaCS) +{ + // FIXME: Don't use frame slot + BlaParams params = G_Deref(V_GpuConst_Frame, StructuredBuffer)[0]; + RWTexture2D bla = G_Deref(params.bla_tex, RWTexture2D); + + i64 samples_count = params.bla_samples_count; + StructuredBuffer samples = G_Deref(params.bla_samples, StructuredBuffer); + + + + Vec2 bla_pos = SV_DispatchThreadID + 0.5; + + Vec2 dims = params.bla_dims; + + + // f32 samp_width = 10 * G_TweakFloat; + f32 samp_width = 3; + + i64 sample_idx = bla_pos.x / samp_width; + + + + + if (all(bla_pos < dims) && sample_idx < samples_count) + { + // // Vec4 color = Color_Red; + // Vec4 color = Color_Black; + // color.b = bla_pos.x / dims.x; + // if (MatchFloor(bla_pos, params.cursor)) + // { + // G_PrintF("bla_pos: %F, dims: %F, color: %F", G_Fmt(bla_pos), G_Fmt(dims), G_Fmt(color)); + // } + // bla[bla_pos] = color; + + + + BlaSample sample = samples[sample_idx]; + // f32 ratio0 = (f32)sample.bla0 / (f32)samples_count; + // f32 ratio1 = (f32)sample.bla1 / (f32)samples_count; + + f32 ratio0 = sample.r0; + f32 ratio1 = sample.r1; + + + + + f32 ratio_y = 1.0 - (bla_pos.y / dims.y); + + + + Vec4 color = 0; + if (ratio_y < ratio0) + { + color = LinearFromSrgb(Vec4(0.82, 0, 0.933, 1)); + } + else if (ratio_y < ratio0 + ratio1) + { + color = LinearFromSrgb(Vec4(0.953, 0.467, 0.208, 1)); + } + else + { + color = 0; + } + + bla[bla_pos] = color; + + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + //////////////////////////////////////////////////////////// //~ Helpers diff --git a/src/pp/pp_vis/pp_vis_shared.cgh b/src/pp/pp_vis/pp_vis_shared.cgh index 842dd965..7dea3e3d 100644 --- a/src/pp/pp_vis/pp_vis_shared.cgh +++ b/src/pp/pp_vis/pp_vis_shared.cgh @@ -267,6 +267,55 @@ Struct(V_Affines) Affine tile_to_world; }; + + + + + + + + + + + + +// FIXME: Remove this + + +Struct(BlaSample) +{ + f32 r0; + f32 r1; +}; + + + + + + + +Struct(BlaParams) +{ + // FIXME: Remove this + i64 bla_samples_count; + G_BufferRef bla_samples; + + Vec2 cursor; + + Vec2 bla_dims; + G_TextureRef bla_tex; +}; + + + + + + + + + + + Struct(V_SharedFrame) { //- Time