Guillotine
A no-std graphical user interface framework for embedded devices prioritizing resource efficiency and ergonomics. The UI declaration API is heavily inspired by GPUI.
Works everywhere embedded-graphics works.
Demo
A demo Guillotine UI on a Waveshare ESP32-C6 1.47" LCD board:
use ;
use *;
Core Concepts
Declarative Definition
- Explain the idea of declaratively building your UI
TODO: Hybrid Immediate & Retained Mode
TODO: Similar tree-based layout to X
- GPUI
State Management
Layout Engine
- Conceptually similar to Flutter (i.e. constraints go down, sizes go up)
- constraints flow downward, sizes flow upward, positions flow downward
- Requirement: single pass.
API
extern crate alloc;
use ;
use *;
Element trees use the display's PixelColor type throughout. Rgb565 views keep the API shown
above; other targets select their color once at the Render<Color> boundary, after which element
constructors and style methods infer it. See the binary-color example.
Insets and the box model
Margin, padding, and border widths accept CSS-like physical-edge shorthands:
column
.margin // all edges
.padding // vertical, horizontal
.border // top, horizontal, bottom
.margin; // top, right, bottom, left
Use Insets::new(top, right, bottom, left) when a named value is clearer. Insets are non-negative
pixel lengths. Guillotine doesn't currently support percentages, auto, logical edges, negative
margins, margin collapsing, per-edge border colors, or border styles. Adjacent margins in rows and
columns add together.
Style::size is the border-box size: padding and border are placed inside it, and margin is added
outside it. The box grows to contain its padding and border when parent constraints allow.
Examples
To run the examples, you need to enable the simulator feature. This pulls in a bundled sdl2 for opening windows. You will need cmake to compile it.
Roadmap
v0.0.1
- Try to mimic GPUI declaration style: https://github.com/zed-industries/zed/blob/main/crates/gpui/examples/hello_world.rs
- Low-level
Element/ParentElementtrait for custom elements and widgets - Support generic
PixelColor - Full immediate mode redrawing
- Make repo ready for publishing:
- README documentation (a la Dioxus)
- Rustdoc documentation
- Examples
- Sizing (insets)
- Fonts
- Cool
- ESP32
- Fix exports
- Dual Apache / MIT license
- Fix sdl2 vendoring for embedded-graphics-simulator
- Benchmarks for Frame building
-
TextStylefonts - Support for non-interactive elements:
- Row
- (formatted) Text
- Column
- Spinner
- Container gaps
v0.1.0
- Custom render modes:
Incremental(only repaint changed regions, requires more memory), orRedraw(full redraw on every render, lowest memory footprint). Either as a feature or runtime flag. - Define inremental redrawing triggers / states:
- New elements
- Dialogs / Modals (floating containers)
- Charts
- Overflow behaviour:
- Visible
- Clip
-
profilefeature withdefmtlogs - No alloc
- Custom elements
- Alignment
- Support for interaction
- Support interactive elements:
- Button
- Slider
Why?
I was trying to build a clean-looking dashboard on a small LCD screen powered by an ESP32-C6, that's supposed to monitor and display the power consumption of my home lab (project here). I wanted to do this in Rust, with the esp-rs ecosystem. The ecosystem is quite mature, but I couldn't really find a UI framework that was:
- Performant
- Very low memory footprint (no Slint / LVGL)
- Beautiful
Additionally, I wanted to learn what it would take to build something like this.