1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-29 04:40:03 -04:00

Introduce UiStack (#4588)

* Closes #4534

This PR:
- Introduces `Ui::stack()`, which returns the `UiStack` structure
providing information on the current `Ui` hierarchy.
- **BREAKING**: `Ui::new()` now takes a `UiStackInfo` argument, which is
used to populate some of this `Ui`'s `UiStack`'s fields.
- **BREAKING**: `Ui::child_ui()` and `Ui::child_ui_with_id_source()` now
take an `Option<UiStackInfo>` argument, which is used to populate some
of the children `Ui`'s `UiStack`'s fields.
- New `Area::kind()` builder function, to set the `UiStackKind` value of
the `Area`'s `Ui`.
- Adds a (minimalistic) demo to egui demo (in the "Misc Demos" window).
- Adds a more thorough `test_ui_stack` test/playground demo.

TODO:
- [x] benchmarks
- [x] add example to demo

Future work:
- Add `UiStackKind` and related support for more container (e.g.
`CollapsingHeader`, etc.)
- Add a tag/property system that would allow adding arbitrary data to a
stack node. This data could then be queried by nested `Ui`s. Probably
needed for #3284.
- Add support to track columnar layouts.

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
This commit is contained in:
Antoine Beyeler
2024-06-04 10:12:23 +02:00
committed by GitHub
parent c0a9800d05
commit a28792194d
23 changed files with 794 additions and 30 deletions

View File

@@ -1,4 +1,5 @@
use super::*;
use egui::*;
/// Showcase some ui code
@@ -154,6 +155,10 @@ impl View for MiscDemoWindow {
});
});
CollapsingHeader::new("Ui Stack")
.default_open(false)
.show(ui, ui_stack_demo);
CollapsingHeader::new("Misc")
.default_open(false)
.show(ui, |ui| {
@@ -492,6 +497,72 @@ impl Tree {
// ----------------------------------------------------------------------------
fn ui_stack_demo(ui: &mut Ui) {
ui.horizontal_wrapped(|ui| {
ui.label("The");
ui.code("egui::Ui");
ui.label("core type is typically deeply nested in");
ui.code("egui");
ui.label(
"applications. To provide context to nested code, it maintains a stack \
with various information.\n\nThis is how the stack looks like here:",
);
});
let stack = ui.stack().clone();
Frame {
inner_margin: ui.spacing().menu_margin,
stroke: ui.visuals().widgets.noninteractive.bg_stroke,
..Default::default()
}
.show(ui, |ui| {
egui_extras::TableBuilder::new(ui)
.column(egui_extras::Column::auto())
.column(egui_extras::Column::auto())
.header(18.0, |mut header| {
header.col(|ui| {
ui.strong("id");
});
header.col(|ui| {
ui.strong("kind");
});
})
.body(|mut body| {
for node in stack.iter() {
body.row(18.0, |mut row| {
row.col(|ui| {
let response = ui.label(format!("{:?}", node.id));
if response.hovered() {
ui.ctx().debug_painter().debug_rect(
node.max_rect,
Color32::GREEN,
"max_rect",
);
ui.ctx().debug_painter().circle_filled(
node.min_rect.min,
2.0,
Color32::RED,
);
}
});
row.col(|ui| {
ui.label(if let Some(kind) = node.kind {
format!("{kind:?}")
} else {
"-".to_owned()
});
});
});
}
});
});
ui.small("Hover on UI's ids to display their origin and max rect.");
}
// ----------------------------------------------------------------------------
fn text_layout_demo(ui: &mut Ui) {
use egui::text::LayoutJob;