diff options
Diffstat (limited to '')
| -rw-r--r-- | core/src/element.rs | 18 | ||||
| -rw-r--r-- | core/src/layout.rs | 106 | ||||
| -rw-r--r-- | core/src/layout/flex.rs | 117 | ||||
| -rw-r--r-- | core/src/layout/limits.rs | 88 | ||||
| -rw-r--r-- | core/src/layout/node.rs | 35 | ||||
| -rw-r--r-- | core/src/length.rs | 18 | ||||
| -rw-r--r-- | core/src/padding.rs | 6 | ||||
| -rw-r--r-- | core/src/point.rs | 20 | ||||
| -rw-r--r-- | core/src/size.rs | 24 | ||||
| -rw-r--r-- | core/src/widget.rs | 15 | ||||
| -rw-r--r-- | core/src/widget/text.rs | 58 | ||||
| -rw-r--r-- | core/src/window/event.rs | 2 | 
12 files changed, 350 insertions, 157 deletions
| diff --git a/core/src/element.rs b/core/src/element.rs index dea111af..8b510218 100644 --- a/core/src/element.rs +++ b/core/src/element.rs @@ -6,7 +6,7 @@ use crate::renderer;  use crate::widget;  use crate::widget::tree::{self, Tree};  use crate::{ -    Clipboard, Color, Layout, Length, Rectangle, Shell, Vector, Widget, +    Clipboard, Color, Layout, Length, Rectangle, Shell, Size, Vector, Widget,  };  use std::any::Any; @@ -296,12 +296,8 @@ where          self.widget.diff(tree);      } -    fn width(&self) -> Length { -        self.widget.width() -    } - -    fn height(&self) -> Length { -        self.widget.height() +    fn size(&self) -> Size<Length> { +        self.widget.size()      }      fn layout( @@ -466,12 +462,8 @@ impl<'a, Message, Renderer> Widget<Message, Renderer>  where      Renderer: crate::Renderer,  { -    fn width(&self) -> Length { -        self.element.widget.width() -    } - -    fn height(&self) -> Length { -        self.element.widget.height() +    fn size(&self) -> Size<Length> { +        self.element.widget.size()      }      fn tag(&self) -> tree::Tag { diff --git a/core/src/layout.rs b/core/src/layout.rs index caf315b6..95720aba 100644 --- a/core/src/layout.rs +++ b/core/src/layout.rs @@ -7,7 +7,7 @@ pub mod flex;  pub use limits::Limits;  pub use node::Node; -use crate::{Point, Rectangle, Size, Vector}; +use crate::{Length, Padding, Point, Rectangle, Size, Vector};  /// The bounds of a [`Node`] and its children, using absolute coordinates.  #[derive(Debug, Clone, Copy)] @@ -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,106 @@ 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)), +        ], +    ) +} + +/// Computes the resulting [`Node`] that fits the [`Limits`] given +/// some width and height requirements and no intrinsic size. +pub fn atomic( +    limits: &Limits, +    width: impl Into<Length>, +    height: impl Into<Length>, +) -> Node { +    let width = width.into(); +    let height = height.into(); + +    Node::new(limits.resolve(width, height, Size::ZERO)) +} + +/// Computes the resulting [`Node`] that fits the [`Limits`] given +/// some width and height requirements and a closure that produces +/// the intrinsic [`Size`] inside the given [`Limits`]. +pub fn sized( +    limits: &Limits, +    width: impl Into<Length>, +    height: impl Into<Length>, +    f: impl FnOnce(&Limits) -> Size, +) -> Node { +    let width = width.into(); +    let height = height.into(); + +    let limits = limits.width(width).height(height); +    let intrinsic_size = f(&limits); + +    Node::new(limits.resolve(width, height, intrinsic_size)) +} + +/// Computes the resulting [`Node`] that fits the [`Limits`] given +/// some width and height requirements and a closure that produces +/// the content [`Node`] inside the given [`Limits`]. +pub fn contained( +    limits: &Limits, +    width: impl Into<Length>, +    height: impl Into<Length>, +    f: impl FnOnce(&Limits) -> Node, +) -> Node { +    let width = width.into(); +    let height = height.into(); + +    let limits = limits.width(width).height(height); +    let content = f(&limits); + +    Node::with_children( +        limits.resolve(width, height, content.size()), +        vec![content], +    ) +} + +/// Computes the [`Node`] that fits the [`Limits`] given some width, height, and +/// [`Padding`] requirements and a closure that produces the content [`Node`] +/// inside the given [`Limits`]. +pub fn padded( +    limits: &Limits, +    width: impl Into<Length>, +    height: impl Into<Length>, +    padding: impl Into<Padding>, +    layout: impl FnOnce(&Limits) -> Node, +) -> Node { +    positioned(limits, width, height, padding, layout, |content, _| content) +} + +/// Computes a [`padded`] [`Node`] with a positioning step. +pub fn positioned( +    limits: &Limits, +    width: impl Into<Length>, +    height: impl Into<Length>, +    padding: impl Into<Padding>, +    layout: impl FnOnce(&Limits) -> Node, +    position: impl FnOnce(Node, Size) -> Node, +) -> Node { +    let width = width.into(); +    let height = height.into(); +    let padding = padding.into(); + +    let limits = limits.width(width).height(height); +    let content = layout(&limits.shrink(padding)); +    let padding = padding.fit(content.size(), limits.max()); + +    let size = limits +        .shrink(padding) +        .resolve(width, height, content.size()); + +    Node::with_children( +        size.expand(padding), +        vec![position(content.move_to((padding.left, padding.top)), size)],      )  } diff --git a/core/src/layout/flex.rs b/core/src/layout/flex.rs index c02b63d8..3358ef3d 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)] @@ -47,7 +47,7 @@ impl Axis {          }      } -    fn pack(&self, main: f32, cross: f32) -> (f32, f32) { +    fn pack<T>(&self, main: T, cross: T) -> (T, T) {          match self {              Axis::Horizontal => (main, cross),              Axis::Vertical => (cross, main), @@ -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,26 +74,64 @@ 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 fill_main_sum = 0; +    let mut cross = match axis { +        Axis::Horizontal => match height { +            Length::Shrink => 0.0, +            _ => max_cross, +        }, +        Axis::Vertical => match width { +            Length::Shrink => 0.0, +            _ => max_cross, +        }, +    }; +      let mut available = axis.main(limits.max()) - total_spacing;      let mut nodes: Vec<Node> = Vec::with_capacity(items.len());      nodes.resize(items.len(), Node::default());      for (i, (child, tree)) in items.iter().zip(trees.iter_mut()).enumerate() { -        let fill_factor = match axis { -            Axis::Horizontal => child.as_widget().width(), -            Axis::Vertical => child.as_widget().height(), +        let (fill_main_factor, fill_cross_factor) = { +            let size = child.as_widget().size(); + +            axis.pack(size.width.fill_factor(), size.height.fill_factor()) +        }; + +        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;          } -        .fill_factor(); +    } -        if fill_factor == 0 { -            let (max_width, max_height) = axis.pack(available, max_cross); +    for (i, (child, tree)) in items.iter().zip(trees.iter_mut()).enumerate() { +        let (fill_main_factor, fill_cross_factor) = { +            let size = child.as_widget().size(); + +            axis.pack(size.width.fill_factor(), size.height.fill_factor()) +        }; + +        if fill_main_factor == 0 && fill_cross_factor != 0 { +            let (max_width, max_height) = axis.pack(available, cross);              let child_limits =                  Limits::new(Size::ZERO, Size::new(max_width, max_height)); @@ -101,34 +141,47 @@ where              let size = layout.size();              available -= axis.main(size); -            cross = cross.max(axis.cross(size)); +            cross = cross.max(axis.cross(layout.size()));              nodes[i] = layout; -        } else { -            fill_sum += fill_factor;          }      } -    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 { -            Axis::Horizontal => child.as_widget().width(), -            Axis::Vertical => child.as_widget().height(), -        } -        .fill_factor(); +        let (fill_main_factor, fill_cross_factor) = { +            let size = child.as_widget().size(); + +            axis.pack(size.width.fill_factor(), size.height.fill_factor()) +        }; + +        if fill_main_factor != 0 { +            let max_main = +                remaining * fill_main_factor as f32 / fill_main_sum as f32; -        if fill_factor != 0 { -            let max_main = remaining * fill_factor as f32 / fill_sum as f32;              let min_main = if max_main.is_infinite() {                  0.0              } else {                  max_main              }; -            let (min_width, min_height) = -                axis.pack(min_main, axis.cross(limits.min())); +            let max_cross = if fill_cross_factor == 0 { +                max_cross +            } else { +                cross +            }; +            let (min_width, min_height) = axis.pack(min_main, 0.0);              let (max_width, max_height) = axis.pack(max_main, max_cross);              let child_limits = Limits::new( @@ -154,18 +207,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), @@ -178,8 +231,12 @@ where          main += axis.main(size);      } -    let (width, height) = axis.pack(main - pad.0, cross); -    let size = limits.resolve(Size::new(width, height)); +    let (intrinsic_width, intrinsic_height) = axis.pack(main - pad.0, cross); +    let size = limits.resolve( +        width, +        height, +        Size::new(intrinsic_width, intrinsic_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..7fbc7b9d 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,39 @@ 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 +    /// Computes the resulting [`Size`] that fits the [`Limits`] given +    /// some width and height requirements and the intrinsic size of +    /// some content. +    pub fn resolve( +        &self, +        width: impl Into<Length>, +        height: impl Into<Length>, +        intrinsic_size: Size, +    ) -> 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..5743a9bd 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 [`Self::align`]. +    pub fn align_mut(          &mut self,          horizontal_alignment: Alignment,          vertical_alignment: Alignment, @@ -70,13 +89,23 @@ impl Node {      }      /// Moves the [`Node`] to the given position. -    pub fn move_to(&mut self, position: Point) { +    pub fn move_to(mut self, position: impl Into<Point>) -> Self { +        self.move_to_mut(position); +        self +    } + +    /// Mutable reference version of [`Self::move_to`]. +    pub fn move_to_mut(&mut self, position: impl Into<Point>) { +        let position = position.into(); +          self.bounds.x = position.x;          self.bounds.y = position.y;      }      /// Translates the [`Node`] by the given translation. -    pub fn translate(self, translation: Vector) -> Self { +    pub fn translate(self, translation: impl Into<Vector>) -> Self { +        let translation = translation.into(); +          Self {              bounds: self.bounds + translation,              ..self diff --git a/core/src/length.rs b/core/src/length.rs index 3adb996e..4c139895 100644 --- a/core/src/length.rs +++ b/core/src/length.rs @@ -36,6 +36,24 @@ 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 +    } + +    /// Returns the "fluid" variant of the [`Length`]. +    /// +    /// Specifically: +    /// - [`Length::Shrink`] if [`Length::Shrink`] or [`Length::Fixed`]. +    /// - [`Length::Fill`] otherwise. +    pub fn fluid(&self) -> Length { +        match self { +            Length::Fill | Length::FillPortion(_) => Length::Fill, +            Length::Shrink | Length::Fixed(_) => Length::Shrink, +        } +    }  }  impl From<Pixels> for Length { 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/point.rs b/core/src/point.rs index ef42852f..cea57518 100644 --- a/core/src/point.rs +++ b/core/src/point.rs @@ -36,20 +36,26 @@ impl<T: Num> Point<T> {      }  } -impl From<[f32; 2]> for Point { -    fn from([x, y]: [f32; 2]) -> Self { +impl<T> From<[T; 2]> for Point<T> +where +    T: Num, +{ +    fn from([x, y]: [T; 2]) -> Self {          Point { x, y }      }  } -impl From<[u16; 2]> for Point<u16> { -    fn from([x, y]: [u16; 2]) -> Self { -        Point::new(x, y) +impl<T> From<(T, T)> for Point<T> +where +    T: Num, +{ +    fn from((x, y): (T, T)) -> Self { +        Self { x, y }      }  } -impl From<Point> for [f32; 2] { -    fn from(point: Point) -> [f32; 2] { +impl<T> From<Point<T>> for [T; 2] { +    fn from(point: Point<T>) -> [T; 2] {          [point.x, point.y]      }  } 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.rs b/core/src/widget.rs index 294d5984..7f5632ae 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.  /// @@ -43,11 +43,16 @@ pub trait Widget<Message, Renderer>  where      Renderer: crate::Renderer,  { -    /// Returns the width of the [`Widget`]. -    fn width(&self) -> Length; +    /// Returns the [`Size`] of the [`Widget`] in lengths. +    fn size(&self) -> Size<Length>; -    /// 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> { +        self.size() +    }      /// Returns the [`layout::Node`] of the [`Widget`].      /// diff --git a/core/src/widget/text.rs b/core/src/widget/text.rs index e020b030..4cabc7ce 100644 --- a/core/src/widget/text.rs +++ b/core/src/widget/text.rs @@ -5,7 +5,9 @@ use crate::mouse;  use crate::renderer;  use crate::text::{self, Paragraph};  use crate::widget::tree::{self, Tree}; -use crate::{Color, Element, Layout, Length, Pixels, Point, Rectangle, Widget}; +use crate::{ +    Color, Element, Layout, Length, Pixels, Point, Rectangle, Size, Widget, +};  use std::borrow::Cow; @@ -134,12 +136,11 @@ where          tree::State::new(State(Renderer::Paragraph::default()))      } -    fn width(&self) -> Length { -        self.width -    } - -    fn height(&self) -> Length { -        self.height +    fn size(&self) -> Size<Length> { +        Size { +            width: self.width, +            height: self.height, +        }      }      fn layout( @@ -205,28 +206,27 @@ pub fn layout<Renderer>(  where      Renderer: text::Renderer,  { -    let limits = limits.width(width).height(height); -    let bounds = limits.max(); - -    let size = size.unwrap_or_else(|| renderer.default_size()); -    let font = font.unwrap_or_else(|| renderer.default_font()); - -    let State(ref mut paragraph) = state; - -    paragraph.update(text::Text { -        content, -        bounds, -        size, -        line_height, -        font, -        horizontal_alignment, -        vertical_alignment, -        shaping, -    }); - -    let size = limits.resolve(paragraph.min_bounds()); - -    layout::Node::new(size) +    layout::sized(limits, width, height, |limits| { +        let bounds = limits.max(); + +        let size = size.unwrap_or_else(|| renderer.default_size()); +        let font = font.unwrap_or_else(|| renderer.default_font()); + +        let State(ref mut paragraph) = state; + +        paragraph.update(text::Text { +            content, +            bounds, +            size, +            line_height, +            font, +            horizontal_alignment, +            vertical_alignment, +            shaping, +        }); + +        paragraph.min_bounds() +    })  }  /// Draws text using the same logic as the [`Text`] widget. diff --git a/core/src/window/event.rs b/core/src/window/event.rs index b9ee7aca..a14d127f 100644 --- a/core/src/window/event.rs +++ b/core/src/window/event.rs @@ -58,7 +58,7 @@ pub enum Event {      /// for each file separately.      FileHovered(PathBuf), -    /// A file has beend dropped into the window. +    /// A file has been dropped into the window.      ///      /// When the user drops multiple files at once, this event will be emitted      /// for each file separately. | 
