new rendering engine
This commit is contained in:
22
CONTEXT.md
22
CONTEXT.md
@@ -18,7 +18,7 @@ Value objects have no identity. They are defined entirely by their content and a
|
||||
|
||||
- **Layout** — the single active layout tree. A recursive structure of LayoutNodes. Always singular — clients display exactly one layout at a time. Replaced wholesale when user reconfigures via the web UI.
|
||||
|
||||
- **LayoutNode** — a node in the layout tree. Either a Container (row or column with ordered children) or a Leaf (references a Widget by ID). Each child in a Container has a sizing mode: Fixed(pixels) or Flex(weight). Layout engine sums fixed sizes, distributes remaining space among flex children by integer weight ratio. All integer math, no floats. Containers have an optional `gap: u8` (uniform spacing between children in pixels) and an optional `padding: u8` (uniform inset on all sides, typically used on root container to keep content off screen edges).
|
||||
- **LayoutNode** — a node in the layout tree. Either a Container (row or column with ordered children) or a Leaf (references a Widget by ID). Each child in a Container has a sizing mode: Fixed(pixels) or Flex(weight). Layout engine sums fixed sizes, distributes remaining space among flex children by integer weight ratio. All integer math, no floats. Containers have an optional `gap: u8` (uniform spacing between children in pixels), an optional `padding: u8` (uniform inset on all sides), a `JustifyContent` (main axis distribution: Start, Center, End, SpaceBetween, SpaceEvenly), and an `AlignItems` (cross axis alignment: Start, Center, End, Stretch). Both default to Start.
|
||||
|
||||
- **KeyMapping** — a rule inside WidgetConfig that extracts a value from a DataSource's raw response using a JSON path expression and maps it to a named key in the WidgetState. E.g. `"$.main.temp" → "value"`. Decouples widget data shape from API response shape. Keeps adapters dumb — they return raw responses, WidgetConfig defines extraction.
|
||||
|
||||
@@ -42,13 +42,27 @@ The client has its own thin domain — hexagonal, chip-agnostic, display-agnosti
|
||||
|
||||
- **BoundingBox** — a rectangular region on screen (x, y, width, height) computed by the layout engine for each node.
|
||||
|
||||
- **WidgetView** — the rendered projection of a WidgetState. Contains resolved display data (text strings, icon references) within a BoundingBox. The client domain decides overflow behavior, truncation, and marquee.
|
||||
- **WidgetView** — the rendered projection of a WidgetState. Contains resolved display data (text spans with colors), scroll state, and computed positions within a BoundingBox. The client domain formats raw WidgetState data according to DisplayHint rules (e.g. KeyValue renders keys in secondary color), applies text alignment (HAlign, VAlign), detects overflow, and manages bounce-scroll animation. Scroll triggers only on overflow — static text stays static. Bounce speed auto-derives from overflow amount for consistent reading pace.
|
||||
|
||||
- **Layout Engine** — pure domain logic. Given a LayoutNode tree and screen dimensions, computes BoundingBoxes for all nodes. Containers split space among children (row = horizontal, column = vertical). Leaves get their final bounds.
|
||||
- **Layout Engine** — pure domain logic. Given a LayoutNode tree and screen dimensions, computes BoundingBoxes for all nodes. Containers split space among children (row = horizontal, column = vertical), applying JustifyContent and AlignItems for positioning. Leaves get their final bounds.
|
||||
|
||||
- **Render Engine** — pure domain logic. Given a WidgetView and FontMetrics, parses inline color markup, performs word-based line wrapping (character fallback for long words), computes alignment offsets, applies scroll position, and emits positioned text spans for the DisplayPort to draw. Owns all text intelligence — the DisplayPort is a thin pixel-pusher.
|
||||
|
||||
- **FontMetrics** — character dimensions for each font size (Small, Large), injected into the domain at init by the adapter. Enables pure-math text measurement (monospace: width = char_count × char_width) without hardware coupling.
|
||||
|
||||
- **Color** — domain-owned RGB color value (u8, u8, u8). Used on all domain and port boundaries. Adapters convert to native format (e.g. Rgb565 on ESP32) at the last mile.
|
||||
|
||||
- **ThemeConfig** — a set of five named Colors that define the visual appearance of the client: `primary`, `secondary`, `accent`, `text` (default for all unmarked content), and `background` (used for all fills/clears). Pushed from server to client independently of layout via a ThemeUpdate message. Client stores current theme and falls back to sensible defaults if no theme has been received. Configured from the web UI.
|
||||
|
||||
- **DisplayPort** — the client's rendering abstraction. A thin pixel-pusher with three methods: `draw_text_span(text, x, y, color, font_size)`, `fill_rect(bounds, color)`, `flush()`. All text intelligence (wrapping, alignment, scrolling, markup parsing) lives in the domain's render engine, not in the port. Adapters convert domain Color to native format and delegate to hardware.
|
||||
|
||||
- **FontSize** — enum selecting which bitmap font to use: Small (body text) or Large (icons). Passed with each draw_text_span call. The domain picks the font; the adapter maps it to a concrete bitmap font.
|
||||
|
||||
## Shared Concepts
|
||||
|
||||
- **DisplayHint** — a domain enum on WidgetConfig indicating how the client should render the widget. Closed set: IconValue, TextBlock, KeyValue, etc. Client handles each variant explicitly, with a fallback to plain text for unknown/unsupported hints. Gives type safety and validation on both sides while remaining forward-compatible. Lives in the protocol crate.
|
||||
- **DisplayHint** — a domain enum on WidgetConfig indicating how the client should render the widget. Closed set: IconValue, TextBlock, KeyValue, etc. Each variant is a rendering recipe — the client-domain's render engine formats raw WidgetState data into styled text spans according to the variant's rules (e.g. KeyValue renders keys in secondary color, values in text color). Carries content-level alignment: HAlign (Left, Center, Right) and VAlign (Top, Middle, Bottom). Client handles each variant explicitly with exhaustive match; fallback to plain text for unknown hints. Lives in the protocol crate.
|
||||
|
||||
- **Inline Color Markup** — lightweight syntax embedded in Value strings for coloring text spans. Syntax: `{#RRGGBB}text{/}` for hex colors, `{primary}text{/}`, `{secondary}text{/}`, `{accent}text{/}` for theme colors. `{/}` resets to the theme's `text` color. Parsed by the client-domain render engine. No bold/italic — hardware constraint on current bitmap fonts.
|
||||
|
||||
- **Value** — domain-owned value type representing structured data. An enum: String, Number, Bool, Array, Object, Null. Adapters convert their native formats (JSON, XML, etc.) into Value. KeyMapping and WidgetState operate on Value exclusively. Zero coupling to serialization libraries. Lives in the protocol crate.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user