diff options
author | 2024-01-05 17:24:43 +0100 | |
---|---|---|
committer | 2024-01-10 10:01:49 +0100 | |
commit | 22226394f7b1a0e0205b9bb5b3ef9b85a3b406f5 (patch) | |
tree | 22214a4ac6bca5033f6d5a227934288019f6ca60 /core | |
parent | 0322e820eb40d36a7425246278b7bcb22b7010aa (diff) | |
download | iced-22226394f7b1a0e0205b9bb5b3ef9b85a3b406f5.tar.gz iced-22226394f7b1a0e0205b9bb5b3ef9b85a3b406f5.tar.bz2 iced-22226394f7b1a0e0205b9bb5b3ef9b85a3b406f5.zip |
Introduce `Widget::size_hint` and fix further layout inconsistencies
Diffstat (limited to 'core')
-rw-r--r-- | core/src/layout/flex.rs | 72 | ||||
-rw-r--r-- | core/src/length.rs | 6 | ||||
-rw-r--r-- | core/src/widget.rs | 10 |
3 files changed, 68 insertions, 20 deletions
diff --git a/core/src/layout/flex.rs b/core/src/layout/flex.rs index 9a4b2cbf..67cc7f2a 100644 --- a/core/src/layout/flex.rs +++ b/core/src/layout/flex.rs @@ -91,8 +91,46 @@ where child.as_widget().height().fill_factor(), ); - if fill_main_factor == 0 && fill_cross_factor == 0 { - let (max_width, max_height) = axis.pack(available, max_cross); + if fill_main_factor == 0 { + if fill_cross_factor == 0 { + let (max_width, max_height) = axis.pack(available, max_cross); + + let child_limits = + Limits::new(Size::ZERO, Size::new(max_width, max_height)); + + let layout = + child.as_widget().layout(tree, renderer, &child_limits); + let size = layout.size(); + + available -= axis.main(size); + cross = cross.max(axis.cross(size)); + + nodes[i] = layout; + } + } else { + fill_main_sum += fill_main_factor; + } + } + + let intrinsic_cross = match axis { + Axis::Horizontal => match height { + Length::Shrink => cross, + _ => max_cross, + }, + Axis::Vertical => match width { + Length::Shrink => cross, + _ => max_cross, + }, + }; + + for (i, (child, tree)) in items.iter().zip(trees.iter_mut()).enumerate() { + let (fill_main_factor, fill_cross_factor) = axis.pack( + child.as_widget().width().fill_factor(), + child.as_widget().height().fill_factor(), + ); + + if fill_main_factor == 0 && fill_cross_factor != 0 { + let (max_width, max_height) = axis.pack(available, intrinsic_cross); let child_limits = Limits::new(Size::ZERO, Size::new(max_width, max_height)); @@ -102,11 +140,8 @@ where let size = layout.size(); available -= axis.main(size); - cross = cross.max(axis.cross(size)); nodes[i] = layout; - } else { - fill_main_sum += fill_main_factor; } } @@ -121,24 +156,13 @@ where }, }; - let max_cross = match axis { - Axis::Horizontal => match height { - Length::Shrink if cross > 0.0 => cross, - _ => max_cross, - }, - Axis::Vertical => match width { - Length::Shrink if cross > 0.0 => cross, - _ => max_cross, - }, - }; - for (i, (child, tree)) in items.iter().zip(trees).enumerate() { let (fill_main_factor, fill_cross_factor) = axis.pack( child.as_widget().width().fill_factor(), child.as_widget().height().fill_factor(), ); - if fill_main_factor != 0 || fill_cross_factor != 0 { + if fill_main_factor != 0 { let max_main = if fill_main_factor == 0 { available.max(0.0) } else { @@ -151,6 +175,12 @@ where max_main }; + let max_cross = if fill_cross_factor == 0 { + max_cross + } else { + intrinsic_cross + }; + let (min_width, min_height) = axis.pack(min_main, axis.cross(limits.min())); @@ -203,8 +233,12 @@ where main += axis.main(size); } - let (width, height) = axis.pack(main - pad.0, cross); - let size = limits.resolve(Size::new(width, height), width, height); + let (intrinsic_width, intrinsic_height) = axis.pack(main - pad.0, cross); + let size = limits.resolve( + Size::new(intrinsic_width, intrinsic_height), + width, + height, + ); Node::with_children(size.expand(padding), nodes) } diff --git a/core/src/length.rs b/core/src/length.rs index 3adb996e..6dc15049 100644 --- a/core/src/length.rs +++ b/core/src/length.rs @@ -36,6 +36,12 @@ impl Length { Length::Fixed(_) => 0, } } + + /// Returns `true` iff the [`Length`] is either [`Length::Fill`] or + // [`Length::FillPortion`]. + pub fn is_fill(&self) -> bool { + self.fill_factor() != 0 + } } impl From<Pixels> for Length { diff --git a/core/src/widget.rs b/core/src/widget.rs index 294d5984..890b3773 100644 --- a/core/src/widget.rs +++ b/core/src/widget.rs @@ -15,7 +15,7 @@ use crate::layout::{self, Layout}; use crate::mouse; use crate::overlay; use crate::renderer; -use crate::{Clipboard, Length, Rectangle, Shell}; +use crate::{Clipboard, Length, Rectangle, Shell, Size}; /// A component that displays information and allows interaction. /// @@ -49,6 +49,14 @@ where /// Returns the height of the [`Widget`]. fn height(&self) -> Length; + /// Returns a [`Size`] hint for laying out the [`Widget`]. + /// + /// This hint may be used by some widget containers to adjust their sizing strategy + /// during construction. + fn size_hint(&self) -> Size<Length> { + Size::new(self.width(), self.height()) + } + /// Returns the [`layout::Node`] of the [`Widget`]. /// /// This [`layout::Node`] is used by the runtime to compute the [`Layout`] of the |