diff options
Diffstat (limited to '')
| -rw-r--r-- | core/src/layout.rs | 12 | ||||
| -rw-r--r-- | core/src/layout/flex.rs | 29 | ||||
| -rw-r--r-- | core/src/layout/limits.rs | 83 | ||||
| -rw-r--r-- | core/src/layout/node.rs | 29 | ||||
| -rw-r--r-- | core/src/padding.rs | 6 | ||||
| -rw-r--r-- | core/src/size.rs | 24 | ||||
| -rw-r--r-- | core/src/widget/text.rs | 2 | 
7 files changed, 107 insertions, 78 deletions
| diff --git a/core/src/layout.rs b/core/src/layout.rs index caf315b6..277473fe 100644 --- a/core/src/layout.rs +++ b/core/src/layout.rs @@ -71,12 +71,12 @@ pub fn next_to_each_other(      left: impl FnOnce(&Limits) -> Node,      right: impl FnOnce(&Limits) -> Node,  ) -> Node { -    let mut left_node = left(limits); +    let left_node = left(limits);      let left_size = left_node.size();      let right_limits = limits.shrink(Size::new(left_size.width + spacing, 0.0)); -    let mut right_node = right(&right_limits); +    let right_node = right(&right_limits);      let right_size = right_node.size();      let (left_y, right_y) = if left_size.height > right_size.height { @@ -85,14 +85,14 @@ pub fn next_to_each_other(          ((right_size.height - left_size.height) / 2.0, 0.0)      }; -    left_node.move_to(Point::new(0.0, left_y)); -    right_node.move_to(Point::new(left_size.width + spacing, right_y)); -      Node::with_children(          Size::new(              left_size.width + spacing + right_size.width,              left_size.height.max(right_size.height),          ), -        vec![left_node, right_node], +        vec![ +            left_node.move_to(Point::new(0.0, left_y)), +            right_node.move_to(Point::new(left_size.width + spacing, right_y)), +        ],      )  } diff --git a/core/src/layout/flex.rs b/core/src/layout/flex.rs index c02b63d8..738dc81d 100644 --- a/core/src/layout/flex.rs +++ b/core/src/layout/flex.rs @@ -20,7 +20,7 @@ use crate::Element;  use crate::layout::{Limits, Node};  use crate::widget; -use crate::{Alignment, Padding, Point, Size}; +use crate::{Alignment, Length, Padding, Point, Size};  /// The main axis of a flex layout.  #[derive(Debug)] @@ -63,6 +63,8 @@ pub fn resolve<Message, Renderer>(      axis: Axis,      renderer: &Renderer,      limits: &Limits, +    width: Length, +    height: Length,      padding: Padding,      spacing: f32,      align_items: Alignment, @@ -72,12 +74,12 @@ pub fn resolve<Message, Renderer>(  where      Renderer: crate::Renderer,  { -    let limits = limits.pad(padding); +    let limits = limits.width(width).height(height).shrink(padding);      let total_spacing = spacing * items.len().saturating_sub(1) as f32;      let max_cross = axis.cross(limits.max());      let mut fill_sum = 0; -    let mut cross = axis.cross(limits.min()).max(axis.cross(limits.fill())); +    let mut cross = 0.0f32;      let mut available = axis.main(limits.max()) - total_spacing;      let mut nodes: Vec<Node> = Vec::with_capacity(items.len()); @@ -109,7 +111,16 @@ where          }      } -    let remaining = available.max(0.0); +    let remaining = match axis { +        Axis::Horizontal => match width { +            Length::Shrink => 0.0, +            _ => available.max(0.0), +        }, +        Axis::Vertical => match height { +            Length::Shrink => 0.0, +            _ => available.max(0.0), +        }, +    };      for (i, (child, tree)) in items.iter().zip(trees).enumerate() {          let fill_factor = match axis { @@ -154,18 +165,18 @@ where          let (x, y) = axis.pack(main, pad.1); -        node.move_to(Point::new(x, y)); +        node.move_to_mut(Point::new(x, y));          match axis {              Axis::Horizontal => { -                node.align( +                node.align_mut(                      Alignment::Start,                      align_items,                      Size::new(0.0, cross),                  );              }              Axis::Vertical => { -                node.align( +                node.align_mut(                      align_items,                      Alignment::Start,                      Size::new(cross, 0.0), @@ -179,7 +190,7 @@ where      }      let (width, height) = axis.pack(main - pad.0, cross); -    let size = limits.resolve(Size::new(width, height)); +    let size = limits.resolve(Size::new(width, height), width, height); -    Node::with_children(size.pad(padding), nodes) +    Node::with_children(size.expand(padding), nodes)  } diff --git a/core/src/layout/limits.rs b/core/src/layout/limits.rs index 39a3d98b..eef4c4c9 100644 --- a/core/src/layout/limits.rs +++ b/core/src/layout/limits.rs @@ -1,12 +1,11 @@  #![allow(clippy::manual_clamp)] -use crate::{Length, Padding, Size}; +use crate::{Length, Size};  /// A set of size constraints for layouting.  #[derive(Debug, Clone, Copy, PartialEq)]  pub struct Limits {      min: Size,      max: Size, -    fill: Size,  }  impl Limits { @@ -14,16 +13,11 @@ impl Limits {      pub const NONE: Limits = Limits {          min: Size::ZERO,          max: Size::INFINITY, -        fill: Size::INFINITY,      };      /// Creates new [`Limits`] with the given minimum and maximum [`Size`].      pub const fn new(min: Size, max: Size) -> Limits { -        Limits { -            min, -            max, -            fill: Size::INFINITY, -        } +        Limits { min, max }      }      /// Returns the minimum [`Size`] of the [`Limits`]. @@ -36,26 +30,15 @@ impl Limits {          self.max      } -    /// Returns the fill [`Size`] of the [`Limits`]. -    pub fn fill(&self) -> Size { -        self.fill -    } -      /// Applies a width constraint to the current [`Limits`].      pub fn width(mut self, width: impl Into<Length>) -> Limits {          match width.into() { -            Length::Shrink => { -                self.fill.width = self.min.width; -            } -            Length::Fill | Length::FillPortion(_) => { -                self.fill.width = self.fill.width.min(self.max.width); -            } +            Length::Shrink | Length::Fill | Length::FillPortion(_) => {}              Length::Fixed(amount) => {                  let new_width = amount.min(self.max.width).max(self.min.width);                  self.min.width = new_width;                  self.max.width = new_width; -                self.fill.width = new_width;              }          } @@ -65,19 +48,13 @@ impl Limits {      /// Applies a height constraint to the current [`Limits`].      pub fn height(mut self, height: impl Into<Length>) -> Limits {          match height.into() { -            Length::Shrink => { -                self.fill.height = self.min.height; -            } -            Length::Fill | Length::FillPortion(_) => { -                self.fill.height = self.fill.height.min(self.max.height); -            } +            Length::Shrink | Length::Fill | Length::FillPortion(_) => {}              Length::Fixed(amount) => {                  let new_height =                      amount.min(self.max.height).max(self.min.height);                  self.min.height = new_height;                  self.max.height = new_height; -                self.fill.height = new_height;              }          } @@ -112,13 +89,10 @@ impl Limits {          self      } -    /// Shrinks the current [`Limits`] to account for the given padding. -    pub fn pad(&self, padding: Padding) -> Limits { -        self.shrink(Size::new(padding.horizontal(), padding.vertical())) -    } -      /// Shrinks the current [`Limits`] by the given [`Size`]. -    pub fn shrink(&self, size: Size) -> Limits { +    pub fn shrink(&self, size: impl Into<Size>) -> Limits { +        let size = size.into(); +          let min = Size::new(              (self.min().width - size.width).max(0.0),              (self.min().height - size.height).max(0.0), @@ -129,12 +103,7 @@ impl Limits {              (self.max().height - size.height).max(0.0),          ); -        let fill = Size::new( -            (self.fill.width - size.width).max(0.0), -            (self.fill.height - size.height).max(0.0), -        ); - -        Limits { min, max, fill } +        Limits { min, max }      }      /// Removes the minimum width constraint for the current [`Limits`]. @@ -142,22 +111,38 @@ impl Limits {          Limits {              min: Size::ZERO,              max: self.max, -            fill: self.fill,          }      }      /// Computes the resulting [`Size`] that fits the [`Limits`] given the      /// intrinsic size of some content. -    pub fn resolve(&self, intrinsic_size: Size) -> Size { -        Size::new( -            intrinsic_size -                .width -                .min(self.max.width) -                .max(self.fill.width), -            intrinsic_size +    pub fn resolve( +        &self, +        intrinsic_size: Size, +        width: impl Into<Length>, +        height: impl Into<Length>, +    ) -> Size { +        let width = match width.into() { +            Length::Fill | Length::FillPortion(_) => self.max.width, +            Length::Fixed(amount) => { +                amount.min(self.max.width).max(self.min.width) +            } +            Length::Shrink => { +                intrinsic_size.width.min(self.max.width).max(self.min.width) +            } +        }; + +        let height = match height.into() { +            Length::Fill | Length::FillPortion(_) => self.max.height, +            Length::Fixed(amount) => { +                amount.min(self.max.height).max(self.min.height) +            } +            Length::Shrink => intrinsic_size                  .height                  .min(self.max.height) -                .max(self.fill.height), -        ) +                .max(self.min.height), +        }; + +        Size::new(width, height)      }  } diff --git a/core/src/layout/node.rs b/core/src/layout/node.rs index 2b44a7d5..00087431 100644 --- a/core/src/layout/node.rs +++ b/core/src/layout/node.rs @@ -1,4 +1,4 @@ -use crate::{Alignment, Point, Rectangle, Size, Vector}; +use crate::{Alignment, Padding, Point, Rectangle, Size, Vector};  /// The bounds of an element and its children.  #[derive(Debug, Clone, Default)] @@ -26,6 +26,14 @@ impl Node {          }      } +    /// Creates a new [`Node`] that wraps a single child with some [`Padding`]. +    pub fn container(child: Self, padding: Padding) -> Self { +        Self::with_children( +            child.bounds.size().expand(padding), +            vec![child.move_to(Point::new(padding.left, padding.top))], +        ) +    } +      /// Returns the [`Size`] of the [`Node`].      pub fn size(&self) -> Size {          Size::new(self.bounds.width, self.bounds.height) @@ -43,6 +51,17 @@ impl Node {      /// Aligns the [`Node`] in the given space.      pub fn align( +        mut self, +        horizontal_alignment: Alignment, +        vertical_alignment: Alignment, +        space: Size, +    ) -> Self { +        self.align_mut(horizontal_alignment, vertical_alignment, space); +        self +    } + +    /// Mutable reference version of [`align`]. +    pub fn align_mut(          &mut self,          horizontal_alignment: Alignment,          vertical_alignment: Alignment, @@ -70,7 +89,13 @@ impl Node {      }      /// Moves the [`Node`] to the given position. -    pub fn move_to(&mut self, position: Point) { +    pub fn move_to(mut self, position: Point) -> Self { +        self.move_to_mut(position); +        self +    } + +    /// Mutable reference version of [`move_to`]. +    pub fn move_to_mut(&mut self, position: Point) {          self.bounds.x = position.x;          self.bounds.y = position.y;      } diff --git a/core/src/padding.rs b/core/src/padding.rs index 0b1bba13..a63f6e29 100644 --- a/core/src/padding.rs +++ b/core/src/padding.rs @@ -154,3 +154,9 @@ impl From<[f32; 4]> for Padding {          }      }  } + +impl From<Padding> for Size { +    fn from(padding: Padding) -> Self { +        Self::new(padding.horizontal(), padding.vertical()) +    } +} diff --git a/core/src/size.rs b/core/src/size.rs index 7ef2f602..90e50d13 100644 --- a/core/src/size.rs +++ b/core/src/size.rs @@ -1,4 +1,4 @@ -use crate::{Padding, Vector}; +use crate::Vector;  /// An amount of space in 2 dimensions.  #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -26,15 +26,7 @@ impl Size {      /// A [`Size`] with infinite width and height.      pub const INFINITY: Size = Size::new(f32::INFINITY, f32::INFINITY); -    /// Increments the [`Size`] to account for the given padding. -    pub fn pad(&self, padding: Padding) -> Self { -        Size { -            width: self.width + padding.horizontal(), -            height: self.height + padding.vertical(), -        } -    } - -    /// Returns the minimum of each component of this size and another +    /// Returns the minimum of each component of this size and another.      pub fn min(self, other: Self) -> Self {          Size {              width: self.width.min(other.width), @@ -42,13 +34,23 @@ impl Size {          }      } -    /// Returns the maximum of each component of this size and another +    /// Returns the maximum of each component of this size and another.      pub fn max(self, other: Self) -> Self {          Size {              width: self.width.max(other.width),              height: self.height.max(other.height),          }      } + +    /// Expands this [`Size`] by the given amount. +    pub fn expand(self, other: impl Into<Size>) -> Self { +        let other = other.into(); + +        Size { +            width: self.width + other.width, +            height: self.height + other.height, +        } +    }  }  impl From<[f32; 2]> for Size { diff --git a/core/src/widget/text.rs b/core/src/widget/text.rs index e020b030..e47e4178 100644 --- a/core/src/widget/text.rs +++ b/core/src/widget/text.rs @@ -224,7 +224,7 @@ where          shaping,      }); -    let size = limits.resolve(paragraph.min_bounds()); +    let size = limits.resolve(paragraph.min_bounds(), width, height);      layout::Node::new(size)  } | 
