refactor(api)!: one namespace per feature, screen split out

Namespaces were shared across features: `settings` was written by core, the
panel and touch, and `input` by touch and buttons. That made "does this
firmware implement the whole feature?" a question no pointer could answer.

Each namespace now belongs to exactly one feature or to core, so a feature is
a provider pointer and the compiler validates completeness:

  gui, node       -> screen, tree, under the screen feature
  settings        -> screen (rotation, theme), sys (timezone),
                     touch (calibration)
  input           -> touch, buttons

Runtime::open() no longer requires a GuiProvider; a firmware without one runs
with no screen/tree globals and reports sys.hasFeature("screen") false.
Rotation is one value again: GuiProvider::setRotation applies and persists, so
an app rotating the panel transiently puts the old value back itself.
This commit is contained in:
2026-08-05 10:26:38 -04:00
parent 445a9b2b8f
commit 75b3a2c490
26 changed files with 556 additions and 626 deletions
+11 -11
View File
@@ -8,8 +8,8 @@ local ORDER = { "back", "left", "up", "down", "right", "confirm" }
local function available()
local roles = {}
if input and input.getButtons then
for _, role in ipairs(input.getButtons()) do
if buttons and buttons.getAll then
for _, role in ipairs(buttons.getAll()) do
roles[role] = true
end
end
@@ -21,11 +21,11 @@ end
---@param options table|nil `y`, `font`, `color`, and `background` overrides.
function hints.draw(actions, options)
options = options or {}
local font = options.font or gui.FONT_SMALL
local color = options.color or gui.color(0, 0, 0)
local background = options.background or gui.color(255, 255, 255)
local height = gui.getFontHeight(font) + 6
local y = options.y or (gui.getHeight() - height)
local font = options.font or screen.FONT_SMALL
local color = options.color or screen.color(0, 0, 0)
local background = options.background or screen.color(255, 255, 255)
local height = screen.getFontHeight(font) + 6
local y = options.y or (screen.getHeight() - height)
local roles = available()
local labels = {}
@@ -35,15 +35,15 @@ function hints.draw(actions, options)
end
end
gui.fillRect(0, y, gui.getWidth(), height, background)
screen.fillRect(0, y, screen.getWidth(), height, background)
if #labels == 0 then
return height
end
local slot = gui.getWidth() // #labels
local slot = screen.getWidth() // #labels
for index, label in ipairs(labels) do
local left = slot * (index - 1) + (slot - gui.getTextWidth(font, label)) // 2
gui.drawText(font, left, y + 3, label, color, gui.STYLE_NORMAL, background)
local left = slot * (index - 1) + (slot - screen.getTextWidth(font, label)) // 2
screen.drawText(font, left, y + 3, label, color, screen.STYLE_NORMAL, background)
end
return height
end