ludic/packages/ludic.ui/popover.ludic

37 lines
1.5 KiB
Text

# popover.ludic - HTML's popover: `<div popover on-close="...">` sits where its position puts it
# (absolutely, in its parent) and is drawn on the top layer, over everything. While one is up the
# pointer and the keyboard are its: a press outside it, or Esc, closes it (on-close), and Tab
# walks only its own controls.
function pp_find(n: UiNode, out: []UiNode) -> void {
if n.popover {
push(out, n)
return
}
for i in 0 .. len(n.children) { pp_find(n.children[i], out) }
}
# the topmost popover open in this tree, or null
function pp_top(root: UiNode) -> UiNode {
if root.popover { return root } # the last one pp_find would list, found with no list made
var found: UiNode = null
for i in 0 .. len(root.children) {
let f = pp_top(root.children[i])
if f != null { found = f }
}
return found
}
# the pointer against the popover: inside it is as usual; a press outside closes it and is spent
function pp_pointer(ui_st: mut UiState, top: UiNode) -> bool {
let i = ui_st.in_now
if not (i.down and not ui_st.in_was_down) { return false }
if i.x >= top.x and i.y >= top.y and i.x < top.x + top.cw and i.y < top.y + top.ch { return false }
ui_st.fr_press_key = ""
ui_fire(ui_st, top, "close", Value.null())
return true
}
function pp_draw_top(ui_st: mut UiState) -> void {
let list = ui_st.pop_list # drawn from while what they open goes to the spare, then swapped
ui_st.pop_list = ui_st.pop_spare
List.clear(ui_st.pop_list)
for i in 0 .. len(list) { fr_draw(ui_st, list[i]) }
ui_st.pop_spare = list
}