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 '')
| -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  | 
