diff options
Diffstat (limited to '')
64 files changed, 805 insertions, 658 deletions
diff --git a/core/src/alignment.rs b/core/src/alignment.rs index 51b7fca9..8f01ef71 100644 --- a/core/src/alignment.rs +++ b/core/src/alignment.rs @@ -46,6 +46,16 @@ pub enum Horizontal {      Right,  } +impl From<Alignment> for Horizontal { +    fn from(alignment: Alignment) -> Self { +        match alignment { +            Alignment::Start => Self::Left, +            Alignment::Center => Self::Center, +            Alignment::End => Self::Right, +        } +    } +} +  /// The vertical [`Alignment`] of some resource.  #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]  pub enum Vertical { @@ -58,3 +68,13 @@ pub enum Vertical {      /// Align bottom      Bottom,  } + +impl From<Alignment> for Vertical { +    fn from(alignment: Alignment) -> Self { +        match alignment { +            Alignment::Start => Self::Top, +            Alignment::Center => Self::Center, +            Alignment::End => Self::Bottom, +        } +    } +} diff --git a/core/src/border.rs b/core/src/border.rs index 2df24988..da0aaa28 100644 --- a/core/src/border.rs +++ b/core/src/border.rs @@ -10,40 +10,64 @@ pub struct Border {      /// The width of the border.      pub width: f32, -    /// The radius of the border. +    /// The [`Radius`] of the border.      pub radius: Radius,  } +/// Creates a new [`Border`] with the given [`Radius`]. +/// +/// ``` +/// # use iced_core::border::{self, Border}; +/// # +/// assert_eq!(border::rounded(10), Border::default().rounded(10)); +/// ``` +pub fn rounded(radius: impl Into<Radius>) -> Border { +    Border::default().rounded(radius) +} + +/// Creates a new [`Border`] with the given [`Color`]. +/// +/// ``` +/// # use iced_core::border::{self, Border}; +/// # use iced_core::Color; +/// # +/// assert_eq!(border::color(Color::BLACK), Border::default().color(Color::BLACK)); +/// ``` +pub fn color(color: impl Into<Color>) -> Border { +    Border::default().color(color) +} + +/// Creates a new [`Border`] with the given `width`. +/// +/// ``` +/// # use iced_core::border::{self, Border}; +/// # use iced_core::Color; +/// # +/// assert_eq!(border::width(10), Border::default().width(10)); +/// ``` +pub fn width(width: impl Into<Pixels>) -> Border { +    Border::default().width(width) +} +  impl Border { -    /// Creates a new default rounded [`Border`] with the given [`Radius`]. -    /// -    /// ``` -    /// # use iced_core::Border; -    /// # -    /// assert_eq!(Border::rounded(10), Border::default().with_radius(10)); -    /// ``` -    pub fn rounded(radius: impl Into<Radius>) -> Self { -        Self::default().with_radius(radius) -    } - -    /// Updates the [`Color`] of the [`Border`]. -    pub fn with_color(self, color: impl Into<Color>) -> Self { +    /// Sets the [`Color`] of the [`Border`]. +    pub fn color(self, color: impl Into<Color>) -> Self {          Self {              color: color.into(),              ..self          }      } -    /// Updates the [`Radius`] of the [`Border`]. -    pub fn with_radius(self, radius: impl Into<Radius>) -> Self { +    /// Sets the [`Radius`] of the [`Border`]. +    pub fn rounded(self, radius: impl Into<Radius>) -> Self {          Self {              radius: radius.into(),              ..self          }      } -    /// Updates the width of the [`Border`]. -    pub fn with_width(self, width: impl Into<Pixels>) -> Self { +    /// Sets the width of the [`Border`]. +    pub fn width(self, width: impl Into<Pixels>) -> Self {          Self {              width: width.into().0,              ..self @@ -54,11 +78,160 @@ impl Border {  /// The border radii for the corners of a graphics primitive in the order:  /// top-left, top-right, bottom-right, bottom-left.  #[derive(Debug, Clone, Copy, PartialEq, Default)] -pub struct Radius([f32; 4]); +pub struct Radius { +    /// Top left radius +    pub top_left: f32, +    /// Top right radius +    pub top_right: f32, +    /// Bottom right radius +    pub bottom_right: f32, +    /// Bottom left radius +    pub bottom_left: f32, +} + +/// Creates a new [`Radius`] with the same value for each corner. +pub fn radius(value: impl Into<Pixels>) -> Radius { +    Radius::new(value) +} + +/// Creates a new [`Radius`] with the given top left value. +pub fn top_left(value: impl Into<Pixels>) -> Radius { +    Radius::default().top_left(value) +} + +/// Creates a new [`Radius`] with the given top right value. +pub fn top_right(value: impl Into<Pixels>) -> Radius { +    Radius::default().top_right(value) +} + +/// Creates a new [`Radius`] with the given bottom right value. +pub fn bottom_right(value: impl Into<Pixels>) -> Radius { +    Radius::default().bottom_right(value) +} + +/// Creates a new [`Radius`] with the given bottom left value. +pub fn bottom_left(value: impl Into<Pixels>) -> Radius { +    Radius::default().bottom_left(value) +} + +/// Creates a new [`Radius`] with the given value as top left and top right. +pub fn top(value: impl Into<Pixels>) -> Radius { +    Radius::default().top(value) +} + +/// Creates a new [`Radius`] with the given value as bottom left and bottom right. +pub fn bottom(value: impl Into<Pixels>) -> Radius { +    Radius::default().bottom(value) +} + +/// Creates a new [`Radius`] with the given value as top left and bottom left. +pub fn left(value: impl Into<Pixels>) -> Radius { +    Radius::default().left(value) +} + +/// Creates a new [`Radius`] with the given value as top right and bottom right. +pub fn right(value: impl Into<Pixels>) -> Radius { +    Radius::default().right(value) +} + +impl Radius { +    /// Creates a new [`Radius`] with the same value for each corner. +    pub fn new(value: impl Into<Pixels>) -> Self { +        let value = value.into().0; + +        Self { +            top_left: value, +            top_right: value, +            bottom_right: value, +            bottom_left: value, +        } +    } + +    /// Sets the top left value of the [`Radius`]. +    pub fn top_left(self, value: impl Into<Pixels>) -> Self { +        Self { +            top_left: value.into().0, +            ..self +        } +    } + +    /// Sets the top right value of the [`Radius`]. +    pub fn top_right(self, value: impl Into<Pixels>) -> Self { +        Self { +            top_right: value.into().0, +            ..self +        } +    } + +    /// Sets the bottom right value of the [`Radius`]. +    pub fn bottom_right(self, value: impl Into<Pixels>) -> Self { +        Self { +            bottom_right: value.into().0, +            ..self +        } +    } + +    /// Sets the bottom left value of the [`Radius`]. +    pub fn bottom_left(self, value: impl Into<Pixels>) -> Self { +        Self { +            bottom_left: value.into().0, +            ..self +        } +    } + +    /// Sets the top left and top right values of the [`Radius`]. +    pub fn top(self, value: impl Into<Pixels>) -> Self { +        let value = value.into().0; + +        Self { +            top_left: value, +            top_right: value, +            ..self +        } +    } + +    /// Sets the bottom left and bottom right values of the [`Radius`]. +    pub fn bottom(self, value: impl Into<Pixels>) -> Self { +        let value = value.into().0; + +        Self { +            bottom_left: value, +            bottom_right: value, +            ..self +        } +    } + +    /// Sets the top left and bottom left values of the [`Radius`]. +    pub fn left(self, value: impl Into<Pixels>) -> Self { +        let value = value.into().0; + +        Self { +            top_left: value, +            bottom_left: value, +            ..self +        } +    } + +    /// Sets the top right and bottom right values of the [`Radius`]. +    pub fn right(self, value: impl Into<Pixels>) -> Self { +        let value = value.into().0; + +        Self { +            top_right: value, +            bottom_right: value, +            ..self +        } +    } +}  impl From<f32> for Radius { -    fn from(w: f32) -> Self { -        Self([w; 4]) +    fn from(radius: f32) -> Self { +        Self { +            top_left: radius, +            top_right: radius, +            bottom_right: radius, +            bottom_left: radius, +        }      }  } @@ -80,14 +253,13 @@ impl From<i32> for Radius {      }  } -impl From<[f32; 4]> for Radius { -    fn from(radi: [f32; 4]) -> Self { -        Self(radi) -    } -} -  impl From<Radius> for [f32; 4] {      fn from(radi: Radius) -> Self { -        radi.0 +        [ +            radi.top_left, +            radi.top_right, +            radi.bottom_right, +            radi.bottom_left, +        ]      }  } diff --git a/core/src/border_radius.rs b/core/src/border_radius.rs deleted file mode 100644 index a444dd74..00000000 --- a/core/src/border_radius.rs +++ /dev/null @@ -1,22 +0,0 @@ -/// The border radii for the corners of a graphics primitive in the order: -/// top-left, top-right, bottom-right, bottom-left. -#[derive(Debug, Clone, Copy, PartialEq, Default)] -pub struct BorderRadius([f32; 4]); - -impl From<f32> for BorderRadius { -    fn from(w: f32) -> Self { -        Self([w; 4]) -    } -} - -impl From<[f32; 4]> for BorderRadius { -    fn from(radi: [f32; 4]) -> Self { -        Self(radi) -    } -} - -impl From<BorderRadius> for [f32; 4] { -    fn from(radi: BorderRadius) -> Self { -        radi.0 -    } -} diff --git a/core/src/lib.rs b/core/src/lib.rs index 32156441..40a288e5 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -20,6 +20,7 @@ pub mod keyboard;  pub mod layout;  pub mod mouse;  pub mod overlay; +pub mod padding;  pub mod renderer;  pub mod svg;  pub mod text; @@ -35,7 +36,6 @@ mod color;  mod content_fit;  mod element;  mod length; -mod padding;  mod pixels;  mod point;  mod rectangle; diff --git a/core/src/padding.rs b/core/src/padding.rs index b8c941d8..fdaa0236 100644 --- a/core/src/padding.rs +++ b/core/src/padding.rs @@ -1,3 +1,4 @@ +//! Space stuff around the perimeter.  use crate::{Pixels, Size};  /// An amount of space to pad for each side of a box @@ -9,7 +10,6 @@ use crate::{Pixels, Size};  /// #  /// let padding = Padding::from(20);              // 20px on all sides  /// let padding = Padding::from([10, 20]);        // top/bottom, left/right -/// let padding = Padding::from([5, 10, 15, 20]); // top, right, bottom, left  /// ```  ///  /// Normally, the `padding` method of a widget will ask for an `Into<Padding>`, @@ -31,9 +31,8 @@ use crate::{Pixels, Size};  ///  /// let widget = Widget::new().padding(20);              // 20px on all sides  /// let widget = Widget::new().padding([10, 20]);        // top/bottom, left/right -/// let widget = Widget::new().padding([5, 10, 15, 20]); // top, right, bottom, left  /// ``` -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, Default)]  pub struct Padding {      /// Top padding      pub top: f32, @@ -45,6 +44,31 @@ pub struct Padding {      pub left: f32,  } +/// Create a [`Padding`] that is equal on all sides. +pub fn all(padding: impl Into<Pixels>) -> Padding { +    Padding::new(padding.into().0) +} + +/// Create some top [`Padding`]. +pub fn top(padding: impl Into<Pixels>) -> Padding { +    Padding::default().top(padding) +} + +/// Create some bottom [`Padding`]. +pub fn bottom(padding: impl Into<Pixels>) -> Padding { +    Padding::default().bottom(padding) +} + +/// Create some left [`Padding`]. +pub fn left(padding: impl Into<Pixels>) -> Padding { +    Padding::default().left(padding) +} + +/// Create some right [`Padding`]. +pub fn right(padding: impl Into<Pixels>) -> Padding { +    Padding::default().right(padding) +} +  impl Padding {      /// Padding of zero      pub const ZERO: Padding = Padding { @@ -64,35 +88,43 @@ impl Padding {          }      } -    /// Create some top [`Padding`]. -    pub fn top(padding: impl Into<Pixels>) -> Self { +    /// Sets the [`top`] of the [`Padding`]. +    /// +    /// [`top`]: Self::top +    pub fn top(self, top: impl Into<Pixels>) -> Self {          Self { -            top: padding.into().0, -            ..Self::ZERO +            top: top.into().0, +            ..self          }      } -    /// Create some right [`Padding`]. -    pub fn right(padding: impl Into<Pixels>) -> Self { +    /// Sets the [`bottom`] of the [`Padding`]. +    /// +    /// [`bottom`]: Self::bottom +    pub fn bottom(self, bottom: impl Into<Pixels>) -> Self {          Self { -            right: padding.into().0, -            ..Self::ZERO +            bottom: bottom.into().0, +            ..self          }      } -    /// Create some bottom [`Padding`]. -    pub fn bottom(padding: impl Into<Pixels>) -> Self { +    /// Sets the [`left`] of the [`Padding`]. +    /// +    /// [`left`]: Self::left +    pub fn left(self, left: impl Into<Pixels>) -> Self {          Self { -            bottom: padding.into().0, -            ..Self::ZERO +            left: left.into().0, +            ..self          }      } -    /// Create some left [`Padding`]. -    pub fn left(padding: impl Into<Pixels>) -> Self { +    /// Sets the [`right`] of the [`Padding`]. +    /// +    /// [`right`]: Self::right +    pub fn right(self, right: impl Into<Pixels>) -> Self {          Self { -            left: padding.into().0, -            ..Self::ZERO +            right: right.into().0, +            ..self          }      } @@ -143,17 +175,6 @@ impl From<[u16; 2]> for Padding {      }  } -impl From<[u16; 4]> for Padding { -    fn from(p: [u16; 4]) -> Self { -        Padding { -            top: f32::from(p[0]), -            right: f32::from(p[1]), -            bottom: f32::from(p[2]), -            left: f32::from(p[3]), -        } -    } -} -  impl From<f32> for Padding {      fn from(p: f32) -> Self {          Padding { @@ -176,17 +197,6 @@ impl From<[f32; 2]> for Padding {      }  } -impl From<[f32; 4]> for Padding { -    fn from(p: [f32; 4]) -> Self { -        Padding { -            top: p[0], -            right: p[1], -            bottom: p[2], -            left: p[3], -        } -    } -} -  impl From<Padding> for Size {      fn from(padding: Padding) -> Self {          Self::new(padding.horizontal(), padding.vertical()) diff --git a/core/src/pixels.rs b/core/src/pixels.rs index 425c0028..f5550a10 100644 --- a/core/src/pixels.rs +++ b/core/src/pixels.rs @@ -6,7 +6,7 @@  /// (e.g. `impl Into<Pixels>`) and, since `Pixels` implements `From` both for  /// `f32` and `u16`, you should be able to provide both integers and float  /// literals as needed. -#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] +#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Default)]  pub struct Pixels(pub f32);  impl From<f32> for Pixels { @@ -27,6 +27,30 @@ impl From<Pixels> for f32 {      }  } +impl std::ops::Add for Pixels { +    type Output = Pixels; + +    fn add(self, rhs: Self) -> Self { +        Pixels(self.0 + rhs.0) +    } +} + +impl std::ops::Add<f32> for Pixels { +    type Output = Pixels; + +    fn add(self, rhs: f32) -> Self { +        Pixels(self.0 + rhs) +    } +} + +impl std::ops::Mul for Pixels { +    type Output = Pixels; + +    fn mul(self, rhs: Self) -> Self { +        Pixels(self.0 * rhs.0) +    } +} +  impl std::ops::Mul<f32> for Pixels {      type Output = Pixels; diff --git a/core/src/widget/text.rs b/core/src/widget/text.rs index 081407e5..990c5567 100644 --- a/core/src/widget/text.rs +++ b/core/src/widget/text.rs @@ -86,21 +86,27 @@ where          self      } +    /// Centers the [`Text`], both horizontally and vertically. +    pub fn center(self) -> Self { +        self.align_x(alignment::Horizontal::Center) +            .align_y(alignment::Vertical::Center) +    } +      /// Sets the [`alignment::Horizontal`] of the [`Text`]. -    pub fn horizontal_alignment( +    pub fn align_x(          mut self, -        alignment: alignment::Horizontal, +        alignment: impl Into<alignment::Horizontal>,      ) -> Self { -        self.horizontal_alignment = alignment; +        self.horizontal_alignment = alignment.into();          self      }      /// Sets the [`alignment::Vertical`] of the [`Text`]. -    pub fn vertical_alignment( +    pub fn align_y(          mut self, -        alignment: alignment::Vertical, +        alignment: impl Into<alignment::Vertical>,      ) -> Self { -        self.vertical_alignment = alignment; +        self.vertical_alignment = alignment.into();          self      } diff --git a/examples/arc/src/main.rs b/examples/arc/src/main.rs index b1e8402a..18873259 100644 --- a/examples/arc/src/main.rs +++ b/examples/arc/src/main.rs @@ -4,7 +4,7 @@ use iced::mouse;  use iced::widget::canvas::{      self, stroke, Cache, Canvas, Geometry, Path, Stroke,  }; -use iced::{Element, Length, Point, Rectangle, Renderer, Subscription, Theme}; +use iced::{Element, Fill, Point, Rectangle, Renderer, Subscription, Theme};  pub fn main() -> iced::Result {      iced::application("Arc - Iced", Arc::update, Arc::view) @@ -30,10 +30,7 @@ impl Arc {      }      fn view(&self) -> Element<Message> { -        Canvas::new(self) -            .width(Length::Fill) -            .height(Length::Fill) -            .into() +        Canvas::new(self).width(Fill).height(Fill).into()      }      fn subscription(&self) -> Subscription<Message> { diff --git a/examples/bezier_tool/src/main.rs b/examples/bezier_tool/src/main.rs index eaf84b97..949bfad7 100644 --- a/examples/bezier_tool/src/main.rs +++ b/examples/bezier_tool/src/main.rs @@ -1,7 +1,6 @@  //! This example showcases an interactive `Canvas` for drawing Bézier curves. -use iced::alignment;  use iced::widget::{button, container, horizontal_space, hover}; -use iced::{Element, Length, Theme}; +use iced::{Element, Fill, Theme};  pub fn main() -> iced::Result {      iced::application("Bezier Tool - Iced", Example::update, Example::view) @@ -48,8 +47,7 @@ impl Example {                          .on_press(Message::Clear),                  )                  .padding(10) -                .width(Length::Fill) -                .align_x(alignment::Horizontal::Right) +                .align_right(Fill)              },          ))          .padding(20) @@ -61,7 +59,7 @@ mod bezier {      use iced::mouse;      use iced::widget::canvas::event::{self, Event};      use iced::widget::canvas::{self, Canvas, Frame, Geometry, Path, Stroke}; -    use iced::{Element, Length, Point, Rectangle, Renderer, Theme}; +    use iced::{Element, Fill, Point, Rectangle, Renderer, Theme};      #[derive(Default)]      pub struct State { @@ -74,8 +72,8 @@ mod bezier {                  state: self,                  curves,              }) -            .width(Length::Fill) -            .height(Length::Fill) +            .width(Fill) +            .height(Fill)              .into()          } diff --git a/examples/clock/src/main.rs b/examples/clock/src/main.rs index 4584a0c7..ef3064c7 100644 --- a/examples/clock/src/main.rs +++ b/examples/clock/src/main.rs @@ -4,7 +4,7 @@ use iced::time;  use iced::widget::canvas::{stroke, Cache, Geometry, LineCap, Path, Stroke};  use iced::widget::{canvas, container};  use iced::{ -    Degrees, Element, Font, Length, Point, Rectangle, Renderer, Subscription, +    Degrees, Element, Fill, Font, Point, Rectangle, Renderer, Subscription,      Theme, Vector,  }; @@ -43,15 +43,9 @@ impl Clock {      }      fn view(&self) -> Element<Message> { -        let canvas = canvas(self as &Self) -            .width(Length::Fill) -            .height(Length::Fill); - -        container(canvas) -            .width(Length::Fill) -            .height(Length::Fill) -            .padding(20) -            .into() +        let canvas = canvas(self as &Self).width(Fill).height(Fill); + +        container(canvas).padding(20).into()      }      fn subscription(&self) -> Subscription<Message> { diff --git a/examples/color_palette/src/main.rs b/examples/color_palette/src/main.rs index e4b19731..7f21003b 100644 --- a/examples/color_palette/src/main.rs +++ b/examples/color_palette/src/main.rs @@ -1,10 +1,10 @@ -use iced::alignment::{self, Alignment}; +use iced::alignment;  use iced::mouse;  use iced::widget::canvas::{self, Canvas, Frame, Geometry, Path};  use iced::widget::{column, row, text, Slider};  use iced::{ -    Color, Element, Font, Length, Pixels, Point, Rectangle, Renderer, Size, -    Vector, +    Center, Color, Element, Fill, Font, Pixels, Point, Rectangle, Renderer, +    Size, Vector,  };  use palette::{convert::FromColor, rgb::Rgb, Darken, Hsl, Lighten, ShiftHue};  use std::marker::PhantomData; @@ -150,10 +150,7 @@ impl Theme {      }      pub fn view(&self) -> Element<Message> { -        Canvas::new(self) -            .width(Length::Fill) -            .height(Length::Fill) -            .into() +        Canvas::new(self).width(Fill).height(Fill).into()      }      fn draw(&self, frame: &mut Frame, text_color: Color) { @@ -320,7 +317,7 @@ impl<C: ColorSpace + Copy> ColorPicker<C> {              text(color.to_string()).width(185).size(12),          ]          .spacing(10) -        .align_items(Alignment::Center) +        .align_y(Center)          .into()      }  } diff --git a/examples/combo_box/src/main.rs b/examples/combo_box/src/main.rs index ff759ab4..af53b17a 100644 --- a/examples/combo_box/src/main.rs +++ b/examples/combo_box/src/main.rs @@ -1,7 +1,7 @@  use iced::widget::{      center, column, combo_box, scrollable, text, vertical_space,  }; -use iced::{Alignment, Element, Length}; +use iced::{Center, Element, Fill};  pub fn main() -> iced::Result {      iced::run("Combo Box - Iced", Example::update, Example::view) @@ -64,8 +64,8 @@ impl Example {              combo_box,              vertical_space().height(150),          ] -        .width(Length::Fill) -        .align_items(Alignment::Center) +        .width(Fill) +        .align_x(Center)          .spacing(10);          center(scrollable(content)).into() diff --git a/examples/component/src/main.rs b/examples/component/src/main.rs index 5625f12a..a5d2e508 100644 --- a/examples/component/src/main.rs +++ b/examples/component/src/main.rs @@ -34,9 +34,8 @@ impl Component {  }  mod numeric_input { -    use iced::alignment::{self, Alignment};      use iced::widget::{button, component, row, text, text_input, Component}; -    use iced::{Element, Length, Size}; +    use iced::{Center, Element, Fill, Length, Size};      pub struct NumericInput<Message> {          value: Option<u32>, @@ -104,16 +103,10 @@ mod numeric_input {          fn view(&self, _state: &Self::State) -> Element<'_, Event, Theme> {              let button = |label, on_press| { -                button( -                    text(label) -                        .width(Length::Fill) -                        .height(Length::Fill) -                        .horizontal_alignment(alignment::Horizontal::Center) -                        .vertical_alignment(alignment::Vertical::Center), -                ) -                .width(40) -                .height(40) -                .on_press(on_press) +                button(text(label).width(Fill).height(Fill).center()) +                    .width(40) +                    .height(40) +                    .on_press(on_press)              };              row![ @@ -130,7 +123,7 @@ mod numeric_input {                  .padding(10),                  button("+", Event::IncrementPressed),              ] -            .align_items(Alignment::Center) +            .align_y(Center)              .spacing(10)              .into()          } diff --git a/examples/counter/src/main.rs b/examples/counter/src/main.rs index 0dd7a976..81684c1c 100644 --- a/examples/counter/src/main.rs +++ b/examples/counter/src/main.rs @@ -1,5 +1,5 @@  use iced::widget::{button, column, text, Column}; -use iced::Alignment; +use iced::Center;  pub fn main() -> iced::Result {      iced::run("A cool counter", Counter::update, Counter::view) @@ -35,6 +35,6 @@ impl Counter {              button("Decrement").on_press(Message::Decrement)          ]          .padding(20) -        .align_items(Alignment::Center) +        .align_x(Center)      }  } diff --git a/examples/custom_quad/src/main.rs b/examples/custom_quad/src/main.rs index b53a40d6..dc425cc6 100644 --- a/examples/custom_quad/src/main.rs +++ b/examples/custom_quad/src/main.rs @@ -3,12 +3,13 @@ mod quad {      use iced::advanced::layout::{self, Layout};      use iced::advanced::renderer;      use iced::advanced::widget::{self, Widget}; +    use iced::border;      use iced::mouse;      use iced::{Border, Color, Element, Length, Rectangle, Shadow, Size};      pub struct CustomQuad {          size: f32, -        radius: [f32; 4], +        radius: border::Radius,          border_width: f32,          shadow: Shadow,      } @@ -16,7 +17,7 @@ mod quad {      impl CustomQuad {          pub fn new(              size: f32, -            radius: [f32; 4], +            radius: border::Radius,              border_width: f32,              shadow: Shadow,          ) -> Self { @@ -63,7 +64,7 @@ mod quad {                  renderer::Quad {                      bounds: layout.bounds(),                      border: Border { -                        radius: self.radius.into(), +                        radius: self.radius,                          width: self.border_width,                          color: Color::from_rgb(1.0, 0.0, 0.0),                      }, @@ -81,15 +82,16 @@ mod quad {      }  } +use iced::border;  use iced::widget::{center, column, slider, text}; -use iced::{Alignment, Color, Element, Shadow, Vector}; +use iced::{Center, Color, Element, Shadow, Vector};  pub fn main() -> iced::Result {      iced::run("Custom Quad - Iced", Example::update, Example::view)  }  struct Example { -    radius: [f32; 4], +    radius: border::Radius,      border_width: f32,      shadow: Shadow,  } @@ -110,7 +112,7 @@ enum Message {  impl Example {      fn new() -> Self {          Self { -            radius: [50.0; 4], +            radius: border::radius(50),              border_width: 0.0,              shadow: Shadow {                  color: Color::from_rgba(0.0, 0.0, 0.0, 0.8), @@ -121,19 +123,18 @@ impl Example {      }      fn update(&mut self, message: Message) { -        let [tl, tr, br, bl] = self.radius;          match message {              Message::RadiusTopLeftChanged(radius) => { -                self.radius = [radius, tr, br, bl]; +                self.radius = self.radius.top_left(radius);              }              Message::RadiusTopRightChanged(radius) => { -                self.radius = [tl, radius, br, bl]; +                self.radius = self.radius.top_right(radius);              }              Message::RadiusBottomRightChanged(radius) => { -                self.radius = [tl, tr, radius, bl]; +                self.radius = self.radius.bottom_right(radius);              }              Message::RadiusBottomLeftChanged(radius) => { -                self.radius = [tl, tr, br, radius]; +                self.radius = self.radius.bottom_left(radius);              }              Message::BorderWidthChanged(width) => {                  self.border_width = width; @@ -151,7 +152,13 @@ impl Example {      }      fn view(&self) -> Element<Message> { -        let [tl, tr, br, bl] = self.radius; +        let border::Radius { +            top_left, +            top_right, +            bottom_right, +            bottom_left, +        } = self.radius; +          let Shadow {              offset: Vector { x: sx, y: sy },              blur_radius: sr, @@ -165,12 +172,12 @@ impl Example {                  self.border_width,                  self.shadow              ), -            text!("Radius: {tl:.2}/{tr:.2}/{br:.2}/{bl:.2}"), -            slider(1.0..=100.0, tl, Message::RadiusTopLeftChanged).step(0.01), -            slider(1.0..=100.0, tr, Message::RadiusTopRightChanged).step(0.01), -            slider(1.0..=100.0, br, Message::RadiusBottomRightChanged) +            text!("Radius: {top_left:.2}/{top_right:.2}/{bottom_right:.2}/{bottom_left:.2}"), +            slider(1.0..=100.0, top_left, Message::RadiusTopLeftChanged).step(0.01), +            slider(1.0..=100.0, top_right, Message::RadiusTopRightChanged).step(0.01), +            slider(1.0..=100.0, bottom_right, Message::RadiusBottomRightChanged)                  .step(0.01), -            slider(1.0..=100.0, bl, Message::RadiusBottomLeftChanged) +            slider(1.0..=100.0, bottom_left, Message::RadiusBottomLeftChanged)                  .step(0.01),              slider(1.0..=10.0, self.border_width, Message::BorderWidthChanged)                  .step(0.01), @@ -185,7 +192,7 @@ impl Example {          .padding(20)          .spacing(20)          .max_width(500) -        .align_items(Alignment::Center); +        .align_x(Center);          center(content).into()      } diff --git a/examples/custom_shader/src/main.rs b/examples/custom_shader/src/main.rs index b04a8183..5886f6bb 100644 --- a/examples/custom_shader/src/main.rs +++ b/examples/custom_shader/src/main.rs @@ -6,7 +6,7 @@ use iced::time::Instant;  use iced::widget::shader::wgpu;  use iced::widget::{center, checkbox, column, row, shader, slider, text};  use iced::window; -use iced::{Alignment, Color, Element, Length, Subscription}; +use iced::{Center, Color, Element, Fill, Subscription};  fn main() -> iced::Result {      iced::application( @@ -122,12 +122,11 @@ impl IcedCubes {          let controls = column![top_controls, bottom_controls,]              .spacing(10)              .padding(20) -            .align_items(Alignment::Center); +            .align_x(Center); -        let shader = -            shader(&self.scene).width(Length::Fill).height(Length::Fill); +        let shader = shader(&self.scene).width(Fill).height(Fill); -        center(column![shader, controls].align_items(Alignment::Center)).into() +        center(column![shader, controls].align_x(Center)).into()      }      fn subscription(&self) -> Subscription<Message> { diff --git a/examples/custom_widget/src/main.rs b/examples/custom_widget/src/main.rs index 3cf10e22..dc3f74ac 100644 --- a/examples/custom_widget/src/main.rs +++ b/examples/custom_widget/src/main.rs @@ -12,8 +12,9 @@ mod circle {      use iced::advanced::layout::{self, Layout};      use iced::advanced::renderer;      use iced::advanced::widget::{self, Widget}; +    use iced::border;      use iced::mouse; -    use iced::{Border, Color, Element, Length, Rectangle, Size}; +    use iced::{Color, Element, Length, Rectangle, Size};      pub struct Circle {          radius: f32, @@ -62,7 +63,7 @@ mod circle {              renderer.fill_quad(                  renderer::Quad {                      bounds: layout.bounds(), -                    border: Border::rounded(self.radius), +                    border: border::rounded(self.radius),                      ..renderer::Quad::default()                  },                  Color::BLACK, @@ -83,7 +84,7 @@ mod circle {  use circle::circle;  use iced::widget::{center, column, slider, text}; -use iced::{Alignment, Element}; +use iced::{Center, Element};  pub fn main() -> iced::Result {      iced::run("Custom Widget - Iced", Example::update, Example::view) @@ -120,7 +121,7 @@ impl Example {          .padding(20)          .spacing(20)          .max_width(500) -        .align_items(Alignment::Center); +        .align_x(Center);          center(content).into()      } diff --git a/examples/download_progress/src/main.rs b/examples/download_progress/src/main.rs index d91e5eab..667fb448 100644 --- a/examples/download_progress/src/main.rs +++ b/examples/download_progress/src/main.rs @@ -1,7 +1,7 @@  mod download;  use iced::widget::{button, center, column, progress_bar, text, Column}; -use iced::{Alignment, Element, Subscription}; +use iced::{Center, Element, Right, Subscription};  pub fn main() -> iced::Result {      iced::application( @@ -69,7 +69,7 @@ impl Example {                          .padding(10),                  )                  .spacing(20) -                .align_items(Alignment::End); +                .align_x(Right);          center(downloads).padding(20).into()      } @@ -160,7 +160,7 @@ impl Download {              State::Finished => {                  column!["Download finished!", button("Start again")]                      .spacing(10) -                    .align_items(Alignment::Center) +                    .align_x(Center)                      .into()              }              State::Downloading { .. } => { @@ -171,14 +171,14 @@ impl Download {                  button("Try again").on_press(Message::Download(self.id)),              ]              .spacing(10) -            .align_items(Alignment::Center) +            .align_x(Center)              .into(),          };          Column::new()              .spacing(10)              .padding(10) -            .align_items(Alignment::Center) +            .align_x(Center)              .push(progress_bar)              .push(control)              .into() diff --git a/examples/editor/src/main.rs b/examples/editor/src/main.rs index ce3c478d..71b1a719 100644 --- a/examples/editor/src/main.rs +++ b/examples/editor/src/main.rs @@ -4,7 +4,7 @@ use iced::widget::{      button, column, container, horizontal_space, pick_list, row, text,      text_editor, tooltip,  }; -use iced::{Alignment, Element, Font, Length, Subscription, Task, Theme}; +use iced::{Center, Element, Fill, Font, Subscription, Task, Theme};  use std::ffi;  use std::io; @@ -158,7 +158,7 @@ impl Editor {              .padding([5, 10])          ]          .spacing(10) -        .align_items(Alignment::Center); +        .align_y(Center);          let status = row![              text(if let Some(path) = &self.file { @@ -184,7 +184,7 @@ impl Editor {          column![              controls,              text_editor(&self.content) -                .height(Length::Fill) +                .height(Fill)                  .on_action(Message::ActionPerformed)                  .highlight::<Highlighter>(                      highlighter::Settings { diff --git a/examples/events/src/main.rs b/examples/events/src/main.rs index 2cd3c5d8..5bada9b5 100644 --- a/examples/events/src/main.rs +++ b/examples/events/src/main.rs @@ -1,8 +1,7 @@ -use iced::alignment;  use iced::event::{self, Event};  use iced::widget::{button, center, checkbox, text, Column};  use iced::window; -use iced::{Alignment, Element, Length, Subscription, Task}; +use iced::{Center, Element, Fill, Subscription, Task};  pub fn main() -> iced::Result {      iced::application("Events - Iced", Events::update, Events::view) @@ -67,17 +66,13 @@ impl Events {          let toggle = checkbox("Listen to runtime events", self.enabled)              .on_toggle(Message::Toggled); -        let exit = button( -            text("Exit") -                .width(Length::Fill) -                .horizontal_alignment(alignment::Horizontal::Center), -        ) -        .width(100) -        .padding(10) -        .on_press(Message::Exit); +        let exit = button(text("Exit").width(Fill).align_x(Center)) +            .width(100) +            .padding(10) +            .on_press(Message::Exit);          let content = Column::new() -            .align_items(Alignment::Center) +            .align_x(Center)              .spacing(20)              .push(events)              .push(toggle) diff --git a/examples/exit/src/main.rs b/examples/exit/src/main.rs index 1f108df2..48b0864c 100644 --- a/examples/exit/src/main.rs +++ b/examples/exit/src/main.rs @@ -1,6 +1,6 @@  use iced::widget::{button, center, column};  use iced::window; -use iced::{Alignment, Element, Task}; +use iced::{Center, Element, Task};  pub fn main() -> iced::Result {      iced::application("Exit - Iced", Exit::update, Exit::view).run() @@ -44,7 +44,7 @@ impl Exit {              ]          }          .spacing(10) -        .align_items(Alignment::Center); +        .align_x(Center);          center(content).padding(20).into()      } diff --git a/examples/ferris/src/main.rs b/examples/ferris/src/main.rs index 88006898..eaf51354 100644 --- a/examples/ferris/src/main.rs +++ b/examples/ferris/src/main.rs @@ -4,8 +4,8 @@ use iced::widget::{  };  use iced::window;  use iced::{ -    Alignment, Color, ContentFit, Degrees, Element, Length, Radians, Rotation, -    Subscription, Theme, +    Bottom, Center, Color, ContentFit, Degrees, Element, Fill, Radians, +    Rotation, Subscription, Theme,  };  pub fn main() -> iced::Result { @@ -108,7 +108,7 @@ impl Image {              "I am Ferris!"          ]          .spacing(20) -        .align_items(Alignment::Center); +        .align_x(Center);          let fit = row![              pick_list( @@ -122,7 +122,7 @@ impl Image {                  Some(self.content_fit),                  Message::ContentFitChanged              ) -            .width(Length::Fill), +            .width(Fill),              pick_list(                  [RotationStrategy::Floating, RotationStrategy::Solid],                  Some(match self.rotation { @@ -131,10 +131,10 @@ impl Image {                  }),                  Message::RotationStrategyChanged,              ) -            .width(Length::Fill), +            .width(Fill),          ]          .spacing(10) -        .align_items(Alignment::End); +        .align_y(Bottom);          let properties = row![              with_value( @@ -159,12 +159,12 @@ impl Image {                          .size(12)                  ]                  .spacing(10) -                .align_items(Alignment::Center), +                .align_y(Center),                  format!("Rotation: {:.0}°", f32::from(self.rotation.degrees()))              )          ]          .spacing(10) -        .align_items(Alignment::End); +        .align_y(Bottom);          container(column![fit, center(i_am_ferris), properties].spacing(10))              .padding(10) @@ -206,6 +206,6 @@ fn with_value<'a>(  ) -> Element<'a, Message> {      column![control.into(), text(value).size(12).line_height(1.0)]          .spacing(2) -        .align_items(Alignment::Center) +        .align_x(Center)          .into()  } diff --git a/examples/game_of_life/src/main.rs b/examples/game_of_life/src/main.rs index 421f862a..9dcebecc 100644 --- a/examples/game_of_life/src/main.rs +++ b/examples/game_of_life/src/main.rs @@ -9,7 +9,7 @@ use iced::time;  use iced::widget::{      button, checkbox, column, container, pick_list, row, slider, text,  }; -use iced::{Alignment, Element, Length, Subscription, Task, Theme}; +use iced::{Center, Element, Fill, Subscription, Task, Theme};  use std::time::Duration;  pub fn main() -> iced::Result { @@ -135,12 +135,9 @@ impl GameOfLife {                  .map(move |message| Message::Grid(message, version)),              controls,          ] -        .height(Length::Fill); +        .height(Fill); -        container(content) -            .width(Length::Fill) -            .height(Length::Fill) -            .into() +        container(content).width(Fill).height(Fill).into()      }  } @@ -169,7 +166,7 @@ fn view_controls<'a>(          slider(1.0..=1000.0, speed as f32, Message::SpeedChanged),          text!("x{speed}").size(16),      ] -    .align_items(Alignment::Center) +    .align_y(Center)      .spacing(10);      row![ @@ -186,7 +183,7 @@ fn view_controls<'a>(      ]      .padding(10)      .spacing(20) -    .align_items(Alignment::Center) +    .align_y(Center)      .into()  } @@ -199,7 +196,7 @@ mod grid {      use iced::widget::canvas::event::{self, Event};      use iced::widget::canvas::{Cache, Canvas, Frame, Geometry, Path, Text};      use iced::{ -        Color, Element, Length, Point, Rectangle, Renderer, Size, Theme, Vector, +        Color, Element, Fill, Point, Rectangle, Renderer, Size, Theme, Vector,      };      use rustc_hash::{FxHashMap, FxHashSet};      use std::future::Future; @@ -333,10 +330,7 @@ mod grid {          }          pub fn view(&self) -> Element<Message> { -            Canvas::new(self) -                .width(Length::Fill) -                .height(Length::Fill) -                .into() +            Canvas::new(self).width(Fill).height(Fill).into()          }          pub fn clear(&mut self) { diff --git a/examples/gradient/src/main.rs b/examples/gradient/src/main.rs index e5b19443..b2de069f 100644 --- a/examples/gradient/src/main.rs +++ b/examples/gradient/src/main.rs @@ -3,7 +3,7 @@ use iced::gradient;  use iced::widget::{      checkbox, column, container, horizontal_space, row, slider, text,  }; -use iced::{Alignment, Color, Element, Length, Radians, Theme}; +use iced::{Center, Color, Element, Fill, Radians, Theme};  pub fn main() -> iced::Result {      tracing_subscriber::fmt::init(); @@ -67,8 +67,8 @@ impl Gradient {                  gradient.into()              }) -            .width(Length::Fill) -            .height(Length::Fill); +            .width(Fill) +            .height(Fill);          let angle_picker = row![              text("Angle").width(64), @@ -77,7 +77,7 @@ impl Gradient {          ]          .spacing(8)          .padding(8) -        .align_items(Alignment::Center); +        .align_y(Center);          let transparency_toggle = iced::widget::Container::new(              checkbox("Transparent window", transparent) @@ -129,6 +129,6 @@ fn color_picker(label: &str, color: Color) -> Element<'_, Color> {      ]      .spacing(8)      .padding(8) -    .align_items(Alignment::Center) +    .align_y(Center)      .into()  } diff --git a/examples/integration/src/controls.rs b/examples/integration/src/controls.rs index d0654996..0b11a323 100644 --- a/examples/integration/src/controls.rs +++ b/examples/integration/src/controls.rs @@ -1,7 +1,6 @@  use iced_wgpu::Renderer;  use iced_widget::{column, container, row, slider, text, text_input}; -use iced_winit::core::alignment; -use iced_winit::core::{Color, Element, Length, Theme}; +use iced_winit::core::{Color, Element, Length::*, Theme};  use iced_winit::runtime::{Program, Task};  pub struct Controls { @@ -86,8 +85,7 @@ impl Program for Controls {              .spacing(10),          )          .padding(10) -        .height(Length::Fill) -        .align_y(alignment::Vertical::Bottom) +        .align_bottom(Fill)          .into()      }  } diff --git a/examples/layout/src/main.rs b/examples/layout/src/main.rs index 2e774415..d0827fad 100644 --- a/examples/layout/src/main.rs +++ b/examples/layout/src/main.rs @@ -5,7 +5,7 @@ use iced::widget::{      pick_list, row, scrollable, text,  };  use iced::{ -    color, Alignment, Element, Font, Length, Point, Rectangle, Renderer, +    color, Center, Element, Fill, Font, Length, Point, Rectangle, Renderer,      Subscription, Theme,  }; @@ -74,7 +74,7 @@ impl Layout {              pick_list(Theme::ALL, Some(&self.theme), Message::ThemeSelected),          ]          .spacing(20) -        .align_items(Alignment::Center); +        .align_y(Center);          let example = center(if self.explain {              self.example.view().explain(color!(0x0000ff)) @@ -234,7 +234,7 @@ fn application<'a>() -> Element<'a, Message> {              square(40),          ]          .padding(10) -        .align_items(Alignment::Center), +        .align_y(Center),      )      .style(|theme| {          let palette = theme.extended_palette(); @@ -248,10 +248,10 @@ fn application<'a>() -> Element<'a, Message> {              .spacing(40)              .padding(10)              .width(200) -            .align_items(Alignment::Center), +            .align_x(Center),      )      .style(container::rounded_box) -    .center_y(Length::Fill); +    .center_y(Fill);      let content = container(          scrollable( @@ -263,10 +263,10 @@ fn application<'a>() -> Element<'a, Message> {                  "The end"              ]              .spacing(40) -            .align_items(Alignment::Center) -            .width(Length::Fill), +            .align_x(Center) +            .width(Fill),          ) -        .height(Length::Fill), +        .height(Fill),      )      .padding(10); diff --git a/examples/lazy/src/main.rs b/examples/lazy/src/main.rs index f24c0d62..8f756210 100644 --- a/examples/lazy/src/main.rs +++ b/examples/lazy/src/main.rs @@ -2,7 +2,7 @@ use iced::widget::{      button, column, horizontal_space, lazy, pick_list, row, scrollable, text,      text_input,  }; -use iced::{Element, Length}; +use iced::{Element, Fill};  use std::collections::HashSet;  use std::hash::Hash; @@ -187,7 +187,7 @@ impl App {          });          column![ -            scrollable(options).height(Length::Fill), +            scrollable(options).height(Fill),              row![                  text_input("Add a new option", &self.input)                      .on_input(Message::InputChanged) diff --git a/examples/loading_spinners/src/main.rs b/examples/loading_spinners/src/main.rs index 503f2d7a..3b178148 100644 --- a/examples/loading_spinners/src/main.rs +++ b/examples/loading_spinners/src/main.rs @@ -1,5 +1,5 @@  use iced::widget::{center, column, row, slider, text}; -use iced::Element; +use iced::{Center, Element};  use std::time::Duration; @@ -67,7 +67,7 @@ impl LoadingSpinners {                          Duration::from_secs_f32(self.cycle_duration)                      )                  ] -                .align_items(iced::Alignment::Center) +                .align_y(Center)                  .spacing(20.0),              )          }) @@ -83,7 +83,7 @@ impl LoadingSpinners {                      .width(200.0),                      text!("{:.2}s", self.cycle_duration),                  ] -                .align_items(iced::Alignment::Center) +                .align_y(Center)                  .spacing(20.0),              ),          ) diff --git a/examples/loupe/src/main.rs b/examples/loupe/src/main.rs index c4d3b449..1c748d42 100644 --- a/examples/loupe/src/main.rs +++ b/examples/loupe/src/main.rs @@ -1,5 +1,5 @@  use iced::widget::{button, center, column, text}; -use iced::{Alignment, Element}; +use iced::{Center, Element};  use loupe::loupe; @@ -39,7 +39,7 @@ impl Loupe {                  button("Decrement").on_press(Message::Decrement)              ]              .padding(20) -            .align_items(Alignment::Center), +            .align_x(Center),          ))          .into()      } diff --git a/examples/modal/src/main.rs b/examples/modal/src/main.rs index 413485e7..f1f0e8ad 100644 --- a/examples/modal/src/main.rs +++ b/examples/modal/src/main.rs @@ -5,7 +5,7 @@ use iced::widget::{      self, button, center, column, container, horizontal_space, mouse_area,      opaque, pick_list, row, stack, text, text_input,  }; -use iced::{Alignment, Color, Element, Length, Subscription, Task}; +use iced::{Bottom, Color, Element, Fill, Subscription, Task};  use std::fmt; @@ -96,18 +96,17 @@ impl App {          let content = container(              column![                  row![text("Top Left"), horizontal_space(), text("Top Right")] -                    .align_items(Alignment::Start) -                    .height(Length::Fill), +                    .height(Fill),                  center(button(text("Show Modal")).on_press(Message::ShowModal)),                  row![                      text("Bottom Left"),                      horizontal_space(),                      text("Bottom Right")                  ] -                .align_items(Alignment::End) -                .height(Length::Fill), +                .align_y(Bottom) +                .height(Fill),              ] -            .height(Length::Fill), +            .height(Fill),          )          .padding(10); diff --git a/examples/multi_window/src/main.rs b/examples/multi_window/src/main.rs index 460ca3b5..3dcb58f5 100644 --- a/examples/multi_window/src/main.rs +++ b/examples/multi_window/src/main.rs @@ -3,7 +3,7 @@ use iced::widget::{      text_input,  };  use iced::window; -use iced::{Alignment, Element, Length, Subscription, Task, Theme, Vector}; +use iced::{Center, Element, Fill, Subscription, Task, Theme, Vector};  use std::collections::BTreeMap; @@ -188,8 +188,8 @@ impl Window {          let content = scrollable(              column![scale_input, title_input, new_window_button]                  .spacing(50) -                .width(Length::Fill) -                .align_items(Alignment::Center), +                .width(Fill) +                .align_x(Center),          );          container(content).center_x(200).into() diff --git a/examples/multitouch/src/main.rs b/examples/multitouch/src/main.rs index 69717310..a0105a8a 100644 --- a/examples/multitouch/src/main.rs +++ b/examples/multitouch/src/main.rs @@ -6,7 +6,7 @@ use iced::touch;  use iced::widget::canvas::event;  use iced::widget::canvas::stroke::{self, Stroke};  use iced::widget::canvas::{self, Canvas, Geometry}; -use iced::{Color, Element, Length, Point, Rectangle, Renderer, Theme}; +use iced::{Color, Element, Fill, Point, Rectangle, Renderer, Theme};  use std::collections::HashMap; @@ -46,10 +46,7 @@ impl Multitouch {      }      fn view(&self) -> Element<Message> { -        Canvas::new(self) -            .width(Length::Fill) -            .height(Length::Fill) -            .into() +        Canvas::new(self).width(Fill).height(Fill).into()      }  } diff --git a/examples/pane_grid/src/main.rs b/examples/pane_grid/src/main.rs index db9f7a05..f18fc5f3 100644 --- a/examples/pane_grid/src/main.rs +++ b/examples/pane_grid/src/main.rs @@ -1,10 +1,9 @@ -use iced::alignment::{self, Alignment};  use iced::keyboard;  use iced::widget::pane_grid::{self, PaneGrid};  use iced::widget::{      button, column, container, responsive, row, scrollable, text,  }; -use iced::{Color, Element, Length, Size, Subscription}; +use iced::{Center, Color, Element, Fill, Size, Subscription};  pub fn main() -> iced::Result {      iced::application("Pane Grid - Iced", Example::update, Example::view) @@ -178,16 +177,16 @@ impl Example {                  style::pane_active              })          }) -        .width(Length::Fill) -        .height(Length::Fill) +        .width(Fill) +        .height(Fill)          .spacing(10)          .on_click(Message::Clicked)          .on_drag(Message::Dragged)          .on_resize(10, Message::Resized);          container(pane_grid) -            .width(Length::Fill) -            .height(Length::Fill) +            .width(Fill) +            .height(Fill)              .padding(10)              .into()      } @@ -255,15 +254,10 @@ fn view_content<'a>(      size: Size,  ) -> Element<'a, Message> {      let button = |label, message| { -        button( -            text(label) -                .width(Length::Fill) -                .horizontal_alignment(alignment::Horizontal::Center) -                .size(16), -        ) -        .width(Length::Fill) -        .padding(8) -        .on_press(message) +        button(text(label).width(Fill).align_x(Center).size(16)) +            .width(Fill) +            .padding(8) +            .on_press(message)      };      let controls = column![ @@ -287,10 +281,10 @@ fn view_content<'a>(      let content =          column![text!("{}x{}", size.width, size.height).size(24), controls,]              .spacing(10) -            .align_items(Alignment::Center); +            .align_x(Center);      container(scrollable(content)) -        .center_y(Length::Fill) +        .center_y(Fill)          .padding(5)          .into()  } diff --git a/examples/pick_list/src/main.rs b/examples/pick_list/src/main.rs index 2be6f5b0..d8b2b389 100644 --- a/examples/pick_list/src/main.rs +++ b/examples/pick_list/src/main.rs @@ -1,5 +1,5 @@  use iced::widget::{column, pick_list, scrollable, vertical_space}; -use iced::{Alignment, Element, Length}; +use iced::{Center, Element, Fill};  pub fn main() -> iced::Result {      iced::run("Pick List - Iced", Example::update, Example::view) @@ -38,8 +38,8 @@ impl Example {              pick_list,              vertical_space().height(600),          ] -        .width(Length::Fill) -        .align_items(Alignment::Center) +        .width(Fill) +        .align_x(Center)          .spacing(10);          scrollable(content).into() diff --git a/examples/pokedex/src/main.rs b/examples/pokedex/src/main.rs index 7414ae54..2e972f6b 100644 --- a/examples/pokedex/src/main.rs +++ b/examples/pokedex/src/main.rs @@ -1,6 +1,6 @@  use iced::futures;  use iced::widget::{self, center, column, image, row, text}; -use iced::{Alignment, Element, Length, Task}; +use iced::{Center, Element, Fill, Right, Task};  pub fn main() -> iced::Result {      iced::application(Pokedex::title, Pokedex::update, Pokedex::view) @@ -63,10 +63,9 @@ impl Pokedex {      }      fn view(&self) -> Element<Message> { -        let content = match self { +        let content: Element<_> = match self {              Pokedex::Loading => { -                column![text("Searching for Pokémon...").size(40),] -                    .width(Length::Shrink) +                text("Searching for Pokémon...").size(40).into()              }              Pokedex::Loaded { pokemon } => column![                  pokemon.view(), @@ -74,13 +73,15 @@ impl Pokedex {              ]              .max_width(500)              .spacing(20) -            .align_items(Alignment::End), +            .align_x(Right) +            .into(),              Pokedex::Errored => column![                  text("Whoops! Something went wrong...").size(40),                  button("Try again").on_press(Message::Search)              ]              .spacing(20) -            .align_items(Alignment::End), +            .align_x(Right) +            .into(),          };          center(content).into() @@ -103,17 +104,17 @@ impl Pokemon {              image::viewer(self.image.clone()),              column![                  row![ -                    text(&self.name).size(30).width(Length::Fill), +                    text(&self.name).size(30).width(Fill),                      text!("#{}", self.number).size(20).color([0.5, 0.5, 0.5]),                  ] -                .align_items(Alignment::Center) +                .align_y(Center)                  .spacing(20),                  self.description.as_ref(),              ]              .spacing(20),          ]          .spacing(20) -        .align_items(Alignment::Center) +        .align_y(Center)          .into()      } diff --git a/examples/qr_code/src/main.rs b/examples/qr_code/src/main.rs index b30ecf15..f1b654e0 100644 --- a/examples/qr_code/src/main.rs +++ b/examples/qr_code/src/main.rs @@ -1,5 +1,5 @@  use iced::widget::{center, column, pick_list, qr_code, row, text, text_input}; -use iced::{Alignment, Element, Theme}; +use iced::{Center, Element, Theme};  pub fn main() -> iced::Result {      iced::application( @@ -58,7 +58,7 @@ impl QRGenerator {              pick_list(Theme::ALL, Some(&self.theme), Message::ThemeChanged,)          ]          .spacing(10) -        .align_items(Alignment::Center); +        .align_y(Center);          let content = column![title, input, choose_theme]              .push_maybe( @@ -68,7 +68,7 @@ impl QRGenerator {              )              .width(700)              .spacing(20) -            .align_items(Alignment::Center); +            .align_x(Center);          center(content).padding(20).into()      } diff --git a/examples/screenshot/src/main.rs b/examples/screenshot/src/main.rs index acde8367..2d980dd9 100644 --- a/examples/screenshot/src/main.rs +++ b/examples/screenshot/src/main.rs @@ -1,10 +1,10 @@ -use iced::alignment;  use iced::keyboard;  use iced::widget::{button, column, container, image, row, text, text_input};  use iced::window;  use iced::window::screenshot::{self, Screenshot};  use iced::{ -    Alignment, ContentFit, Element, Length, Rectangle, Subscription, Task, +    Center, ContentFit, Element, Fill, FillPortion, Rectangle, Subscription, +    Task,  };  use ::image as img; @@ -114,45 +114,37 @@ impl Example {                  screenshot.clone(),              ))              .content_fit(ContentFit::Contain) -            .width(Length::Fill) -            .height(Length::Fill) +            .width(Fill) +            .height(Fill)              .into()          } else {              text("Press the button to take a screenshot!").into()          };          let image = container(image) -            .center_y(Length::FillPortion(2)) +            .center_y(FillPortion(2))              .padding(10)              .style(container::rounded_box);          let crop_origin_controls = row![ -            text("X:") -                .vertical_alignment(alignment::Vertical::Center) -                .width(30), +            text("X:").width(30),              numeric_input("0", self.x_input_value).map(Message::XInputChanged), -            text("Y:") -                .vertical_alignment(alignment::Vertical::Center) -                .width(30), +            text("Y:").width(30),              numeric_input("0", self.y_input_value).map(Message::YInputChanged)          ]          .spacing(10) -        .align_items(Alignment::Center); +        .align_y(Center);          let crop_dimension_controls = row![ -            text("W:") -                .vertical_alignment(alignment::Vertical::Center) -                .width(30), +            text("W:").width(30),              numeric_input("0", self.width_input_value)                  .map(Message::WidthInputChanged), -            text("H:") -                .vertical_alignment(alignment::Vertical::Center) -                .width(30), +            text("H:").width(30),              numeric_input("0", self.height_input_value)                  .map(Message::HeightInputChanged)          ]          .spacing(10) -        .align_items(Alignment::Center); +        .align_y(Center);          let crop_controls =              column![crop_origin_controls, crop_dimension_controls] @@ -162,7 +154,7 @@ impl Example {                          .map(|error| text!("Crop error! \n{error}")),                  )                  .spacing(10) -                .align_items(Alignment::Center); +                .align_x(Center);          let controls = {              let save_result = @@ -178,8 +170,8 @@ impl Example {              column![                  column![                      button(centered_text("Screenshot!")) -                        .padding([10, 20, 10, 20]) -                        .width(Length::Fill) +                        .padding([10, 20]) +                        .width(Fill)                          .on_press(Message::Screenshot),                      if !self.png_saving {                          button(centered_text("Save as png")).on_press_maybe( @@ -190,8 +182,8 @@ impl Example {                              .style(button::secondary)                      }                      .style(button::secondary) -                    .padding([10, 20, 10, 20]) -                    .width(Length::Fill) +                    .padding([10, 20]) +                    .width(Fill)                  ]                  .spacing(10),                  column![ @@ -199,23 +191,23 @@ impl Example {                      button(centered_text("Crop"))                          .on_press(Message::Crop)                          .style(button::danger) -                        .padding([10, 20, 10, 20]) -                        .width(Length::Fill), +                        .padding([10, 20]) +                        .width(Fill),                  ]                  .spacing(10) -                .align_items(Alignment::Center), +                .align_x(Center),              ]              .push_maybe(save_result.map(text))              .spacing(40)          }; -        let side_content = container(controls).center_y(Length::Fill); +        let side_content = container(controls).center_y(Fill);          let content = row![side_content, image]              .spacing(10) -            .width(Length::Fill) -            .height(Length::Fill) -            .align_items(Alignment::Center); +            .width(Fill) +            .height(Fill) +            .align_y(Center);          container(content).padding(10).into()      } @@ -276,8 +268,5 @@ fn numeric_input(  }  fn centered_text(content: &str) -> Element<'_, Message> { -    text(content) -        .width(Length::Fill) -        .horizontal_alignment(alignment::Horizontal::Center) -        .into() +    text(content).width(Fill).align_x(Center).into()  } diff --git a/examples/scrollable/src/main.rs b/examples/scrollable/src/main.rs index 067dcd70..969f385e 100644 --- a/examples/scrollable/src/main.rs +++ b/examples/scrollable/src/main.rs @@ -2,7 +2,7 @@ use iced::widget::{      button, column, container, horizontal_space, progress_bar, radio, row,      scrollable, slider, text, vertical_space,  }; -use iced::{Alignment, Border, Color, Element, Length, Task, Theme}; +use iced::{Border, Center, Color, Element, Fill, Task, Theme};  use once_cell::sync::Lazy; @@ -24,7 +24,7 @@ struct ScrollableDemo {      scrollbar_margin: u16,      scroller_width: u16,      current_scroll_offset: scrollable::RelativeOffset, -    alignment: scrollable::Alignment, +    anchor: scrollable::Anchor,  }  #[derive(Debug, Clone, Eq, PartialEq, Copy)] @@ -37,7 +37,7 @@ enum Direction {  #[derive(Debug, Clone)]  enum Message {      SwitchDirection(Direction), -    AlignmentChanged(scrollable::Alignment), +    AlignmentChanged(scrollable::Anchor),      ScrollbarWidthChanged(u16),      ScrollbarMarginChanged(u16),      ScrollerWidthChanged(u16), @@ -54,7 +54,7 @@ impl ScrollableDemo {              scrollbar_margin: 0,              scroller_width: 10,              current_scroll_offset: scrollable::RelativeOffset::START, -            alignment: scrollable::Alignment::Start, +            anchor: scrollable::Anchor::Start,          }      } @@ -71,7 +71,7 @@ impl ScrollableDemo {              }              Message::AlignmentChanged(alignment) => {                  self.current_scroll_offset = scrollable::RelativeOffset::START; -                self.alignment = alignment; +                self.anchor = alignment;                  scrollable::snap_to(                      SCROLLABLE_ID.clone(), @@ -168,14 +168,14 @@ impl ScrollableDemo {              text("Scrollable alignment:"),              radio(                  "Start", -                scrollable::Alignment::Start, -                Some(self.alignment), +                scrollable::Anchor::Start, +                Some(self.anchor),                  Message::AlignmentChanged,              ),              radio(                  "End", -                scrollable::Alignment::End, -                Some(self.alignment), +                scrollable::Anchor::End, +                Some(self.anchor),                  Message::AlignmentChanged,              )          ] @@ -212,19 +212,20 @@ impl ScrollableDemo {                          text("End!"),                          scroll_to_beginning_button(),                      ] -                    .align_items(Alignment::Center) -                    .padding([40, 0, 40, 0]) +                    .align_x(Center) +                    .padding([40, 0])                      .spacing(40),                  ) -                .direction(scrollable::Direction::Vertical( -                    scrollable::Scrollbar::new() +                .direction(scrollable::Direction::Vertical { +                    scrollbar: scrollable::Scrollbar::new()                          .width(self.scrollbar_width)                          .margin(self.scrollbar_margin)                          .scroller_width(self.scroller_width) -                        .alignment(self.alignment), -                )) -                .width(Length::Fill) -                .height(Length::Fill) +                        .anchor(self.anchor), +                    spacing: None, +                }) +                .width(Fill) +                .height(Fill)                  .id(SCROLLABLE_ID.clone())                  .on_scroll(Message::Scrolled),                  Direction::Horizontal => scrollable( @@ -238,19 +239,20 @@ impl ScrollableDemo {                          scroll_to_beginning_button(),                      ]                      .height(450) -                    .align_items(Alignment::Center) -                    .padding([0, 40, 0, 40]) +                    .align_y(Center) +                    .padding([0, 40])                      .spacing(40),                  ) -                .direction(scrollable::Direction::Horizontal( -                    scrollable::Scrollbar::new() +                .direction(scrollable::Direction::Horizontal { +                    scrollbar: scrollable::Scrollbar::new()                          .width(self.scrollbar_width)                          .margin(self.scrollbar_margin)                          .scroller_width(self.scroller_width) -                        .alignment(self.alignment), -                )) -                .width(Length::Fill) -                .height(Length::Fill) +                        .anchor(self.anchor), +                    spacing: None, +                }) +                .width(Fill) +                .height(Fill)                  .id(SCROLLABLE_ID.clone())                  .on_scroll(Message::Scrolled),                  Direction::Multi => scrollable( @@ -280,8 +282,8 @@ impl ScrollableDemo {                          text("Horizontal - End!"),                          scroll_to_beginning_button(),                      ] -                    .align_items(Alignment::Center) -                    .padding([0, 40, 0, 40]) +                    .align_y(Center) +                    .padding([0, 40])                      .spacing(40),                  )                  .direction({ @@ -289,15 +291,15 @@ impl ScrollableDemo {                          .width(self.scrollbar_width)                          .margin(self.scrollbar_margin)                          .scroller_width(self.scroller_width) -                        .alignment(self.alignment); +                        .anchor(self.anchor);                      scrollable::Direction::Both {                          horizontal: scrollbar,                          vertical: scrollbar,                      }                  }) -                .width(Length::Fill) -                .height(Length::Fill) +                .width(Fill) +                .height(Fill)                  .id(SCROLLABLE_ID.clone())                  .on_scroll(Message::Scrolled),              }); @@ -322,7 +324,7 @@ impl ScrollableDemo {          let content: Element<Message> =              column![scroll_controls, scrollable_content, progress_bars] -                .align_items(Alignment::Center) +                .align_x(Center)                  .spacing(10)                  .into(); diff --git a/examples/sierpinski_triangle/src/main.rs b/examples/sierpinski_triangle/src/main.rs index 4c751937..99e7900a 100644 --- a/examples/sierpinski_triangle/src/main.rs +++ b/examples/sierpinski_triangle/src/main.rs @@ -2,7 +2,7 @@ use iced::mouse;  use iced::widget::canvas::event::{self, Event};  use iced::widget::canvas::{self, Canvas, Geometry};  use iced::widget::{column, row, slider, text}; -use iced::{Color, Length, Point, Rectangle, Renderer, Size, Theme}; +use iced::{Center, Color, Fill, Point, Rectangle, Renderer, Size, Theme};  use rand::Rng;  use std::fmt::Debug; @@ -50,9 +50,7 @@ impl SierpinskiEmulator {      fn view(&self) -> iced::Element<'_, Message> {          column![ -            Canvas::new(&self.graph) -                .width(Length::Fill) -                .height(Length::Fill), +            Canvas::new(&self.graph).width(Fill).height(Fill),              row![                  text!("Iteration: {:?}", self.graph.iteration),                  slider(0..=10000, self.graph.iteration, Message::IterationSet) @@ -60,7 +58,7 @@ impl SierpinskiEmulator {              .padding(10)              .spacing(20),          ] -        .align_items(iced::Alignment::Center) +        .align_x(Center)          .into()      }  } diff --git a/examples/slider/src/main.rs b/examples/slider/src/main.rs index fd312763..ffb5475f 100644 --- a/examples/slider/src/main.rs +++ b/examples/slider/src/main.rs @@ -1,5 +1,5 @@  use iced::widget::{column, container, iced, slider, text, vertical_slider}; -use iced::{Alignment, Element, Length}; +use iced::{Center, Element, Fill};  pub fn main() -> iced::Result {      iced::run("Slider - Iced", Slider::update, Slider::view) @@ -45,8 +45,8 @@ impl Slider {          let text = text(self.value);          column![v_slider, h_slider, text, iced(self.value as f32),] -            .width(Length::Fill) -            .align_items(Alignment::Center) +            .width(Fill) +            .align_x(Center)              .spacing(20)              .padding(20)              .into() diff --git a/examples/solar_system/src/main.rs b/examples/solar_system/src/main.rs index 2a67e23e..a6f1ba6f 100644 --- a/examples/solar_system/src/main.rs +++ b/examples/solar_system/src/main.rs @@ -13,7 +13,7 @@ use iced::widget::canvas::stroke::{self, Stroke};  use iced::widget::canvas::{Geometry, Path};  use iced::window;  use iced::{ -    Color, Element, Length, Point, Rectangle, Renderer, Size, Subscription, +    Color, Element, Fill, Point, Rectangle, Renderer, Size, Subscription,      Theme, Vector,  }; @@ -52,10 +52,7 @@ impl SolarSystem {      }      fn view(&self) -> Element<Message> { -        canvas(&self.state) -            .width(Length::Fill) -            .height(Length::Fill) -            .into() +        canvas(&self.state).width(Fill).height(Fill).into()      }      fn theme(&self) -> Theme { diff --git a/examples/stopwatch/src/main.rs b/examples/stopwatch/src/main.rs index bd56785a..0d824d36 100644 --- a/examples/stopwatch/src/main.rs +++ b/examples/stopwatch/src/main.rs @@ -1,8 +1,7 @@ -use iced::alignment;  use iced::keyboard;  use iced::time;  use iced::widget::{button, center, column, row, text}; -use iced::{Alignment, Element, Subscription, Theme}; +use iced::{Center, Element, Subscription, Theme};  use std::time::{Duration, Instant}; @@ -101,13 +100,8 @@ impl Stopwatch {          )          .size(40); -        let button = |label| { -            button( -                text(label).horizontal_alignment(alignment::Horizontal::Center), -            ) -            .padding(10) -            .width(80) -        }; +        let button = +            |label| button(text(label).align_x(Center)).padding(10).width(80);          let toggle_button = {              let label = match self.state { @@ -124,9 +118,7 @@ impl Stopwatch {          let controls = row![toggle_button, reset_button].spacing(20); -        let content = column![duration, controls] -            .align_items(Alignment::Center) -            .spacing(20); +        let content = column![duration, controls].align_x(Center).spacing(20);          center(content).into()      } diff --git a/examples/styling/src/main.rs b/examples/styling/src/main.rs index 3124493b..527aaa29 100644 --- a/examples/styling/src/main.rs +++ b/examples/styling/src/main.rs @@ -3,7 +3,7 @@ use iced::widget::{      row, scrollable, slider, text, text_input, toggler, vertical_rule,      vertical_space,  }; -use iced::{Alignment, Element, Length, Theme}; +use iced::{Center, Element, Fill, Theme};  pub fn main() -> iced::Result {      iced::application("Styling - Iced", Styling::update, Styling::view) @@ -48,7 +48,7 @@ impl Styling {          let choose_theme = column![              text("Theme:"),              pick_list(Theme::ALL, Some(&self.theme), Message::ThemeChanged) -                .width(Length::Fill), +                .width(Fill),          ]          .spacing(10); @@ -71,7 +71,7 @@ impl Styling {              vertical_space().height(800),              "You did it!"          ]) -        .width(Length::Fill) +        .width(Fill)          .height(100);          let checkbox = checkbox("Check me!", self.checkbox_value) @@ -82,15 +82,12 @@ impl Styling {              self.toggler_value,              Message::TogglerToggled,          ) -        .width(Length::Shrink)          .spacing(10);          let content = column![              choose_theme,              horizontal_rule(38), -            row![text_input, button] -                .spacing(10) -                .align_items(Alignment::Center), +            row![text_input, button].spacing(10).align_y(Center),              slider,              progress_bar,              row![ @@ -100,7 +97,7 @@ impl Styling {              ]              .spacing(10)              .height(100) -            .align_items(Alignment::Center), +            .align_y(Center),          ]          .spacing(20)          .padding(20) diff --git a/examples/svg/src/main.rs b/examples/svg/src/main.rs index e071c3af..02cb85cc 100644 --- a/examples/svg/src/main.rs +++ b/examples/svg/src/main.rs @@ -1,5 +1,5 @@  use iced::widget::{center, checkbox, column, container, svg}; -use iced::{color, Element, Length}; +use iced::{color, Element, Fill};  pub fn main() -> iced::Result {      iced::run("SVG - Iced", Tiger::update, Tiger::view) @@ -30,24 +30,26 @@ impl Tiger {              env!("CARGO_MANIFEST_DIR")          )); -        let svg = svg(handle).width(Length::Fill).height(Length::Fill).style( -            |_theme, _status| svg::Style { -                color: if self.apply_color_filter { -                    Some(color!(0x0000ff)) -                } else { -                    None -                }, -            }, -        ); +        let svg = +            svg(handle) +                .width(Fill) +                .height(Fill) +                .style(|_theme, _status| svg::Style { +                    color: if self.apply_color_filter { +                        Some(color!(0x0000ff)) +                    } else { +                        None +                    }, +                });          let apply_color_filter =              checkbox("Apply a color filter", self.apply_color_filter)                  .on_toggle(Message::ToggleColorFilter);          center( -            column![svg, container(apply_color_filter).center_x(Length::Fill)] +            column![svg, container(apply_color_filter).center_x(Fill)]                  .spacing(20) -                .height(Length::Fill), +                .height(Fill),          )          .padding(20)          .into() diff --git a/examples/the_matrix/src/main.rs b/examples/the_matrix/src/main.rs index 2ae1cc3a..0ed52dda 100644 --- a/examples/the_matrix/src/main.rs +++ b/examples/the_matrix/src/main.rs @@ -2,8 +2,7 @@ use iced::mouse;  use iced::time::{self, Instant};  use iced::widget::canvas;  use iced::{ -    Color, Element, Font, Length, Point, Rectangle, Renderer, Subscription, -    Theme, +    Color, Element, Fill, Font, Point, Rectangle, Renderer, Subscription, Theme,  };  use std::cell::RefCell; @@ -37,10 +36,7 @@ impl TheMatrix {      }      fn view(&self) -> Element<Message> { -        canvas(self as &Self) -            .width(Length::Fill) -            .height(Length::Fill) -            .into() +        canvas(self as &Self).width(Fill).height(Fill).into()      }      fn subscription(&self) -> Subscription<Message> { diff --git a/examples/toast/src/main.rs b/examples/toast/src/main.rs index 232133b1..040c19bd 100644 --- a/examples/toast/src/main.rs +++ b/examples/toast/src/main.rs @@ -4,7 +4,7 @@ use iced::keyboard::key;  use iced::widget::{      self, button, center, column, pick_list, row, slider, text, text_input,  }; -use iced::{Alignment, Element, Length, Subscription, Task}; +use iced::{Center, Element, Fill, Subscription, Task};  use toast::{Status, Toast}; @@ -125,7 +125,7 @@ impl App {                          Some(self.editing.status),                          Message::Status                      ) -                    .width(Length::Fill) +                    .width(Fill)                      .into()                  ),                  subtitle( @@ -142,7 +142,7 @@ impl App {                      .spacing(5)                      .into()                  ), -                column![add_toast].align_items(Alignment::End) +                column![add_toast].align_x(Center)              ]              .spacing(10)              .max_width(200), @@ -177,8 +177,8 @@ mod toast {      };      use iced::window;      use iced::{ -        Alignment, Element, Length, Point, Rectangle, Renderer, Size, Theme, -        Vector, +        Alignment, Center, Element, Fill, Length, Point, Rectangle, Renderer, +        Size, Theme, Vector,      };      pub const DEFAULT_TIMEOUT: u64 = 5; @@ -245,9 +245,9 @@ mod toast {                                      .on_press((on_close)(index))                                      .padding(3),                              ] -                            .align_items(Alignment::Center) +                            .align_y(Center)                          ) -                        .width(Length::Fill) +                        .width(Fill)                          .padding(5)                          .style(match toast.status {                              Status::Primary => primary, @@ -257,7 +257,7 @@ mod toast {                          }),                          horizontal_rule(1),                          container(text(toast.body.as_str())) -                            .width(Length::Fill) +                            .width(Fill)                              .padding(5)                              .style(container::rounded_box),                      ]) @@ -479,8 +479,8 @@ mod toast {                  layout::flex::Axis::Vertical,                  renderer,                  &limits, -                Length::Fill, -                Length::Fill, +                Fill, +                Fill,                  10.into(),                  10.0,                  Alignment::End, diff --git a/examples/todos/src/main.rs b/examples/todos/src/main.rs index b34f71ce..86845f87 100644 --- a/examples/todos/src/main.rs +++ b/examples/todos/src/main.rs @@ -1,11 +1,10 @@ -use iced::alignment::{self, Alignment};  use iced::keyboard;  use iced::widget::{      self, button, center, checkbox, column, container, keyed_column, row,      scrollable, text, text_input, Text,  };  use iced::window; -use iced::{Element, Font, Length, Subscription, Task as Command}; +use iced::{Center, Element, Fill, Font, Subscription, Task as Command};  use once_cell::sync::Lazy;  use serde::{Deserialize, Serialize}; @@ -193,10 +192,10 @@ impl Todos {                  ..              }) => {                  let title = text("todos") -                    .width(Length::Fill) +                    .width(Fill)                      .size(100)                      .color([0.5, 0.5, 0.5]) -                    .horizontal_alignment(alignment::Horizontal::Center); +                    .align_x(Center);                  let input = text_input("What needs to be done?", input_value)                      .id(INPUT_ID.clone()) @@ -240,10 +239,7 @@ impl Todos {                      .spacing(20)                      .max_width(800); -                scrollable( -                    container(content).center_x(Length::Fill).padding(40), -                ) -                .into() +                scrollable(container(content).center_x(Fill).padding(40)).into()              }          }      } @@ -343,7 +339,7 @@ impl Task {              TaskState::Idle => {                  let checkbox = checkbox(&self.description, self.completed)                      .on_toggle(TaskMessage::Completed) -                    .width(Length::Fill) +                    .width(Fill)                      .size(17)                      .text_shaping(text::Shaping::Advanced); @@ -355,7 +351,7 @@ impl Task {                          .style(button::text),                  ]                  .spacing(20) -                .align_items(Alignment::Center) +                .align_y(Center)                  .into()              }              TaskState::Editing => { @@ -371,14 +367,14 @@ impl Task {                      button(                          row![delete_icon(), "Delete"]                              .spacing(10) -                            .align_items(Alignment::Center) +                            .align_y(Center)                      )                      .on_press(TaskMessage::Delete)                      .padding(10)                      .style(button::danger)                  ]                  .spacing(20) -                .align_items(Alignment::Center) +                .align_y(Center)                  .into()              }          } @@ -405,17 +401,16 @@ fn view_controls(tasks: &[Task], current_filter: Filter) -> Element<Message> {              "{tasks_left} {} left",              if tasks_left == 1 { "task" } else { "tasks" }          ) -        .width(Length::Fill), +        .width(Fill),          row![              filter_button("All", Filter::All, current_filter),              filter_button("Active", Filter::Active, current_filter),              filter_button("Completed", Filter::Completed, current_filter,),          ] -        .width(Length::Shrink)          .spacing(10)      ]      .spacing(20) -    .align_items(Alignment::Center) +    .align_y(Center)      .into()  } @@ -440,20 +435,15 @@ impl Filter {  }  fn loading_message<'a>() -> Element<'a, Message> { -    center( -        text("Loading...") -            .horizontal_alignment(alignment::Horizontal::Center) -            .size(50), -    ) -    .into() +    center(text("Loading...").width(Fill).align_x(Center).size(50)).into()  }  fn empty_message(message: &str) -> Element<'_, Message> {      center(          text(message) -            .width(Length::Fill) +            .width(Fill)              .size(25) -            .horizontal_alignment(alignment::Horizontal::Center) +            .align_x(Center)              .color([0.7, 0.7, 0.7]),      )      .height(200) @@ -467,7 +457,7 @@ fn icon(unicode: char) -> Text<'static> {      text(unicode.to_string())          .font(ICONS)          .width(20) -        .horizontal_alignment(alignment::Horizontal::Center) +        .align_x(Center)  }  fn edit_icon() -> Text<'static> { diff --git a/examples/tour/src/main.rs b/examples/tour/src/main.rs index 94ba78ee..ee4754e6 100644 --- a/examples/tour/src/main.rs +++ b/examples/tour/src/main.rs @@ -1,10 +1,9 @@ -use iced::alignment::{self, Alignment};  use iced::widget::{      button, checkbox, column, container, horizontal_space, image, radio, row,      scrollable, slider, text, text_input, toggler, vertical_space,  };  use iced::widget::{Button, Column, Container, Slider}; -use iced::{Color, Element, Font, Length, Pixels}; +use iced::{Center, Color, Element, Fill, Font, Pixels};  pub fn main() -> iced::Result {      #[cfg(target_arch = "wasm32")] @@ -173,10 +172,10 @@ impl Tour {              } else {                  content              }) -            .center_x(Length::Fill), +            .center_x(Fill),          ); -        container(scrollable).center_y(Length::Fill).into() +        container(scrollable).center_y(Fill).into()      }      fn can_continue(&self) -> bool { @@ -235,11 +234,7 @@ impl Tour {                   0 to 100:",              )              .push(slider(0..=100, self.slider, Message::SliderChanged)) -            .push( -                text(self.slider.to_string()) -                    .width(Length::Fill) -                    .horizontal_alignment(alignment::Horizontal::Center), -            ) +            .push(text(self.slider.to_string()).width(Fill).align_x(Center))      }      fn rows_and_columns(&self) -> Column<Message> { @@ -268,9 +263,7 @@ impl Tour {          let spacing_section = column![              slider(0..=80, self.spacing, Message::SpacingChanged), -            text!("{} px", self.spacing) -                .width(Length::Fill) -                .horizontal_alignment(alignment::Horizontal::Center), +            text!("{} px", self.spacing).width(Fill).align_x(Center),          ]          .spacing(10); @@ -381,11 +374,7 @@ impl Tour {              .push("An image that tries to keep its aspect ratio.")              .push(ferris(width, filter_method))              .push(slider(100..=500, width, Message::ImageWidthChanged)) -            .push( -                text!("Width: {width} px") -                    .width(Length::Fill) -                    .horizontal_alignment(alignment::Horizontal::Center), -            ) +            .push(text!("Width: {width} px").width(Fill).align_x(Center))              .push(                  checkbox(                      "Use nearest interpolation", @@ -393,7 +382,7 @@ impl Tour {                  )                  .on_toggle(Message::ImageUseNearestToggled),              ) -            .align_items(Alignment::Center) +            .align_x(Center)      }      fn scrollable(&self) -> Column<Message> { @@ -409,18 +398,13 @@ impl Tour {              .push(vertical_space().height(4096))              .push(                  text("You are halfway there!") -                    .width(Length::Fill) +                    .width(Fill)                      .size(30) -                    .horizontal_alignment(alignment::Horizontal::Center), +                    .align_x(Center),              )              .push(vertical_space().height(4096))              .push(ferris(300, image::FilterMethod::Linear)) -            .push( -                text("You made it!") -                    .width(Length::Fill) -                    .size(50) -                    .horizontal_alignment(alignment::Horizontal::Center), -            ) +            .push(text("You made it!").width(Fill).size(50).align_x(Center))      }      fn text_input(&self) -> Column<Message> { @@ -464,8 +448,8 @@ impl Tour {                  } else {                      value                  }) -                .width(Length::Fill) -                .horizontal_alignment(alignment::Horizontal::Center), +                .width(Fill) +                .align_x(Center),              )      } @@ -570,7 +554,7 @@ fn ferris<'a>(          .filter_method(filter_method)          .width(width),      ) -    .center_x(Length::Fill) +    .center_x(Fill)  }  fn padded_button<Message: Clone>(label: &str) -> Button<'_, Message> { diff --git a/examples/vectorial_text/src/main.rs b/examples/vectorial_text/src/main.rs index 6dd3273a..ce34d826 100644 --- a/examples/vectorial_text/src/main.rs +++ b/examples/vectorial_text/src/main.rs @@ -1,9 +1,9 @@ -use iced::alignment::{self, Alignment}; +use iced::alignment;  use iced::mouse;  use iced::widget::{      canvas, checkbox, column, horizontal_space, row, slider, text,  }; -use iced::{Element, Length, Point, Rectangle, Renderer, Theme, Vector}; +use iced::{Center, Element, Fill, Point, Rectangle, Renderer, Theme, Vector};  pub fn main() -> iced::Result {      iced::application( @@ -59,7 +59,7 @@ impl VectorialText {          };          column![ -            canvas(&self.state).width(Length::Fill).height(Length::Fill), +            canvas(&self.state).width(Fill).height(Fill),              column![                  checkbox("Use Japanese", self.state.use_japanese,)                      .on_toggle(Message::ToggleJapanese), @@ -85,7 +85,7 @@ impl VectorialText {                  ]                  .spacing(20),              ] -            .align_items(Alignment::Center) +            .align_x(Center)              .spacing(10)          ]          .spacing(10) diff --git a/examples/visible_bounds/src/main.rs b/examples/visible_bounds/src/main.rs index e46d1ff0..77fec65e 100644 --- a/examples/visible_bounds/src/main.rs +++ b/examples/visible_bounds/src/main.rs @@ -5,8 +5,8 @@ use iced::widget::{  };  use iced::window;  use iced::{ -    Alignment, Color, Element, Font, Length, Point, Rectangle, Subscription, -    Task, Theme, +    Center, Color, Element, Fill, Font, Point, Rectangle, Subscription, Task, +    Theme,  };  pub fn main() -> iced::Result { @@ -70,7 +70,7 @@ impl Example {                      .color_maybe(color),              ]              .height(40) -            .align_items(Alignment::Center) +            .align_y(Center)          };          let view_bounds = |label, bounds: Option<Rectangle>| { @@ -130,13 +130,13 @@ impl Example {                          .padding(20)                      )                      .on_scroll(|_| Message::Scrolled) -                    .width(Length::Fill) +                    .width(Fill)                      .height(300),                  ]                  .padding(20)              )              .on_scroll(|_| Message::Scrolled) -            .width(Length::Fill) +            .width(Fill)              .height(300),          ]          .spacing(10) diff --git a/examples/websocket/src/main.rs b/examples/websocket/src/main.rs index d8246436..8b1efb41 100644 --- a/examples/websocket/src/main.rs +++ b/examples/websocket/src/main.rs @@ -1,10 +1,9 @@  mod echo; -use iced::alignment::{self, Alignment};  use iced::widget::{      self, button, center, column, row, scrollable, text, text_input,  }; -use iced::{color, Element, Length, Subscription, Task}; +use iced::{color, Center, Element, Fill, Subscription, Task};  use once_cell::sync::Lazy;  pub fn main() -> iced::Result { @@ -104,7 +103,7 @@ impl WebSocket {                      .spacing(10),              )              .id(MESSAGE_LOG.clone()) -            .height(Length::Fill) +            .height(Fill)              .into()          }; @@ -113,12 +112,8 @@ impl WebSocket {                  .on_input(Message::NewMessageChanged)                  .padding(10); -            let mut button = button( -                text("Send") -                    .height(40) -                    .vertical_alignment(alignment::Vertical::Center), -            ) -            .padding([0, 20]); +            let mut button = button(text("Send").height(40).align_y(Center)) +                .padding([0, 20]);              if matches!(self.state, State::Connected(_)) {                  if let Some(message) = echo::Message::new(&self.new_message) { @@ -127,13 +122,11 @@ impl WebSocket {                  }              } -            row![input, button] -                .spacing(10) -                .align_items(Alignment::Center) +            row![input, button].spacing(10).align_y(Center)          };          column![message_log, new_message_input] -            .height(Length::Fill) +            .height(Fill)              .padding(20)              .spacing(10)              .into() @@ -196,6 +196,7 @@ pub use crate::core::alignment;  pub use crate::core::border;  pub use crate::core::color;  pub use crate::core::gradient; +pub use crate::core::padding;  pub use crate::core::theme;  pub use crate::core::{      Alignment, Background, Border, Color, ContentFit, Degrees, Gradient, @@ -205,6 +206,11 @@ pub use crate::core::{  pub use crate::runtime::exit;  pub use iced_futures::Subscription; +pub use alignment::Horizontal::{Left, Right}; +pub use alignment::Vertical::{Bottom, Top}; +pub use Alignment::Center; +pub use Length::{Fill, FillPortion, Shrink}; +  pub mod task {      //! Create runtime tasks.      pub use crate::runtime::task::{Handle, Task}; diff --git a/widget/src/button.rs b/widget/src/button.rs index fb505d6e..64a639d2 100644 --- a/widget/src/button.rs +++ b/widget/src/button.rs @@ -1,4 +1,5 @@  //! Allow your users to perform actions by pressing a button. +use crate::core::border::{self, Border};  use crate::core::event::{self, Event};  use crate::core::layout;  use crate::core::mouse; @@ -9,8 +10,8 @@ use crate::core::touch;  use crate::core::widget::tree::{self, Tree};  use crate::core::widget::Operation;  use crate::core::{ -    Background, Border, Clipboard, Color, Element, Layout, Length, Padding, -    Rectangle, Shadow, Shell, Size, Theme, Vector, Widget, +    Background, Clipboard, Color, Element, Layout, Length, Padding, Rectangle, +    Shadow, Shell, Size, Theme, Vector, Widget,  };  /// A generic widget that produces a message when pressed. @@ -591,7 +592,7 @@ fn styled(pair: palette::Pair) -> Style {      Style {          background: Some(Background::Color(pair.color)),          text_color: pair.text, -        border: Border::rounded(2), +        border: border::rounded(2),          ..Style::default()      }  } diff --git a/widget/src/column.rs b/widget/src/column.rs index 0b81c545..ae82ccaa 100644 --- a/widget/src/column.rs +++ b/widget/src/column.rs @@ -1,4 +1,5 @@  //! Distribute content vertically. +use crate::core::alignment::{self, Alignment};  use crate::core::event::{self, Event};  use crate::core::layout;  use crate::core::mouse; @@ -6,8 +7,8 @@ use crate::core::overlay;  use crate::core::renderer;  use crate::core::widget::{Operation, Tree};  use crate::core::{ -    Alignment, Clipboard, Element, Layout, Length, Padding, Pixels, Rectangle, -    Shell, Size, Vector, Widget, +    Clipboard, Element, Layout, Length, Padding, Pixels, Rectangle, Shell, +    Size, Vector, Widget,  };  /// A container that distributes its contents vertically. @@ -19,7 +20,7 @@ pub struct Column<'a, Message, Theme = crate::Theme, Renderer = crate::Renderer>      width: Length,      height: Length,      max_width: f32, -    align_items: Alignment, +    align: Alignment,      clip: bool,      children: Vec<Element<'a, Message, Theme, Renderer>>,  } @@ -63,7 +64,7 @@ where              width: Length::Shrink,              height: Length::Shrink,              max_width: f32::INFINITY, -            align_items: Alignment::Start, +            align: Alignment::Start,              clip: false,              children,          } @@ -104,8 +105,8 @@ where      }      /// Sets the horizontal alignment of the contents of the [`Column`] . -    pub fn align_items(mut self, align: Alignment) -> Self { -        self.align_items = align; +    pub fn align_x(mut self, align: impl Into<alignment::Horizontal>) -> Self { +        self.align = Alignment::from(align.into());          self      } @@ -210,7 +211,7 @@ where              self.height,              self.padding,              self.spacing, -            self.align_items, +            self.align,              &self.children,              &mut tree.children,          ) diff --git a/widget/src/container.rs b/widget/src/container.rs index 08d5cb17..5680bc30 100644 --- a/widget/src/container.rs +++ b/widget/src/container.rs @@ -1,5 +1,6 @@  //! Decorate content and apply alignment.  use crate::core::alignment::{self, Alignment}; +use crate::core::border::{self, Border};  use crate::core::event::{self, Event};  use crate::core::gradient::{self, Gradient};  use crate::core::layout; @@ -9,9 +10,8 @@ use crate::core::renderer;  use crate::core::widget::tree::{self, Tree};  use crate::core::widget::{self, Operation};  use crate::core::{ -    self, Background, Border, Clipboard, Color, Element, Layout, Length, -    Padding, Pixels, Point, Rectangle, Shadow, Shell, Size, Theme, Vector, -    Widget, +    self, Background, Clipboard, Color, Element, Layout, Length, Padding, +    Pixels, Point, Rectangle, Shadow, Shell, Size, Theme, Vector, Widget,  };  use crate::runtime::task::{self, Task}; @@ -92,46 +92,6 @@ where          self      } -    /// Sets the [`Container`] to fill the available space in the horizontal axis. -    /// -    /// This can be useful to quickly position content when chained with -    /// alignment functions—like [`center_x`]. -    /// -    /// Calling this method is equivalent to calling [`width`] with a -    /// [`Length::Fill`]. -    /// -    /// [`center_x`]: Self::center_x -    /// [`width`]: Self::width -    pub fn fill_x(self) -> Self { -        self.width(Length::Fill) -    } - -    /// Sets the [`Container`] to fill the available space in the vetical axis. -    /// -    /// This can be useful to quickly position content when chained with -    /// alignment functions—like [`center_y`]. -    /// -    /// Calling this method is equivalent to calling [`height`] with a -    /// [`Length::Fill`]. -    /// -    /// [`center_y`]: Self::center_x -    /// [`height`]: Self::height -    pub fn fill_y(self) -> Self { -        self.height(Length::Fill) -    } - -    /// Sets the [`Container`] to fill all the available space. -    /// -    /// Calling this method is equivalent to chaining [`fill_x`] and -    /// [`fill_y`]. -    /// -    /// [`center`]: Self::center -    /// [`fill_x`]: Self::fill_x -    /// [`fill_y`]: Self::fill_y -    pub fn fill(self) -> Self { -        self.width(Length::Fill).height(Length::Fill) -    } -      /// Sets the maximum width of the [`Container`].      pub fn max_width(mut self, max_width: impl Into<Pixels>) -> Self {          self.max_width = max_width.into().0; @@ -144,18 +104,6 @@ where          self      } -    /// Sets the content alignment for the horizontal axis of the [`Container`]. -    pub fn align_x(mut self, alignment: alignment::Horizontal) -> Self { -        self.horizontal_alignment = alignment; -        self -    } - -    /// Sets the content alignment for the vertical axis of the [`Container`]. -    pub fn align_y(mut self, alignment: alignment::Vertical) -> Self { -        self.vertical_alignment = alignment; -        self -    } -      /// Sets the width of the [`Container`] and centers its contents horizontally.      pub fn center_x(self, width: impl Into<Length>) -> Self {          self.width(width).align_x(alignment::Horizontal::Center) @@ -179,6 +127,44 @@ where          self.center_x(length).center_y(length)      } +    /// Aligns the contents of the [`Container`] to the left. +    pub fn align_left(self, width: impl Into<Length>) -> Self { +        self.width(width).align_x(alignment::Horizontal::Left) +    } + +    /// Aligns the contents of the [`Container`] to the right. +    pub fn align_right(self, width: impl Into<Length>) -> Self { +        self.width(width).align_x(alignment::Horizontal::Right) +    } + +    /// Aligns the contents of the [`Container`] to the top. +    pub fn align_top(self, height: impl Into<Length>) -> Self { +        self.height(height).align_y(alignment::Vertical::Top) +    } + +    /// Aligns the contents of the [`Container`] to the bottom. +    pub fn align_bottom(self, height: impl Into<Length>) -> Self { +        self.height(height).align_y(alignment::Vertical::Bottom) +    } + +    /// Sets the content alignment for the horizontal axis of the [`Container`]. +    pub fn align_x( +        mut self, +        alignment: impl Into<alignment::Horizontal>, +    ) -> Self { +        self.horizontal_alignment = alignment.into(); +        self +    } + +    /// Sets the content alignment for the vertical axis of the [`Container`]. +    pub fn align_y( +        mut self, +        alignment: impl Into<alignment::Vertical>, +    ) -> Self { +        self.vertical_alignment = alignment.into(); +        self +    } +      /// Sets whether the contents of the [`Container`] should be clipped on      /// overflow.      pub fn clip(mut self, clip: bool) -> Self { @@ -641,7 +627,7 @@ pub fn rounded_box(theme: &Theme) -> Style {      Style {          background: Some(palette.background.weak.color.into()), -        border: Border::rounded(2), +        border: border::rounded(2),          ..Style::default()      }  } diff --git a/widget/src/helpers.rs b/widget/src/helpers.rs index d7631959..1f282f54 100644 --- a/widget/src/helpers.rs +++ b/widget/src/helpers.rs @@ -921,7 +921,7 @@ where          text("iced").size(text_size).font(Font::MONOSPACE)      ]      .spacing(text_size.0 / 3.0) -    .align_items(Alignment::Center) +    .align_y(Alignment::Center)      .into()  } diff --git a/widget/src/overlay/menu.rs b/widget/src/overlay/menu.rs index a43c8e8b..73d1cc8c 100644 --- a/widget/src/overlay/menu.rs +++ b/widget/src/overlay/menu.rs @@ -1,5 +1,6 @@  //! Build and show dropdown menus.  use crate::core::alignment; +use crate::core::border::{self, Border};  use crate::core::event::{self, Event};  use crate::core::layout::{self, Layout};  use crate::core::mouse; @@ -9,8 +10,8 @@ use crate::core::text::{self, Text};  use crate::core::touch;  use crate::core::widget::Tree;  use crate::core::{ -    Background, Border, Clipboard, Color, Length, Padding, Pixels, Point, -    Rectangle, Size, Theme, Vector, +    Background, Clipboard, Color, Length, Padding, Pixels, Point, Rectangle, +    Size, Theme, Vector,  };  use crate::core::{Element, Shell, Widget};  use crate::scrollable::{self, Scrollable}; @@ -514,7 +515,7 @@ where                              width: bounds.width - style.border.width * 2.0,                              ..bounds                          }, -                        border: Border::rounded(style.border.radius), +                        border: border::rounded(style.border.radius),                          ..renderer::Quad::default()                      },                      style.selected_background, diff --git a/widget/src/progress_bar.rs b/widget/src/progress_bar.rs index e7821b43..88d1850a 100644 --- a/widget/src/progress_bar.rs +++ b/widget/src/progress_bar.rs @@ -1,11 +1,11 @@  //! Provide progress feedback to your users. +use crate::core::border::{self, Border};  use crate::core::layout;  use crate::core::mouse;  use crate::core::renderer;  use crate::core::widget::Tree;  use crate::core::{ -    self, Background, Border, Element, Layout, Length, Rectangle, Size, Theme, -    Widget, +    self, Background, Element, Layout, Length, Rectangle, Size, Theme, Widget,  };  use std::ops::RangeInclusive; @@ -151,7 +151,7 @@ where                          width: active_progress_width,                          ..bounds                      }, -                    border: Border::rounded(style.border.radius), +                    border: border::rounded(style.border.radius),                      ..renderer::Quad::default()                  },                  style.bar, @@ -255,6 +255,6 @@ fn styled(      Style {          background: background.into(),          bar: bar.into(), -        border: Border::rounded(2), +        border: border::rounded(2),      }  } diff --git a/widget/src/radio.rs b/widget/src/radio.rs index 6b22961d..ccc6a21e 100644 --- a/widget/src/radio.rs +++ b/widget/src/radio.rs @@ -1,5 +1,6 @@  //! Create choices using radio buttons.  use crate::core::alignment; +use crate::core::border::{self, Border};  use crate::core::event::{self, Event};  use crate::core::layout;  use crate::core::mouse; @@ -9,8 +10,8 @@ use crate::core::touch;  use crate::core::widget;  use crate::core::widget::tree::{self, Tree};  use crate::core::{ -    Background, Border, Clipboard, Color, Element, Layout, Length, Pixels, -    Rectangle, Shell, Size, Theme, Widget, +    Background, Clipboard, Color, Element, Layout, Length, Pixels, Rectangle, +    Shell, Size, Theme, Widget,  };  /// A circular button representing a choice. @@ -342,7 +343,7 @@ where                              width: bounds.width - dot_size,                              height: bounds.height - dot_size,                          }, -                        border: Border::rounded(dot_size / 2.0), +                        border: border::rounded(dot_size / 2.0),                          ..renderer::Quad::default()                      },                      style.dot_color, diff --git a/widget/src/row.rs b/widget/src/row.rs index c8fcdb61..3feeaa7e 100644 --- a/widget/src/row.rs +++ b/widget/src/row.rs @@ -1,4 +1,5 @@  //! Distribute content horizontally. +use crate::core::alignment::{self, Alignment};  use crate::core::event::{self, Event};  use crate::core::layout::{self, Layout};  use crate::core::mouse; @@ -6,8 +7,8 @@ use crate::core::overlay;  use crate::core::renderer;  use crate::core::widget::{Operation, Tree};  use crate::core::{ -    Alignment, Clipboard, Element, Length, Padding, Pixels, Rectangle, Shell, -    Size, Vector, Widget, +    Clipboard, Element, Length, Padding, Pixels, Rectangle, Shell, Size, +    Vector, Widget,  };  /// A container that distributes its contents horizontally. @@ -17,7 +18,7 @@ pub struct Row<'a, Message, Theme = crate::Theme, Renderer = crate::Renderer> {      padding: Padding,      width: Length,      height: Length, -    align_items: Alignment, +    align: Alignment,      clip: bool,      children: Vec<Element<'a, Message, Theme, Renderer>>,  } @@ -60,7 +61,7 @@ where              padding: Padding::ZERO,              width: Length::Shrink,              height: Length::Shrink, -            align_items: Alignment::Start, +            align: Alignment::Start,              clip: false,              children,          } @@ -95,8 +96,8 @@ where      }      /// Sets the vertical alignment of the contents of the [`Row`] . -    pub fn align_items(mut self, align: Alignment) -> Self { -        self.align_items = align; +    pub fn align_y(mut self, align: impl Into<alignment::Vertical>) -> Self { +        self.align = Alignment::from(align.into());          self      } @@ -199,7 +200,7 @@ where              self.height,              self.padding,              self.spacing, -            self.align_items, +            self.align,              &self.children,              &mut tree.children,          ) diff --git a/widget/src/rule.rs b/widget/src/rule.rs index 1a536d2f..bbcd577e 100644 --- a/widget/src/rule.rs +++ b/widget/src/rule.rs @@ -1,6 +1,6 @@  //! Display a horizontal or vertical rule for dividing content.  use crate::core; -use crate::core::border::{self, Border}; +use crate::core::border;  use crate::core::layout;  use crate::core::mouse;  use crate::core::renderer; @@ -132,7 +132,7 @@ where          renderer.fill_quad(              renderer::Quad {                  bounds, -                border: Border::rounded(style.radius), +                border: border::rounded(style.radius),                  ..renderer::Quad::default()              },              style.color, diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index e6208528..52e5391e 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -1,5 +1,6 @@  //! Navigate an endless amount of content with a scrollbar.  use crate::container; +use crate::core::border::{self, Border};  use crate::core::event::{self, Event};  use crate::core::keyboard;  use crate::core::layout; @@ -11,8 +12,8 @@ use crate::core::widget;  use crate::core::widget::operation::{self, Operation};  use crate::core::widget::tree::{self, Tree};  use crate::core::{ -    self, Background, Border, Clipboard, Color, Element, Layout, Length, -    Padding, Pixels, Point, Rectangle, Shell, Size, Theme, Vector, Widget, +    self, Background, Clipboard, Color, Element, Layout, Length, Padding, +    Pixels, Point, Rectangle, Shell, Size, Theme, Vector, Widget,  };  use crate::runtime::task::{self, Task};  use crate::runtime::Action; @@ -109,53 +110,70 @@ where          self      } -    /// Sets the alignment of the horizontal direction of the [`Scrollable`], if applicable. -    pub fn align_x(mut self, alignment: Alignment) -> Self { +    /// Anchors the vertical [`Scrollable`] direction to the top. +    pub fn anchor_top(self) -> Self { +        self.anchor_y(Anchor::Start) +    } + +    /// Anchors the vertical [`Scrollable`] direction to the bottom. +    pub fn anchor_bottom(self) -> Self { +        self.anchor_y(Anchor::End) +    } + +    /// Anchors the horizontal [`Scrollable`] direction to the left. +    pub fn anchor_left(self) -> Self { +        self.anchor_x(Anchor::Start) +    } + +    /// Anchors the horizontal [`Scrollable`] direction to the right. +    pub fn anchor_right(self) -> Self { +        self.anchor_x(Anchor::End) +    } + +    /// Sets the [`Anchor`] of the horizontal direction of the [`Scrollable`], if applicable. +    pub fn anchor_x(mut self, alignment: Anchor) -> Self {          match &mut self.direction { -            Direction::Horizontal(horizontal) +            Direction::Horizontal { +                scrollbar: horizontal, +                .. +            }              | Direction::Both { horizontal, .. } => {                  horizontal.alignment = alignment;              } -            Direction::Vertical(_) => {} +            Direction::Vertical { .. } => {}          }          self      } -    /// Sets the alignment of the vertical direction of the [`Scrollable`], if applicable. -    pub fn align_y(mut self, alignment: Alignment) -> Self { +    /// Sets the [`Anchor`] of the vertical direction of the [`Scrollable`], if applicable. +    pub fn anchor_y(mut self, alignment: Anchor) -> Self {          match &mut self.direction { -            Direction::Vertical(vertical) +            Direction::Vertical { +                scrollbar: vertical, +                .. +            }              | Direction::Both { vertical, .. } => {                  vertical.alignment = alignment;              } -            Direction::Horizontal(_) => {} +            Direction::Horizontal { .. } => {}          }          self      } -    /// Sets whether the horizontal [`Scrollbar`] should be embedded in the [`Scrollable`]. -    pub fn embed_x(mut self, embedded: bool) -> Self { -        match &mut self.direction { -            Direction::Horizontal(horizontal) -            | Direction::Both { horizontal, .. } => { -                horizontal.embedded = embedded; -            } -            Direction::Vertical(_) => {} -        } - -        self -    } - -    /// Sets whether the vertical [`Scrollbar`] should be embedded in the [`Scrollable`]. -    pub fn embed_y(mut self, embedded: bool) -> Self { +    /// Embeds the [`Scrollbar`] into the [`Scrollable`], instead of floating on top of the +    /// content. +    /// +    /// The `spacing` provided will be used as space between the [`Scrollbar`] and the contents +    /// of the [`Scrollable`]. +    pub fn spacing(mut self, new_spacing: impl Into<Pixels>) -> Self {          match &mut self.direction { -            Direction::Vertical(vertical) -            | Direction::Both { vertical, .. } => { -                vertical.embedded = embedded; +            Direction::Horizontal { spacing, .. } +            | Direction::Vertical { spacing, .. } => { +                *spacing = Some(new_spacing.into().0);              } -            Direction::Horizontal(_) => {} +            Direction::Both { .. } => {}          }          self @@ -184,9 +202,19 @@ where  #[derive(Debug, Clone, Copy, PartialEq)]  pub enum Direction {      /// Vertical scrolling -    Vertical(Scrollbar), +    Vertical { +        /// The vertical [`Scrollbar`]. +        scrollbar: Scrollbar, +        /// The amount of spacing between the [`Scrollbar`] and the contents, if embedded. +        spacing: Option<f32>, +    },      /// Horizontal scrolling -    Horizontal(Scrollbar), +    Horizontal { +        /// The horizontal [`Scrollbar`]. +        scrollbar: Scrollbar, +        /// The amount of spacing between the [`Scrollbar`] and the contents, if embedded. +        spacing: Option<f32>, +    },      /// Both vertical and horizontal scrolling      Both {          /// The properties of the vertical scrollbar. @@ -200,25 +228,28 @@ impl Direction {      /// Returns the horizontal [`Scrollbar`], if any.      pub fn horizontal(&self) -> Option<&Scrollbar> {          match self { -            Self::Horizontal(properties) => Some(properties), +            Self::Horizontal { scrollbar, .. } => Some(scrollbar),              Self::Both { horizontal, .. } => Some(horizontal), -            Self::Vertical(_) => None, +            Self::Vertical { .. } => None,          }      }      /// Returns the vertical [`Scrollbar`], if any.      pub fn vertical(&self) -> Option<&Scrollbar> {          match self { -            Self::Vertical(properties) => Some(properties), +            Self::Vertical { scrollbar, .. } => Some(scrollbar),              Self::Both { vertical, .. } => Some(vertical), -            Self::Horizontal(_) => None, +            Self::Horizontal { .. } => None,          }      }  }  impl Default for Direction {      fn default() -> Self { -        Self::Vertical(Scrollbar::default()) +        Self::Vertical { +            scrollbar: Scrollbar::default(), +            spacing: None, +        }      }  } @@ -228,8 +259,8 @@ pub struct Scrollbar {      width: f32,      margin: f32,      scroller_width: f32, -    alignment: Alignment, -    embedded: bool, +    alignment: Anchor, +    spacing: Option<f32>,  }  impl Default for Scrollbar { @@ -238,8 +269,8 @@ impl Default for Scrollbar {              width: 10.0,              margin: 0.0,              scroller_width: 10.0, -            alignment: Alignment::Start, -            embedded: false, +            alignment: Anchor::Start, +            spacing: None,          }      }  } @@ -250,47 +281,49 @@ impl Scrollbar {          Self::default()      } -    /// Sets the scrollbar width of the [`Scrollable`] . +    /// Sets the scrollbar width of the [`Scrollbar`] .      pub fn width(mut self, width: impl Into<Pixels>) -> Self {          self.width = width.into().0.max(0.0);          self      } -    /// Sets the scrollbar margin of the [`Scrollable`] . +    /// Sets the scrollbar margin of the [`Scrollbar`] .      pub fn margin(mut self, margin: impl Into<Pixels>) -> Self {          self.margin = margin.into().0;          self      } -    /// Sets the scroller width of the [`Scrollable`] . +    /// Sets the scroller width of the [`Scrollbar`] .      pub fn scroller_width(mut self, scroller_width: impl Into<Pixels>) -> Self {          self.scroller_width = scroller_width.into().0.max(0.0);          self      } -    /// Sets the alignment of the [`Scrollable`] . -    pub fn alignment(mut self, alignment: Alignment) -> Self { +    /// Sets the [`Anchor`] of the [`Scrollbar`] . +    pub fn anchor(mut self, alignment: Anchor) -> Self {          self.alignment = alignment;          self      } -    /// Sets whether the [`Scrollbar`] should be embedded in the [`Scrollable`]. +    /// Sets whether the [`Scrollbar`] should be embedded in the [`Scrollable`], using +    /// the given spacing between itself and the contents.      ///      /// An embedded [`Scrollbar`] will always be displayed, will take layout space,      /// and will not float over the contents. -    pub fn embedded(mut self, embedded: bool) -> Self { -        self.embedded = embedded; +    pub fn spacing(mut self, spacing: impl Into<Pixels>) -> Self { +        self.spacing = Some(spacing.into().0);          self      }  } -/// Alignment of the scrollable's content relative to it's [`Viewport`] in one direction. +/// The anchor of the scroller of the [`Scrollable`] relative to its [`Viewport`] +/// on a given axis.  #[derive(Debug, Clone, Copy, Default, PartialEq, Eq)] -pub enum Alignment { -    /// Content is aligned to the start of the [`Viewport`]. +pub enum Anchor { +    /// Scroller is anchoer to the start of the [`Viewport`].      #[default]      Start, -    /// Content is aligned to the end of the [`Viewport`] +    /// Content is aligned to the end of the [`Viewport`].      End,  } @@ -330,12 +363,14 @@ where          limits: &layout::Limits,      ) -> layout::Node {          let (right_padding, bottom_padding) = match self.direction { -            Direction::Vertical(scrollbar) if scrollbar.embedded => { -                (scrollbar.width + scrollbar.margin * 2.0, 0.0) -            } -            Direction::Horizontal(scrollbar) if scrollbar.embedded => { -                (0.0, scrollbar.width + scrollbar.margin * 2.0) -            } +            Direction::Vertical { +                scrollbar, +                spacing: Some(spacing), +            } => (scrollbar.width + scrollbar.margin * 2.0 + spacing, 0.0), +            Direction::Horizontal { +                scrollbar, +                spacing: Some(spacing), +            } => (0.0, scrollbar.width + scrollbar.margin * 2.0 + spacing),              _ => (0.0, 0.0),          }; @@ -1159,13 +1194,13 @@ impl Offset {          self,          viewport: f32,          content: f32, -        alignment: Alignment, +        alignment: Anchor,      ) -> f32 {          let offset = self.absolute(viewport, content);          match alignment { -            Alignment::Start => offset, -            Alignment::End => ((content - viewport).max(0.0) - offset).max(0.0), +            Anchor::Start => offset, +            Anchor::End => ((content - viewport).max(0.0) - offset).max(0.0),          }      }  } @@ -1252,9 +1287,9 @@ impl State {              .map(|p| p.alignment)              .unwrap_or_default(); -        let align = |alignment: Alignment, delta: f32| match alignment { -            Alignment::Start => delta, -            Alignment::End => -delta, +        let align = |alignment: Anchor, delta: f32| match alignment { +            Anchor::Start => delta, +            Anchor::End => -delta,          };          let delta = Vector::new( @@ -1385,11 +1420,11 @@ impl Scrollbars {          let translation = state.translation(direction, bounds, content_bounds);          let show_scrollbar_x = direction.horizontal().filter(|scrollbar| { -            scrollbar.embedded || content_bounds.width > bounds.width +            scrollbar.spacing.is_some() || content_bounds.width > bounds.width          });          let show_scrollbar_y = direction.vertical().filter(|scrollbar| { -            scrollbar.embedded || content_bounds.height > bounds.height +            scrollbar.spacing.is_some() || content_bounds.height > bounds.height          });          let y_scrollbar = if let Some(vertical) = show_scrollbar_y { @@ -1592,14 +1627,14 @@ impl Scrollbars {  pub(super) mod internals {      use crate::core::{Point, Rectangle}; -    use super::Alignment; +    use super::Anchor;      #[derive(Debug, Copy, Clone)]      pub struct Scrollbar {          pub total_bounds: Rectangle,          pub bounds: Rectangle,          pub scroller: Option<Scroller>, -        pub alignment: Alignment, +        pub alignment: Anchor,      }      impl Scrollbar { @@ -1621,8 +1656,8 @@ pub(super) mod internals {                      / (self.bounds.height - scroller.bounds.height);                  match self.alignment { -                    Alignment::Start => percentage, -                    Alignment::End => 1.0 - percentage, +                    Anchor::Start => percentage, +                    Anchor::End => 1.0 - percentage,                  }              } else {                  0.0 @@ -1642,8 +1677,8 @@ pub(super) mod internals {                      / (self.bounds.width - scroller.bounds.width);                  match self.alignment { -                    Alignment::Start => percentage, -                    Alignment::End => 1.0 - percentage, +                    Anchor::Start => percentage, +                    Anchor::End => 1.0 - percentage,                  }              } else {                  0.0 @@ -1746,10 +1781,10 @@ pub fn default(theme: &Theme, status: Status) -> Style {      let scrollbar = Rail {          background: Some(palette.background.weak.color.into()), -        border: Border::rounded(2), +        border: border::rounded(2),          scroller: Scroller {              color: palette.background.strong.color, -            border: Border::rounded(2), +            border: border::rounded(2),          },      }; diff --git a/widget/src/slider.rs b/widget/src/slider.rs index 74e6f8d3..b9419232 100644 --- a/widget/src/slider.rs +++ b/widget/src/slider.rs @@ -1,5 +1,5 @@  //! Display an interactive selector of a single value from a range of values. -use crate::core::border; +use crate::core::border::{self, Border};  use crate::core::event::{self, Event};  use crate::core::keyboard;  use crate::core::keyboard::key::{self, Key}; @@ -9,8 +9,8 @@ use crate::core::renderer;  use crate::core::touch;  use crate::core::widget::tree::{self, Tree};  use crate::core::{ -    self, Border, Clipboard, Color, Element, Layout, Length, Pixels, Point, -    Rectangle, Shell, Size, Theme, Widget, +    self, Clipboard, Color, Element, Layout, Length, Pixels, Point, Rectangle, +    Shell, Size, Theme, Widget,  };  use std::ops::RangeInclusive; @@ -408,7 +408,7 @@ where                      width: offset + handle_width / 2.0,                      height: style.rail.width,                  }, -                border: Border::rounded(style.rail.border_radius), +                border: border::rounded(style.rail.border_radius),                  ..renderer::Quad::default()              },              style.rail.colors.0, @@ -422,7 +422,7 @@ where                      width: bounds.width - offset - handle_width / 2.0,                      height: style.rail.width,                  }, -                border: Border::rounded(style.rail.border_radius), +                border: border::rounded(style.rail.border_radius),                  ..renderer::Quad::default()              },              style.rail.colors.1, diff --git a/widget/src/vertical_slider.rs b/widget/src/vertical_slider.rs index 33c591f5..6185295b 100644 --- a/widget/src/vertical_slider.rs +++ b/widget/src/vertical_slider.rs @@ -5,6 +5,7 @@ pub use crate::slider::{      default, Catalog, Handle, HandleShape, Status, Style, StyleFn,  }; +use crate::core::border::{self, Border};  use crate::core::event::{self, Event};  use crate::core::keyboard;  use crate::core::keyboard::key::{self, Key}; @@ -14,8 +15,8 @@ use crate::core::renderer;  use crate::core::touch;  use crate::core::widget::tree::{self, Tree};  use crate::core::{ -    self, Border, Clipboard, Element, Length, Pixels, Point, Rectangle, Shell, -    Size, Widget, +    self, Clipboard, Element, Length, Pixels, Point, Rectangle, Shell, Size, +    Widget,  };  /// An vertical bar and a handle that selects a single value from a range of @@ -412,7 +413,7 @@ where                      width: style.rail.width,                      height: offset + handle_width / 2.0,                  }, -                border: Border::rounded(style.rail.border_radius), +                border: border::rounded(style.rail.border_radius),                  ..renderer::Quad::default()              },              style.rail.colors.1, @@ -426,7 +427,7 @@ where                      width: style.rail.width,                      height: bounds.height - offset - handle_width / 2.0,                  }, -                border: Border::rounded(style.rail.border_radius), +                border: border::rounded(style.rail.border_radius),                  ..renderer::Quad::default()              },              style.rail.colors.0,  | 
