Files
slate32/sdcard/apps/Paint/main.lua
evan 7c0928d84e feat(ui): add drag gestures and a scrollable box
The firmware now fires on_touch_move with a 2px noise threshold; gesture
intent is the toolkit's 8px slop, since a painting app's stroke starts at
the first real pixel. Past the slop, Screen:move hands the drag to the
nearest scroll ancestor and cancels the widget under the finger.

ui.scroll leans on the app viewport for clipping, so it must reach both
panel edges. Paint and Scroll demo both halves of the gesture split.
2026-08-02 16:59:42 -04:00

49 lines
1.2 KiB
Lua

local ui = require("ui")
-- No components: a canvas has one gesture and every pixel is content, so the app takes
-- the touch callbacks raw. It wants the firmware's noise threshold and no gesture slop --
-- a three pixel stroke is a stroke, not a mis-tap.
local theme = ui.theme
local CLEAR = {x = 0, y = 0, w = 64, h = 28}
local BRUSH = 2
local lastX, lastY
local function inClear(x, y)
return x < CLEAR.w and y < CLEAR.h
end
local function clear()
gui.clear(theme.bg)
gui.roundRect(CLEAR.x, CLEAR.y, CLEAR.w, CLEAR.h, theme.radius, theme.bg,
theme.face[1], theme.face[2], theme.fg)
gui.drawText("clear", 14, 10, theme.fg)
end
function init()
clear()
log.info("paint ready")
end
function on_touch_down(x, y)
if inClear(x, y) then
lastX = nil
return clear()
end
lastX, lastY = x, y
gui.fillCircle(x, y, BRUSH, theme.accent)
end
-- Strokes are joined with a line because the poll rate, not the finger, decides the gap:
-- a fast swipe reports points tens of pixels apart and dots alone would look dotted.
function on_touch_move(x, y)
if not lastX then return end
gui.drawLine(lastX, lastY, x, y, theme.accent)
gui.fillCircle(x, y, BRUSH, theme.accent)
lastX, lastY = x, y
end
function on_touch_up()
lastX = nil
end