From 0819655322aba1df956cc31544c1b402e65e8095 Mon Sep 17 00:00:00 2001 From: jacob Date: Tue, 4 Nov 2025 01:07:17 -0600 Subject: [PATCH] corner-aware cursor testing --- src/ui/ui_core.c | 40 +++++++++++++++++++++++++++++++--------- src/ui/ui_core.h | 1 + 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index f4c6341a..630c0aea 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -503,6 +503,30 @@ void UI_SetBackgroundTexture(UI_Box *box, GPU_Resource *texture, Vec2 uv0, Vec2 box->background_texture_uv1 = uv1; } +b32 UI_IsPointInBox(UI_Box *box, Vec2 point) +{ + /* TODO: More efficient test. This logic is just copied from the renderer's SDF function for now. */ + Vec2 p0 = box->p0; + Vec2 p1 = box->p1; + f32 inside_edge_dist = MinF32(MinF32(point.x - p0.x, p1.x - point.x), MinF32(point.y - p0.y, p1.y - point.y)); + if (inside_edge_dist > 0) + { + f32 tl_radius = box->rounding_tl; + f32 tr_radius = box->rounding_tr; + f32 br_radius = box->rounding_br; + f32 bl_radius = box->rounding_bl; + Vec2 tl = VEC2(p0.x + tl_radius, p0.y + tl_radius); + Vec2 tr = VEC2(p1.x - tr_radius, p0.y + tr_radius); + Vec2 br = VEC2(p1.x - br_radius, p1.y - br_radius); + Vec2 bl = VEC2(p0.x + bl_radius, p1.y - bl_radius); + if (point.x < tl.x && point.y < tl.y) inside_edge_dist = MinF32(inside_edge_dist, tl_radius - Vec2Len(SubVec2(tl, point))); + if (point.x > tr.x && point.y < tr.y) inside_edge_dist = MinF32(inside_edge_dist, tr_radius - Vec2Len(SubVec2(tr, point))); + if (point.x > br.x && point.y > br.y) inside_edge_dist = MinF32(inside_edge_dist, br_radius - Vec2Len(SubVec2(br, point))); + if (point.x < bl.x && point.y > bl.y) inside_edge_dist = MinF32(inside_edge_dist, bl_radius - Vec2Len(SubVec2(bl, point))); + } + return inside_edge_dist >= 0; +} + //////////////////////////////////////////////////////////// //~ Event @@ -561,24 +585,22 @@ void UI_BeginBuild(ControllerEventsArray controller_events, UI_BuildFlag build_f case ControllerEventKind_CursorMove: { - g->cursor_pos = MulXformV2(screen_to_ui_xf, Vec2FromFields(cev.cursor_pos)); + if (hovered_box) + { + hovered_box->event.flags &= ~UI_EventFlag_Hovered; + hovered_box = 0; + } /* Iterate boxes in reverse render order */ - for (u64 pre_index = g->boxes_count; pre_index-- > 0;) + for (u64 pre_index = g->boxes_count; pre_index-- > 0 && hovered_box == 0;) { UI_Box *box = g->boxes_pre[pre_index]; if (box->key.hash != 0) { - if (g->cursor_pos.x > box->p0.x && g->cursor_pos.x < box->p1.x && - g->cursor_pos.y > box->p0.y && g->cursor_pos.y < box->p1.y) + if (UI_IsPointInBox(box, g->cursor_pos)) { - if (hovered_box) - { - hovered_box->event.flags &= ~UI_EventFlag_Hovered; - } box->event.flags |= UI_EventFlag_Hovered; hovered_box = box; - break; } } } diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index a7a1b99a..bcfa9519 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -377,6 +377,7 @@ UI_Box *UI_BuildPad(UI_Box *parent, UI_Pad padding); UI_Box *UI_BuildBox(String seed); void UI_SetBackgroundTexture(UI_Box *box, GPU_Resource *texture, Vec2 uv0, Vec2 uv1); +b32 UI_IsPointInBox(UI_Box *box, Vec2 point); //////////////////////////////////////////////////////////// //~ Event