Files
slate32/test/statusbar_dirty.lua
T
evan b5146b8642 refactor(lua): give the status bar its own dirty tracking and split settings out of sys
The bar repainted itself whole every second. It now compares each field against what
it last painted, adds seconds and a memory percentage, and keys the cache on
gui.getRotation() and ui.themeName so rotation and theme changes still repaint it.
Invalidation lives entirely in Lua; the firmware's push flag and gfx/statusbar.h are gone.

Bindings follow getName/setName/isName, persisted preferences move from sys to a settings
table, and gui.setRotation takes degrees like settings does. A bar that dies mid-run now
keeps its rows reserved rather than silently resizing the running app.
2026-08-02 10:49:01 -04:00

60 lines
2.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/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 = {}
statusbar.draw(true)
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(#paint() == 0, "an unchanged bar paints nothing")
device.freeHeap = device.freeHeap - 32000
local memOnly = paint()
assert(#memOnly == 1 and memOnly[1]:find("%%"), "only the memory slot repaints")
device.status = {state = "connected", ssid = "x", ip = "", rssi = -50}
assert(#paint() == 0, "signal bars are not text, so nothing is drawn")
device.status = {state = "disconnected", ssid = "", ip = "", rssi = 0}
-- 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")
device.theme = "dark"
ui.reloadTheme()
assert(has(paint(), device.appName), "a theme change repaints the whole bar")
-- Leaving fullscreen is the one change draw() cannot see: the app painted over the bar
-- while nothing about the bar's own state moved.
device.theme = "light"
ui.reloadTheme()
paint()
statusbar.setFullscreen(true)
statusbar.setFullscreen(false)
assert(has(paint(), device.appName), "leaving fullscreen repaints the whole bar")
print("ok")