Files
slate32/sdcard/lib/statusbar.lua
T
evan b9b620ad2b feat(ui): add a home button to the status bar, rename launcher to home
Leaving an app was the app's own responsibility, so one that shipped without
an exit could only be escaped with a reset. The bar now paints a back button
into its leading square and the firmware treats that rect as home, acting on
release so a press sliding into the app cancels. The app it returns to is
/apps/home, which is what it is to the user.

Card grids in home and settings centre left to right as a unit.
2026-08-01 23:13:20 -04:00

66 lines
2.2 KiB
Lua

-- The top bar, painted by the firmware once a second in every app. It draws in panel
-- coordinates (the firmware drops the app viewport around the call), so gui.width()
-- here is the whole screen.
local ui = require("ui")
local PAD = 6
-- The firmware reads both: `height` is the strip it keeps apps out of, `interval` is how
-- often it calls draw().
local M = {height = 22, interval = 1000}
local BAR_H = M.height
local function clock()
return sys.clockSynced() and os.date("%H:%M") or "--:--"
end
-- Bars rather than glyphs: there is no icon font, and signal strength is a scale.
local function drawSignal(x, y, color, muted)
local status = wifi.status()
local bars = 0
if status.state == "connected" then
bars = status.rssi >= -60 and 3 or status.rssi >= -75 and 2 or 1
end
for i = 1, 3 do
local h = i * 3
gui.fillRect(x + (i - 1) * 4, y + 9 - h, 3, h, i <= bars and color or muted)
end
end
-- Fills the leading square of the bar, which is the rect the firmware treats as home.
-- Drawn as a button rather than left as a hidden hit region: a target nobody can see is
-- one nobody finds.
local function drawHome(theme)
local inset = 3
local side = BAR_H - 1 - inset * 2
gui.roundRect(inset, inset, side, side, 4, theme.bg, theme.face[1], theme.face[2], theme.muted)
local x, y = inset + side // 2 + 1, inset + side // 2
for offset = 0, 1 do -- two passes, because a one pixel chevron reads as a speck
gui.drawLine(x + offset, y - 4, x + offset - 4, y, theme.fg)
gui.drawLine(x + offset - 4, y, x + offset, y + 4, theme.fg)
end
end
function M.draw(home)
local theme = ui.theme
gui.setTextSize(1) -- panel state: the app may have left it scaled up
local w = gui.width()
gui.fillRect(0, 0, w, BAR_H, theme.bg)
gui.fillRect(0, BAR_H - 1, w, 1, theme.muted) -- a rule, so the bar reads as chrome
local textY = math.floor((BAR_H - 1 - gui.fontHeight()) / 2)
local nameX = PAD
if home then
drawHome(theme)
nameX = BAR_H + PAD
end
gui.drawText(sys.appName(), nameX, textY, theme.fg, theme.bg)
local time = clock()
gui.drawText(time, w - PAD - gui.textWidth(time), textY, theme.muted, theme.bg)
drawSignal(w - PAD - gui.textWidth(time) - 8 - 11, textY, theme.fg, theme.muted)
end
return M