Files
slate32/test/statusbar_dirty.lua
T
evan 2bc370a4ca feat(ui): restyle the status bar title, back button and wifi icon
The app name now uses the UI font like a card title, with its own baseline so
the larger text stays centred. The back button loses its border, since the
fill already carries the pressed state, and the firmware reports that state so
it can repaint. An offline radio draws faded bars behind a cross rather than
vanishing.
2026-08-04 13:11:28 -04:00

81 lines
3.1 KiB
Lua

-- Run: lua test/statusbar_dirty.lua
-- Asserts the bar repaints only what changed, and that it notices the two things it can
-- only learn by looking: rotation and theme. The clock is pinned unsynced so its text is
-- constant and every other field can be steered on its own.
package.path = "sdcard/.lua/lib/?.lua;test/?.lua;" .. package.path
local device = require("fake_device").install()
local ui = require("ui")
local statusbar = require("statusbar")
device.clockSynced = false
-- Returns the labels drawn by one draw() call.
local function paint()
device.painted = {}
device.lines = {}
statusbar.draw(true, false)
local labels = {}
for _, entry in ipairs(device.painted) do labels[#labels + 1] = entry.label end
return labels
end
local function has(labels, want)
for _, label in ipairs(labels) do if label == want then return true end end
return false
end
local first = paint()
assert(has(first, device.appName), "first draw paints the app name")
assert(has(first, "--:--:--"), "first draw paints the clock")
assert(has(first, "117kB"), "first draw paints used memory")
assert(#device.lines == 5, "offline wifi adds one diagonal to the back chevron lines")
assert(#paint() == 0, "an unchanged bar paints nothing")
device.freeHeap = device.freeHeap - 32000
local memOnly = paint()
assert(#memOnly == 1 and memOnly[1] == "148kB", "only the memory slot repaints")
device.status = {state = "connected", ssid = "x", ip = "", rssi = -50}
assert(#paint() == 0 and #device.lines == 0, "connected signal bars have no cross")
device.status = {state = "disconnected", ssid = "", ip = "", rssi = 0}
assert(#paint() == 0 and #device.lines == 1, "disconnected wifi draws one diagonal cross")
local beforePressed = #device.roundRects
statusbar.draw(true, true)
assert(#device.roundRects == beforePressed + 1, "pressing back repaints its button")
statusbar.draw(true, false)
-- Rotation and theme invalidate everything, because every slot moves or recolors.
device.rotation = 180
assert(has(paint(), device.appName), "rotation repaints the whole bar")
assert(#paint() == 0, "and settles again afterwards")
ui.setTheme("dark")
assert(has(paint(), device.appName), "a theme change repaints the whole bar")
-- An app renaming itself is a bar change like any other, with no invalidation call.
sys.setAppTitle("settings - wifi")
assert(has(paint(), "settings - wifi"), "a renamed app repaints the whole bar")
assert(#paint() == 0, "and settles again afterwards")
-- A name wide enough to reach the memory slot is clipped, not drawn over it.
sys.setAppTitle(string.rep("w", 60))
local clipped
for _, label in ipairs(paint()) do
if label:sub(1, 1) == "w" then clipped = label end
end
assert(clipped and #clipped < 60, "an over-long name is clipped, got " .. #(clipped or ""))
sys.setAppTitle("test")
-- Leaving fullscreen is the one change draw() cannot see: the app painted over the bar
-- while nothing about the bar's own state moved.
ui.setTheme("light")
paint()
statusbar.setFullscreen(true)
statusbar.setFullscreen(false)
assert(has(paint(), device.appName), "leaving fullscreen repaints the whole bar")
print("ok")