21 unstable releases (5 breaking)
0.6.1 | May 31, 2023 |
---|---|
0.6.0 | Mar 29, 2023 |
0.5.0 | Feb 16, 2023 |
0.4.0 | Oct 9, 2022 |
0.0.2 |
|
#713 in GUI
112 downloads per month
260KB
5.5K
SLoC
rui
Experimental Rust UI library, inspired by SwiftUI. Early days, but some stuff already works. rui will be used for a future version of Audulus
rui is immediate mode (there is no retained tree of views), GPU rendered, updates reactively (when your state changes), and has richer layout options than other immediate mode UIs.
- macOS ✅
- Windows ✅
- Linux ✅
- iOS ✅ (see https://github.com/audulus/rui-ios)
- wasm (WIP)
Examples
obligatory Counter (cargo run --example counter
):
use rui::*;
fn main() {
rui(state(
|| 1,
|count, cx| {
vstack((
cx[count].padding(Auto),
button("increment", move |cx| {
cx[count] += 1;
})
.padding(Auto),
))
},
));
}
some shapes (cargo run --example shapes
):
use rui::*;
fn main() {
rui(vstack((
circle()
.color(RED_HIGHLIGHT)
.padding(Auto),
rectangle()
.corner_radius(5.0)
.color(AZURE_HIGHLIGHT)
.padding(Auto)
)));
}
canvas for gpu drawing (cargo run --example canvas
):
use rui::*;
fn main() {
rui(canvas(|_, rect, vger| {
vger.translate(rect.center() - LocalPoint::zero());
let paint = vger.linear_gradient(
[-100.0, -100.0],
[100.0, 100.0],
AZURE_HIGHLIGHT,
RED_HIGHLIGHT,
0.0,
);
let radius = 100.0;
vger.fill_circle(LocalPoint::zero(), radius, paint);
}));
}
slider
with map
(cargo run --example slider
):
use rui::*;
#[derive(Default)]
struct MyState {
value: f32,
}
/// A slider with a value.
fn my_slider(s: impl Binding<f32>) -> impl View {
with_ref(s, move |v| {
vstack((
v.to_string().font_size(10).padding(Auto),
hslider(s).thumb_color(RED_HIGHLIGHT).padding(Auto),
))
})
}
fn main() {
rui(state(MyState::default, |state, cx|
map(
cx[state].value,
move |v, cx| cx[state].value = v,
|s, _| my_slider(s),
),
));
}
widget gallery (cargo run --example gallery
):
Goals
- Encode UI in types to ensure stable identity.
- Optimize to reduce redraw.
- Use vger-rs for rendering.
- Minimal boilerplate.
- Good looking.
- No
unsafe
. - Accessibility for assistive technologies.
Optional Features
winit
- (enabled by default) use winit for windowing.- Use
default-features = false
if you are embedding rui (see https://github.com/audulus/rui-ios).
Why?
In the long term, I'd like to move Audulus over to Rust. After looking at other available UI options, it seemed best to implement something resembling the existing immediate mode UI system I already have working in Audulus, but better.
Status
- ✅ basic shapes: circle, rounded rectangle
- ✅ basic gestures: tap, drag
- ✅ hstack/vstack
- ✅ text
- ✅ padding
- ✅ offsets
- ✅ state
- ✅ zstack
- ✅ canvas (GPU vector graphics with vger)
- ✅ bindings
- ✅ list
- ✅ sliders
- ✅ knobs
- ✅ editable text (still a bit rough)
- ✅ any_view (view type erasure)
- ✅ layout feedback
- ✅ animation
- ✅ UI unit testing
References
Towards principled reactive UI
Dependencies
~9–46MB
~668K SLoC