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:
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user