68 lines
1.8 KiB
Lua
68 lines
1.8 KiB
Lua
local ui = require "ui"
|
|
|
|
-- A scrolling list with no band management of its own: the painter composites the dirty
|
|
-- region into offscreen bands and pushes each once, so this just draws every visible row in
|
|
-- screen coordinates and invalidates on each tick. The rows straddle band edges freely --
|
|
-- roundRect's corner spans clip to the band in the driver, so a split row is drawn correctly
|
|
-- in each half.
|
|
local ROWS = 60
|
|
local ROW_H = 64
|
|
local GAP = 8
|
|
local FONT = screen.FONT_LARGE
|
|
local SPEED = 6 -- pixels per 20ms tick
|
|
|
|
---@class ScrollApp : SlateApp
|
|
local M = {}
|
|
local node
|
|
local area
|
|
local scrollY = 0
|
|
local velocity = SPEED
|
|
|
|
local function render(x, y, w, h)
|
|
area = { x = x, y = y, w = w, h = h }
|
|
local textH = screen.getFontHeight(FONT)
|
|
for i = 0, ROWS - 1 do
|
|
local top = y + i * ROW_H - scrollY
|
|
if top + ROW_H > y and top < y + h then
|
|
local fill = (i % 2 == 0) and ui.theme.face or ui.theme.background
|
|
screen.roundRect(x + GAP, top + GAP, w - 2 * GAP, ROW_H - 2 * GAP,
|
|
ui.theme.radius, ui.theme.background, fill, nil, ui.theme.muted)
|
|
local label = "Row " .. (i + 1)
|
|
local tx = x + (w - screen.getTextWidth(FONT, label)) // 2
|
|
screen.drawText(FONT, tx, top + (ROW_H - textH) // 2, label, ui.theme.color)
|
|
end
|
|
end
|
|
end
|
|
|
|
function M.init()
|
|
timer.every(20, function()
|
|
if not area then
|
|
return
|
|
end
|
|
scrollY = scrollY + velocity
|
|
local maxScroll = ROWS * ROW_H - area.h
|
|
if scrollY <= 0 then
|
|
scrollY = 0
|
|
velocity = math.abs(velocity)
|
|
elseif scrollY >= maxScroll then
|
|
scrollY = maxScroll
|
|
velocity = -math.abs(velocity)
|
|
end
|
|
ui.invalidate(node)
|
|
end)
|
|
log.info "scroll demo ready"
|
|
end
|
|
|
|
function M.node()
|
|
node = ui.custom {
|
|
w = "fill",
|
|
h = "fill",
|
|
paint = function(_, x, y, w, h)
|
|
render(x, y, w, h)
|
|
end,
|
|
}
|
|
return node
|
|
end
|
|
|
|
return M
|