9 releases (5 breaking)
new 0.6.0 | Jan 11, 2025 |
---|---|
0.5.0 | Dec 27, 2024 |
0.4.0 | Dec 19, 2024 |
0.3.0 | Dec 19, 2024 |
0.1.2 | Nov 25, 2024 |
#76 in GUI
1,457 downloads per month
82KB
1.5K
SLoC
egui_taffy: Egui Taffy Ui
Flexible egui layout library that supports CSS Block, Flexbox, Grid layouts. It uses high-performance taffy library under the hood.
This library is in active development and some breaking changes are expected, but they will be kept as small as possible.
👉 Web Demo 👈 of the latest released version.
Version compatibility
egui_taffy | egui | taffy | MSRV |
---|---|---|---|
0.6 | 0.30 | 0.7.3 | 1.81 |
0.5 | 0.30 | 0.7 | 1.83 |
0.4 | 0.30 | 0.7 | 1.83 |
0.3 | 0.29 | 0.7 | 1.83 |
0.2 | 0.29 | 0.7 | 1.83 |
0.1.2 | 0.29 | 0.6 | 1.83 |
0.1 | 0.29 | 0.6 | 1.83 (nightly) |
To use add egui_taffy
to your project dependencies in Cargo.toml
file.
See CHANGELOG for changes between versions.
Examples
Check out ./examples/demo.rs
(cargo run --example demo).
Flex wrap demo example:
egui::Window::new("Flex wrap demo").show(ctx, |ui| {
tui(ui, ui.id().with("demo"))
.reserve_available_space() // Reserve full space of this window for layout
.style(Style {
flex_direction: taffy::FlexDirection::Column,
align_items: Some(taffy::AlignItems::Stretch),
..default_style()
})
.show(|tui| {
// Add egui ui as node
tui.ui(|ui| {
ui.label("Hello from egui ui!");
ui.button("Egui button");
});
// Add egui widgets directly to UI that implements [`TuiWidget`] trait
tui.ui_add(egui::Label::new("label"));
tui.ui_add(egui::Button::new("button"));
// Or use couple of supported helper function
tui.separator();
tui.label("Text");
// You can add custom style or unique id to every element that is added to the ui
// by calling id, style, mut_style methods on it first using builder pattern
// Provide full style
tui.style(Style {
align_self: Some(taffy::AlignItems::Center),
..Default::default()
})
.label("Centered text");
tui.style(default_style())
.mut_style(|style| {
// Modify one field of the style
style.align_self = Some(taffy::AlignItems::End);
})
.label("Right aligned text");
// You can add elements with custom background using add_with_ family of methods
tui.add_with_border(|tui| {
tui.label("Text with border");
});
tui.separator();
tui.style(Style {
flex_wrap: taffy::FlexWrap::Wrap,
justify_items: Some(taffy::AlignItems::Stretch),
..default_style()
})
.add(|tui| {
for word in FLEX_ITEMS {
tui.style(default_style()).add_with_border(|tui| {
tui.label(word);
});
}
});
});
});
Preview:
Button example
Grid example
Flex example
Grow demo
Overflow demo
Supports scrollable elements!
Sticky elements (Sticky row and column in scrollable grid)
https://github.com/user-attachments/assets/07546146-7a90-422b-b291-99b758fd7704
Virtual grid (virtual table rows)
Support grids with equal virtual row height. Rows can contain merged cells (colspan
).
https://github.com/user-attachments/assets/a3c8ebba-e72f-44c2-9233-29004b97d070
Egui options
Max passes
For best visual look you should enable egui multiple passes support so layout can be immediately recalculated upon some changes.
ctx.options_mut(|options| {
options.max_passes = std::num::NonZeroUsize::new(2).unwrap();
});
If integrating with egui implementations such as bevy_egui
, for egui multipass (request_discard) functionality to work you need to use special approach. See bevy_egui
simple_multipass
example for such case.
Text wrapping
By default egui text wrapping tries to utilize as less width as possible. In dynamic layouts it results in text where letters are placed in a column.
Instead you should use one of the following options:
- Specify minimal width or width for the elements, set text elements to fill width of the parent.
- Set custom egui wrap mode when necessary.
tui.wrap_mode(egui::TextWrapMode::Truncate).add(|tui| { ... })
- Disable text wrapping:
ctx.style_mut(|style| { style.wrap_mode = Some(egui::TextWrapMode::Extend); });
Inspiration
This crate is inspired by lucasmerlin previous exploration in this direction by such crates as:
It combines ideas from both crates and builds upon them to provide easy to use egui like API to write your UI with modern layout support.
Library uses intrinsic size and request_discard egui functionality to measure layout and request immediate frame redraw (without even drawing the current frame) if layout has changed.
Contributing
Contributions are welcome. Please add your improvements to examples so that it is easy to see and validate.
Dependencies
~5–10MB
~105K SLoC