Introduce helper methods for alignment for all widgets

This commit is contained in:
Héctor Ramón Jiménez 2024-07-12 15:11:30 +02:00
parent be06060117
commit f9dd5cbb09
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
45 changed files with 380 additions and 282 deletions

View file

@ -1,5 +1,30 @@
//! Align and position widgets. //! Align and position widgets.
/// Returns a value representing center alignment.
pub const fn center() -> Alignment {
Alignment::Center
}
/// Returns a value representing left alignment.
pub const fn left() -> Horizontal {
Horizontal::Left
}
/// Returns a value representing right alignment.
pub const fn right() -> Horizontal {
Horizontal::Right
}
/// Returns a value representing top alignment.
pub const fn top() -> Vertical {
Vertical::Top
}
/// Returns a value representing bottom alignment.
pub const fn bottom() -> Vertical {
Vertical::Bottom
}
/// Alignment on the axis of a container. /// Alignment on the axis of a container.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Alignment { pub enum Alignment {
@ -46,6 +71,16 @@ pub enum Horizontal {
Right, 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. /// The vertical [`Alignment`] of some resource.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Vertical { pub enum Vertical {
@ -58,3 +93,13 @@ pub enum Vertical {
/// Align bottom /// Align bottom
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,
}
}
}

View file

@ -6,7 +6,7 @@
/// (e.g. `impl Into<Pixels>`) and, since `Pixels` implements `From` both for /// (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 /// `f32` and `u16`, you should be able to provide both integers and float
/// literals as needed. /// literals as needed.
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] #[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Default)]
pub struct Pixels(pub f32); pub struct Pixels(pub f32);
impl From<f32> for Pixels { 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 { impl std::ops::Mul<f32> for Pixels {
type Output = Pixels; type Output = Pixels;

View file

@ -86,21 +86,56 @@ where
self self
} }
/// Centers the [`Text`], both horizontally and vertically.
pub fn center(self) -> Self {
self.center_x().center_y()
}
/// Centers the [`Text`] horizontally.
pub fn center_x(self) -> Self {
self.align_x(alignment::center())
}
/// Aligns the [`Text`] to the left, the default.
pub fn align_left(self) -> Self {
self.align_x(alignment::left())
}
/// Aligns the [`Text`] to the right.
pub fn align_right(self) -> Self {
self.align_x(alignment::right())
}
/// Centers the [`Text`] vertically.
pub fn center_y(self) -> Self {
self.align_y(alignment::center())
}
/// Aligns the [`Text`] to the top, the default.
pub fn align_top(self) -> Self {
self.align_y(alignment::top())
}
/// Aligns the [`Text`] to the bottom.
pub fn align_bottom(self) -> Self {
self.align_y(alignment::bottom())
}
/// Sets the [`alignment::Horizontal`] of the [`Text`]. /// Sets the [`alignment::Horizontal`] of the [`Text`].
pub fn horizontal_alignment( pub fn align_x(
mut self, mut self,
alignment: alignment::Horizontal, alignment: impl Into<alignment::Horizontal>,
) -> Self { ) -> Self {
self.horizontal_alignment = alignment; self.horizontal_alignment = alignment.into();
self self
} }
/// Sets the [`alignment::Vertical`] of the [`Text`]. /// Sets the [`alignment::Vertical`] of the [`Text`].
pub fn vertical_alignment( pub fn align_y(
mut self, mut self,
alignment: alignment::Vertical, alignment: impl Into<alignment::Vertical>,
) -> Self { ) -> Self {
self.vertical_alignment = alignment; self.vertical_alignment = alignment.into();
self self
} }

View file

@ -1,5 +1,4 @@
//! This example showcases an interactive `Canvas` for drawing Bézier curves. //! This example showcases an interactive `Canvas` for drawing Bézier curves.
use iced::alignment;
use iced::widget::{button, container, horizontal_space, hover}; use iced::widget::{button, container, horizontal_space, hover};
use iced::{Element, Length, Theme}; use iced::{Element, Length, Theme};
@ -49,7 +48,7 @@ impl Example {
) )
.padding(10) .padding(10)
.width(Length::Fill) .width(Length::Fill)
.align_x(alignment::Horizontal::Right) .align_right()
}, },
)) ))
.padding(20) .padding(20)

View file

@ -1,4 +1,4 @@
use iced::alignment::{self, Alignment}; use iced::alignment;
use iced::mouse; use iced::mouse;
use iced::widget::canvas::{self, Canvas, Frame, Geometry, Path}; use iced::widget::canvas::{self, Canvas, Frame, Geometry, Path};
use iced::widget::{column, row, text, Slider}; use iced::widget::{column, row, text, Slider};
@ -320,7 +320,7 @@ impl<C: ColorSpace + Copy> ColorPicker<C> {
text(color.to_string()).width(185).size(12), text(color.to_string()).width(185).size(12),
] ]
.spacing(10) .spacing(10)
.align_items(Alignment::Center) .center_y()
.into() .into()
} }
} }

View file

@ -1,7 +1,7 @@
use iced::widget::{ use iced::widget::{
center, column, combo_box, scrollable, text, vertical_space, center, column, combo_box, scrollable, text, vertical_space,
}; };
use iced::{Alignment, Element, Length}; use iced::{Element, Length};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::run("Combo Box - Iced", Example::update, Example::view) iced::run("Combo Box - Iced", Example::update, Example::view)
@ -65,7 +65,7 @@ impl Example {
vertical_space().height(150), vertical_space().height(150),
] ]
.width(Length::Fill) .width(Length::Fill)
.align_items(Alignment::Center) .center_x()
.spacing(10); .spacing(10);
center(scrollable(content)).into() center(scrollable(content)).into()

View file

@ -34,7 +34,6 @@ impl Component {
} }
mod numeric_input { mod numeric_input {
use iced::alignment::{self, Alignment};
use iced::widget::{button, component, row, text, text_input, Component}; use iced::widget::{button, component, row, text, text_input, Component};
use iced::{Element, Length, Size}; use iced::{Element, Length, Size};
@ -108,8 +107,7 @@ mod numeric_input {
text(label) text(label)
.width(Length::Fill) .width(Length::Fill)
.height(Length::Fill) .height(Length::Fill)
.horizontal_alignment(alignment::Horizontal::Center) .center(),
.vertical_alignment(alignment::Vertical::Center),
) )
.width(40) .width(40)
.height(40) .height(40)
@ -130,7 +128,7 @@ mod numeric_input {
.padding(10), .padding(10),
button("+", Event::IncrementPressed), button("+", Event::IncrementPressed),
] ]
.align_items(Alignment::Center) .center_y()
.spacing(10) .spacing(10)
.into() .into()
} }

View file

@ -1,5 +1,4 @@
use iced::widget::{button, column, text, Column}; use iced::widget::{button, column, text, Column};
use iced::Alignment;
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::run("A cool counter", Counter::update, Counter::view) iced::run("A cool counter", Counter::update, Counter::view)
@ -35,6 +34,6 @@ impl Counter {
button("Decrement").on_press(Message::Decrement) button("Decrement").on_press(Message::Decrement)
] ]
.padding(20) .padding(20)
.align_items(Alignment::Center) .center_x()
} }
} }

View file

@ -82,7 +82,7 @@ mod quad {
} }
use iced::widget::{center, column, slider, text}; use iced::widget::{center, column, slider, text};
use iced::{Alignment, Color, Element, Shadow, Vector}; use iced::{Color, Element, Shadow, Vector};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::run("Custom Quad - Iced", Example::update, Example::view) iced::run("Custom Quad - Iced", Example::update, Example::view)
@ -185,7 +185,7 @@ impl Example {
.padding(20) .padding(20)
.spacing(20) .spacing(20)
.max_width(500) .max_width(500)
.align_items(Alignment::Center); .center_x();
center(content).into() center(content).into()
} }

View file

