From 2be3381c928cd27831f50c01c2b886decd23ab03 Mon Sep 17 00:00:00 2001 From: jacob Date: Sun, 28 Dec 2025 17:20:05 -0600 Subject: [PATCH] better vis mouse focus checking --- src/base/base_controller.c | 5 +++ src/base/base_controller.h | 1 + src/pp/pp_vis/pp_vis_core.c | 56 ++++++++++++++++++++++++++++---- src/pp/pp_vis/pp_vis_shaders.cgh | 2 ++ src/pp/pp_vis/pp_vis_shaders.g | 48 ++++++++++++++------------- src/ui/ui_core.c | 32 ++++++++++++++---- src/ui/ui_core.h | 3 ++ 7 files changed, 111 insertions(+), 36 deletions(-) diff --git a/src/base/base_controller.c b/src/base/base_controller.c index be1f8cea..171f3728 100644 --- a/src/base/base_controller.c +++ b/src/base/base_controller.c @@ -107,3 +107,8 @@ String StringFromButton(Button button) } return name; } + +b32 IsMouseButton(Button button) +{ + return button >= Button_M1 && button <= Button_MWheelDown; +} diff --git a/src/base/base_controller.h b/src/base/base_controller.h index 09701fd1..e2b4bb1f 100644 --- a/src/base/base_controller.h +++ b/src/base/base_controller.h @@ -158,3 +158,4 @@ Struct(ControllerEventsArray) //~ Button helpers String StringFromButton(Button button); +b32 IsMouseButton(Button button); diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index 94c439aa..d92ae289 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -611,10 +611,30 @@ void V_TickForever(WaveLaneCtx *lane) V_CmdNode *first_cmd_node = 0; V_CmdNode *last_cmd_node = 0; - b32 has_focus = window_frame.has_focus && (UI_MatchKey(ui_frame->hovered_box, vis_box) || UI_MatchKey(ui_frame->active_box, vis_box)); - if (!has_focus) + b32 has_mouse_focus = (UI_MatchKey(ui_frame->hovered_box, vis_box) && UI_IsKeyNil(ui_frame->active_box)) || UI_MatchKey(ui_frame->active_box, vis_box); + b32 has_keyboard_focus = 1; + if (!window_frame.has_focus) { - ZeroStructs(frame->held_buttons, countof(frame->held_buttons)); + has_mouse_focus = 0; + has_keyboard_focus = 0; + } + + for (Button btn = 0; btn < countof(frame->held_buttons); ++btn) + { + if (btn == Button_M1 || btn == Button_M2) + { + if (!has_mouse_focus) + { + frame->held_buttons[btn] = 0; + } + } + else + { + if (!has_keyboard_focus) + { + frame->held_buttons[btn] = 0; + } + } } for (u64 i = 0; i < window_frame.controller_events.count; ++i) @@ -622,7 +642,27 @@ void V_TickForever(WaveLaneCtx *lane) ControllerEvent cev = window_frame.controller_events.events[i]; b32 down = cev.kind == ControllerEventKind_ButtonDown; b32 up = cev.kind == ControllerEventKind_ButtonUp; - if (up || (down && has_focus)) + + b32 ignore = 0; + if (down) + { + if (cev.button == Button_M1 || cev.button == Button_M2) + { + if (!has_mouse_focus) + { + ignore = 1; + } + } + else + { + if (!has_keyboard_focus) + { + ignore = 1; + } + } + } + + if (!ignore) { V_Hotkey hotkey = Zi; hotkey.button = cev.button; @@ -727,7 +767,7 @@ void V_TickForever(WaveLaneCtx *lane) } else { - frame->camera_lerp_ratio = 30.0 * frame->dt; + frame->camera_lerp_ratio = 40.0 * frame->dt; } } else @@ -1152,7 +1192,7 @@ void V_TickForever(WaveLaneCtx *lane) UI_SetNext(AxisSize, UI_PIX(10, 1), .axis = !panel->axis); UI_BuildBoxEx(divider_key); - if (rep.is_hovered || rep.is_m1_held) + if (rep.is_hot || rep.is_m1_held) { if (panel->axis == Axis_X) { @@ -1564,7 +1604,7 @@ void V_TickForever(WaveLaneCtx *lane) { if (!frame->is_panning) { - f32 edit_move_speed = 15.0 * MaxF32(frame->edit_camera_zoom, min_zoom); + f32 edit_move_speed = 20.0 * MaxF32(frame->edit_camera_zoom, min_zoom); frame->edit_camera_pos = AddVec2(frame->edit_camera_pos, MulVec2(move, edit_move_speed * frame->dt)); } } @@ -1678,6 +1718,8 @@ void V_TickForever(WaveLaneCtx *lane) params.selection_mode = frame->selection_mode; params.equipped_tile = frame->equipped_tile; + params.has_mouse_focus = has_mouse_focus; + params.has_keyboard_focus = has_keyboard_focus; params.ui_cursor = frame->ui_cursor; params.draw_cursor = frame->draw_cursor; params.world_cursor = frame->world_cursor; diff --git a/src/pp/pp_vis/pp_vis_shaders.cgh b/src/pp/pp_vis/pp_vis_shaders.cgh index 08becb9e..44e40b19 100644 --- a/src/pp/pp_vis/pp_vis_shaders.cgh +++ b/src/pp/pp_vis/pp_vis_shaders.cgh @@ -21,6 +21,8 @@ Struct(V_DParams) V_SelectionMode selection_mode; S_TileKind equipped_tile; + b32 has_mouse_focus; + b32 has_keyboard_focus; Vec2 ui_cursor; Vec2 draw_cursor; Vec2 world_cursor; diff --git a/src/pp/pp_vis/pp_vis_shaders.g b/src/pp/pp_vis/pp_vis_shaders.g index 6fe8ab36..fa1389ee 100644 --- a/src/pp/pp_vis/pp_vis_shaders.g +++ b/src/pp/pp_vis/pp_vis_shaders.g @@ -236,36 +236,38 @@ PixelShader(V_OverlayPS, V_OverlayPSOutput, V_OverlayPSInput input) tile_selection.p0 = S_TilePosFromWorldPos(world_selection.p0); tile_selection.p1 = S_TilePosFromWorldPos(world_selection.p1); - if (params.selection_mode == V_SelectionMode_Tile) + if (params.has_mouse_focus) { - f32 dist = 100000000; - dist = min(dist, screen_pos.x - screen_selection.p0.x); - dist = min(dist, screen_pos.y - screen_selection.p0.y); - dist = min(dist, screen_selection.p1.x - screen_pos.x); - dist = min(dist, screen_selection.p1.y - screen_pos.y); - dist = -dist; - - // if (dist >= -half_thickness && dist <= half_thickness) - // { - // result = border_color; - // } - // else + if (params.selection_mode == V_SelectionMode_Tile) { - if (world_pos.x > -(S_WorldSize / 2) && - world_pos.y > -(S_WorldSize / 2) && - world_pos.x < (S_WorldSize / 2) && - world_pos.y < (S_WorldSize / 2) && - tile_pos.x >= tile_selection.p0.x && - tile_pos.x <= tile_selection.p1.x && - tile_pos.y >= tile_selection.p0.y && - tile_pos.y <= tile_selection.p1.y) + f32 dist = 100000000; + dist = min(dist, screen_pos.x - screen_selection.p0.x); + dist = min(dist, screen_pos.y - screen_selection.p0.y); + dist = min(dist, screen_selection.p1.x - screen_pos.x); + dist = min(dist, screen_selection.p1.y - screen_pos.y); + dist = -dist; + + // if (dist >= -half_thickness && dist <= half_thickness) + // { + // result = border_color; + // } + // else { - result = inner_color; + if (world_pos.x > -(S_WorldSize / 2) && + world_pos.y > -(S_WorldSize / 2) && + world_pos.x < (S_WorldSize / 2) && + world_pos.y < (S_WorldSize / 2) && + tile_pos.x >= tile_selection.p0.x && + tile_pos.x <= tile_selection.p1.x && + tile_pos.y >= tile_selection.p0.y && + tile_pos.y <= tile_selection.p1.y) + { + result = inner_color; + } } } } - V_OverlayPSOutput output; output.sv_target0 = result; return output; diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index b9b0a8d8..84ad4439 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -23,6 +23,11 @@ b32 UI_MatchKey(UI_Key a, UI_Key b) return a.hash == b.hash; } +b32 UI_IsKeyNil(UI_Key key) +{ + return key.hash == 0; +} + UI_Key UI_KeyFromString(String str) { u64 top_tag = UI_UseTop(Tag); @@ -690,13 +695,20 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color) case ControllerEventKind_ButtonDown: { - if (cev.button == Button_M1) + if (cev.button == Button_M1 || cev.button == Button_M2) { if (hovered_box) { ++hovered_box->report.m1_downs; - hovered_box->report.is_m1_held = 1; hovered_box->report.last_m1_offset = SubVec2(frame->cursor_pos, hovered_box->rect.p0); + if (cev.button == Button_M1) + { + hovered_box->report.is_m1_held = 1; + } + else if (cev.button == Button_M2) + { + hovered_box->report.is_m2_held = 1; + } active_box = hovered_box; } } @@ -704,7 +716,7 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color) case ControllerEventKind_ButtonUp: { - if (cev.button == Button_M1) + if (cev.button == Button_M1 || cev.button == Button_M2) { if (active_box) { @@ -713,7 +725,14 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color) ++active_box->report.m1_presses; } ++active_box->report.m1_ups; - active_box->report.is_m1_held = 0; + if (cev.button == Button_M1) + { + active_box->report.is_m1_held = 0; + } + else if (cev.button == Button_M2) + { + active_box->report.is_m2_held = 0; + } active_box = 0; } } @@ -732,9 +751,10 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color) UI_Box *box = last_frame->boxes_pre[pre_index]; UI_Report *report = &box->report; report->is_hovered = box == hovered_box; - f32 target_hot = box == active_box || (box == hovered_box && (box == active_box || active_box == 0)); + report->is_hot = box == active_box || (box == hovered_box && (box == active_box || active_box == 0)); + f32 target_hovered = report->is_hovered; + f32 target_hot = report->is_hot; f32 target_active = box == active_box; - f32 target_hovered = box == hovered_box; f32 hot_blend_rate = target_hot == 1 ? 1 : (20 * dt); f32 active_blend_rate = target_active == 1 ? 1 : (20 * dt); f32 hovered_blend_rate = target_hovered == 1 ? 1 : (20 * dt); diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index dc8f63ce..34f27d69 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -175,7 +175,9 @@ Struct(UI_Stack) Struct(UI_Report) { b32 is_m1_held; + b32 is_m2_held; b32 is_hovered; + b32 is_hot; f32 hovered; f32 hot; @@ -395,6 +397,7 @@ GC_FontKey UI_GetDefaultFont(void); //~ Key helpers b32 UI_MatchKey(UI_Key a, UI_Key b); +b32 UI_IsKeyNil(UI_Key key); UI_Key UI_KeyFromString(String str); UI_Key UI_KeyF_(String fmt, ...); #define UI_KeyF(fmt_cstr, ...) UI_KeyF_(StringFromCstrNoLimit(fmt_cstr), __VA_ARGS__, FmtEnd)