ludic.ui: the pointer looks through a box with no size; a control's parts answer :hover

From the user's play, reproduced on Maroon Lake's customisation screen with the pointer scripted over
each control (the lab's R3D_CLICKS): nothing on it was ever pressed or hovered.

- A screen's root <div> round a positioned panel (a component's root holding the kit Screen's
  modal) lays out to 0x0, and the hit test (fr_pick) and :hover (fr_under) only walked into a child
  whose box held the point - so nothing under it was reachable. A box with no size holds no point and
  clips nothing: both look through it now (fr_empty), without hovering it.
- A control's parts (a select's < and >, a range's thumb) are made by ct_part, which never set
  `hovered`: `select .ui-prev:hover` could not match anywhere. It is set as an element's is.

Golden ui_pointer_through: the panel's button pressed and hovered through the empty root, and a
select's > hovered (before this: pressed 0, hovered 0). The 36 ui examples pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-29 13:26:33 +03:00
parent 06ecc5cd8e
commit 9b3d3e3298
5 changed files with 67 additions and 2 deletions

View file

@ -42,8 +42,9 @@ function fr_active(ui_st: UiState, n: UiNode) -> bool {
return ui_st.fr_key_press != "" and lc_mine(ui_st.fr_key_press, n.key)
}
function fr_under(n: UiNode, px: float, py: float, keys: []string) -> void {
if px < n.x or py < n.y or px >= n.x + n.cw or py >= n.y + n.ch { return }
if n.key != "" { ui_kept(keys, n.key) }
let out = px < n.x or py < n.y or px >= n.x + n.cw or py >= n.y + n.ch
if out and not fr_empty(n) { return }
if not out and n.key != "" { ui_kept(keys, n.key) }
for i in 0 .. len(n.children) { fr_under(n.children[i], px, py, keys) }
}
# the control (or pressable element) the pointer is on: out from the topmost element under it