feat(ui): setText on text nodes

Assigning .label repainted nothing until the caller also remembered to invalidate, and
forgetting produced a screen that silently stopped updating with no error to follow.
setText makes the pair atomic and skips the repaint when the text is unchanged, so an
app can push a value on every tick without comparing first.
This commit is contained in:
2026-08-01 18:09:08 -04:00
parent f36292734a
commit 5a3aabf220
3 changed files with 19 additions and 5 deletions
+1 -5
View File
@@ -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
+7
View File
@@ -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
+11
View File
@@ -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