@ -6,7 +6,7 @@ use iced::time::Instant;
use iced::widget::shader::wgpu; use iced::widget::shader::wgpu;
use iced::widget::{center, checkbox, column, row, shader, slider, text}; use iced::widget::{center, checkbox, column, row, shader, slider, text};
use iced::window; use iced::window;
use iced::{Alignment, Color, Element, Length, Subscription}; use iced::{Color, Element, Length, Subscription};
fn main() -> iced::Result { fn main() -> iced::Result {
iced::application( iced::application(
@ -122,12 +122,12 @@ impl IcedCubes {
let controls = column![top_controls, bottom_controls,] let controls = column![top_controls, bottom_controls,]
.spacing(10) .spacing(10)
.padding(20) .padding(20)
.align_items(Alignment::Center); .center_x();
let shader = let shader =
shader(&self.scene).width(Length::Fill).height(Length::Fill); shader(&self.scene).width(Length::Fill).height(Length::Fill);
center(column![shader, controls].align_items(Alignment::Center)).into() center(column![shader, controls].center_x()).into()
} }
fn subscription(&self) -> Subscription<Message> { fn subscription(&self) -> Subscription<Message> {

View file

@ -83,7 +83,7 @@ mod circle {
use circle::circle; use circle::circle;
use iced::widget::{center, column, slider, text}; use iced::widget::{center, column, slider, text};
use iced::{Alignment, Element}; use iced::Element;
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::run("Custom Widget - Iced", Example::update, Example::view) iced::run("Custom Widget - Iced", Example::update, Example::view)
@ -120,7 +120,7 @@ impl Example {
.padding(20) .padding(20)
.spacing(20) .spacing(20)
.max_width(500) .max_width(500)
.align_items(Alignment::Center); .center_x();
center(content).into() center(content).into()
} }

View file

@ -1,7 +1,7 @@
mod download; mod download;
use iced::widget::{button, center, column, progress_bar, text, Column}; use iced::widget::{button, center, column, progress_bar, text, Column};
use iced::{Alignment, Element, Subscription}; use iced::{Element, Subscription};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application( iced::application(
@ -69,7 +69,7 @@ impl Example {
.padding(10), .padding(10),
) )
.spacing(20) .spacing(20)
.align_items(Alignment::End); .align_right();
center(downloads).padding(20).into() center(downloads).padding(20).into()
} }
@ -160,7 +160,7 @@ impl Download {
State::Finished => { State::Finished => {
column!["Download finished!", button("Start again")] column!["Download finished!", button("Start again")]
.spacing(10) .spacing(10)
.align_items(Alignment::Center) .center_x()
.into() .into()
} }
State::Downloading { .. } => { State::Downloading { .. } => {
@ -171,14 +171,14 @@ impl Download {
button("Try again").on_press(Message::Download(self.id)), button("Try again").on_press(Message::Download(self.id)),
] ]
.spacing(10) .spacing(10)
.align_items(Alignment::Center) .center_x()
.into(), .into(),
}; };
Column::new() Column::new()
.spacing(10) .spacing(10)
.padding(10) .padding(10)
.align_items(Alignment::Center) .center_x()
.push(progress_bar) .push(progress_bar)
.push(control) .push(control)
.into() .into()

View file

@ -4,7 +4,7 @@ use iced::widget::{
button, column, container, horizontal_space, pick_list, row, text, button, column, container, horizontal_space, pick_list, row, text,
text_editor, tooltip, text_editor, tooltip,
}; };
use iced::{Alignment, Element, Font, Length, Subscription, Task, Theme}; use iced::{Element, Font, Length, Subscription, Task, Theme};
use std::ffi; use std::ffi;
use std::io; use std::io;
@ -158,7 +158,7 @@ impl Editor {
.padding([5, 10]) .padding([5, 10])
] ]
.spacing(10) .spacing(10)
.align_items(Alignment::Center); .center_y();
let status = row![ let status = row![
text(if let Some(path) = &self.file { text(if let Some(path) = &self.file {

View file

@ -1,8 +1,7 @@
use iced::alignment;
use iced::event::{self, Event}; use iced::event::{self, Event};
use iced::widget::{button, center, checkbox, text, Column}; use iced::widget::{button, center, checkbox, text, Column};
use iced::window; use iced::window;
use iced::{Alignment, Element, Length, Subscription, Task}; use iced::{Element, Length, Subscription, Task};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application("Events - Iced", Events::update, Events::view) iced::application("Events - Iced", Events::update, Events::view)
@ -67,17 +66,13 @@ impl Events {
let toggle = checkbox("Listen to runtime events", self.enabled) let toggle = checkbox("Listen to runtime events", self.enabled)
.on_toggle(Message::Toggled); .on_toggle(Message::Toggled);
let exit = button( let exit = button(text("Exit").width(Length::Fill).center_x())
text("Exit") .width(100)
.width(Length::Fill) .padding(10)
.horizontal_alignment(alignment::Horizontal::Center), .on_press(Message::Exit);
)
.width(100)
.padding(10)
.on_press(Message::Exit);
let content = Column::new() let content = Column::new()
.align_items(Alignment::Center) .center_x()
.spacing(20) .spacing(20)
.push(events) .push(events)
.push(toggle) .push(toggle)

View file

@ -1,6 +1,6 @@
use iced::widget::{button, center, column}; use iced::widget::{button, center, column};
use iced::window; use iced::window;
use iced::{Alignment, Element, Task}; use iced::{Element, Task};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application("Exit - Iced", Exit::update, Exit::view).run() iced::application("Exit - Iced", Exit::update, Exit::view).run()
@ -44,7 +44,7 @@ impl Exit {
] ]
} }
.spacing(10) .spacing(10)
.align_items(Alignment::Center); .center_x();
center(content).padding(20).into() center(content).padding(20).into()
} }

View file

@ -4,7 +4,7 @@ use iced::widget::{
}; };
use iced::window; use iced::window;
use iced::{ use iced::{
Alignment, Color, ContentFit, Degrees, Element, Length, Radians, Rotation, Color, ContentFit, Degrees, Element, Length, Radians, Rotation,
Subscription, Theme, Subscription, Theme,
}; };
@ -108,7 +108,7 @@ impl Image {
"I am Ferris!" "I am Ferris!"
] ]
.spacing(20) .spacing(20)
.align_items(Alignment::Center); .center_x();
let fit = row![ let fit = row![
pick_list( pick_list(
@ -134,7 +134,7 @@ impl Image {
.width(Length::Fill), .width(Length::Fill),
] ]
.spacing(10) .spacing(10)
.align_items(Alignment::End); .align_bottom();
let properties = row![ let properties = row![
with_value( with_value(
@ -159,12 +159,12 @@ impl Image {
.size(12) .size(12)
] ]
.spacing(10) .spacing(10)
.align_items(Alignment::Center), .center_y(),
format!("Rotation: {:.0}°", f32::from(self.rotation.degrees())) format!("Rotation: {:.0}°", f32::from(self.rotation.degrees()))
) )
] ]
.spacing(10) .spacing(10)
.align_items(Alignment::End); .align_bottom();
container(column![fit, center(i_am_ferris), properties].spacing(10)) container(column![fit, center(i_am_ferris), properties].spacing(10))
.padding(10) .padding(10)
@ -206,6 +206,6 @@ fn with_value<'a>(
) -> Element<'a, Message> { ) -> Element<'a, Message> {
column![control.into(), text(value).size(12).line_height(1.0)] column![control.into(), text(value).size(12).line_height(1.0)]
.spacing(2) .spacing(2)
.align_items(Alignment::Center) .center_x()
.into() .into()
} }

View file

@ -9,7 +9,7 @@ use iced::time;
use iced::widget::{ use iced::widget::{
button, checkbox, column, container, pick_list, row, slider, text, button, checkbox, column, container, pick_list, row, slider, text,
}; };
use iced::{Alignment, Element, Length, Subscription, Task, Theme}; use iced::{Element, Length, Subscription, Task, Theme};
use std::time::Duration; use std::time::Duration;
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
@ -169,7 +169,7 @@ fn view_controls<'a>(
slider(1.0..=1000.0, speed as f32, Message::SpeedChanged), slider(1.0..=1000.0, speed as f32, Message::SpeedChanged),
text!("x{speed}").size(16), text!("x{speed}").size(16),
] ]
.align_items(Alignment::Center) .center_y()
.spacing(10); .spacing(10);
row![ row![
@ -186,7 +186,7 @@ fn view_controls<'a>(
] ]
.padding(10) .padding(10)
.spacing(20) .spacing(20)
.align_items(Alignment::Center) .center_y()
.into() .into()
} }

View file

@ -3,7 +3,7 @@ use iced::gradient;
use iced::widget::{ use iced::widget::{
checkbox, column, container, horizontal_space, row, slider, text, checkbox, column, container, horizontal_space, row, slider, text,
}; };
use iced::{Alignment, Color, Element, Length, Radians, Theme}; use iced::{Color, Element, Length, Radians, Theme};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
@ -77,7 +77,7 @@ impl Gradient {
] ]
.spacing(8) .spacing(8)
.padding(8) .padding(8)
.align_items(Alignment::Center); .center_y();
let transparency_toggle = iced::widget::Container::new( let transparency_toggle = iced::widget::Container::new(
checkbox("Transparent window", transparent) checkbox("Transparent window", transparent)
@ -129,6 +129,6 @@ fn color_picker(label: &str, color: Color) -> Element<'_, Color> {
] ]
.spacing(8) .spacing(8)
.padding(8) .padding(8)
.align_items(Alignment::Center) .center_y()
.into() .into()
} }

View file

@ -1,6 +1,5 @@
use iced_wgpu::Renderer; use iced_wgpu::Renderer;
use iced_widget::{column, container, row, slider, text, text_input}; 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}; use iced_winit::runtime::{Program, Task};
@ -87,7 +86,7 @@ impl Program for Controls {
) )
.padding(10) .padding(10)
.height(Length::Fill) .height(Length::Fill)
.align_y(alignment::Vertical::Bottom) .align_bottom()
.into() .into()
} }
} }

View file

@ -5,8 +5,8 @@ use iced::widget::{
pick_list, row, scrollable, text, pick_list, row, scrollable, text,
}; };
use iced::{ use iced::{
color, Alignment, Element, Font, Length, Point, Rectangle, Renderer, color, Element, Font, Length, Point, Rectangle, Renderer, Subscription,
Subscription, Theme, Theme,
}; };
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
@ -74,7 +74,7 @@ impl Layout {
pick_list(Theme::ALL, Some(&self.theme), Message::ThemeSelected), pick_list(Theme::ALL, Some(&self.theme), Message::ThemeSelected),
] ]
.spacing(20) .spacing(20)
.align_items(Alignment::Center); .center_y();
let example = center(if self.explain { let example = center(if self.explain {
self.example.view().explain(color!(0x0000ff)) self.example.view().explain(color!(0x0000ff))
@ -234,7 +234,7 @@ fn application<'a>() -> Element<'a, Message> {
square(40), square(40),
] ]
.padding(10) .padding(10)
.align_items(Alignment::Center), .center_y(),
) )
.style(|theme| { .style(|theme| {
let palette = theme.extended_palette(); let palette = theme.extended_palette();
@ -248,7 +248,7 @@ fn application<'a>() -> Element<'a, Message> {
.spacing(40) .spacing(40)
.padding(10) .padding(10)
.width(200) .width(200)
.align_items(Alignment::Center), .center_x(),
) )
.style(container::rounded_box) .style(container::rounded_box)
.center_y(Length::Fill); .center_y(Length::Fill);
@ -263,7 +263,7 @@ fn application<'a>() -> Element<'a, Message> {
"The end" "The end"
] ]
.spacing(40) .spacing(40)
.align_items(Alignment::Center) .center_x()
.width(Length::Fill), .width(Length::Fill),
) )
.height(Length::Fill), .height(Length::Fill),

View file

@ -67,7 +67,7 @@ impl LoadingSpinners {
Duration::from_secs_f32(self.cycle_duration) Duration::from_secs_f32(self.cycle_duration)
) )
] ]
.align_items(iced::Alignment::Center) .center_y()
.spacing(20.0), .spacing(20.0),
) )
}) })
@ -83,7 +83,7 @@ impl LoadingSpinners {
.width(200.0), .width(200.0),
text!("{:.2}s", self.cycle_duration), text!("{:.2}s", self.cycle_duration),
] ]
.align_items(iced::Alignment::Center) .center_y()
.spacing(20.0), .spacing(20.0),
), ),
) )

View file

@ -1,5 +1,5 @@
use iced::widget::{button, center, column, text}; use iced::widget::{button, center, column, text};
use iced::{Alignment, Element}; use iced::Element;
use loupe::loupe; use loupe::loupe;
@ -39,7 +39,7 @@ impl Loupe {
button("Decrement").on_press(Message::Decrement) button("Decrement").on_press(Message::Decrement)
] ]
.padding(20) .padding(20)
.align_items(Alignment::Center), .center_x(),
)) ))
.into() .into()
} }

View file

@ -5,7 +5,7 @@ use iced::widget::{
self, button, center, column, container, horizontal_space, mouse_area, self, button, center, column, container, horizontal_space, mouse_area,
opaque, pick_list, row, stack, text, text_input, opaque, pick_list, row, stack, text, text_input,
}; };
use iced::{Alignment, Color, Element, Length, Subscription, Task}; use iced::{Color, Element, Length, Subscription, Task};
use std::fmt; use std::fmt;
@ -96,7 +96,6 @@ impl App {
let content = container( let content = container(
column![ column![
row![text("Top Left"), horizontal_space(), text("Top Right")] row![text("Top Left"), horizontal_space(), text("Top Right")]
.align_items(Alignment::Start)
.height(Length::Fill), .height(Length::Fill),
center(button(text("Show Modal")).on_press(Message::ShowModal)), center(button(text("Show Modal")).on_press(Message::ShowModal)),
row![ row![
@ -104,7 +103,7 @@ impl App {
horizontal_space(), horizontal_space(),
text("Bottom Right") text("Bottom Right")
] ]
.align_items(Alignment::End) .align_bottom()
.height(Length::Fill), .height(Length::Fill),
] ]
.height(Length::Fill), .height(Length::Fill),

View file

@ -3,7 +3,7 @@ use iced::widget::{
text_input, text_input,
}; };
use iced::window; use iced::window;
use iced::{Alignment, Element, Length, Subscription, Task, Theme, Vector}; use iced::{Element, Length, Subscription, Task, Theme, Vector};
use std::collections::BTreeMap; use std::collections::BTreeMap;
@ -189,7 +189,7 @@ impl Window {
column![scale_input, title_input, new_window_button] column![scale_input, title_input, new_window_button]
.spacing(50) .spacing(50)
.width(Length::Fill) .width(Length::Fill)
.align_items(Alignment::Center), .center_x(),
); );
container(content).center_x(200).into() container(content).center_x(200).into()

View file

@ -1,4 +1,3 @@
use iced::alignment::{self, Alignment};
use iced::keyboard; use iced::keyboard;
use iced::widget::pane_grid::{self, PaneGrid}; use iced::widget::pane_grid::{self, PaneGrid};
use iced::widget::{ use iced::widget::{
@ -255,15 +254,10 @@ fn view_content<'a>(
size: Size, size: Size,
) -> Element<'a, Message> { ) -> Element<'a, Message> {
let button = |label, message| { let button = |label, message| {
button( button(text(label).width(Length::Fill).center_x().size(16))
text(label) .width(Length::Fill)
.width(Length::Fill) .padding(8)
.horizontal_alignment(alignment::Horizontal::Center) .on_press(message)
.size(16),
)
.width(Length::Fill)
.padding(8)
.on_press(message)
}; };
let controls = column![ let controls = column![
@ -287,7 +281,7 @@ fn view_content<'a>(
let content = let content =
column![text!("{}x{}", size.width, size.height).size(24), controls,] column![text!("{}x{}", size.width, size.height).size(24), controls,]
.spacing(10) .spacing(10)
.align_items(Alignment::Center); .center_x();
container(scrollable(content)) container(scrollable(content))
.center_y(Length::Fill) .center_y(Length::Fill)

View file

@ -1,5 +1,5 @@
use iced::widget::{column, pick_list, scrollable, vertical_space}; use iced::widget::{column, pick_list, scrollable, vertical_space};
use iced::{Alignment, Element, Length}; use iced::{Element, Length};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::run("Pick List - Iced", Example::update, Example::view) iced::run("Pick List - Iced", Example::update, Example::view)
@ -39,7 +39,7 @@ impl Example {
vertical_space().height(600), vertical_space().height(600),
] ]
.width(Length::Fill) .width(Length::Fill)
.align_items(Alignment::Center) .center_x()
.spacing(10); .spacing(10);
scrollable(content).into() scrollable(content).into()

View file

@ -1,6 +1,6 @@
use iced::futures; use iced::futures;
use iced::widget::{self, center, column, image, row, text}; use iced::widget::{self, center, column, image, row, text};
use iced::{Alignment, Element, Length, Task}; use iced::{Element, Length, Task};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application(Pokedex::title, Pokedex::update, Pokedex::view) iced::application(Pokedex::title, Pokedex::update, Pokedex::view)
@ -74,13 +74,13 @@ impl Pokedex {
] ]
.max_width(500) .max_width(500)
.spacing(20) .spacing(20)
.align_items(Alignment::End), .align_right(),
Pokedex::Errored => column![ Pokedex::Errored => column![
text("Whoops! Something went wrong...").size(40), text("Whoops! Something went wrong...").size(40),
button("Try again").on_press(Message::Search) button("Try again").on_press(Message::Search)
] ]
.spacing(20) .spacing(20)
.align_items(Alignment::End), .align_right(),
}; };
center(content).into() center(content).into()
@ -106,14 +106,14 @@ impl Pokemon {
text(&self.name).size(30).width(Length::Fill), text(&self.name).size(30).width(Length::Fill),
text!("#{}", self.number).size(20).color([0.5, 0.5, 0.5]), text!("#{}", self.number).size(20).color([0.5, 0.5, 0.5]),
] ]
.align_items(Alignment::Center) .center_y()
.spacing(20), .spacing(20),
self.description.as_ref(), self.description.as_ref(),
] ]
.spacing(20), .spacing(20),
] ]
.spacing(20) .spacing(20)
.align_items(Alignment::Center) .center_y()
.into() .into()
} }

View file

@ -1,5 +1,5 @@
use iced::widget::{center, column, pick_list, qr_code, row, text, text_input}; use iced::widget::{center, column, pick_list, qr_code, row, text, text_input};
use iced::{Alignment, Element, Theme}; use iced::{Element, Theme};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application( iced::application(
@ -58,7 +58,7 @@ impl QRGenerator {
pick_list(Theme::ALL, Some(&self.theme), Message::ThemeChanged,) pick_list(Theme::ALL, Some(&self.theme), Message::ThemeChanged,)
] ]
.spacing(10) .spacing(10)
.align_items(Alignment::Center); .center_y();
let content = column![title, input, choose_theme] let content = column![title, input, choose_theme]
.push_maybe( .push_maybe(
@ -68,7 +68,7 @@ impl QRGenerator {
) )
.width(700) .width(700)
.spacing(20) .spacing(20)
.align_items(Alignment::Center); .center_x();
center(content).padding(20).into() center(content).padding(20).into()
} }

View file

@ -1,11 +1,8 @@
use iced::alignment;
use iced::keyboard; use iced::keyboard;
use iced::widget::{button, column, container, image, row, text, text_input}; use iced::widget::{button, column, container, image, row, text, text_input};
use iced::window; use iced::window;
use iced::window::screenshot::{self, Screenshot}; use iced::window::screenshot::{self, Screenshot};
use iced::{ use iced::{ContentFit, Element, Length, Rectangle, Subscription, Task};
Alignment, ContentFit, Element, Length, Rectangle, Subscription, Task,
};
use ::image as img; use ::image as img;
use ::image::ColorType; use ::image::ColorType;
@ -127,32 +124,24 @@ impl Example {
.style(container::rounded_box); .style(container::rounded_box);
let crop_origin_controls = row![ let crop_origin_controls = row![
text("X:") text("X:").width(30),
.vertical_alignment(alignment::Vertical::Center)
.width(30),
numeric_input("0", self.x_input_value).map(Message::XInputChanged), numeric_input("0", self.x_input_value).map(Message::XInputChanged),
text("Y:") text("Y:").width(30),
.vertical_alignment(alignment::Vertical::Center)
.width(30),
numeric_input("0", self.y_input_value).map(Message::YInputChanged) numeric_input("0", self.y_input_value).map(Message::YInputChanged)
] ]
.spacing(10) .spacing(10)
.align_items(Alignment::Center); .center_y();
let crop_dimension_controls = row![ let crop_dimension_controls = row![
text("W:") text("W:").width(30),
.vertical_alignment(alignment::Vertical::Center)
.width(30),
numeric_input("0", self.width_input_value) numeric_input("0", self.width_input_value)
.map(Message::WidthInputChanged), .map(Message::WidthInputChanged),
text("H:") text("H:").width(30),
.vertical_alignment(alignment::Vertical::Center)
.width(30),
numeric_input("0", self.height_input_value) numeric_input("0", self.height_input_value)
.map(Message::HeightInputChanged) .map(Message::HeightInputChanged)
] ]
.spacing(10) .spacing(10)
.align_items(Alignment::Center); .center_y();
let crop_controls = let crop_controls =
column![crop_origin_controls, crop_dimension_controls] column![crop_origin_controls, crop_dimension_controls]
@ -162,7 +151,7 @@ impl Example {
.map(|error| text!("Crop error! \n{error}")), .map(|error| text!("Crop error! \n{error}")),
) )
.spacing(10) .spacing(10)
.align_items(Alignment::Center); .center_x();
let controls = { let controls = {
let save_result = let save_result =
@ -203,7 +192,7 @@ impl Example {
.width(Length::Fill), .width(Length::Fill),
] ]
.spacing(10) .spacing(10)
.align_items(Alignment::Center), .center_x(),
] ]
.push_maybe(save_result.map(text)) .push_maybe(save_result.map(text))
.spacing(40) .spacing(40)
@ -215,7 +204,7 @@ impl Example {
.spacing(10) .spacing(10)
.width(Length::Fill) .width(Length::Fill)
.height(Length::Fill) .height(Length::Fill)
.align_items(Alignment::Center); .center_y();
container(content).padding(10).into() container(content).padding(10).into()
} }
@ -276,8 +265,5 @@ fn numeric_input(
} }
fn centered_text(content: &str) -> Element<'_, Message> { fn centered_text(content: &str) -> Element<'_, Message> {
text(content) text(content).width(Length::Fill).center_x().into()
.width(Length::Fill)
.horizontal_alignment(alignment::Horizontal::Center)
.into()
} }

View file

@ -2,7 +2,7 @@ use iced::widget::{
button, column, container, horizontal_space, progress_bar, radio, row, button, column, container, horizontal_space, progress_bar, radio, row,
scrollable, slider, text, vertical_space, scrollable, slider, text, vertical_space,
}; };
use iced::{Alignment, Border, Color, Element, Length, Task, Theme}; use iced::{Border, Color, Element, Length, Task, Theme};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
@ -24,7 +24,7 @@ struct ScrollableDemo {
scrollbar_margin: u16, scrollbar_margin: u16,
scroller_width: u16, scroller_width: u16,
current_scroll_offset: scrollable::RelativeOffset, current_scroll_offset: scrollable::RelativeOffset,
alignment: scrollable::Alignment, anchor: scrollable::Anchor,
} }
#[derive(Debug, Clone, Eq, PartialEq, Copy)] #[derive(Debug, Clone, Eq, PartialEq, Copy)]
@ -37,7 +37,7 @@ enum Direction {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
enum Message { enum Message {
SwitchDirection(Direction), SwitchDirection(Direction),
AlignmentChanged(scrollable::Alignment), AlignmentChanged(scrollable::Anchor),
ScrollbarWidthChanged(u16), ScrollbarWidthChanged(u16),
ScrollbarMarginChanged(u16), ScrollbarMarginChanged(u16),
ScrollerWidthChanged(u16), ScrollerWidthChanged(u16),
@ -54,7 +54,7 @@ impl ScrollableDemo {
scrollbar_margin: 0, scrollbar_margin: 0,
scroller_width: 10, scroller_width: 10,
current_scroll_offset: scrollable::RelativeOffset::START, current_scroll_offset: scrollable::RelativeOffset::START,
alignment: scrollable::Alignment::Start, anchor: scrollable::Anchor::Start,
} }
} }
@ -71,7 +71,7 @@ impl ScrollableDemo {
} }
Message::AlignmentChanged(alignment) => { Message::AlignmentChanged(alignment) => {
self.current_scroll_offset = scrollable::RelativeOffset::START; self.current_scroll_offset = scrollable::RelativeOffset::START;
self.alignment = alignment; self.anchor = alignment;
scrollable::snap_to( scrollable::snap_to(
SCROLLABLE_ID.clone(), SCROLLABLE_ID.clone(),
@ -168,14 +168,14 @@ impl ScrollableDemo {
text("Scrollable alignment:"), text("Scrollable alignment:"),
radio( radio(
"Start", "Start",
scrollable::Alignment::Start, scrollable::Anchor::Start,
Some(self.alignment), Some(self.anchor),
Message::AlignmentChanged, Message::AlignmentChanged,
), ),
radio( radio(
"End", "End",
scrollable::Alignment::End, scrollable::Anchor::End,
Some(self.alignment), Some(self.anchor),
Message::AlignmentChanged, Message::AlignmentChanged,
) )
] ]
@ -212,7 +212,7 @@ impl ScrollableDemo {
text("End!"), text("End!"),
scroll_to_beginning_button(), scroll_to_beginning_button(),
] ]
.align_items(Alignment::Center) .center_x()
.padding([40, 0, 40, 0]) .padding([40, 0, 40, 0])
.spacing(40), .spacing(40),
) )
@ -221,7 +221,7 @@ impl ScrollableDemo {
.width(self.scrollbar_width) .width(self.scrollbar_width)
.margin(self.scrollbar_margin) .margin(self.scrollbar_margin)
.scroller_width(self.scroller_width) .scroller_width(self.scroller_width)
.alignment(self.alignment), .anchor(self.anchor),
)) ))
.width(Length::Fill) .width(Length::Fill)
.height(Length::Fill) .height(Length::Fill)
@ -238,7 +238,7 @@ impl ScrollableDemo {
scroll_to_beginning_button(), scroll_to_beginning_button(),
] ]
.height(450) .height(450)
.align_items(Alignment::Center) .center_y()
.padding([0, 40, 0, 40]) .padding([0, 40, 0, 40])
.spacing(40), .spacing(40),
) )
@ -247,7 +247,7 @@ impl ScrollableDemo {
.width(self.scrollbar_width) .width(self.scrollbar_width)
.margin(self.scrollbar_margin) .margin(self.scrollbar_margin)
.scroller_width(self.scroller_width) .scroller_width(self.scroller_width)
.alignment(self.alignment), .anchor(self.anchor),
)) ))
.width(Length::Fill) .width(Length::Fill)
.height(Length::Fill) .height(Length::Fill)
@ -280,7 +280,7 @@ impl ScrollableDemo {
text("Horizontal - End!"), text("Horizontal - End!"),
scroll_to_beginning_button(), scroll_to_beginning_button(),
] ]
.align_items(Alignment::Center) .center_y()
.padding([0, 40, 0, 40]) .padding([0, 40, 0, 40])
.spacing(40), .spacing(40),
) )
@ -289,7 +289,7 @@ impl ScrollableDemo {
.width(self.scrollbar_width) .width(self.scrollbar_width)
.margin(self.scrollbar_margin) .margin(self.scrollbar_margin)
.scroller_width(self.scroller_width) .scroller_width(self.scroller_width)
.alignment(self.alignment); .anchor(self.anchor);
scrollable::Direction::Both { scrollable::Direction::Both {
horizontal: scrollbar, horizontal: scrollbar,
@ -322,7 +322,7 @@ impl ScrollableDemo {
let content: Element<Message> = let content: Element<Message> =
column![scroll_controls, scrollable_content, progress_bars] column![scroll_controls, scrollable_content, progress_bars]
.align_items(Alignment::Center) .center_x()
.spacing(10) .spacing(10)
.into(); .into();

View file

@ -60,7 +60,7 @@ impl SierpinskiEmulator {
.padding(10) .padding(10)
.spacing(20), .spacing(20),
] ]
.align_items(iced::Alignment::Center) .center_x()
.into() .into()
} }
} }

View file

@ -1,5 +1,5 @@
use iced::widget::{column, container, iced, slider, text, vertical_slider}; use iced::widget::{column, container, iced, slider, text, vertical_slider};
use iced::{Alignment, Element, Length}; use iced::{Element, Length};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::run("Slider - Iced", Slider::update, Slider::view) iced::run("Slider - Iced", Slider::update, Slider::view)
@ -46,7 +46,7 @@ impl Slider {
column![v_slider, h_slider, text, iced(self.value as f32),] column![v_slider, h_slider, text, iced(self.value as f32),]
.width(Length::Fill) .width(Length::Fill)
.align_items(Alignment::Center) .center_x()
.spacing(20) .spacing(20)
.padding(20) .padding(20)
.into() .into()

View file

@ -1,8 +1,7 @@
use iced::alignment;
use iced::keyboard; use iced::keyboard;
use iced::time; use iced::time;
use iced::widget::{button, center, column, row, text}; use iced::widget::{button, center, column, row, text};
use iced::{Alignment, Element, Subscription, Theme}; use iced::{Element, Subscription, Theme};
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
@ -101,13 +100,8 @@ impl Stopwatch {
) )
.size(40); .size(40);
let button = |label| { let button =
button( |label| button(text(label).center_x()).padding(10).width(80);
text(label).horizontal_alignment(alignment::Horizontal::Center),
)
.padding(10)
.width(80)
};
let toggle_button = { let toggle_button = {
let label = match self.state { let label = match self.state {
@ -124,9 +118,7 @@ impl Stopwatch {
let controls = row![toggle_button, reset_button].spacing(20); let controls = row![toggle_button, reset_button].spacing(20);
let content = column![duration, controls] let content = column![duration, controls].center_x().spacing(20);
.align_items(Alignment::Center)
.spacing(20);
center(content).into() center(content).into()
} }

View file

@ -3,7 +3,7 @@ use iced::widget::{
row, scrollable, slider, text, text_input, toggler, vertical_rule, row, scrollable, slider, text, text_input, toggler, vertical_rule,
vertical_space, vertical_space,
}; };
use iced::{Alignment, Element, Length, Theme}; use iced::{Element, Length, Theme};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application("Styling - Iced", Styling::update, Styling::view) iced::application("Styling - Iced", Styling::update, Styling::view)
@ -88,9 +88,7 @@ impl Styling {
let content = column![ let content = column![
choose_theme, choose_theme,
horizontal_rule(38), horizontal_rule(38),
row![text_input, button] row![text_input, button].spacing(10).center_y(),
.spacing(10)
.align_items(Alignment::Center),
slider, slider,
progress_bar, progress_bar,
row![ row![
@ -100,7 +98,7 @@ impl Styling {
] ]
.spacing(10) .spacing(10)
.height(100) .height(100)
.align_items(Alignment::Center), .center_y(),
] ]
.spacing(20) .spacing(20)
.padding(20) .padding(20)

View file

@ -4,7 +4,7 @@ use iced::keyboard::key;
use iced::widget::{ use iced::widget::{
self, button, center, column, pick_list, row, slider, text, text_input, self, button, center, column, pick_list, row, slider, text, text_input,
}; };
use iced::{Alignment, Element, Length, Subscription, Task}; use iced::{Element, Length, Subscription, Task};
use toast::{Status, Toast}; use toast::{Status, Toast};
@ -142,7 +142,7 @@ impl App {
.spacing(5) .spacing(5)
.into() .into()
), ),
column![add_toast].align_items(Alignment::End) column![add_toast].center_x()
] ]
.spacing(10) .spacing(10)
.max_width(200), .max_width(200),
@ -245,7 +245,7 @@ mod toast {
.on_press((on_close)(index)) .on_press((on_close)(index))
.padding(3), .padding(3),
] ]
.align_items(Alignment::Center) .center_y()
) )
.width(Length::Fill) .width(Length::Fill)
.padding(5) .padding(5)

View file

@ -1,4 +1,3 @@
use iced::alignment::{self, Alignment};
use iced::keyboard; use iced::keyboard;
use iced::widget::{ use iced::widget::{
self, button, center, checkbox, column, container, keyed_column, row, self, button, center, checkbox, column, container, keyed_column, row,
@ -196,7 +195,7 @@ impl Todos {
.width(Length::Fill) .width(Length::Fill)
.size(100) .size(100)
.color([0.5, 0.5, 0.5]) .color([0.5, 0.5, 0.5])
.horizontal_alignment(alignment::Horizontal::Center); .center_x();
let input = text_input("What needs to be done?", input_value) let input = text_input("What needs to be done?", input_value)
.id(INPUT_ID.clone()) .id(INPUT_ID.clone())
@ -355,7 +354,7 @@ impl Task {
.style(button::text), .style(button::text),
] ]
.spacing(20) .spacing(20)
.align_items(Alignment::Center) .center_y()
.into() .into()
} }
TaskState::Editing => { TaskState::Editing => {
@ -369,16 +368,14 @@ impl Task {
row![ row![
text_input, text_input,
button( button(
row![delete_icon(), "Delete"] row![delete_icon(), "Delete"].spacing(10).center_y()
.spacing(10)
.align_items(Alignment::Center)
) )
.on_press(TaskMessage::Delete) .on_press(TaskMessage::Delete)
.padding(10) .padding(10)
.style(button::danger) .style(button::danger)
] ]
.spacing(20) .spacing(20)
.align_items(Alignment::Center) .center_y()
.into() .into()
} }
} }
@ -415,7 +412,7 @@ fn view_controls(tasks: &[Task], current_filter: Filter) -> Element<Message> {
.spacing(10) .spacing(10)
] ]
.spacing(20) .spacing(20)
.align_items(Alignment::Center) .center_y()
.into() .into()
} }
@ -440,12 +437,7 @@ impl Filter {
} }
fn loading_message<'a>() -> Element<'a, Message> { fn loading_message<'a>() -> Element<'a, Message> {
center( center(text("Loading...").center_x().size(50)).into()
text("Loading...")
.horizontal_alignment(alignment::Horizontal::Center)
.size(50),
)
.into()
} }
fn empty_message(message: &str) -> Element<'_, Message> { fn empty_message(message: &str) -> Element<'_, Message> {
@ -453,7 +445,7 @@ fn empty_message(message: &str) -> Element<'_, Message> {
text(message) text(message)
.width(Length::Fill) .width(Length::Fill)
.size(25) .size(25)
.horizontal_alignment(alignment::Horizontal::Center) .center_x()
.color([0.7, 0.7, 0.7]), .color([0.7, 0.7, 0.7]),
) )
.height(200) .height(200)
@ -464,10 +456,7 @@ fn empty_message(message: &str) -> Element<'_, Message> {
const ICONS: Font = Font::with_name("Iced-Todos-Icons"); const ICONS: Font = Font::with_name("Iced-Todos-Icons");
fn icon(unicode: char) -> Text<'static> { fn icon(unicode: char) -> Text<'static> {
text(unicode.to_string()) text(unicode.to_string()).font(ICONS).width(20).center_x()
.font(ICONS)
.width(20)
.horizontal_alignment(alignment::Horizontal::Center)
} }
fn edit_icon() -> Text<'static> { fn edit_icon() -> Text<'static> {

View file

@ -1,4 +1,3 @@
use iced::alignment::{self, Alignment};
use iced::widget::{ use iced::widget::{
button, checkbox, column, container, horizontal_space, image, radio, row, button, checkbox, column, container, horizontal_space, image, radio, row,
scrollable, slider, text, text_input, toggler, vertical_space, scrollable, slider, text, text_input, toggler, vertical_space,
@ -235,11 +234,7 @@ impl Tour {
0 to 100:", 0 to 100:",
) )
.push(slider(0..=100, self.slider, Message::SliderChanged)) .push(slider(0..=100, self.slider, Message::SliderChanged))
.push( .push(text(self.slider.to_string()).width(Length::Fill).center_x())
text(self.slider.to_string())
.width(Length::Fill)
.horizontal_alignment(alignment::Horizontal::Center),
)
} }
fn rows_and_columns(&self) -> Column<Message> { fn rows_and_columns(&self) -> Column<Message> {
@ -268,9 +263,7 @@ impl Tour {
let spacing_section = column![ let spacing_section = column![
slider(0..=80, self.spacing, Message::SpacingChanged), slider(0..=80, self.spacing, Message::SpacingChanged),
text!("{} px", self.spacing) text!("{} px", self.spacing).width(Length::Fill).center_x(),
.width(Length::Fill)
.horizontal_alignment(alignment::Horizontal::Center),
] ]
.spacing(10); .spacing(10);
@ -381,11 +374,7 @@ impl Tour {
.push("An image that tries to keep its aspect ratio.") .push("An image that tries to keep its aspect ratio.")
.push(ferris(width, filter_method)) .push(ferris(width, filter_method))
.push(slider(100..=500, width, Message::ImageWidthChanged)) .push(slider(100..=500, width, Message::ImageWidthChanged))
.push( .push(text!("Width: {width} px").width(Length::Fill).center_x())
text!("Width: {width} px")
.width(Length::Fill)
.horizontal_alignment(alignment::Horizontal::Center),
)
.push( .push(
checkbox( checkbox(
"Use nearest interpolation", "Use nearest interpolation",
@ -393,7 +382,7 @@ impl Tour {
) )
.on_toggle(Message::ImageUseNearestToggled), .on_toggle(Message::ImageUseNearestToggled),
) )
.align_items(Alignment::Center) .center_x()
} }
fn scrollable(&self) -> Column<Message> { fn scrollable(&self) -> Column<Message> {
@ -411,16 +400,11 @@ impl Tour {
text("You are halfway there!") text("You are halfway there!")
.width(Length::Fill) .width(Length::Fill)
.size(30) .size(30)
.horizontal_alignment(alignment::Horizontal::Center), .center_x(),
) )
.push(vertical_space().height(4096)) .push(vertical_space().height(4096))
.push(ferris(300, image::FilterMethod::Linear)) .push(ferris(300, image::FilterMethod::Linear))
.push( .push(text("You made it!").width(Length::Fill).size(50).center_x())
text("You made it!")
.width(Length::Fill)
.size(50)
.horizontal_alignment(alignment::Horizontal::Center),
)
} }
fn text_input(&self) -> Column<Message> { fn text_input(&self) -> Column<Message> {
@ -465,7 +449,7 @@ impl Tour {
value value
}) })
.width(Length::Fill) .width(Length::Fill)
.horizontal_alignment(alignment::Horizontal::Center), .center_x(),
) )
} }

View file

@ -1,4 +1,4 @@
use iced::alignment::{self, Alignment}; use iced::alignment;
use iced::mouse; use iced::mouse;
use iced::widget::{ use iced::widget::{
canvas, checkbox, column, horizontal_space, row, slider, text, canvas, checkbox, column, horizontal_space, row, slider, text,
@ -85,7 +85,7 @@ impl VectorialText {
] ]
.spacing(20), .spacing(20),
] ]
.align_items(Alignment::Center) .center_x()
.spacing(10) .spacing(10)
] ]
.spacing(10) .spacing(10)

View file

@ -5,8 +5,7 @@ use iced::widget::{
}; };
use iced::window; use iced::window;
use iced::{ use iced::{
Alignment, Color, Element, Font, Length, Point, Rectangle, Subscription, Color, Element, Font, Length, Point, Rectangle, Subscription, Task, Theme,
Task, Theme,
}; };
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
@ -70,7 +69,7 @@ impl Example {
.color_maybe(color), .color_maybe(color),
] ]
.height(40) .height(40)
.align_items(Alignment::Center) .center_y()
}; };
let view_bounds = |label, bounds: Option<Rectangle>| { let view_bounds = |label, bounds: Option<Rectangle>| {

View file

@ -1,6 +1,5 @@
mod echo; mod echo;
use iced::alignment::{self, Alignment};
use iced::widget::{ use iced::widget::{
self, button, center, column, row, scrollable, text, text_input, self, button, center, column, row, scrollable, text, text_input,
}; };
@ -113,12 +112,8 @@ impl WebSocket {
.on_input(Message::NewMessageChanged) .on_input(Message::NewMessageChanged)
.padding(10); .padding(10);
let mut button = button( let mut button =
text("Send") button(text("Send").height(40).center_y()).padding([0, 20]);
.height(40)
.vertical_alignment(alignment::Vertical::Center),
)
.padding([0, 20]);
if matches!(self.state, State::Connected(_)) { if matches!(self.state, State::Connected(_)) {
if let Some(message) = echo::Message::new(&self.new_message) { if let Some(message) = echo::Message::new(&self.new_message) {
@ -127,9 +122,7 @@ impl WebSocket {
} }
} }
row![input, button] row![input, button].spacing(10).center_y()
.spacing(10)
.align_items(Alignment::Center)
}; };
column![message_log, new_message_input] column![message_log, new_message_input]

View file

@ -1,4 +1,5 @@
//! Distribute content vertically. //! Distribute content vertically.
use crate::core::alignment::{self, Alignment};
use crate::core::event::{self, Event}; use crate::core::event::{self, Event};
use crate::core::layout; use crate::core::layout;
use crate::core::mouse; use crate::core::mouse;
@ -6,8 +7,8 @@ use crate::core::overlay;
use crate::core::renderer; use crate::core::renderer;
use crate::core::widget::{Operation, Tree}; use crate::core::widget::{Operation, Tree};
use crate::core::{ use crate::core::{
Alignment, Clipboard, Element, Layout, Length, Padding, Pixels, Rectangle, Clipboard, Element, Layout, Length, Padding, Pixels, Rectangle, Shell,
Shell, Size, Vector, Widget, Size, Vector, Widget,
}; };
/// A container that distributes its contents vertically. /// A container that distributes its contents vertically.
@ -19,7 +20,7 @@ pub struct Column<'a, Message, Theme = crate::Theme, Renderer = crate::Renderer>
width: Length, width: Length,
height: Length, height: Length,
max_width: f32, max_width: f32,
align_items: Alignment, align: Alignment,
clip: bool, clip: bool,
children: Vec<Element<'a, Message, Theme, Renderer>>, children: Vec<Element<'a, Message, Theme, Renderer>>,
} }
@ -63,7 +64,7 @@ where
width: Length::Shrink, width: Length::Shrink,
height: Length::Shrink, height: Length::Shrink,
max_width: f32::INFINITY, max_width: f32::INFINITY,
align_items: Alignment::Start, align: Alignment::Start,
clip: false, clip: false,
children, children,
} }
@ -103,9 +104,24 @@ where
self self
} }
/// Centers the contents of the [`Column`] horizontally.
pub fn center_x(self) -> Self {
self.align_x(Alignment::Center)
}
/// Aligns the contents of the [`Column`] to the left.
pub fn align_left(self) -> Self {
self.align_x(alignment::left())
}
/// Aligns the contents of the [`Column`] to the right.
pub fn align_right(self) -> Self {
self.align_x(alignment::right())
}
/// Sets the horizontal alignment of the contents of the [`Column`] . /// Sets the horizontal alignment of the contents of the [`Column`] .
pub fn align_items(mut self, align: Alignment) -> Self { pub fn align_x(mut self, align: impl Into<alignment::Horizontal>) -> Self {
self.align_items = align; self.align = Alignment::from(align.into());
self self
} }
@ -210,7 +226,7 @@ where
self.height, self.height,
self.padding, self.padding,
self.spacing, self.spacing,
self.align_items, self.align,
&self.children, &self.children,
&mut tree.children, &mut tree.children,
) )

View file

@ -94,27 +94,19 @@ where
/// Sets the [`Container`] to fill the available space in the horizontal axis. /// 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 /// Calling this method is equivalent to calling [`width`] with a
/// [`Length::Fill`]. /// [`Length::Fill`].
/// ///
/// [`center_x`]: Self::center_x
/// [`width`]: Self::width /// [`width`]: Self::width
pub fn fill_x(self) -> Self { pub fn fill_x(self) -> Self {
self.width(Length::Fill) self.width(Length::Fill)
} }
/// Sets the [`Container`] to fill the available space in the vetical axis. /// Sets the [`Container`] to fill the available space in the vertical 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 /// Calling this method is equivalent to calling [`height`] with a
/// [`Length::Fill`]. /// [`Length::Fill`].
/// ///
/// [`center_y`]: Self::center_x
/// [`height`]: Self::height /// [`height`]: Self::height
pub fn fill_y(self) -> Self { pub fn fill_y(self) -> Self {
self.height(Length::Fill) self.height(Length::Fill)
@ -125,7 +117,6 @@ where
/// Calling this method is equivalent to chaining [`fill_x`] and /// Calling this method is equivalent to chaining [`fill_x`] and
/// [`fill_y`]. /// [`fill_y`].
/// ///
/// [`center`]: Self::center
/// [`fill_x`]: Self::fill_x /// [`fill_x`]: Self::fill_x
/// [`fill_y`]: Self::fill_y /// [`fill_y`]: Self::fill_y
pub fn fill(self) -> Self { pub fn fill(self) -> Self {
@ -144,18 +135,6 @@ where
self 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. /// Sets the width of the [`Container`] and centers its contents horizontally.
pub fn center_x(self, width: impl Into<Length>) -> Self { pub fn center_x(self, width: impl Into<Length>) -> Self {
self.width(width).align_x(alignment::Horizontal::Center) self.width(width).align_x(alignment::Horizontal::Center)
@ -179,6 +158,44 @@ where
self.center_x(length).center_y(length) self.center_x(length).center_y(length)
} }
/// Aligns the contents of the [`Container`] to the left.
pub fn align_left(self) -> Self {
self.align_x(alignment::left())
}
/// Aligns the contents of the [`Container`] to the right.
pub fn align_right(self) -> Self {
self.align_x(alignment::right())
}
/// Aligns the contents of the [`Container`] to the top.
pub fn align_top(self) -> Self {
self.align_y(alignment::top())
}
/// Aligns the contents of the [`Container`] to the bottom.
pub fn align_bottom(self) -> Self {
self.align_y(alignment::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 /// Sets whether the contents of the [`Container`] should be clipped on
/// overflow. /// overflow.
pub fn clip(mut self, clip: bool) -> Self { pub fn clip(mut self, clip: bool) -> Self {

View file

@ -906,7 +906,7 @@ where
+ 'a, + 'a,
Theme: text::Catalog + crate::svg::Catalog + 'a, Theme: text::Catalog + crate::svg::Catalog + 'a,
{ {
use crate::core::{Alignment, Font}; use crate::core::Font;
use crate::svg; use crate::svg;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
@ -921,7 +921,7 @@ where
text("iced").size(text_size).font(Font::MONOSPACE) text("iced").size(text_size).font(Font::MONOSPACE)
] ]
.spacing(text_size.0 / 3.0) .spacing(text_size.0 / 3.0)
.align_items(Alignment::Center) .center_y()
.into() .into()
} }

View file

@ -1,4 +1,5 @@
//! Distribute content horizontally. //! Distribute content horizontally.
use crate::core::alignment::{self, Alignment};
use crate::core::event::{self, Event}; use crate::core::event::{self, Event};
use crate::core::layout::{self, Layout}; use crate::core::layout::{self, Layout};
use crate::core::mouse; use crate::core::mouse;
@ -6,8 +7,8 @@ use crate::core::overlay;
use crate::core::renderer; use crate::core::renderer;
use crate::core::widget::{Operation, Tree}; use crate::core::widget::{Operation, Tree};
use crate::core::{ use crate::core::{
Alignment, Clipboard, Element, Length, Padding, Pixels, Rectangle, Shell, Clipboard, Element, Length, Padding, Pixels, Rectangle, Shell, Size,
Size, Vector, Widget, Vector, Widget,
}; };
/// A container that distributes its contents horizontally. /// A container that distributes its contents horizontally.
@ -17,7 +18,7 @@ pub struct Row<'a, Message, Theme = crate::Theme, Renderer = crate::Renderer> {
padding: Padding, padding: Padding,
width: Length, width: Length,
height: Length, height: Length,
align_items: Alignment, align: Alignment,
clip: bool, clip: bool,
children: Vec<Element<'a, Message, Theme, Renderer>>, children: Vec<Element<'a, Message, Theme, Renderer>>,
} }
@ -60,7 +61,7 @@ where
padding: Padding::ZERO, padding: Padding::ZERO,
width: Length::Shrink, width: Length::Shrink,
height: Length::Shrink, height: Length::Shrink,
align_items: Alignment::Start, align: Alignment::Start,
clip: false, clip: false,
children, children,
} }
@ -94,9 +95,24 @@ where
self self
} }
/// Centers the contents of the [`Row`] vertically.
pub fn center_y(self) -> Self {
self.align_y(Alignment::Center)
}
/// Aligns the contents of the [`Row`] to the top.
pub fn align_top(self) -> Self {
self.align_y(alignment::top())
}
/// Aligns the contents of the [`Row`] to the bottom.
pub fn align_bottom(self) -> Self {
self.align_y(alignment::bottom())
}
/// Sets the vertical alignment of the contents of the [`Row`] . /// Sets the vertical alignment of the contents of the [`Row`] .
pub fn align_items(mut self, align: Alignment) -> Self { pub fn align_y(mut self, align: impl Into<alignment::Vertical>) -> Self {
self.align_items = align; self.align = Alignment::from(align.into());
self self
} }
@ -199,7 +215,7 @@ where
self.height, self.height,
self.padding, self.padding,
self.spacing, self.spacing,
self.align_items, self.align,
&self.children, &self.children,
&mut tree.children, &mut tree.children,
) )

View file

@ -109,8 +109,28 @@ where
self self
} }
/// Sets the alignment of the horizontal direction of the [`Scrollable`], if applicable. /// Anchors the vertical [`Scrollable`] direction to the top.
pub fn align_x(mut self, alignment: Alignment) -> Self { 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 { match &mut self.direction {
Direction::Horizontal(horizontal) Direction::Horizontal(horizontal)
| Direction::Both { horizontal, .. } => { | Direction::Both { horizontal, .. } => {
@ -122,8 +142,8 @@ where
self self
} }
/// Sets the alignment of the vertical direction of the [`Scrollable`], if applicable. /// Sets the [`Anchor`] of the vertical direction of the [`Scrollable`], if applicable.
pub fn align_y(mut self, alignment: Alignment) -> Self { pub fn anchor_y(mut self, alignment: Anchor) -> Self {
match &mut self.direction { match &mut self.direction {
Direction::Vertical(vertical) Direction::Vertical(vertical)
| Direction::Both { vertical, .. } => { | Direction::Both { vertical, .. } => {
@ -228,7 +248,7 @@ pub struct Scrollbar {
width: f32, width: f32,
margin: f32, margin: f32,
scroller_width: f32, scroller_width: f32,
alignment: Alignment, alignment: Anchor,
embedded: bool, embedded: bool,
} }
@ -238,7 +258,7 @@ impl Default for Scrollbar {
width: 10.0, width: 10.0,
margin: 0.0, margin: 0.0,
scroller_width: 10.0, scroller_width: 10.0,
alignment: Alignment::Start, alignment: Anchor::Start,
embedded: false, embedded: false,
} }
} }
@ -250,26 +270,26 @@ impl Scrollbar {
Self::default() 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 { pub fn width(mut self, width: impl Into<Pixels>) -> Self {
self.width = width.into().0.max(0.0); self.width = width.into().0.max(0.0);
self 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 { pub fn margin(mut self, margin: impl Into<Pixels>) -> Self {
self.margin = margin.into().0; self.margin = margin.into().0;
self 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 { pub fn scroller_width(mut self, scroller_width: impl Into<Pixels>) -> Self {
self.scroller_width = scroller_width.into().0.max(0.0); self.scroller_width = scroller_width.into().0.max(0.0);
self self
} }
/// Sets the alignment of the [`Scrollable`] . /// Sets the [`Anchor`] of the [`Scrollbar`] .
pub fn alignment(mut self, alignment: Alignment) -> Self { pub fn anchor(mut self, alignment: Anchor) -> Self {
self.alignment = alignment; self.alignment = alignment;
self self
} }
@ -284,13 +304,14 @@ impl Scrollbar {
} }
} }
/// 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)] #[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub enum Alignment { pub enum Anchor {
/// Content is aligned to the start of the [`Viewport`]. /// Scroller is anchoer to the start of the [`Viewport`].
#[default] #[default]
Start, Start,
/// Content is aligned to the end of the [`Viewport`] /// Content is aligned to the end of the [`Viewport`].
End, End,
} }
@ -1159,13 +1180,13 @@ impl Offset {
self, self,
viewport: f32, viewport: f32,
content: f32, content: f32,
alignment: Alignment, alignment: Anchor,
) -> f32 { ) -> f32 {
let offset = self.absolute(viewport, content); let offset = self.absolute(viewport, content);
match alignment { match alignment {
Alignment::Start => offset, Anchor::Start => offset,
Alignment::End => ((content - viewport).max(0.0) - offset).max(0.0), Anchor::End => ((content - viewport).max(0.0) - offset).max(0.0),
} }
} }
} }
@ -1252,9 +1273,9 @@ impl State {
.map(|p| p.alignment) .map(|p| p.alignment)
.unwrap_or_default(); .unwrap_or_default();
let align = |alignment: Alignment, delta: f32| match alignment { let align = |alignment: Anchor, delta: f32| match alignment {
Alignment::Start => delta, Anchor::Start => delta,
Alignment::End => -delta, Anchor::End => -delta,
}; };
let delta = Vector::new( let delta = Vector::new(
@ -1592,14 +1613,14 @@ impl Scrollbars {
pub(super) mod internals { pub(super) mod internals {
use crate::core::{Point, Rectangle}; use crate::core::{Point, Rectangle};
use super::Alignment; use super::Anchor;
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct Scrollbar { pub struct Scrollbar {
pub total_bounds: Rectangle, pub total_bounds: Rectangle,
pub bounds: Rectangle, pub bounds: Rectangle,
pub scroller: Option<Scroller>, pub scroller: Option<Scroller>,
pub alignment: Alignment, pub alignment: Anchor,
} }
impl Scrollbar { impl Scrollbar {
@ -1621,8 +1642,8 @@ pub(super) mod internals {
/ (self.bounds.height - scroller.bounds.height); / (self.bounds.height - scroller.bounds.height);
match self.alignment { match self.alignment {
Alignment::Start => percentage, Anchor::Start => percentage,
Alignment::End => 1.0 - percentage, Anchor::End => 1.0 - percentage,
} }
} else { } else {
0.0 0.0
@ -1642,8 +1663,8 @@ pub(super) mod internals {
/ (self.bounds.width - scroller.bounds.width); / (self.bounds.width - scroller.bounds.width);
match self.alignment { match self.alignment {
Alignment::Start => percentage, Anchor::Start => percentage,
Alignment::End => 1.0 - percentage, Anchor::End => 1.0 - percentage,
} }
} else { } else {
0.0 0.0