feat: scrolling
This commit is contained in:
+36
-3
@@ -27,8 +27,10 @@ local ui = {}
|
||||
---@field on_enter? UiHandler
|
||||
---@field on_exit? UiHandler
|
||||
---@field on_click? UiHandler
|
||||
---@field paint? fun(id: NodeId, x: integer, y: integer, w: integer, h: integer)
|
||||
---@field paint? fun(id: NodeId, x: integer, y: integer, w: integer, h: integer, clipX: integer, clipY: integer, clipW: integer, clipH: integer)
|
||||
---@field press_style? boolean False for a widget that paints its own press feedback.
|
||||
---@field scrollX? boolean Children measure unbounded across, and the box pans horizontally.
|
||||
---@field scrollY? boolean Children measure unbounded down, and the box pans vertically.
|
||||
|
||||
---@class UiConfirmSpec
|
||||
---@field title string
|
||||
@@ -135,10 +137,13 @@ local function clearState()
|
||||
pressStyles = {}
|
||||
end
|
||||
|
||||
tree.setPainter(function(id, x, y, w, h)
|
||||
-- The clip is the slice of the node being repainted now, which for a composited repaint is
|
||||
-- one band. A painter that ignores it still draws correctly; one that culls to it stops
|
||||
-- redrawing its whole contents once per band it spans.
|
||||
tree.setPainter(function(id, x, y, w, h, clipX, clipY, clipW, clipH)
|
||||
local painter = painters[id]
|
||||
if painter then
|
||||
painter(id, x, y, w, h)
|
||||
painter(id, x, y, w, h, clipX, clipY, clipW, clipH)
|
||||
end
|
||||
end)
|
||||
|
||||
@@ -308,6 +313,29 @@ function ui.invalidate(id)
|
||||
tree.invalidate(id)
|
||||
end
|
||||
|
||||
---Pans a scrollable node, clamped to its content. The node is marked dirty, so the next
|
||||
---ui.draw() repaints it -- there is nothing for the app to draw and no handle to refresh,
|
||||
---which is the whole point of scrolling in the tree rather than in a painter.
|
||||
---@param id NodeId
|
||||
---@param x integer
|
||||
---@param y integer
|
||||
function ui.setScroll(id, x, y)
|
||||
tree.setScroll(id, x, y)
|
||||
end
|
||||
|
||||
---@param id NodeId
|
||||
---@return integer x, integer y
|
||||
function ui.getScroll(id)
|
||||
return tree.getScroll(id)
|
||||
end
|
||||
|
||||
---How far each axis can pan. Zero on an axis whose content already fits.
|
||||
---@param id NodeId
|
||||
---@return integer maxX, integer maxY
|
||||
function ui.getScrollRange(id)
|
||||
return tree.getScrollRange(id)
|
||||
end
|
||||
|
||||
---@param spec UiConfirmSpec
|
||||
---@return NodeId
|
||||
function ui.confirm(spec)
|
||||
@@ -393,10 +421,15 @@ function ui.rebuild()
|
||||
collectgarbage()
|
||||
end
|
||||
|
||||
-- One GC step a frame, because the collector's default pace is the painter's problem: a
|
||||
-- band buffer needs a contiguous block, and letting the heap double before a cycle lets
|
||||
-- garbage take the block the band was going to get. Stepping keeps the sawtooth shallow
|
||||
-- enough that beginBuffer() keeps succeeding instead of falling back to the panel.
|
||||
function ui.draw()
|
||||
if root then
|
||||
tree.draw(root)
|
||||
end
|
||||
collectgarbage "step"
|
||||
end
|
||||
|
||||
local function inside(id, x, y)
|
||||
|
||||
Reference in New Issue
Block a user