Conversation
|
Preview available at https://egui-pr-preview.github.io/pr/8026-lucasatom-ignore-spacing View snapshot changes at kitdiff |
| pub align: Align2, | ||
|
|
||
| /// See [`crate::AtomExt::atom_ignore_spacing`] | ||
| pub ignore_spacing: bool, |
There was a problem hiding this comment.
My initial reaction is that this is getting a bit complicated.
We now have five things controlling size (size, max_size, grow, shrink, ignore_spacing). The test space grows with the cartesian product of these.
I suspect there is a simpler solution to be found. Let's discuss tomorrow morning.
There was a problem hiding this comment.
I'm not very familiar with the inner workings of atoms so perhaps this doesn't make much sense but what about ignoring spacing for AtomKind::Empty atoms by default? My understanding is they are mostly (only?) used as separators so they themselves should be the spacing... This reasoning could be potentially extended to grow atoms for which available size is larger than the content because at that point the external padding would already be acting as spacing .
There was a problem hiding this comment.
Empty atoms can also be used to add custom content. You can assign it an id and then read the rect from the AtomLayoutResponse and use ui.place to add e.g. a button or do custom painting.
There was a problem hiding this comment.
Ah I see, AtomKind::Custom was removed and Empty is also used for custom content now... Since Atoms use a flex-like layout perhaps it could be sensible to have a dedicated spacer atom with its own rules that only helps with the layout (like the absence of inter-atom margin in this instance).
Alternatively, and specifically addressing @emilk's concern about the complexity of the current system, I think atoms could be reworked to be expressed by the combination of:
content_size: predictably, this is simply the actual size of the content.size: a range that fully encapsulates the dynamic behavior of the atom.margin: this is sort of the lower bound of the inner margin in dynamic scenarios
Together they allow for a quite a bit of functionality without much clutter, including:
- zero-sized empty atoms (size = 0..=0).
- overlapping outer padding and spacing.
- unified grow and shrink, since within any given frame an atom can either grow or shrink, not both.
- abstract spacing away from AtomLayout: total is just
atom0.size() + atom1.size() ... + atomN.size(). - arbitrary fixed sizes or nicely wrapping around the content (size = content_size..=content_size).
- custom margins per-atom, which adds flexibility overall.
The way this would work is we take the outer size as the absolute space taken up by the atom and then we compute how much space the content will actually use based on this simple formula: outer_size - (outer_size - content_size).max(margin). For instance, here's a few cases:
content_size = 20
margin = 5
size = 10..=50
outer size = 10 => content size = 5, inner margin = 5
outer size = 25 => content size = 20, inner margin = 5
outer size = 50 => content size = 20, inner margin = 30
Basically the way this works is that as the atom grows in outer size, the inner size grows up to the size of the content with a fixed inner margin, but beyond that it's just the margin that grows to pad the content.
During the layouting phase we check what the atom is supposed to do (grow, shrink...) based on its size range, and then we decide what size (within its range) we want to use based on the other atoms, available space and so on, which shouldn't be too big a change compared to the current system.
Obviously this is just an idea and there's surely a number of edge cases (like what if margin is more than the minimum outer size?) or possible refinements (split min and max instead of using a range) but hopefully this can be useful in some form.
No description provided.