Skip to content

Commit f7b5460

Browse files
committed
docs: update README with thorough, structured capability overview and organized example paths
1 parent 538820b commit f7b5460

1 file changed

Lines changed: 79 additions & 212 deletions

File tree

README.md

Lines changed: 79 additions & 212 deletions
Original file line numberDiff line numberDiff line change
@@ -5,262 +5,129 @@
55
[![CI](https://github.com/leftger/embedded-gui/actions/workflows/ci.yml/badge.svg)](https://github.com/leftger/embedded-gui/actions/workflows/ci.yml)
66
[![License: MIT OR Apache-2.0](https://img.shields.io/badge/license-MIT%20OR%20Apache--2.0-blue.svg)](LICENSE-MIT)
77

8-
`embedded-gui` is a `no_std` GUI/HUD crate for `embedded-graphics` displays.
9-
It is built around fixed-capacity data structures, deterministic rendering, and
10-
embedded-friendly interaction patterns (pointer, encoder, and keyboard-style input).
11-
12-
Heavily inspired by the [Pebble](https://developer.rebble.io/developer.pebble.com/docs/index.html)
13-
smartwatch UI framework — its animation model, interaction contracts, and cinematic motion
14-
primitives draw directly from Pebble's design language. [LVGL](https://lvgl.io) is a
15-
secondary influence, particularly for widget composition and style-state conventions.
16-
17-
## Current State
18-
19-
`embedded-gui` currently provides a broad baseline of widgets, interaction semantics,
20-
fixed-capacity animation primitives, and screen transition tooling for embedded UIs.
21-
Recent work has focused on tightening interaction fidelity, expanding state transition
22-
coverage, and improving regression-focused examples/docs.
23-
24-
- Pointer release semantics now consistently target the originally pressed widget.
25-
- Focused open dropdowns now close on `Back` before global back handling.
26-
- State transitions now cover keyboard and pointer press feedback paths.
27-
- Enabled/disabled flag changes now participate in state transitions with regression coverage.
28-
- Style-class state overrides now participate correctly in transition endpoint blending.
29-
- Select activation now supports configurable double-select recognition (`DoubleClicked` events).
30-
- Per-widget raw key input policy now supports `SelectPressed/Released` and `BackPressed/Released`.
31-
- Pointer interaction now supports configurable double-click recognition (`DoubleClicked` events).
32-
- Per-widget key bindings can override `Select`/`Back` behavior (`Default`, `Ignore`, `Activate`, `Back`).
33-
- Textarea no-op edits avoid emitting mutation events, with regression coverage.
34-
- Wrapped-line selection navigation (`SelectHome`/`SelectEnd`) now has dedicated edge-case coverage.
35-
- Cross-widget interaction matrix coverage now includes dropdown/list/tabs/roller keyboard navigation paths.
36-
- Nested layout + clip behavior now has dedicated regression coverage for parent-relative composition.
37-
- A dedicated interaction semantics simulator example is available in `examples/interaction_semantics_showcase.rs`.
8+
`embedded-gui` is a lightweight, deterministic, zero-allocation (`no_std`) GUI & HUD framework for microcontrollers and [`embedded-graphics`](https://crates.io/crates/embedded-graphics) displays.
389

39-
## Quick Start
40-
41-
```rust
42-
use embedded_gui::prelude::*;
43-
44-
let mut gui = GuiContext::<8, 4, 8>::new(Rect::new(0, 0, 128, 64));
45-
gui.add_label(Rect::new(4, 4, 80, 8), "READY", Style::label())?;
46-
gui.add_progress_bar(Rect::new(4, 18, 80, 8), 0.6, Style::progress())?;
47-
gui.render(&mut display)?;
48-
```
49-
50-
## Implemented Feature Surface
51-
52-
### Widgets and primitives
53-
54-
The current widget set includes:
55-
56-
- labels, panels, buttons, icon buttons, borders/spacers
57-
- progress bars, sliders, toggles, checkboxes, value labels
58-
- lists, menus, tabs, dialogs, toasts, scroll views
59-
- dropdowns, rollers, tables
60-
- chart (line and bars), spinner, meter/gauge/arc gauge/needle
61-
- textareas and on-screen keyboards
62-
- image widgets (`ImageRef`, `ImageFit`, atlas/sprite helpers)
63-
64-
### Input and events
65-
66-
- `InputEvent` supports D-pad/encoder navigation, pointer events, and text-editing-oriented key events
67-
- UI-level events (`UiEvent`) and widget-level events (`WidgetEvent`) are both exposed
68-
- Event flow supports capture, target, and bubble phases with filterable dispatch policy hooks
69-
- Pointer semantics include long-press, gesture dispatch, drag scrolling, inertia, and press-repeat timing hooks
10+
Heavily inspired by the **Pebble** smartwatch UI framework—its animation model, interaction contracts, and cinematic motion primitives draw directly from Pebble's design language. **LVGL** serves as a secondary influence for widget composition, layout rules, and state-variant styling.
7011

71-
### Layout, styling, and text
12+
---
7213

73-
- `LinearLayout` and constraint-based item layout (`Length`, `Min/Max`, `Percent`, `Ratio`, `Fill`)
74-
- Style model with stateful variants (`normal`, `focused`, `pressed`, `disabled`)
75-
- Style interpolation and transition primitives (`StyleTransition`, `lerp_style`)
76-
- Text layout primitives (`Span`, `Line`, `Text`) with alignment, wrapping, spacing, overflow controls
77-
- Text shaping interface (`TextShaper`) with a basic shaping implementation for embedded-safe defaults
14+
## Key Capabilities
7815

79-
### Animation and transitions
16+
- 🧱 **Zero-Allocation (`no_std`)**: Built entirely on fixed-capacity data structures (`heapless`) with strict memory bounds and deterministic execution times.
17+
- 🧩 **Rich Built-in Widgets**: Buttons, Sliders, Dropdowns, Toggles, Checkboxes, Gauges, Meters, Sweeping Arcs, Plotters/Charts, TextAreas, On-Screen Keyboards, and Circular Lists.
18+
- 🛠️ **Native Custom Widgets**: Extensible third-party widget support via type-erased `WidgetStorage<'a>` and object-safe `Widget` trait contracts.
19+
- 🎬 **Unified Motion Engine**: Pebble-inspired spatial easing curves (`moook`), spring dynamics, timeline keyframing, property mutator bindings, and screen stack transitions (flip-card, peek/glance, shutter, portal).
20+
- 🎨 **Decoupled Rendering Engine**: Bounding-box dirty tracking, opacity layering, software IIR blur, subpixel anti-aliasing, and custom display backends.
21+
-**Async DMA & Double/Triple Buffering**: Zero-copy presentation via `CompletionSlot` and `StandardSwapChain`, fully compatible with Embassy `async/await` or bare-metal superloop polling.
22+
- 🎯 **Multi-Target Tested**: Continuously verified across ARM Cortex-M0/M0+ (`thumbv6m`), Cortex-M4F/M7F (`thumbv7em`), Cortex-M33/M55 (`thumbv8m.main`), and RISC-V (`riscv32imac`).
8023

81-
- Core animation manager and easing/tween/path/spring/inertia primitives
82-
- Spatial timing (`moook_curve`, `TransitionPreset`) — see `docs/transition-presets.md`
83-
- Widget property animation (`WidgetAnimator`) and preset helpers (`presets`)
84-
- Timeline/keyframe sequencing support (`AnimationSequence`, `SequencePlayer`)
85-
- Screen stack + transition primitives for app-level flows (fade, slide, wipe, shutter, port-hole, round-flip, modal)
24+
---
8625

87-
## Animation Quickstart
88-
89-
`embedded-gui` includes fixed-capacity animation primitives that stay `no_std` friendly.
26+
## Quick Start
9027

9128
```rust
29+
use embedded_graphics::pixelcolor::Rgb565;
9230
use embedded_gui::prelude::*;
9331

94-
let mut animator = WidgetAnimator::<8, 8>::new();
95-
let progress = gui.add_progress_bar(Rect::new(4, 18, 80, 8), 0.0, Style::progress())?;
96-
animator.animate_progress(progress, 0.0, 1.0, 600, Easing::InOutSine)?;
97-
98-
// In your frame loop:
99-
animator.tick(16, &mut gui)?;
100-
gui.render_dirty(&mut display)?;
101-
gui.clear_dirty();
102-
```
103-
104-
## Textarea Editing Input
105-
106-
Textarea widgets support editor-style navigation and mutation events, including:
32+
// 1. Create a fixed-capacity GUI context (Max Widgets, Focus Group Capacity, Dirty Rects)
33+
let mut gui = GuiContext::<16, 4, 8>::new(Rect::new(0, 0, 320, 240));
10734

108-
- `InputEvent::WordLeft` / `InputEvent::WordRight`
109-
- `InputEvent::Home` / `InputEvent::End`
110-
- `InputEvent::Select*` expansion variants
111-
- `InputEvent::Undo` / `InputEvent::Redo`
112-
- selection-replace behavior on typing/backspace/delete
35+
// 2. Spawn widgets using the fluent builder pattern
36+
let status_label = gui.spawn(
37+
WidgetBuilder::new(Rect::new(10, 10, 150, 20))
38+
.with_style_class("header")
39+
.build()
40+
)?;
11341

114-
See `docs/textarea-input-keybindings.md` for mappings and loop snippets.
115-
116-
## Font Glyph Overrides
117-
118-
The build pipeline supports external glyph overrides from:
119-
120-
- `assets/fonts/ascii_3x5.txt`
121-
- `assets/fonts/ascii_4x7.txt`
122-
123-
Format per line:
124-
125-
```text
126-
key:row0,row1,row2,row3,row4
127-
```
42+
// 3. Mutate properties dynamically using the generic property engine
43+
gui.set_widget_property(status_label, PropertyKey::Text, PropertyValue::Text("SYSTEM OK"))?;
12844

129-
- `key`: a single character or `space`
130-
- each row: 3 bits using `0`/`1` (left to right)
131-
- blank lines and `#` comments are ignored
132-
133-
Example:
134-
135-
```text
136-
?:111,001,010,000,010
137-
!:010,010,010,000,010
138-
space:000,000,000,000,000
139-
```
140-
141-
Unspecified glyphs fall back to built-in defaults in `build.rs`.
142-
143-
Preview helper:
144-
145-
```bash
146-
python3 scripts/preview_glyphs.py assets/fonts/ascii_3x5.txt "?!@"
45+
// 4. Render only dirty regions to your embedded-graphics DrawTarget
46+
gui.render(&mut display)?;
14747
```
14848

149-
## Examples
150-
151-
The `examples/` folder currently includes:
152-
153-
- `widgets_showcase.rs`
154-
- `dashboard_app.rs`
155-
- `simulator_menu.rs`
156-
- `event_dispatch_showcase.rs`
157-
- `interaction_semantics_showcase.rs`
158-
- `raw_key_input_showcase.rs`
159-
- `form_flow_showcase.rs`
160-
- `complex_layout_showcase.rs`
161-
- `input_gesture_drag_repeat_showcase.rs`
162-
- `long_press_input_showcase.rs`
163-
- `text_layout_showcase.rs`
164-
- `font_text_model_showcase.rs`
165-
- `animation_motion_showcase.rs`
166-
- `animation_kitchen_sink_showcase.rs`
167-
- `animation_dirty_showcase.rs`
168-
- `timeline_transition_showcase.rs`
169-
- `visual_quality_showcase.rs`
170-
- `embedded_3dgfx_overlay.rs`
171-
172-
## Behavior Notes
173-
174-
- Input and widget interaction guarantees are documented in `docs/interaction-behavior-contract.md`.
49+
---
17550

17651
## Visual Showcase
17752

178-
Animation and transition capabilities (generated from simulator output):
179-
53+
### Pebble-style Cinematic Motion & Transitions
18054
![Animation and transition showcase](docs/screenshots/motion.gif)
18155

182-
Flip-card screen transition (`RoundFlipLeft`) — card selection between views:
183-
56+
### Flip-card Screen Stack Transitions
18457
![Flipcard selection transition](docs/screenshots/flipcard.gif)
18558

186-
Cinematic peek/glance/carddeck — launcher-style glance tiles cycling with slide-prominence animation, peek reveal, and card story transitions:
187-
59+
### Launcher Glance Tiles & Card Story Deck
18860
![Cinematic peek glance carddeck showcase](docs/screenshots/cinematic.gif)
18961

190-
Dashboard-style UI composition:
191-
62+
### Dashboard UI Composition
19263
![Dashboard UI screenshot](docs/screenshots/dashboard.png)
19364

194-
Typography and mixed-font text model:
195-
65+
### Mixed Typography & Font Models
19666
![Mixed font showcase screenshot](docs/screenshots/fonts.png)
19767

198-
Static motion frame preview:
199-
200-
![Motion frame screenshot](docs/screenshots/motion.png)
68+
---
20169

202-
## Async present and DMA double-buffering
70+
## Feature Architecture
20371

204-
Both `embedded-gui` and `embedded-3dgfx` share a runtime-agnostic present stack:
72+
### 1. Widgets & Layouts
73+
- **Controls**: Buttons, Icon Buttons, Sliders, Toggles, Checkboxes, Dropdowns, Rollers.
74+
- **Data & Display**: Progress Bars, Gauges, Meters, Sweeping Arcs, Plotters/Line Charts, Bar Charts, Busy Wheels.
75+
- **Structure & Layout**: Linear Layouts (Row/Column with spacing & constraints), Panels, Tabs, Cards, Dialogs, Circular Lists.
76+
- **Input & Text**: TextAreas (word wrap, selection, undo/redo), On-Screen Keyboards.
20577

206-
- **Sync (fastest poll path):** `swap.try_present()` / `gui.try_present_dirty()` — ideal for RTIC tasks and bare-metal superloops.
207-
- **Blocking:** `swap.present()` — simple bring-up.
208-
- **Async:** `swap.present_async().await` — yields while DMA runs; works with Embassy or any `core::future` executor.
78+
### 2. Motion Framework (`src/motion/`)
79+
- **Easing & Physics**: Standard Easings (Linear, Quad, Cubic, Sine, Exponential) + Pebble Spatial Easing (`moook_curve`), Spring Physics, Inertia.
80+
- **Timelines & Keyframes**: Multi-track property keyframing and sequence controllers.
81+
- **Screen Stack Transitions**: Slide, Fade, Portal, Shutter, Modal Overlay, Round-Flip Card.
20982

210-
Core types (always available, no Embassy dependency):
83+
### 3. Render Engine (`src/render/`)
84+
- **Dirty Region Tracking**: Merges overlapping invalidate rectangles to minimize SPI/I2C/Parallel bus transfers.
85+
- **Compositing**: Software alpha blending, opacity stacks, subpixel anti-aliasing, and IIR blur filters (RGB565, RGBA8888, GRAY8).
21186

212-
- [`CompletionSlot`](https://docs.rs/embedded-gui/latest/embedded_gui/struct.CompletionSlot.html) — ISR-safe DMA done flag + waker.
213-
- [`WaitTransfer`](https://docs.rs/embedded-gui/latest/embedded_gui/struct.WaitTransfer.html) — reference `AsyncDmaTransfer` token wired to a `CompletionSlot`.
87+
### 4. Input & Semantics (`src/input/`)
88+
- Multi-device event mapping: Rotary Encoders (CW/CCW/Press), D-Pad/Keyboards (Arrow keys, Select, Back), Touch/Pointer (Tap, Long Press, Drag, Flick).
89+
- Configurable per-widget focus navigation, raw key policies, and event routing phases (Capture, Target, Bubble).
21490

215-
Optional Cargo features:
91+
---
21692

217-
| Feature | Purpose |
218-
|---------|---------|
219-
| `embedded-graphics` | Enables transparent `embedded-graphics` `MonoFont` support (`&FONT_6X10`, `&FONT_9X15`, etc.) across `FontId`, `TextStyle`, `Style`, and `RenderCtx`. |
220-
| `embedded-text` | Enables `embedded-text` `TextBox` interop adapter |
221-
| `embedded-layout` | Enables `embedded-layout` `View` alignment adapter |
222-
| `embassy-time` | Monotonic `dt_ms` via `embassy_time::Instant` |
223-
| `embassy` | [`EmbassyWaitTransfer`](https://docs.rs/embedded-gui/latest/embedded_gui/struct.EmbassyWaitTransfer.html) + [`FrameClock`](https://docs.rs/embedded-gui/latest/embedded_gui/struct.FrameClock.html) |
224-
| `triple-buffering` | Triple-buffer swap chain for bursty frame times |
93+
## Examples Directory
22594

226-
### `embedded-graphics` MonoFont Quickstart
95+
The repository includes showcase examples categorized under `examples/`:
22796

228-
To use any `embedded-graphics` `MonoFont` (such as `ascii::FONT_6X10`, `FONT_7X13`, `FONT_9X15`, `FONT_10X20`, `profont`, etc.) transparently in `embedded-gui`, enable the `embedded-graphics` feature in your `Cargo.toml`:
97+
| Directory | Purpose & Highlights |
98+
|-----------|----------------------|
99+
| **`examples/basics/`** | Core layout rules, dashboard layout, form flows, interaction semantics, raw key input, and keyboard navigation (`dashboard_app.rs`, `complex_layout_showcase.rs`, `form_flow_showcase.rs`). |
100+
| **`examples/widgets/`** | Comprehensive widget showcases, gauges, sweeping arcs, alpha blending, and visual quality benchmarks (`widgets_showcase.rs`, `visual_quality_showcase.rs`, `sweeping_arc_widget_showcase.rs`). |
101+
| **`examples/motion/`** | Motion framework, Pebble-style spring physics, dirty-region animation, timeline keyframing, and cinematic peek/glance cards (`animation_motion_showcase.rs`, `cinematic_peek_glance_carddeck_showcase.rs`). |
102+
| **`examples/integrations/`** | Third-party interop, Embassy async frames, DMA swapchain simulation, and 3D graphics overlays (`embassy_gui_frame.rs`, `completion_swapchain_sim.rs`, `embedded_3dgfx_overlay.rs`). |
229103

230-
```toml
231-
[dependencies]
232-
embedded-gui = { version = "0.1.5", features = ["embedded-graphics"] }
233-
embedded-graphics = "0.8"
104+
Run any example using Cargo:
105+
```bash
106+
cargo run --example dashboard_app --features std
107+
cargo run --example animation_motion_showcase --features std
234108
```
235109

236-
Then pass `&MonoFont` references directly into `TextStyle`, `Style`, or `RenderCtx`:
237-
238-
```rust
239-
use embedded_graphics::mono_font::ascii::{FONT_6X10, FONT_9X15};
240-
use embedded_gui::prelude::*;
241-
242-
// 1. Direct style construction:
243-
let title_style = TextStyle::new(Rgb565::CYAN).with_font(&FONT_9X15);
244-
let body_style = Style::new().with_font(&FONT_6X10);
245-
246-
// 2. RenderCtx calls:
247-
ctx.draw_text_in_with_font(rect, "DOOM HUD", title_style, &FONT_6X10)?;
248-
```
110+
---
249111

250-
Examples:
112+
## Cargo Features
251113

252-
```bash
253-
cargo run --example completion_swapchain_sim --features std
254-
cargo run --example embassy_gui_frame --features embassy,std
255-
```
114+
| Feature | Description |
115+
|---------|-------------|
116+
| `embedded-graphics` | *(Default)* Transparent support for `embedded-graphics` `MonoFont` references (`&FONT_6X10`, `&FONT_9X15`) in styles and text rendering. |
117+
| `libm` | Provides floating-point math support (`f32::sin`, `cos`, `round`, `sqrt`) when building for `no_std` targets without standard library floats. |
118+
| `rich-widgets` | Enables advanced visual widgets including Gauges, Plotters, TextAreas, and On-Screen Keyboards. |
119+
| `embedded-text` | Enables interoperability adapters for `embedded-text` `TextBox`. |
120+
| `embedded-layout` | Enables interoperability adapters for `embedded-layout` `View` alignment. |
121+
| `embassy` | Adds `EmbassyWaitTransfer` and `FrameClock` for Embassy async executor integration. |
122+
| `triple-buffering` | Enables triple-buffer swapchain for bursty display frame rates. |
256123

257-
**Performance note:** triangle and widget rasterization stay synchronous. Async is for **present/wait** only — overlapping CPU render with DMA scan-out. Making inner pixel loops async would add executor overhead without speeding up single-core MCUs.
124+
---
258125

259126
## License
260127

261-
The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_
262-
License. That means you can choose either the MIT license or the Apache 2.0
263-
license when you re-use this code. See [`LICENSE-MIT`](./LICENSE-MIT) or
264-
[`LICENSE-APACHE`](./LICENSE-APACHE) for more information on each specific
265-
license. Our Apache 2.0 notices can be found in [`NOTICE`](./NOTICE).
128+
Dual-licensed under either of:
129+
130+
- **MIT License** ([`LICENSE-MIT`](./LICENSE-MIT))
131+
- **Apache License, Version 2.0** ([`LICENSE-APACHE`](./LICENSE-APACHE))
266132

133+
at your option.

0 commit comments

Comments
 (0)