-- Run: lua test/ui_theme.lua -- Asserts the palette ui.lua derives from a theme's three seed colors. The fake packs -- channels into one integer, so contrast between roles stays checkable. package.path = "sdcard/lib/?.lua;test/?.lua;" .. package.path local device = require("fake_device").install() local ui = require("ui") local BLACK, WHITE = gui.color(0, 0, 0), gui.color(255, 255, 255) local function reload(name) device.theme = name return ui.reloadTheme() end -- Seeds pass through untouched. local light = reload("light") assert(light.bg == WHITE, "light bg") assert(light.fg == BLACK, "light fg") assert(light.accent == gui.color(0, 120, 255), "light accent") -- Muted sits between the text and the surface, so it reads as secondary on both. assert(light.muted > BLACK and light.muted < WHITE, "muted between fg and bg") -- Contrast is derived, never configured: text on a dark accent must be light. assert(light.accent_fg == WHITE, "white text on the blue accent") assert(reload("mono").accent_fg == WHITE, "white text on the black accent") -- A pale accent has to flip the label to black; no theme file can get this wrong. local pale = ui.themeNames() -- force the module to be loaded before patching it assert(#pale >= 3, "expected the canned themes") package.loaded["theme"].pale = {bg = {255, 255, 255}, fg = {0, 0, 0}, accent = {255, 235, 120}} assert(reload("pale").accent_fg == BLACK, "black text on a pale accent") -- Dark inverts the surface without any per-component configuration. local dark = reload("dark") assert(dark.bg < dark.fg, "dark theme keeps light text on a dark surface") assert(#dark.face == 2 and #dark.face_pressed == 2, "button gradients are pairs") -- Pinned roles win over derived ones, which is the deviation hatch. assert(reload("mono").radius == 0, "mono pins radius") assert(light.radius == 6, "light keeps the derived radius") -- An unknown name must not leave an app without colors. local missing = reload("does-not-exist") assert(missing.bg == WHITE and missing.fg == BLACK, "unknown theme falls back to light") -- Dimming re-derives every role rather than blending pixels, because the panel has no -- alpha to composite a scrim with. reload("light") assert(ui.theme.dim.bg ~= ui.theme.bg, "the dim palette matches the lit one") assert(ui.theme.dim.muted ~= ui.theme.muted, "dimming did not reach derived roles") -- Which node ends up wearing which role is inheritance, and inheritance is the firmware's -- half: test/ui_layout_test.cpp asserts it against the same code the panel runs. print("ok")