# pointer_pick.ludic - what the pointer is on: the topmost element under it in painting order (a # positioned one by its z-index over the flow), and from there out to the nearest element that wants # what is asked - a control to press, or pointer events. pointer-events: none lets it through. const PK_CONTROL: int = 0 const PK_POINTER: int = 1 const PK_WHEEL: int = 2 function fr_in(n: UiNode, px: float, py: float) -> bool { if n.ex != null and n.ex.no_pointer { return false } return px >= n.x and py >= n.y and px < n.x + n.cw and py < n.y + n.ch } # the nearest element that wants `kind`, out from the topmost one under the point: the children are # walked the other way from how they are painted (positioned ones by z-index, highest first, then # the flow, last first; a popover is on the top layer, not here), with no list made for it function fr_pick(n: UiNode, px: float, py: float, kind: int) -> UiNode { if n.children == null { return fr_wants(n, kind) } var lo = 1000000 var hi = -1000000 for i in 0 .. len(n.children) { let c = n.children[i] if c.pos != 0 and not c.popover { lo = Math.min(lo, c.z) hi = Math.max(hi, c.z) } } var z = hi while z >= lo { var i = len(n.children) - 1 while i >= 0 { let c = n.children[i] if c.pos != 0 and not c.popover and c.z == z and fr_in(c, px, py) { return fr_pick_in(n, c, px, py, kind) } i -= 1 } z -= 1 } var k = len(n.children) - 1 while k >= 0 { let c = n.children[k] if c.pos == 0 and not c.popover and fr_in(c, px, py) { return fr_pick_in(n, c, px, py, kind) } if c.pos == 0 and not c.popover and fr_empty(c) { let r = fr_pick(c, px, py, kind) if r != null and r != c { return r } } k -= 1 } return fr_wants(n, kind) } # a box with no size of its own - a component's root