Use smallest-area tiebreaker for mouse click hit-testing too

Same overlap fix applied to handleMouseClick: when multiple controls
contain the click point, prefer the one with the smallest bounding
area instead of the one with the largest left-edge X. This is more
robust for any layout (vertical menus, grids, overlapping panels)
and matches the hover path logic.

Those changes were initially made in order to fix the teleport ui for the mouse but broke every other well working ui.
This commit is contained in:
MrTheShy 2026-03-06 05:25:47 +01:00
parent 9432005056
commit 1377575462
2 changed files with 8 additions and 10 deletions

View file

@ -469,12 +469,10 @@ bool UIScene::handleMouseClick(F32 x, F32 y)
vector<UIControl *> *controls = GetControls(); vector<UIControl *> *controls = GetControls();
if (!controls) return false; if (!controls) return false;
// Flash may report overlapping bounds for side-by-side controls (e.g. // Hit-test controls and pick the smallest-area match to handle
// TextInputs with full 630px width in debug scenes). Among all controls // overlapping Flash bounds correctly without sacrificing precision.
// that contain the click point, pick the one whose left edge (cx) is
// closest to the click X — i.e. largest cx that is still <= x.
int bestId = -1; int bestId = -1;
S32 bestCx = -1; S32 bestArea = INT_MAX;
UIControl *bestCtrl = NULL; UIControl *bestCtrl = NULL;
for (size_t i = 0; i < controls->size(); ++i) for (size_t i = 0; i < controls->size(); ++i)
@ -501,9 +499,10 @@ bool UIScene::handleMouseClick(F32 x, F32 y)
if (x >= cx && x <= cx + cw && y >= cy && y <= cy + ch) if (x >= cx && x <= cx + cw && y >= cy && y <= cy + ch)
{ {
if (cx > bestCx) S32 area = cw * ch;
if (area < bestArea)
{ {
bestCx = cx; bestArea = area;
bestId = ctrl->getId(); bestId = ctrl->getId();
bestCtrl = ctrl; bestCtrl = ctrl;
} }

View file

@ -184,9 +184,8 @@ public:
virtual UIControl* GetMainPanel(); virtual UIControl* GetMainPanel();
#ifdef _WINDOWS64 #ifdef _WINDOWS64
// Mouse click dispatch. Default implementation hit-tests C++ controls with // Mouse click dispatch. Hit-tests C++ controls and picks the smallest-area
// "best match" logic (largest left-edge X) to handle overlapping Flash bounds, // match, then calls handlePress. Override for custom behaviour (e.g. crafting).
// then calls the virtual handlePress. Override for custom behaviour (e.g. crafting).
virtual bool handleMouseClick(F32 x, F32 y); virtual bool handleMouseClick(F32 x, F32 y);
#endif #endif