4e5796fd51
Apps describe nesting instead of coordinates: /lib/ui.lua borrows CSS block flow, the box model and auto sizing, and owns hit testing, press capture and the pressed repaint. The runtime gains require backed by the SD card, on_touch_down/on_touch_up, text metrics and rounded gradient fills, so the launcher becomes an ordinary Lua app and the firmware keeps only a fallback screen for an unreadable card.
50 lines
1.4 KiB
Lua
50 lines
1.4 KiB
Lua
local ui = require("ui")
|
|
|
|
local BLACK, WHITE = gui.color(0, 0, 0), gui.color(255, 255, 255)
|
|
local ACCENT, MUTED = gui.color(0, 120, 255), gui.color(120, 120, 120)
|
|
local FACE = {gui.color(255, 255, 255), gui.color(222, 228, 236)}
|
|
local FACE_PRESSED = {gui.color(0, 140, 255), gui.color(0, 96, 220)}
|
|
|
|
local screen
|
|
|
|
-- Rows are interactive containers rather than plain buttons, so each can carry a
|
|
-- name plus secondary text (and an icon later) while still being one tap target.
|
|
local function appRow(name)
|
|
return ui.button{
|
|
pad = {t = 8, r = 10, b = 8, l = 10},
|
|
align = "start",
|
|
on_press = function() sys.launch("/apps/" .. name .. "/main.lua") end,
|
|
ui.text(name),
|
|
}
|
|
end
|
|
|
|
function setup()
|
|
local items = {
|
|
pad = 12,
|
|
gap = 8,
|
|
color = BLACK,
|
|
bg = WHITE,
|
|
press_bg = ACCENT,
|
|
press_color = WHITE,
|
|
gradient = FACE,
|
|
press_gradient = FACE_PRESSED,
|
|
ui.text("esp32-lcd"),
|
|
}
|
|
|
|
local names = fs.listDirs("/apps")
|
|
table.sort(names)
|
|
for _, name in ipairs(names) do
|
|
if name ~= "launcher" then items[#items + 1] = appRow(name) end
|
|
end
|
|
if #names <= 1 then
|
|
items[#items + 1] = ui.text("no apps in /apps", {color = MUTED})
|
|
end
|
|
|
|
screen = ui.screen(ui.box(items))
|
|
log.info("launcher ready")
|
|
end
|
|
|
|
function draw() screen:draw() end
|
|
function on_touch_down(x, y) screen:down(x, y) end
|
|
function on_touch_up(x, y) screen:up(x, y) end
|