Files
slate32/sdcard/.lua/apps/Scroll/main.lua
T
2026-08-06 09:05:14 -04:00

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