[Bugfix] Grid children get grid-world pixel coords in click_at, Frame children get frame-local — inconsistent #360

Closed
opened 2026-07-12 19:20:04 +00:00 by john · 0 comments
Owner

Summary

Child hit-testing uses two different coordinate spaces depending on the parent:

  • UIFrame::click_at (src/UIFrame.cpp:18-62) passes children a frame-local point: localPoint = point - position.
  • UIGrid::click_at (src/UIGrid.cpp:556-571) passes children grid-world pixels: sf::Vector2f(grid_world_x, grid_world_y) — i.e. camera/zoom-transformed, not view-local.

Neither is documented. A child Frame docked into a Grid therefore hit-tests against a different origin than the same Frame docked into a Frame.

Why it matters now

#355 ports the child/entity hit-test from UIGrid::click_at onto UIGridView::click_at. That port must either faithfully reproduce the grid-world convention (preserving the inconsistency) or fix it — and fixing it silently breaks anyone who has positioned a child inside a grid.

Decision for #355: reproduce the existing grid-world behavior exactly, and resolve this separately so the fix and the behavior change are not entangled in one diff.

Resolution

Keep grid-world (children pan/zoom with the grid — arguably the correct semantic for something anchored to grid content) and document it, including in the Grid.children docstring.

This is not an accident, it's just underdocumented. Frames have no ability to pan around their content, so their children are always in screen coordinates. Entities on Grids are positioned by cell. Drawables are positioned by pixels, but from the same origin as Entities. The use case is putting Drawables (like speech bubbles, or diagetic UI elements) spatially on the Grid near Entities.

If users want UI elements to float on top of the grid, then Grid children are not the solution. Build this structure instead:

  • Scene (or Frame, container)
    • Grid (pan, zoom, etc)
      • children and entities: positioned in grid world coordinates, the grid's camera position brings them in and out of view.
    • Frame (overlay)
      • children: positioned in frame coordinates.

the Grid and overlay should have the same position and size on their container, and the overlay draws on top of the Grid.

Blocked-ish on #355 landing first (don't change the convention in the same commit that revives the code path).


editing to confirm that yes, children of grids are drawables in the grid's pixel-world coordinates. It would make no sense to test for objects at their visible coordinates as moving the GridView's camera would break all positioning.

## Summary Child hit-testing uses two different coordinate spaces depending on the parent: - `UIFrame::click_at` (src/UIFrame.cpp:18-62) passes children a **frame-local** point: `localPoint = point - position`. - `UIGrid::click_at` (src/UIGrid.cpp:556-571) passes children **grid-world pixels**: `sf::Vector2f(grid_world_x, grid_world_y)` — i.e. camera/zoom-transformed, not view-local. Neither is documented. A child Frame docked into a Grid therefore hit-tests against a different origin than the same Frame docked into a Frame. ## Why it matters now #355 ports the child/entity hit-test from `UIGrid::click_at` onto `UIGridView::click_at`. That port must either faithfully reproduce the grid-world convention (preserving the inconsistency) or fix it — and fixing it silently breaks anyone who has positioned a child inside a grid. **Decision for #355: reproduce the existing grid-world behavior exactly, and resolve this separately** so the fix and the behavior change are not entangled in one diff. ## Resolution Keep grid-world (children pan/zoom with the grid — arguably the *correct* semantic for something anchored to grid content) and **document it**, including in the `Grid.children` docstring. This is not an accident, it's just underdocumented. Frames have no ability to pan around their content, so their children are always in screen coordinates. Entities on Grids are positioned by cell. Drawables are positioned by pixels, but from the same origin as Entities. The use case is putting Drawables (like speech bubbles, or diagetic UI elements) spatially on the Grid near Entities. If users want UI elements to float on top of the grid, then Grid children are not the solution. Build this structure instead: * Scene (or Frame, container) * Grid (pan, zoom, etc) * children and entities: positioned in grid world coordinates, the grid's camera position brings them in and out of view. * Frame (overlay) * children: positioned in frame coordinates. the Grid and overlay should have the same position and size on their container, and the overlay draws on top of the Grid. Blocked-ish on #355 landing first (don't change the convention in the same commit that revives the code path). --- editing to confirm that **yes, children of grids are drawables in the grid's pixel-world coordinates**. It would make no sense to test for objects at their visible coordinates as moving the GridView's camera would break all positioning.
john closed this issue 2026-07-13 11:44:13 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
john/McRogueFace#360
No description provided.