diff --git a/sdcard/apps/launcher/main.lua b/sdcard/apps/launcher/main.lua index dbc9832..b9c4078 100644 --- a/sdcard/apps/launcher/main.lua +++ b/sdcard/apps/launcher/main.lua @@ -40,11 +40,7 @@ function init() end function on_tick() - local label = sys.clockSynced() and os.date("%H:%M:%S") or PLACEHOLDER - if label ~= clock.label then - clock.label = label - clock:invalidate() - end + clock:setText(sys.clockSynced() and os.date("%H:%M:%S") or PLACEHOLDER) end function draw() screen:draw() end diff --git a/sdcard/lib/ui.lua b/sdcard/lib/ui.lua index 851af23..dadb57a 100644 --- a/sdcard/lib/ui.lua +++ b/sdcard/lib/ui.lua @@ -260,6 +260,13 @@ function ui.text(label, spec) node.paint = function(self) gui.drawText(self.label, self.rect.x, self.rect.y, self.color, self.bg) end + -- Setting .label alone repaints nothing, which fails silently. Unchanged text also + -- costs nothing, so a caller can push a value every tick without thinking about it. + node.setText = function(self, text) + if text == self.label then return end + self.label = text + self:invalidate() + end return node end diff --git a/test/ui_layout.lua b/test/ui_layout.lua index a4b0142..7574e21 100644 --- a/test/ui_layout.lua +++ b/test/ui_layout.lua @@ -87,6 +87,17 @@ app:down(100, 20) app:up(100, 20) assert(fired == 1, "release inside must fire once") +-- setText repaints only on a real change, so a caller may push a value every tick. +local label = ui.text("12:00:00") +local clockScreen = ui.screen(ui.box{label}) +clockScreen:draw() +assert(not label.dirty, "a drawn node starts clean") +label:setText("12:00:00") +assert(not label.dirty, "unchanged text must not repaint") +label:setText("12:00:01") +assert(label.dirty, "changed text must repaint") +assert(label.label == "12:00:01", label.label) + -- The pressed look is held briefly, then cleared on a later draw. assert(button.pressed, "pressed look must outlast the release") device.now = device.now + 100