Round dashboards: one face at a time, a face per widget type, paged by swipe, dots and keys; slider reading; face row in the editor

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Melvin Strobl
2026-10-14 15:24:25 +02:00
co-authored by Claude Opus 5.5
parent 8b8cb5cda9
commit 84071ee106
20 changed files with 1238 additions and 604 deletions
+70 -29
View File
@@ -171,48 +171,89 @@ restrict API permissions and does not disable controls in edit mode.
## Round dashboards
For a round screen such as a rotary knob, set the canvas to **Round** in the
dashboard settings, or pick the **Knob** preset (360×360). A round dashboard is
drawn in the circle its canvas holds, so its canvas is square (`shape: "round"`
forces `canvas_height` to `canvas_width`). Tiles are drawn without a card, and
there is no rail; a panel with several dashboards shows page dots instead.
dashboard settings, or pick the **Knob** preset (360×360). A round canvas is
square (`shape: "round"` forces `canvas_height` to `canvas_width`), and nothing
outside its circle is drawn.
One Slider, Selector, Colour or Gauge can go **On the ring** (`ring: <widget
id>`): it is drawn along the edge instead of in the grid. Drag along the ring or
use the mouse wheel; one notch is one step, one option or one hue step
(`hue_step`, default 5°, wrapping). The value moves at once and is published
once, 300 ms after the last notch or when the pointer is released. A gauge on
the ring only shows. When the ring is the only widget, its reading is written
large in the middle.
A round dashboard has no grid. It shows one widget at a time, each drawn as the
whole face, in the order of `widgets`; `layout` is not read. In the editor, the
faces are a row above the dock: press one to show it and open its settings,
drag it along the row (or Alt+←/→) to move it, and add more with **Add widget**.
The editor shades what lies outside the circle and warns about tiles whose
corners leave it. Inputs, button grids, charts, forecasts, agendas, websites
and a segmented Selector are marked as a poor fit, but allowed.
A Slider, Selector, Colour or Gauge draws on the **ring** along the edge, which
a knob's own ring turns. In a browser, drag along the ring or use the mouse
wheel (or the arrow keys once it has focus): one notch is one step, one option
(no wrap) or one hue step (`hue_step`, default 5°, wrapping). The value moves
at once and is published once, 300 ms after the last notch or when the pointer
is released. A Gauge only shows. On any other face, turning a knob only wakes
the screen.
A Slider can also show what it sets against, such as the room's temperature
beside a setpoint: **Beside it** binds `reading: {message, dtype, label}` to a
`float` or `int`. That reading is written large in the middle, in the slider's
unit and to its step's decimals, under its label; the slider's own title and
value move to the line in the ring's gap.
Value, Switch, Button, Clock, Icon, Notification and Text have faces of their
own. Every other type is drawn as its rectangular body in the middle of the
face, and the editor marks it **Poor fit for round**.
### Moving between faces
| Gesture | Effect |
|---|---|
| Swipe left / right | next / previous face of this dashboard; stops at either end |
| Swipe up / down | next / previous dashboard of the panel (`/panel/{id}` only); stops at either end |
| Page dot | that face |
| PageDown / PageUp | next / previous face |
| Shift+PageDown / Shift+PageUp | next / previous dashboard of the panel |
| Arrow keys | turn the ring, not the page |
A swipe is a drag of at least 40 canvas pixels, decided by its longer axis; a
drag that starts on the ring turns the ring instead. A dashboard reopens on the
face it was last left on in this session, otherwise on its first. Landing on
another dashboard shows its title and icon in the middle of the face for one
second; a round panel has no rail.
### Geometry
Devices that draw dashboards natively use these numbers. They are canvas
pixels, scaled with the canvas; S is the canvas width. Angles are degrees
clockwise from three o'clock.
pixels, scaled with the canvas; S is the canvas width and c = S/2. Angles are
degrees clockwise from three o'clock. Text sizes are font sizes; muted is the
look's muted text colour.
| Part | Value |
|---|---|
| Face | circle of diameter S at (S/2, S/2); nothing is drawn outside it |
| Ring band | 40 along the edge, only when a ring is set |
| Grid area | the square inset by 12, plus 40 with a ring; columns, rows and cell proportions as on a rectangular canvas. Knob, 4 columns, ring: 256×256, columns 55, rows 30 at a 42 pitch, 6 rows |
| Safe circle | radius S/2 − 40 with a ring, S/2 without; a tile corner outside it is warned about |
| Ring arc | start 120°, sweep 300° (ends at 60°), centre-line radius S/2 − 20, stroke 16 with round caps |
| Slider | track over the sweep, value arc from the start to the value (none at the minimum), handle 28 across |
| Selector | a 6 mark per option at i/(n−1) of the sweep (one option: the middle), the selected one under the handle; no wrap |
| Colour | hue h at h/360 of the sweep, red at both ends; the handle is filled with the colour |
| Gauge | track and value arc, no handle |
| Gap line | centred at y = S − 28, 13 high, at most 160 wide: the title (muted), then the reading unless it is in the middle; a colour has none |
| Page dots | 6 dots 16 apart, centred at y = S − 12; the current one in the text colour, the others muted at half opacity |
| Centre reading | value 72 with its unit at 0.4 em, muted; a Selector's label 36; a colour swatch 96 across with a hairline border |
| Tiles | no surface, border or shadow; padding 8; title 12, muted and centred; a single reading centred |
| Face | circle of diameter S at (c, c) |
| Title | one line centred at y = c − 80, 15, muted, at most 200 wide; the widget's title, or the label of a slider's reading |
| Middle | a 240 × 128 box centred at (c, c); what a face draws in its middle is centred in it and clipped to it |
| Centre reading | centred at (c, c), line height 1, its unit after it at 0.4 em, muted. Size: 72, or 240 ÷ (0.6 × the characters written) rounded down where that is smaller, never below 24 |
| Ring band | 40 along the edge |
| Ring arc | start 120°, sweep 300° (ends at 60°), centre-line radius c − 20, stroke 16 with round caps |
| Slider | track over the sweep, value arc from the start to the value (none at the minimum), handle 28 across; the value as the centre reading |
| Slider with a reading | the reading as the centre reading; the gap line holds the title (muted) and the slider's value |
| Selector | a 6 mark per option at i/(n−1) of the sweep (one option: the middle), the selected one under the handle; its label as the centre reading, at most 36 |
| Colour | hue h at h/360 of the sweep in 150 strokes of 2°, red at both ends; the handle filled with the colour; a swatch 96 across in the middle, with a hairline border |
| Gauge | track and value arc, no handle; the value as the centre reading |
| Gap line | centred at y = S − 28, 13, at most 160 wide |
| Value | the reading as the centre reading, to its precision; a word shrinks like any other |
| Switch | a disc 128 across centred at (c, c): the look's button, filled when on and tonal when off, with a power glyph 40 over the word On or Off at 15; a press toggles |
| Button | a disc 128 across centred at (c, c), tonal, its label at 15 over at most three lines; a press sends its value |
| Clock | the time (hours and minutes, the device's locale) sized as a centre reading, over the date (weekday, day, month) at 15, muted, 4 apart; the pair centred at (c, c) |
| Icon | the glyph 96 across over its label at 15, muted, 4 apart; the pair centred at (c, c). Nothing matched: a dash at 72, muted |
| Notification | the title at 15, medium (an error in the destructive colour, led by ⚠), over the body at 15, muted; centred lines in the middle |
| Text | centred lines at 15: `#` at 1.35 em and `##` medium, `###` muted, list items led by a bullet; in the middle |
| Not wired | the problem, at 15, muted, in the middle; a ring type draws no ring |
| Any other type | its rectangular body, without a card, from y = c − 64 to c + S/(2√2), x = c ± S/(2√2) (Knob: 53–307 × 116–307) |
| Page dots | one per face, from two faces: dots 6 across on targets 16 apart (closer when more than 128 wide would be needed), centred at y = S − 12; the current one in the text colour, the others muted at half opacity |
| Dashboard name | a pill centred at (c, c), 36 high: the icon 16 and the title at 15, medium, at most 220 wide, on the frosted surface; for 1000 ms |
| Paging | a new face slides in 48 from the side it was paged towards and fades in; the old one leaves the other way |
| Locked | controls do nothing and read as disabled; the ring at 0.45 opacity |
Paint follows the look: Fluksio draws a muted track, a primary value and a
handle of the ground colour ringed in primary; Material a tonal track and a
primary handle; Glass a translucent track, a glowing value and a white handle.
A Switch or Button face wears the look's own button.
## Showing one