Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Store a Ui/Frame-stack #4534

Closed
emilk opened this issue May 24, 2024 · 0 comments · Fixed by #4588
Closed

Store a Ui/Frame-stack #4534

emilk opened this issue May 24, 2024 · 0 comments · Fixed by #4588
Assignees
Labels
layout Related to widget layout rerun Desired for Rerun.io style visuals and theming

Comments

@emilk
Copy link
Owner

emilk commented May 24, 2024

Sometimes you want to answer the question "What is this Ui part of?". For instance: sometimes you want to paint the background of a widget to extend to the edges of the panel it is in, but that panel may be several Uis removed from the current widget.

What you want is access to a stack of parent Ui frames, with some semantics.

Each stack should contain:

  • Id
  • Frame (inner & outer margins, stroke, …)
  • min_size and max_size (with/without margins)
  • Type (Panel, Area, Group, …)

We would push onto this stack each time we create a new Ui.

This means the root of the stack is created by Ui::new (most often created by Area/Window and Panel).
Then things like ui.group, ui.horizontal, egui::Frame etc would push onto this stack before calling into its contents, and then pop afterwards.

Working name: StackFrame.

Then we add impl Ui { pub fn stack(&self) -> &Stack { … } } and then users can walk the stack to implement advanced styling.

Implementation

Ui::new creates the stack as a Rc<RefCell<Stack>> and hands it to its children.

Future work: columns

We can use this architecture to implement columnar layouts, allowing aligning widgets that share an ancestor.
Each StackFrame has an optional field for column widths.

An egui::Grid would create such a special stack frame.
When adding a widget, we would walk up the stack to find which column we are in, and align to that, then register if we overflowed that width.
ui.end_row() would reset a column=0.

Maybe this should be a separate stack? Probably.

Anyway, this requires more design, so let's not discuss this further here.

@emilk emilk added this to the Next Major Release milestone May 24, 2024
@emilk emilk added rerun Desired for Rerun.io style visuals and theming layout Related to widget layout labels May 24, 2024
@emilk emilk assigned emilk and abey79 and unassigned emilk May 28, 2024
@abey79 abey79 mentioned this issue May 30, 2024
2 tasks
abey79 added a commit that referenced this issue Jun 4, 2024
* 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 <[email protected]>
hacknus pushed a commit to hacknus/egui that referenced this issue Oct 30, 2024
* Closes emilk#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 emilk#3284.
- Add support to track columnar layouts.

---------

Co-authored-by: Emil Ernerfeldt <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
layout Related to widget layout rerun Desired for Rerun.io style visuals and theming
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants