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

Layout consistency #2192

Merged
merged 26 commits into from
Jan 12, 2024
Merged

Layout consistency #2192

merged 26 commits into from
Jan 12, 2024

Conversation

hecrj
Copy link
Member

@hecrj hecrj commented Jan 10, 2024

This PR improves the intuitiveness of our layout engine by solving a bunch of inconsistencies related to our sizing strategies.

Shrunken fills

Until now, it was considered an invalid layout to have a container with Length::Shrink containing some widget with Length::Fill in a specific dimension. Specifically, this use case would cause the Fill item to steal all the available space independently of the position of the parent in the widget tree (see #2186). In practice, this could cause widgets to fully disappear unexpectedly in completely unrelated places of the application unless Fill was explicitly set everywhere.

The changes here modify our flex layout logic so that Shrink actually takes priority over Fill. As a result, a container with a Shrink strategy containing some widget with a Fill strategy will simply collapse its contents. Effectively, this makes invalid layouts local and avoids them from leaking through multiple levels of the widget tree.

Furthermore, a Shrink parent with a Fill children in its cross axis will only collapse if the parent does not have any Shrink children. If some children are Shrink, then the Fill children will fill as much space as the widest child. This behavior can be leveraged to satisfy a bunch of use cases that previously were impossible to model without using custom widgets.

For instance, this layout

image

can now be achieved with row and vertical_rule:

row![vertical_rule(2), "Original text"].height(Length::Shrink)

While a vertical_rule uses a Fill strategy for its height and the parent row is set to Shrink, the layout works as expected because the text has a Shrink height.

Adaptive containers

But wait! What happens with containers that by default Shrink but only have Fill children? Do we have to manually set Fill everywhere now for its contents to not disappear? No! Containers now adapt their sizing strategy based on their children.

The width and height methods of the Widget trait are now consolidated into a single size method that returns a Size<Length>. A new size_hint method also exists, which by default returns size, and it is leveraged by containers to guess the proper sizing strategy during construction.

In practice, this means that if we want a container to Shrink when some of its children are Fill, we need to opt in on this behavior explicitly. It also means that we do not need to explicitly set Fill everywhere in order for layouts to work as expected.

A layout example

I have also created a new example: layout, which is meant to showcase a bunch of common, useful layouts that can be easily achieved with the built-in widgets:

image

Other (useful) minor changes

  • The fill field in layout::Limits has been removed, simplifying its meaning considerably.
  • The column and row functions now take an IntoIterator instead of a Vec.
  • The layout module now has a bunch of new helpers with common layout strategies; useful for custom widgets.
  • container::Appearance can be directly used as the style of a Container.

Fixes #2186.

@hecrj hecrj added this to the 0.12 milestone Jan 10, 2024
@hecrj hecrj added bug Something isn't working styling fix labels Jan 11, 2024
@hecrj hecrj merged commit 50c310f into master Jan 12, 2024
26 checks passed
@hecrj hecrj deleted the fix/layout-inconsistencies branch January 12, 2024 13:41
quintenpalmer added a commit to quintenpalmer/protomusiq that referenced this pull request Feb 15, 2024
This fixes an issue where Fill-width elements in the column would
disappear, maybe because of these issues:

iced-rs/iced#715
iced-rs/iced#2186
iced-rs/iced#2192
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Length::Fill steals all the available space from other widgets
1 participant