From 7531e18245e2f57db44a1a68a742467409711ff5 Mon Sep 17 00:00:00 2001 From: jacob Date: Thu, 18 Dec 2025 14:17:09 -0600 Subject: [PATCH] merge vis widgets w/ core --- src/pp/pp_vis/pp_vis.lay | 2 - src/pp/pp_vis/pp_vis_core.c | 446 ++++++++++++++++++++++++++++++++- src/pp/pp_vis/pp_vis_core.h | 85 +++++++ src/pp/pp_vis/pp_vis_shaders.g | 40 ++- src/pp/pp_vis/pp_vis_widgets.c | 426 ------------------------------- src/pp/pp_vis/pp_vis_widgets.h | 93 ------- 6 files changed, 538 insertions(+), 554 deletions(-) delete mode 100644 src/pp/pp_vis/pp_vis_widgets.c delete mode 100644 src/pp/pp_vis/pp_vis_widgets.h diff --git a/src/pp/pp_vis/pp_vis.lay b/src/pp/pp_vis/pp_vis.lay index 4bfa543e..7fdda791 100644 --- a/src/pp/pp_vis/pp_vis.lay +++ b/src/pp/pp_vis/pp_vis.lay @@ -26,7 +26,6 @@ ////////////////////////////// //- Api -@IncludeC pp_vis_widgets.h @IncludeC pp_vis_shaders.cgh @IncludeC pp_vis_draw.h @IncludeC pp_vis_core.h @@ -39,7 +38,6 @@ ////////////////////////////// //- Impl -@IncludeC pp_vis_widgets.c @IncludeC pp_vis_draw.c @IncludeC pp_vis_core.c diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index b21969af..adf13600 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -32,6 +32,287 @@ S_Cmd *V_PushSimCmd(S_CmdKind kind) return &n->cmd; } +String V_StringFromHotkey(Arena *arena, V_Hotkey hotkey) +{ + TempArena scratch = BeginScratch(arena); + StringList parts = Zi; + if (hotkey.ctrl) + { + PushStringToList(scratch.arena, &parts, Lit("Ctrl")); + } + if (hotkey.alt) + { + PushStringToList(scratch.arena, &parts, Lit("Alt")); + } + if (hotkey.shift) + { + PushStringToList(scratch.arena, &parts, Lit("Shift")); + } + PushStringToList(scratch.arena, &parts, StringFromButton(hotkey.button)); + EndScratch(scratch); + return StringFromList(arena, parts, Lit(" + ")); +} + +//////////////////////////////////////////////////////////// +//~ Theme + +V_WidgetTheme V_GetWidgetTheme(void) +{ + V_WidgetTheme theme = Zi; + + theme.font = GC_FontKeyFromResource(ResourceKeyFromStore(&V_Resources, Lit("font/fixedsys.ttf"))); + theme.font_size = 16; + + // theme.font = GC_FontKeyFromResource(ResourceKeyFromStore(&V_Resources, Lit("font/fixedsys.ttf"))); + // theme.font_size = 64; + + // theme.font = GC_FontKeyFromResource(ResourceKeyFromStore(&V_Resources, Lit("font/roboto-med.ttf"))); + // theme.font_size = 100; + + theme.window_background_color = Rgb32(0xff1a1d1e); + theme.window_border_color = Rgb32(0xff343a3b); + theme.window_border = 1; + theme.window_width = 500; + theme.window_padding = theme.window_border - 1; + theme.divider_color = theme.window_border_color; + + theme.window_title_font_size = 16; + theme.text_padding_x = 3; + theme.text_padding_y = 3; + + return theme; +} + +void V_PushWidgetThemeStyles(V_WidgetTheme theme) +{ + UI_Push(Font, theme.font); + UI_Push(FontSize, theme.font_size); +} + +//////////////////////////////////////////////////////////// +//~ Commands widget + +void V_BeginCommandsWidget(V_CommandsWidget *widget) +{ + ZeroStruct(&widget->build); + widget->build.cp = UI_PushCP(UI_NilKey); + UI_Push(Tag, HashF("commands widget")); +} + +V_CommandsWidgetItemReport V_PushCommandsWidgetItem(V_CommandsWidget *widget, V_CommandsWidgetItemDesc desc) +{ + Arena *frame_arena = UI_FrameArena(); + + UI_Key key = UI_KeyF("btn%F", FmtSint(widget->build.num_items)); + { + V_CommandsWidgetItem *item = PushStruct(frame_arena, V_CommandsWidgetItem); + item->key = key; + item->desc = desc; + SllQueuePush(widget->build.first_item, widget->build.last_item, item); + ++widget->build.num_items; + } + + V_CommandsWidgetItemReport 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_EndCommandsWidget(V_CommandsWidget *widget) +{ + V_WidgetTheme theme = V_GetWidgetTheme(); + Vec2 cursor_pos = UI_CursorPos(); + + UI_Push(Tag, HashF("commands widget")); + + UI_Key titlebar_key = UI_KeyF("title bar"); + + Vec4 window_background_color = theme.window_background_color; + Vec4 window_border_color = theme.window_border_color; + Vec4 titlebar_color = Zi; + Vec4 titlebar_border_color = Zi; + Vec4 divider_color = theme.divider_color; + { + UI_Report rep = UI_ReportFromKey(titlebar_key); + if (rep.m1_held) + { + widget->pos = SubVec2(cursor_pos, rep.last_m1_offset); + } + // window_border_color = BlendSrgb(window_border_color, Rgb(0.5, 0.5, 0.5), rep.hot); + window_border_color = BlendSrgb(window_border_color, Rgb32(0x0078a6), rep.hot); + } + + 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(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, widget->pos); + UI_SetNext(Flags, UI_BoxFlag_Floating); + UI_PushCP(UI_BuildBoxEx(UI_KeyF("titlebar"))); + { + /* 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("Commands")); + 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_CommandsWidgetItem *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; + Vec4 btn_border_color = Zi; + { + Vec4 hovered_color = Rgb32(0x103c4c); + Vec4 pressed_color = hovered_color; + pressed_color.w = 0.2; + f32 btn_hot = btn_rep.hot; + f32 btn_active = btn_rep.active; + f32 btn_hovered = btn_rep.hovered; + btn_color = BlendSrgb(btn_color, hovered_color, btn_hot); + btn_color = BlendSrgb(btn_color, pressed_color, btn_active * btn_hovered); + btn_border_color = BlendSrgb(btn_border_color, Rgb32(0x0078a6), btn_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_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 = BlendSrgb(hotkey_color, hovered_color, hotkey_hot); + hotkey_color = BlendSrgb(hotkey_color, pressed_color, hotkey_active * hotkey_hovered); + hotkey_border_color = BlendSrgb(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 @@ -43,8 +324,8 @@ void V_TickForever(WaveLaneCtx *lane) const i32 world_size = S_WorldSize; const f32 zoom_rate = 1.50; const f32 min_zoom = 0.03; - const f32 max_zoom = 10.0; - const f32 meters_per_draw_width = 20; + const f32 max_zoom = 15.0; + const f32 meters_per_draw_width = 18; ////////////////////////////// //- Init vis state @@ -205,7 +486,7 @@ void V_TickForever(WaveLaneCtx *lane) ent->local_shape = S_ShapeFromDesc( .mass = 10, .count = 1, - .radius = 0.4, + .radius = 0.3, ); } // ent->local_xf = XformFromPos(VEC2(200, 200)); @@ -508,6 +789,21 @@ void V_TickForever(WaveLaneCtx *lane) } } + ////////////////////////////// + //- Build editor UI + + // if (frame->is_editing) + // { + // UI_SetNext(BackgroundColor, VEC4(0, 0, 0, 1)); + // UI_SetNext(Width, UI_SHRINK(0, 1)); + // UI_SetNext(Height, UI_SHRINK(0, 1)); + // UI_PushCP(UI_BuildRow()); + // { + // UI_BuildLabelF("Tiles"); + // } + // UI_PopCP(UI_TopCP()); + // } + ////////////////////////////// //- Build command palette @@ -540,10 +836,143 @@ void V_TickForever(WaveLaneCtx *lane) ////////////////////////////// //- Build console UI + /* TODO: Remove this whole thing */ if (frame->show_console) { b32 minimized = 0; - V_BuildConsoleWidget(minimized); + + // i32 console_level = minimized ? LogLevel_Success : LogLevel_Debug; + i32 console_level = LogLevel_Debug; + + Vec4 colors[LogLevel_Count][2] = Zi; + SetBytes(colors, 0xFF, sizeof(colors)); + /* Debug colors */ + colors[LogLevel_Debug][0] = Rgb(0.4, 0.1, 0.4); + colors[LogLevel_Debug][1] = Rgb(0.5, 0.2, 0.5); + /* Info colors */ + colors[LogLevel_Info][0] = Rgb(0.4, 0.4, 0.4); + colors[LogLevel_Info][1] = Rgb(0.5, 0.5, 0.5); + /* Success colors */ + colors[LogLevel_Success][0] = Rgb(0.1, 0.3, 0.1); + colors[LogLevel_Success][1] = Rgb(0.2, 0.4, 0.2); + /* Warning colors */ + colors[LogLevel_Warning][0] = Rgb(0.4, 0.4, 0.1); + colors[LogLevel_Warning][1] = Rgb(0.5, 0.5, 0.2); + /* Error colors */ + colors[LogLevel_Error][0] = Rgb(0.4, 0.1, 0.1); + colors[LogLevel_Error][1] = Rgb(0.5, 0.2, 0.2); + + i64 max_time_ns = I64Max; + i64 fade_time_ns = max_time_ns; + if (minimized) + { + max_time_ns = NsFromSeconds(10); + fade_time_ns = max_time_ns; + } + f32 fade_curve = 0.5; + + i64 now_ns = TimeNs(); + UI_Key console_box = Zi; + { + UI_Push(FloatingPos, VEC2(0, 0)); + UI_SetNext(Flags, UI_BoxFlag_Floating); + UI_SetNext(Border, 0); + if (minimized) + { + UI_SetNext(BackgroundColor, 0); + UI_SetNext(Width, UI_PIX(500, 0)); + UI_SetNext(Height, UI_SHRINK(0, 1)); + } + else + { + UI_SetNext(BackgroundColor, Rgba(1, 1, 1, 0.02)); + UI_SetNext(Width, UI_GROW(1, 0)); + UI_SetNext(Height, UI_SHRINK(0, 1)); + } + console_box = UI_BuildColumnEx(UI_KeyF("Console box")); + UI_PushCP(console_box); + { + /* Gather display logs */ + u64 max = 20; + u64 display_count = 0; + LogEvent *display_logs = PushStructs(frame->arena, LogEvent, max); + { + b32 done = 0; + if (minimized) + { + max = 5; + } + LogEventsArray logs = GetLogEvents(); + for (u64 i = logs.count; i-- > 0 && display_count < max && !done;) + { + LogEvent ev = logs.logs[i]; + if (ev.time_ns > (now_ns - max_time_ns)) + { + if (ev.level <= console_level) + { + display_logs[display_count] = ev; + ++display_count; + } + } + else + { + done = 1; + } + } + } + /* Display logs in reverse */ + for (u64 i = display_count; i-- > 0;) + { + LogEvent log = display_logs[i]; + f32 opacity = 0.75; + f32 lin = 1.0 - ClampF64((f64)(now_ns - log.time_ns) / (f64)fade_time_ns, 0, 1); + opacity *= PowF32(lin, fade_curve); + String text = log.msg; + if (!minimized) + { + DateTime datetime = log.datetime; + text = StringF( + frame->arena, + "[%F:%F:%F.%F] %F", + FmtUint(datetime.hour, .z = 2), + FmtUint(datetime.minute, .z = 2), + FmtUint(datetime.second, .z = 2), + FmtUint(datetime.milliseconds, .z = 3), + FmtString(text)); + } + UI_PushCP(UI_NilKey); + { + Vec4 tint = VEC4(1, 1, 1, opacity); + UI_Push(Tint, tint); + { + Vec4 color = colors[log.level][log.level_id % 2]; + UI_Push(BackgroundColor, color); + UI_Push(Width, UI_GROW(1, 0)); + UI_Push(Height, UI_FNT(1.5, 1)); + UI_Push(BorderColor, Rgb(0.25, 0.25, 0.25)); + UI_Push(Rounding, UI_RPIX(0)); + UI_Push(Border, 1); + UI_Push(ChildAlignment, UI_Alignment_Left); + UI_PushCP(UI_BuildRow()); + { + // UI_SetNext(Height, UI_PIX(100, 0)); + UI_BuildSpacer(UI_PIX(10, 0), Axis_X); + UI_Push(BackgroundColor, 0); + UI_Push(Border, 0); + UI_Push(Text, text); + UI_Push(Width, UI_GROW(1, 0)); + UI_Push(Height, UI_SHRINK(0, 1)); + UI_Push(Flags, UI_BoxFlag_DrawText); + UI_BuildBox(); + } + UI_PopCP(UI_TopCP()); + } + } + UI_PopCP(UI_TopCP()); + } + } + UI_PopCP(UI_TopCP()); + } } ////////////////////////////// @@ -616,13 +1045,6 @@ void V_TickForever(WaveLaneCtx *lane) UI_PopCP(UI_TopCP()); } - ////////////////////////////// - //- Build edit mode UI - - if (frame->is_editing) - { - } - ////////////////////////////// //- Process vis commands @@ -804,7 +1226,7 @@ void V_TickForever(WaveLaneCtx *lane) { Vec4 color = Color_Cyan; f32 width = 0.1; - f32 height = 1; + f32 height = 0.75; S_Shape local_shape = S_ShapeFromDesc( .count = 4, .points = { diff --git a/src/pp/pp_vis/pp_vis_core.h b/src/pp/pp_vis/pp_vis_core.h index 99ac13d0..dc81ee7a 100644 --- a/src/pp/pp_vis/pp_vis_core.h +++ b/src/pp/pp_vis/pp_vis_core.h @@ -15,6 +15,38 @@ X(spawn, Spawn, V_CmdDescFlag_None, V_HOTKEY( Button_S, .ctrl = 1 ), ) \ /* -------------------------------------------------------------------------------------------------------------------- */ +//////////////////////////////////////////////////////////// +//~ Theme types + +Struct(V_WidgetTheme) +{ + GC_FontKey font; + f32 font_size; + f32 window_title_font_size; + + Vec4 window_background_color; + Vec4 window_border_color; + Vec4 divider_color; + f32 window_border; + f32 window_padding; + f32 window_width; + + f32 text_padding_x; + f32 text_padding_y; +}; + +//////////////////////////////////////////////////////////// +//~ Hotkey types + +#define V_HOTKEY(_button, ...) { .button = _button, __VA_ARGS__ } +Struct(V_Hotkey) +{ + Button button; + b32 ctrl; + b32 alt; + b32 shift; +}; + //////////////////////////////////////////////////////////// //~ Command types @@ -73,6 +105,45 @@ Global Readonly V_CmdDesc V_cmd_descs[V_CmdKind_Count] = { #undef X }; +//////////////////////////////////////////////////////////// +//~ Commands widget types + +Struct(V_CommandsWidgetItemReport) +{ + b32 pressed; + b32 hotkey_changed; + UI_Report ui_report; + V_Hotkey new_hotkeys[8]; +}; + +Struct(V_CommandsWidgetItemDesc) +{ + String display_name; + V_Hotkey hotkeys[8]; +}; + +Struct(V_CommandsWidgetItem) +{ + V_CommandsWidgetItem *next; + UI_Key key; + V_CommandsWidgetItemDesc desc; +}; + +Struct(V_CommandsWidget) +{ + /* Persistent state */ + Vec2 pos; + + /* Per-build state */ + struct + { + UI_Checkpoint cp; + V_CommandsWidgetItem *first_item; + V_CommandsWidgetItem *last_item; + u64 num_items; + } build; +}; + //////////////////////////////////////////////////////////// //~ Context types @@ -182,6 +253,20 @@ void V_Shutdown(void); V_Frame *V_CurrentFrame(void); S_Cmd *V_PushSimCmd(S_CmdKind kind); +String V_StringFromHotkey(Arena *arena, V_Hotkey hotkey); + +//////////////////////////////////////////////////////////// +//~ Theme + +V_WidgetTheme V_GetWidgetTheme(void); +void V_PushWidgetThemeStyles(V_WidgetTheme theme); + +//////////////////////////////////////////////////////////// +//~ Commands widget + +void V_BeginCommandsWidget(V_CommandsWidget *widget); +V_CommandsWidgetItemReport V_PushCommandsWidgetItem(V_CommandsWidget *widget, V_CommandsWidgetItemDesc desc); +void V_EndCommandsWidget(V_CommandsWidget *widget); //////////////////////////////////////////////////////////// //~ Vis tick diff --git a/src/pp/pp_vis/pp_vis_shaders.g b/src/pp/pp_vis/pp_vis_shaders.g index 4e1deb6e..64de1852 100644 --- a/src/pp/pp_vis/pp_vis_shaders.g +++ b/src/pp/pp_vis/pp_vis_shaders.g @@ -14,22 +14,21 @@ ComputeShader2D(V_BackdropCS, 8, 8) const Vec4 y_axis_color = LinearFromSrgb(Vec4(0, 0.75, 0, 1)); const Vec4 bounds_color = LinearFromSrgb(Vec4(0.75, 0.75, 0, 1)); - Vec2U32 target_pos = SV_DispatchThreadID; - Vec2I32 target_size = params.target_size; - if (target_pos.x < target_size.x && target_pos.y < target_size.y) + Vec2 screen_pos = Vec2(SV_DispatchThreadID) + Vec2(0.5, 0.5); + if (screen_pos.x < params.target_size.x && screen_pos.y < params.target_size.y) { Vec4 result = Vec4(0.025, 0.025, 0.025, 1); - Vec2 world_pos = mul(params.draw_to_world_xf, Vec3(target_pos, 1)); + Vec2 world_pos = mul(params.draw_to_world_xf, Vec3(screen_pos, 1)); Vec2I32 tile_pos = S_TilePosFromWorldPos(world_pos); f32 half_thickness = 1; f32 half_bounds_size = params.world_size * 0.5; Vec2 bounds_screen_p0 = mul(params.world_to_draw_xf, Vec3(-half_bounds_size, -half_bounds_size, 1)); Vec2 bounds_screen_p1 = mul(params.world_to_draw_xf, Vec3(half_bounds_size, half_bounds_size, 1)); - b32 is_in_bounds = target_pos.x > (bounds_screen_p0.x - half_thickness) && - target_pos.y > (bounds_screen_p0.y - half_thickness) && - target_pos.x < (bounds_screen_p1.x + half_thickness) && - target_pos.y < (bounds_screen_p1.y + half_thickness); + b32 is_in_bounds = screen_pos.x > (bounds_screen_p0.x - half_thickness) && + screen_pos.y > (bounds_screen_p0.y - half_thickness) && + screen_pos.x < (bounds_screen_p1.x + half_thickness) && + screen_pos.y < (bounds_screen_p1.y + half_thickness); if (is_in_bounds) { /* Grid checker */ @@ -64,10 +63,10 @@ ComputeShader2D(V_BackdropCS, 8, 8) Vec2 grid_screen_p0 = mul(params.world_to_draw_xf, Vec3(floor(world_pos), 1)); Vec2 grid_screen_p1 = mul(params.world_to_draw_xf, Vec3(ceil(world_pos), 1)); f32 grid_dist = 100000; - grid_dist = min(grid_dist, abs(target_pos.x - grid_screen_p0.x)); - grid_dist = min(grid_dist, abs(target_pos.x - grid_screen_p1.x)); - grid_dist = min(grid_dist, abs(target_pos.y - grid_screen_p0.y)); - grid_dist = min(grid_dist, abs(target_pos.y - grid_screen_p1.y)); + grid_dist = min(grid_dist, abs(screen_pos.x - grid_screen_p0.x)); + grid_dist = min(grid_dist, abs(screen_pos.x - grid_screen_p1.x)); + grid_dist = min(grid_dist, abs(screen_pos.y - grid_screen_p0.y)); + grid_dist = min(grid_dist, abs(screen_pos.y - grid_screen_p1.y)); if (grid_dist <= half_thickness) { result = grid_color; @@ -93,10 +92,9 @@ ComputeShader2D(V_BackdropCS, 8, 8) } /* Axis */ { - f32 half_thickness = 1; Vec2 zero_screen = mul(params.world_to_draw_xf, Vec3(0, 0, 1)); - f32 x_dist = abs(target_pos.x - zero_screen.x); - f32 y_dist = abs(target_pos.y - zero_screen.y); + f32 x_dist = abs(screen_pos.x - zero_screen.x); + f32 y_dist = abs(screen_pos.y - zero_screen.y); if (y_dist <= half_thickness) { result = x_axis_color; @@ -109,10 +107,10 @@ ComputeShader2D(V_BackdropCS, 8, 8) /* World bounds */ { f32 bounds_dist = 100000; - bounds_dist = min(bounds_dist, abs(target_pos.x - bounds_screen_p0.x)); - bounds_dist = min(bounds_dist, abs(target_pos.x - bounds_screen_p1.x)); - bounds_dist = min(bounds_dist, abs(target_pos.y - bounds_screen_p0.y)); - bounds_dist = min(bounds_dist, abs(target_pos.y - bounds_screen_p1.y)); + bounds_dist = min(bounds_dist, abs(screen_pos.x - bounds_screen_p0.x)); + bounds_dist = min(bounds_dist, abs(screen_pos.x - bounds_screen_p1.x)); + bounds_dist = min(bounds_dist, abs(screen_pos.y - bounds_screen_p0.y)); + bounds_dist = min(bounds_dist, abs(screen_pos.y - bounds_screen_p1.y)); if (bounds_dist <= half_thickness) { result = bounds_color; @@ -121,7 +119,7 @@ ComputeShader2D(V_BackdropCS, 8, 8) } - target[target_pos] = result; + target[trunc(screen_pos)] = result; } } @@ -248,7 +246,7 @@ PixelShader(V_OverlayPS, V_OverlayPSOutput, V_OverlayPSInput input) dist = min(dist, screen_selection.p1.y - screen_pos.y); dist = -dist; - // if (dist > -half_thickness && dist < half_thickness) + // if (dist >= -half_thickness && dist <= half_thickness) // { // result = border_color; // } diff --git a/src/pp/pp_vis/pp_vis_widgets.c b/src/pp/pp_vis/pp_vis_widgets.c deleted file mode 100644 index 82addb53..00000000 --- a/src/pp/pp_vis/pp_vis_widgets.c +++ /dev/null @@ -1,426 +0,0 @@ -//////////////////////////////////////////////////////////// -//~ Theme helpers - -V_WidgetTheme V_GetWidgetTheme(void) -{ - V_WidgetTheme theme = Zi; - - theme.font = GC_FontKeyFromResource(ResourceKeyFromStore(&V_Resources, Lit("font/fixedsys.ttf"))); - theme.font_size = 16; - - // theme.font = GC_FontKeyFromResource(ResourceKeyFromStore(&V_Resources, Lit("font/fixedsys.ttf"))); - // theme.font_size = 64; - - // theme.font = GC_FontKeyFromResource(ResourceKeyFromStore(&V_Resources, Lit("font/roboto-med.ttf"))); - // theme.font_size = 100; - - theme.window_background_color = Rgb32(0xff1a1d1e); - theme.window_border_color = Rgb32(0xff343a3b); - theme.window_border = 1; - theme.window_width = 500; - theme.window_padding = theme.window_border - 1; - theme.divider_color = theme.window_border_color; - - theme.window_title_font_size = 16; - theme.text_padding_x = 3; - theme.text_padding_y = 3; - - return theme; -} - -void V_PushWidgetThemeStyles(V_WidgetTheme theme) -{ - UI_Push(Font, theme.font); - UI_Push(FontSize, theme.font_size); -} - -//////////////////////////////////////////////////////////// -//~ Hotkey helpers - -String V_StringFromHotkey(Arena *arena, V_Hotkey hotkey) -{ - TempArena scratch = BeginScratch(arena); - StringList parts = Zi; - if (hotkey.ctrl) - { - PushStringToList(scratch.arena, &parts, Lit("Ctrl")); - } - if (hotkey.alt) - { - PushStringToList(scratch.arena, &parts, Lit("Alt")); - } - if (hotkey.shift) - { - PushStringToList(scratch.arena, &parts, Lit("Shift")); - } - PushStringToList(scratch.arena, &parts, StringFromButton(hotkey.button)); - EndScratch(scratch); - return StringFromList(arena, parts, Lit(" + ")); -} - -//////////////////////////////////////////////////////////// -//~ Commands widget - -void V_BeginCommandsWidget(V_CommandsWidget *widget) -{ - ZeroStruct(&widget->build); - widget->build.cp = UI_PushCP(UI_NilKey); - UI_Push(Tag, HashF("commands widget")); -} - -V_CommandsWidgetItemReport V_PushCommandsWidgetItem(V_CommandsWidget *widget, V_CommandsWidgetItemDesc desc) -{ - Arena *frame_arena = UI_FrameArena(); - - UI_Key key = UI_KeyF("btn%F", FmtSint(widget->build.num_items)); - { - V_CommandsWidgetItem *item = PushStruct(frame_arena, V_CommandsWidgetItem); - item->key = key; - item->desc = desc; - SllQueuePush(widget->build.first_item, widget->build.last_item, item); - ++widget->build.num_items; - } - - V_CommandsWidgetItemReport 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_EndCommandsWidget(V_CommandsWidget *widget) -{ - V_WidgetTheme theme = V_GetWidgetTheme(); - Vec2 cursor_pos = UI_CursorPos(); - - UI_Push(Tag, HashF("commands widget")); - - UI_Key titlebar_key = UI_KeyF("title bar"); - - Vec4 window_background_color = theme.window_background_color; - Vec4 window_border_color = theme.window_border_color; - Vec4 titlebar_color = Zi; - Vec4 titlebar_border_color = Zi; - Vec4 divider_color = theme.divider_color; - { - UI_Report rep = UI_ReportFromKey(titlebar_key); - if (rep.m1_held) - { - widget->pos = SubVec2(cursor_pos, rep.last_m1_offset); - } - // window_border_color = BlendSrgb(window_border_color, Rgb(0.5, 0.5, 0.5), rep.hot); - window_border_color = BlendSrgb(window_border_color, Rgb32(0x0078a6), rep.hot); - } - - 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(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, widget->pos); - UI_SetNext(Flags, UI_BoxFlag_Floating); - UI_PushCP(UI_BuildBoxEx(UI_KeyF("titlebar"))); - { - /* 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("Commands")); - 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_CommandsWidgetItem *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; - Vec4 btn_border_color = Zi; - { - Vec4 hovered_color = Rgb32(0x103c4c); - Vec4 pressed_color = hovered_color; - pressed_color.w = 0.2; - f32 btn_hot = btn_rep.hot; - f32 btn_active = btn_rep.active; - f32 btn_hovered = btn_rep.hovered; - btn_color = BlendSrgb(btn_color, hovered_color, btn_hot); - btn_color = BlendSrgb(btn_color, pressed_color, btn_active * btn_hovered); - btn_border_color = BlendSrgb(btn_border_color, Rgb32(0x0078a6), btn_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_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 = BlendSrgb(hotkey_color, hovered_color, hotkey_hot); - hotkey_color = BlendSrgb(hotkey_color, pressed_color, hotkey_active * hotkey_hovered); - hotkey_border_color = BlendSrgb(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); -} - -//////////////////////////////////////////////////////////// -//~ Console widget - -UI_Key V_BuildConsoleWidget(b32 minimized) -{ - /* TODO: Remove this whole thing */ - TempArena scratch = BeginScratchNoConflict(); - - // i32 console_level = minimized ? LogLevel_Success : LogLevel_Debug; - i32 console_level = LogLevel_Debug; - - Vec4 colors[LogLevel_Count][2] = Zi; - SetBytes(colors, 0xFF, sizeof(colors)); - /* Debug colors */ - colors[LogLevel_Debug][0] = Rgb(0.4, 0.1, 0.4); - colors[LogLevel_Debug][1] = Rgb(0.5, 0.2, 0.5); - /* Info colors */ - colors[LogLevel_Info][0] = Rgb(0.4, 0.4, 0.4); - colors[LogLevel_Info][1] = Rgb(0.5, 0.5, 0.5); - /* Success colors */ - colors[LogLevel_Success][0] = Rgb(0.1, 0.3, 0.1); - colors[LogLevel_Success][1] = Rgb(0.2, 0.4, 0.2); - /* Warning colors */ - colors[LogLevel_Warning][0] = Rgb(0.4, 0.4, 0.1); - colors[LogLevel_Warning][1] = Rgb(0.5, 0.5, 0.2); - /* Error colors */ - colors[LogLevel_Error][0] = Rgb(0.4, 0.1, 0.1); - colors[LogLevel_Error][1] = Rgb(0.5, 0.2, 0.2); - - i64 max_time_ns = I64Max; - i64 fade_time_ns = max_time_ns; - if (minimized) - { - max_time_ns = NsFromSeconds(10); - fade_time_ns = max_time_ns; - } - f32 fade_curve = 0.5; - - i64 now_ns = TimeNs(); - UI_Key console_box = Zi; - { - UI_SetNext(Border, 0); - if (minimized) - { - UI_SetNext(BackgroundColor, 0); - UI_SetNext(Width, UI_PIX(500, 0)); - UI_SetNext(Height, UI_SHRINK(0, 1)); - } - else - { - UI_SetNext(BackgroundColor, Rgba(1, 1, 1, 0.02)); - UI_SetNext(Width, UI_GROW(1, 0)); - UI_SetNext(Height, UI_SHRINK(0, 1)); - } - console_box = UI_BuildColumnEx(UI_KeyF("Console box")); - UI_PushCP(console_box); - { - /* Gather display logs */ - u64 max = 20; - u64 display_count = 0; - LogEvent *display_logs = PushStructs(scratch.arena, LogEvent, max); - { - b32 done = 0; - if (minimized) - { - max = 5; - } - LogEventsArray logs = GetLogEvents(); - for (u64 i = logs.count; i-- > 0 && display_count < max && !done;) - { - LogEvent ev = logs.logs[i]; - if (ev.time_ns > (now_ns - max_time_ns)) - { - if (ev.level <= console_level) - { - display_logs[display_count] = ev; - ++display_count; - } - } - else - { - done = 1; - } - } - } - /* Display logs in reverse */ - for (u64 i = display_count; i-- > 0;) - { - LogEvent log = display_logs[i]; - f32 opacity = 0.75; - f32 lin = 1.0 - ClampF64((f64)(now_ns - log.time_ns) / (f64)fade_time_ns, 0, 1); - opacity *= PowF32(lin, fade_curve); - String text = log.msg; - if (!minimized) - { - DateTime datetime = log.datetime; - text = StringF( - scratch.arena, - "[%F:%F:%F.%F] %F", - FmtUint(datetime.hour, .z = 2), - FmtUint(datetime.minute, .z = 2), - FmtUint(datetime.second, .z = 2), - FmtUint(datetime.milliseconds, .z = 3), - FmtString(text)); - } - UI_PushCP(UI_NilKey); - { - Vec4 tint = VEC4(1, 1, 1, opacity); - UI_Push(Tint, tint); - { - Vec4 color = colors[log.level][log.level_id % 2]; - UI_Push(BackgroundColor, color); - UI_Push(Width, UI_GROW(1, 0)); - UI_Push(Height, UI_FNT(1.5, 1)); - UI_Push(BorderColor, Rgb(0.25, 0.25, 0.25)); - UI_Push(Rounding, UI_RPIX(0)); - UI_Push(Border, 1); - UI_Push(ChildAlignment, UI_Alignment_Left); - UI_PushCP(UI_BuildRow()); - { - // UI_SetNext(Height, UI_PIX(100, 0)); - UI_BuildSpacer(UI_PIX(10, 0), Axis_X); - UI_Push(BackgroundColor, 0); - UI_Push(Border, 0); - UI_Push(Text, text); - UI_Push(Width, UI_GROW(1, 0)); - UI_Push(Height, UI_SHRINK(0, 1)); - UI_Push(Flags, UI_BoxFlag_DrawText); - UI_BuildBox(); - } - UI_PopCP(UI_TopCP()); - } - } - UI_PopCP(UI_TopCP()); - } - } - UI_PopCP(UI_TopCP()); - } - - EndScratch(scratch); - return console_box; -} diff --git a/src/pp/pp_vis/pp_vis_widgets.h b/src/pp/pp_vis/pp_vis_widgets.h deleted file mode 100644 index 06e8896c..00000000 --- a/src/pp/pp_vis/pp_vis_widgets.h +++ /dev/null @@ -1,93 +0,0 @@ -//////////////////////////////////////////////////////////// -//~ Theme types - -Struct(V_WidgetTheme) -{ - GC_FontKey font; - f32 font_size; - f32 window_title_font_size; - - Vec4 window_background_color; - Vec4 window_border_color; - Vec4 divider_color; - f32 window_border; - f32 window_padding; - f32 window_width; - - f32 text_padding_x; - f32 text_padding_y; -}; - -//////////////////////////////////////////////////////////// -//~ Hotkey types - -#define V_HOTKEY(_button, ...) { .button = _button, __VA_ARGS__ } -Struct(V_Hotkey) -{ - Button button; - b32 ctrl; - b32 alt; - b32 shift; -}; - -//////////////////////////////////////////////////////////// -//~ Commands widget types - -Struct(V_CommandsWidgetItemReport) -{ - b32 pressed; - b32 hotkey_changed; - UI_Report ui_report; - V_Hotkey new_hotkeys[8]; -}; - -Struct(V_CommandsWidgetItemDesc) -{ - String display_name; - V_Hotkey hotkeys[8]; -}; - -Struct(V_CommandsWidgetItem) -{ - V_CommandsWidgetItem *next; - UI_Key key; - V_CommandsWidgetItemDesc desc; -}; - -Struct(V_CommandsWidget) -{ - /* Persistent state */ - Vec2 pos; - - /* Per-build state */ - struct - { - UI_Checkpoint cp; - V_CommandsWidgetItem *first_item; - V_CommandsWidgetItem *last_item; - u64 num_items; - } build; -}; - -//////////////////////////////////////////////////////////// -//~ Theme helpers - -V_WidgetTheme V_GetWidgetThemeStyles(void); -void V_PushWidgetTheme(V_WidgetTheme theme); - -//////////////////////////////////////////////////////////// -//~ Hotkey helpers - -String V_StringFromHotkey(Arena *arena, V_Hotkey hotkey); - -//////////////////////////////////////////////////////////// -//~ Commands widget - -void V_BeginCommandsWidget(V_CommandsWidget *widget); -V_CommandsWidgetItemReport V_PushCommandsWidgetItem(V_CommandsWidget *widget, V_CommandsWidgetItemDesc desc); -void V_EndCommandsWidget(V_CommandsWidget *widget); - -//////////////////////////////////////////////////////////// -//~ Console widget - -UI_Key V_BuildConsoleWidget(b32 minimized);