feat(ui): one mounted tree instead of a screen object per build
Chrome and the app now share a tree, so a screen is no longer something an app constructs and holds: ui.mount() takes the function that builds the whole thing and ui.rebuild() runs it again. Building a node after layout is refused rather than silently resetting the arena under the panel.
This commit is contained in:
+44
-30
@@ -186,27 +186,30 @@ local function handler(name)
|
||||
end
|
||||
end
|
||||
|
||||
local first = ui.button {
|
||||
label = "one",
|
||||
on_enter = handler "enter",
|
||||
on_exit = handler "exit",
|
||||
on_click = handler "click",
|
||||
}
|
||||
local second = ui.button {
|
||||
label = "two",
|
||||
on_enter = handler "enter",
|
||||
on_exit = handler "exit",
|
||||
on_click = handler "click",
|
||||
}
|
||||
local screen = ui.screen(ui.box { row = true, first, second })
|
||||
local first, second
|
||||
ui.mount(function()
|
||||
first = ui.button {
|
||||
label = "one",
|
||||
on_enter = handler "enter",
|
||||
on_exit = handler "exit",
|
||||
on_click = handler "click",
|
||||
}
|
||||
second = ui.button {
|
||||
label = "two",
|
||||
on_enter = handler "enter",
|
||||
on_exit = handler "exit",
|
||||
on_click = handler "click",
|
||||
}
|
||||
return ui.box { row = true, first, second }
|
||||
end)
|
||||
|
||||
assert(screen:down(10, 10))
|
||||
assert(ui.down(10, 10))
|
||||
assert(node.isPressed(first))
|
||||
assert(screen:move(95, 10))
|
||||
assert(ui.move(95, 10))
|
||||
assert(not node.isPressed(first))
|
||||
assert(screen:move(10, 10))
|
||||
assert(ui.move(10, 10))
|
||||
assert(node.isPressed(first))
|
||||
assert(screen:up(10, 10))
|
||||
assert(ui.up(10, 10))
|
||||
assert(not node.isPressed(first))
|
||||
|
||||
local expectedTouch = { "enter", "exit", "enter", "exit", "click" }
|
||||
@@ -218,16 +221,16 @@ for index, name in ipairs(expectedTouch) do
|
||||
end
|
||||
|
||||
events = {}
|
||||
assert(screen:button("right", true))
|
||||
assert(screen:button("right", false))
|
||||
assert(ui.buttonPress("right", true))
|
||||
assert(ui.buttonPress("right", false))
|
||||
assert(node.getFocus() == first)
|
||||
assert(screen:button("right", true))
|
||||
assert(ui.buttonPress("right", true))
|
||||
assert(node.getFocus() == second)
|
||||
assert(screen:button("confirm", true))
|
||||
assert(ui.buttonPress("confirm", true))
|
||||
assert(node.isPressed(second))
|
||||
assert(screen:button("confirm", false))
|
||||
assert(ui.buttonPress("confirm", false))
|
||||
assert(not node.isPressed(second))
|
||||
assert(screen:button("back", true) == false)
|
||||
assert(ui.buttonPress("back", true) == false)
|
||||
|
||||
local expectedButtons = {
|
||||
{ "enter", first },
|
||||
@@ -246,7 +249,7 @@ assert(ui.setTheme "mono" == true)
|
||||
assert(ui.getTheme() == "mono" and #invalidated == before + 1)
|
||||
assert(cleared == ui.theme.background)
|
||||
|
||||
screen:draw()
|
||||
ui.draw()
|
||||
|
||||
-- 320x480 portrait: two columns, and the reserve comes off the height budget.
|
||||
local side, columns = ui.cardSide(5, 12, 8)
|
||||
@@ -265,21 +268,32 @@ local pressedCalls = {}
|
||||
node.setPressed = function(_, on)
|
||||
pressedCalls[#pressedCalls + 1] = on
|
||||
end
|
||||
local own = ui.custom { h = 20, press_style = false, on_click = function() end }
|
||||
local styled = ui.button { h = 20, label = "ok", on_click = function() end }
|
||||
local board = ui.screen(ui.box { own, styled })
|
||||
local own, styled
|
||||
ui.mount(function()
|
||||
own = ui.custom { h = 20, press_style = false, on_click = function() end }
|
||||
styled = ui.button { h = 20, label = "ok", on_click = function() end }
|
||||
return ui.box { own, styled }
|
||||
end)
|
||||
local target
|
||||
node.hit = function()
|
||||
return target
|
||||
end
|
||||
|
||||
target = own
|
||||
board:down(0, 0)
|
||||
board:up(0, 0)
|
||||
ui.down(0, 0)
|
||||
ui.up(0, 0)
|
||||
assert(#pressedCalls == 0, "a self-painting widget is not styled on press")
|
||||
|
||||
target = styled
|
||||
board:down(0, 0)
|
||||
ui.down(0, 0)
|
||||
assert(pressedCalls[1] == true, "an ordinary widget still gets its pressed style")
|
||||
|
||||
-- Building outside a rebuild would reset the arena under the screen on the panel.
|
||||
local built = pcall(ui.button, { label = "stray" })
|
||||
assert(not built, "a node built after layout is refused")
|
||||
local rebuilt = false
|
||||
ui.rebuild()
|
||||
rebuilt = true
|
||||
assert(rebuilt and ui.down(0, 0), "a rebuild replaces the screen and keeps dispatch live")
|
||||
|
||||
print "ok"
|
||||
|
||||
Reference in New Issue
Block a user