diff options
Diffstat (limited to '')
| -rw-r--r-- | native/src/layout.rs | 16 | ||||
| -rw-r--r-- | native/src/layout/flex.rs | 24 | ||||
| -rw-r--r-- | native/src/layout/limits.rs | 53 | ||||
| -rw-r--r-- | native/src/layout/node.rs | 23 | 
4 files changed, 107 insertions, 9 deletions
diff --git a/native/src/layout.rs b/native/src/layout.rs index 0a744346..e945706b 100644 --- a/native/src/layout.rs +++ b/native/src/layout.rs @@ -1,3 +1,4 @@ +//! Position your widgets properly.  mod limits;  mod node; @@ -8,6 +9,9 @@ pub use node::Node;  use crate::{Point, Rectangle, Vector}; +/// The bounds of a [`Node`] and its children, using absolute coordinates. +/// +/// [`Node`]: struct.Node.html  #[derive(Debug, Clone, Copy)]  pub struct Layout<'a> {      position: Point, @@ -28,6 +32,14 @@ impl<'a> Layout<'a> {          }      } +    /// Gets the bounds of the [`Layout`]. +    /// +    /// The returned [`Rectangle`] describes the position and size of a +    /// [`Node`]. +    /// +    /// [`Layout`]: struct.Layout.html +    /// [`Rectangle`]: struct.Rectangle.html +    /// [`Node`]: struct.Node.html      pub fn bounds(&self) -> Rectangle {          let bounds = self.node.bounds(); @@ -39,6 +51,10 @@ impl<'a> Layout<'a> {          }      } +    /// Returns an iterator over the [`Layout`] of the children of a [`Node`]. +    /// +    /// [`Layout`]: struct.Layout.html +    /// [`Node`]: struct.Node.html      pub fn children(&'a self) -> impl Iterator<Item = Layout<'a>> {          self.node.children().iter().map(move |node| {              Layout::with_offset( diff --git a/native/src/layout/flex.rs b/native/src/layout/flex.rs index 7a2b0d70..bc90553e 100644 --- a/native/src/layout/flex.rs +++ b/native/src/layout/flex.rs @@ -1,3 +1,4 @@ +//! Distribute elements using a flex-based layout.  // This code is heavily inspired by the [`druid`] codebase.  //  // [`druid`]: https://github.com/xi-editor/druid @@ -20,9 +21,13 @@ use crate::{      Align, Element, Size,  }; +/// The main axis of a flex layout.  #[derive(Debug)]  pub enum Axis { +    /// The horizontal axis      Horizontal, + +    /// The vertical axis      Vertical,  } @@ -49,7 +54,12 @@ impl Axis {      }  } -// TODO: Remove `Message` type parameter +/// Computes the flex layout with the given axis and limits, applying spacing, +/// padding and alignment to the items as needed. +/// +/// It returns a new layout [`Node`]. +/// +/// [`Node`]: ../struct.Node.html  pub fn resolve<Message, Renderer>(      axis: Axis,      renderer: &Renderer, @@ -57,7 +67,7 @@ pub fn resolve<Message, Renderer>(      padding: f32,      spacing: f32,      align_items: Align, -    children: &[Element<'_, Message, Renderer>], +    items: &[Element<'_, Message, Renderer>],  ) -> Node  where      Renderer: crate::Renderer, @@ -65,14 +75,14 @@ where      let limits = limits.pad(padding);      let mut total_non_fill = -        spacing as f32 * (children.len() as i32 - 1).max(0) as f32; +        spacing as f32 * (items.len() as i32 - 1).max(0) as f32;      let mut fill_sum = 0;      let mut cross = axis.cross(limits.min()); -    let mut nodes: Vec<Node> = Vec::with_capacity(children.len()); -    nodes.resize(children.len(), Node::default()); +    let mut nodes: Vec<Node> = Vec::with_capacity(items.len()); +    nodes.resize(items.len(), Node::default()); -    for (i, child) in children.iter().enumerate() { +    for (i, child) in items.iter().enumerate() {          let fill_factor = match axis {              Axis::Horizontal => child.width(),              Axis::Vertical => child.height(), @@ -97,7 +107,7 @@ where      let available = axis.main(limits.max());      let remaining = (available - total_non_fill).max(0.0); -    for (i, child) in children.iter().enumerate() { +    for (i, child) in items.iter().enumerate() {          let fill_factor = match axis {              Axis::Horizontal => child.width(),              Axis::Vertical => child.height(), diff --git a/native/src/layout/limits.rs b/native/src/layout/limits.rs index af269acd..2705a47d 100644 --- a/native/src/layout/limits.rs +++ b/native/src/layout/limits.rs @@ -1,5 +1,6 @@  use crate::{Length, Size}; +/// A set of size constraints for layouting.  #[derive(Debug, Clone, Copy)]  pub struct Limits {      min: Size, @@ -8,12 +9,17 @@ pub struct Limits {  }  impl Limits { +    /// No 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`]. +    /// +    /// [`Limits`]: struct.Limits.html +    /// [`Size`]: ../struct.Size.html      pub fn new(min: Size, max: Size) -> Limits {          Limits {              min, @@ -22,14 +28,25 @@ impl Limits {          }      } +    /// Returns the minimum [`Size`] of the [`Limits`]. +    /// +    /// [`Limits`]: struct.Limits.html +    /// [`Size`]: ../struct.Size.html      pub fn min(&self) -> Size {          self.min      } +    /// Returns the maximum [`Size`] of the [`Limits`]. +    /// +    /// [`Limits`]: struct.Limits.html +    /// [`Size`]: ../struct.Size.html      pub fn max(&self) -> Size {          self.max      } +    /// Applies a width constraint to the current [`Limits`]. +    /// +    /// [`Limits`]: struct.Limits.html      pub fn width(mut self, width: Length) -> Limits {          match width {              Length::Shrink => { @@ -51,6 +68,9 @@ impl Limits {          self      } +    /// Applies a height constraint to the current [`Limits`]. +    /// +    /// [`Limits`]: struct.Limits.html      pub fn height(mut self, height: Length) -> Limits {          match height {              Length::Shrink => { @@ -72,6 +92,9 @@ impl Limits {          self      } +    /// Applies a minimum width constraint to the current [`Limits`]. +    /// +    /// [`Limits`]: struct.Limits.html      pub fn min_width(mut self, min_width: u32) -> Limits {          self.min.width =              self.min.width.max(min_width as f32).min(self.max.width); @@ -79,6 +102,9 @@ impl Limits {          self      } +    /// Applies a maximum width constraint to the current [`Limits`]. +    /// +    /// [`Limits`]: struct.Limits.html      pub fn max_width(mut self, max_width: u32) -> Limits {          self.max.width =              self.max.width.min(max_width as f32).max(self.min.width); @@ -86,6 +112,19 @@ impl Limits {          self      } +    /// Applies a minimum height constraint to the current [`Limits`]. +    /// +    /// [`Limits`]: struct.Limits.html +    pub fn min_height(mut self, min_height: u32) -> Limits { +        self.min.height = +            self.min.height.max(min_height as f32).min(self.max.height); + +        self +    } + +    /// Applies a maximum height constraint to the current [`Limits`]. +    /// +    /// [`Limits`]: struct.Limits.html      pub fn max_height(mut self, max_height: u32) -> Limits {          self.max.height =              self.max.height.min(max_height as f32).max(self.min.height); @@ -93,10 +132,17 @@ impl Limits {          self      } +    /// Shrinks the current [`Limits`] to account for the given padding. +    /// +    /// [`Limits`]: struct.Limits.html      pub fn pad(&self, padding: f32) -> Limits {          self.shrink(Size::new(padding * 2.0, padding * 2.0))      } +    /// Shrinks the current [`Limits`] by the given [`Size`]. +    /// +    /// [`Limits`]: struct.Limits.html +    /// [`Size`]: ../struct.Size.html      pub fn shrink(&self, size: Size) -> Limits {          let min = Size::new(              (self.min().width - size.width).max(0.0), @@ -116,6 +162,9 @@ impl Limits {          Limits { min, max, fill }      } +    /// Removes the minimum width constraint for the current [`Limits`]. +    /// +    /// [`Limits`]: struct.Limits.html      pub fn loose(&self) -> Limits {          Limits {              min: Size::ZERO, @@ -124,6 +173,10 @@ impl Limits {          }      } +    /// Computes the resulting [`Size`] that fits the [`Limits`] given the +    /// intrinsic size of some content. +    /// +    /// [`Limits`]: struct.Limits.html      pub fn resolve(&self, intrinsic_size: Size) -> Size {          Size::new(              intrinsic_size diff --git a/native/src/layout/node.rs b/native/src/layout/node.rs index 64ebf2d0..ed1cd3da 100644 --- a/native/src/layout/node.rs +++ b/native/src/layout/node.rs @@ -1,16 +1,25 @@  use crate::{Align, Rectangle, Size}; +/// The bounds of an element and its children.  #[derive(Debug, Clone, Default)]  pub struct Node { -    pub bounds: Rectangle, +    pub(crate) bounds: Rectangle,      children: Vec<Node>,  }  impl Node { +    /// Creates a new [`Node`] with the given [`Size`]. +    /// +    /// [`Node`]: struct.Node.html +    /// [`Size`]: ../struct.Size.html      pub fn new(size: Size) -> Self {          Self::with_children(size, Vec::new())      } +    /// Creates a new [`Node`] with the given [`Size`] and children. +    /// +    /// [`Node`]: struct.Node.html +    /// [`Size`]: ../struct.Size.html      pub fn with_children(size: Size, children: Vec<Node>) -> Self {          Node {              bounds: Rectangle { @@ -23,19 +32,29 @@ impl Node {          }      } +    /// Returns the [`Size`] of the [`Node`]. +    /// +    /// [`Node`]: struct.Node.html +    /// [`Size`]: ../struct.Size.html      pub fn size(&self) -> Size {          Size::new(self.bounds.width, self.bounds.height)      } +    /// Returns the bounds of the [`Node`]. +    /// +    /// [`Node`]: struct.Node.html      pub fn bounds(&self) -> Rectangle {          self.bounds      } +    /// Returns the children of the [`Node`]. +    /// +    /// [`Node`]: struct.Node.html      pub fn children(&self) -> &[Node] {          &self.children      } -    pub fn align( +    pub(crate) fn align(          &mut self,          horizontal_alignment: Align,          vertical_alignment: Align,  | 
