embedded-gui is a lightweight, deterministic, zero-allocation (no_std) GUI & HUD framework for microcontrollers and embedded-graphics displays.
Heavily inspired by modern wearable and smartwatch UI frameworks—its animation model, interaction contracts, and cinematic motion primitives draw from fluid, tactile embedded design patterns for widget composition, layout rules, and state-variant styling.
- Zero-Allocation (
no_std): Built entirely on fixed-capacity data structures (heapless) with strict memory bounds and deterministic execution times. - Declarative KDL GUI Markup & Codegen: Author complex UI screens in clean KDL markup and compile directly into zero-allocation
#![no_std]Rust code at build time withinclude_gui!orgui_kdl!. - 2D Grid Layout Engine: CSS-style track resolution (
"140px 1fr 2fr auto"), cell placement, and multi-track spans (col_span,row_span). - Rich Built-in Widgets: Buttons, Sliders, Dropdowns, Toggles, Checkboxes, Gauges, Meters, Sweeping Arcs, Plotters/Charts, TextAreas, On-Screen Keyboards, and Circular Lists.
- Native Custom Widgets: Extensible third-party widget support via type-erased
WidgetStorage<'a>and object-safeWidgettrait contracts. - Unified Motion Engine: Tactile spatial easing curves (
moook), spring dynamics, timeline keyframing, property mutator bindings, and screen stack transitions (flip-card, peek/glance, shutter, portal). - Decoupled Rendering Engine: Bounding-box dirty tracking, opacity layering, software IIR blur, subpixel anti-aliasing, and custom display backends.
- Async DMA & Double/Triple Buffering: Zero-copy presentation via
CompletionSlotandStandardSwapChain, fully compatible with Embassyasync/awaitor bare-metal superloop polling. - Multi-Target Tested: Continuously verified across ARM Cortex-M0/M0+ (
thumbv6m), Cortex-M4F/M7F (thumbv7em), Cortex-M33/M55 (thumbv8m.main), and RISC-V (riscv32imac).
Author your UI screen in declarative KDL (ui/dashboard.kdl):
screen id="Dashboard" width=320 height=240 theme="dark" {
grid cols="140px 1fr" rows="24px 1fr 48px" gap=6 padding=8 {
banner col=0 row=0 col_span=2 text="Living Room Climate"
spinbox id="TempSetpoint" col=0 row=1 min=100 max=350 value=225 digits=4 decimals=1
scale id="RoomGauge" col=1 row=1 mode="radial" min=10.0 max=40.0 value=22.5
button id="FanBtn" col=0 row=2 text="FAN HIGH"
toggle id="EcoMode" col=1 row=2 checked=true
}
}
Zero-Allocation Result: 2D Grid Layout, decimal spinbox, tachometer scale, button, and toggle compiled directly into pure
no_std Rust.
Include and compile directly into zero-allocation #![no_std] Rust code:
use embedded_gui::prelude::*;
// Embeds and compiles the KDL file at build time into DashboardApp and DashboardWidgets
include_gui!("ui/dashboard.kdl");
fn main() {
let mut gui = GuiContext::<64, 32, 16>::new(Rect::new(0, 0, 320, 240));
let app = DashboardApp::build(&mut gui).expect("failed to build UI");
// Strongly-typed widget IDs generated automatically:
// app.widgets.room_gauge
// app.widgets.temp_setpoint
// app.widgets.fan_btn
// app.widgets.eco_mode
}For complete syntax, full widget catalog, and styling options, see the Declarative KDL GUI Codegen Guide.
use embedded_graphics::pixelcolor::Rgb565;
use embedded_gui::prelude::*;
// 1. Create a fixed-capacity GUI context (Max Widgets, Focus Group Capacity, Dirty Rects)
let mut gui = GuiContext::<16, 4, 8>::new(Rect::new(0, 0, 320, 240));
// 2. Spawn widgets using the fluent builder pattern
let status_label = gui.spawn(
WidgetBuilder::new(Rect::new(10, 10, 150, 20))
.with_style_class("header")
.build()
)?;
// 3. Mutate properties dynamically using the generic property engine
gui.set_widget_property(status_label, PropertyKey::Text, PropertyValue::Text("SYSTEM OK"))?;
// 4. Render only dirty regions to your embedded-graphics DrawTarget
gui.render(&mut display)?;Zero-allocation 2D GridLayout (fractional fr & fixed px tracks), radial tachometer & linear graduated scales, interactive table grid with cell navigation, precision decimal spinbox, and stroked Bézier vector paths.
- Controls: Buttons, Icon Buttons, Sliders, Toggles, Checkboxes, Dropdowns, Rollers.
- Data & Display: Progress Bars, Gauges, Meters, Sweeping Arcs, Plotters/Line Charts, Bar Charts, Busy Wheels.
- Structure & Layout: Linear Layouts (Row/Column with spacing & constraints), Panels, Tabs, Cards, Dialogs, Circular Lists.
- Input & Text: TextAreas (word wrap, selection, undo/redo), On-Screen Keyboards.
- Easing & Physics: Standard Easings (Linear, Quad, Cubic, Sine, Exponential) + Spatial Easing (
moook_curve), Spring Physics, Inertia. - Timelines & Keyframes: Multi-track property keyframing and sequence controllers.
- Screen Stack Transitions: Slide, Fade, Portal, Shutter, Modal Overlay, Round-Flip Card.
- Dirty Region Tracking: Merges overlapping invalidate rectangles to minimize SPI/I2C/Parallel bus transfers.
- Compositing: Software alpha blending, opacity stacks, subpixel anti-aliasing, and IIR blur filters (RGB565, RGBA8888, GRAY8).
- Multi-device event mapping: Rotary Encoders (CW/CCW/Press), D-Pad/Keyboards (Arrow keys, Select, Back), Touch/Pointer (Tap, Long Press, Drag, Flick).
- Configurable per-widget focus navigation, raw key policies, and event routing phases (Capture, Target, Bubble).
Detailed architecture specifications and integration guides are available in docs/:
- 📐 Declarative KDL GUI Markup & Codegen Guide: Complete reference manual for KDL screen syntax, 2D grid layouts, full widget catalog, vector Bézier paths, and zero-allocation Rust codegen.
- 🔤 Custom Font Abstraction & Interop Guide: Drop-in custom bitmap fonts (
BitmapFont),Fonttrait abstraction, andembedded-graphicsMonoFontinterop. - 🎬 Animation Presets Guide: Easing curves, spring physics, and timeline keyframing specifications.
- 🔀 Transition Presets Guide: Screen stack slide, fade, portal, and flip-card transition rules.
- 🎹 TextArea & Keybindings Specification: Input policies, key bindings, and text editing behavior.
- 🎯 Interaction Behavior Contract: Focus management, event bubble paths, and pointer semantics.
The repository includes showcase examples categorized under examples/:
| Directory | Purpose & Highlights |
|---|---|
examples/basics/ |
Core layout rules, custom font drop-in interop, dashboard layout, form flows, interaction semantics, raw key input, and keyboard navigation (custom_font_showcase.rs, dashboard_app.rs, complex_layout_showcase.rs). |
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). |
examples/motion/ |
Motion framework, spring physics, dirty-region animation, timeline keyframing, and cinematic peek/glance cards (animation_motion_showcase.rs, cinematic_peek_glance_carddeck_showcase.rs). |
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). |
Run any example using Cargo:
cargo run --example dashboard_app --features std
cargo run --example animation_motion_showcase --features std| Feature | Description |
|---|---|
embedded-graphics |
(Default) Transparent support for embedded-graphics MonoFont references (&FONT_6X10, &FONT_9X15) in styles and text rendering. |
libm |
Provides floating-point math support (f32::sin, cos, round, sqrt) when building for no_std targets without standard library floats. |
rich-widgets |
Enables advanced visual widgets including Gauges, Plotters, TextAreas, and On-Screen Keyboards. |
embedded-text |
Enables interoperability adapters for embedded-text TextBox. |
embedded-layout |
Enables interoperability adapters for embedded-layout View alignment. |
embassy |
Adds EmbassyWaitTransfer and FrameClock for Embassy async executor integration. |
triple-buffering |
Enables triple-buffer swapchain for bursty display frame rates. |
Version 0.2.0 introduces a flexible, trait-based font system supporting custom raw bitmap arrays (BitmapFont) and dynamic font providers (Font trait):
FontIdEnum Variants: AddedFontId::Bitmap(&'static BitmapFont)andFontId::Dynamic(&'static dyn Font). Exhaustivematchstatements onFontIdmust include these new variants or a wildcard fallback arm (_ => ...).- Non-
constGeometry Methods:FontId::advance()andFontId::line_height()are now standardfnmethods instead ofconst fnto allow dispatching to dynamic trait references. - Enhanced
CustomFontSupport: Legacy 3x5PackedFontusage can be upgraded to the newBitmapFontstruct (BitmapFont::new_8x16,new_8x8, or custom dimensions) for arbitrary glyph sizes andfill_rectspan acceleration.
Dual-licensed under either of:
- MIT License (
LICENSE-MIT) - Apache License, Version 2.0 (
LICENSE-APACHE)
at your option.



