Columns and Rows
The two most important structs for laying out widgets are Column
and Row
.
Both lay out their children in one direction. The column organizes the widgets vertically and the row horizontally.
By default, they align the items in the top left corner of their space.
A convenient way to create columns and rows is with the column!
and row!
macros.
We saw one of them in the Minimal Application - Counter.
use iced::widget;
struct Counter {
// This will be our state of the counter app
// a.k.a the current count value
count: i32,
}
#[derive(Debug, Clone, Copy)]
enum Message {
// Emitted when the increment ("+") button is pressed
IncrementCount,
// Emitted when decrement ("-") button is pressed
DecrementCount,
}
// Implement our Counter
impl Counter {
fn new() -> Self {
// initialize the counter struct
// with count value as 0.
Self { count: 0 }
}
fn update(&mut self, message: Message) -> iced::Task<Message> {
// handle emitted messages
match message {
Message::IncrementCount => self.count += 1,
Message::DecrementCount => self.count -= 1,
}
iced::Task::none()
}
fn view(&self) -> iced::Element<'_, Message> {
// create the View Logic (UI)
let row = widget::row![
widget::button("-").on_press(Message::DecrementCount),
widget::text(self.count),
widget::button("+").on_press(Message::IncrementCount)
];
widget::container(row)
.center_x(iced::Length::Fill)
.center_y(iced::Length::Fill)
.width(iced::Length::Fill)
.height(iced::Length::Fill)
.into()
}
}
fn main() -> Result<(), iced::Error> {
// run the app from main function
iced::application("Counter Example", Counter::update, Counter::view).run_with(|| (Counter::new(), iced::Task::none()))
}
There, we created a Column
with three children inside. One text and two buttons. The syntax for rows is the same.
You can put any Element
inside a Column
or Row
.
Alignment
Of course, we can change the horizontal alignment for columns and the vertical alignment for rows.
This is how they would align in the center.
In code, if you want to set the Alignment
you can call the align_x
method on your column/row. It will return itself with the new alignment.
let some_column = iced::widget::column![
iced::widget::text("Hello World!"),
iced::widget::text("Another Hello World!")
].align_x(iced::Alignment::Center)
Spacing
Because you cannot set margins in Iced and often want to add space between elements.
Columns and rows provide a spacing
method to control the gap/spacing.
Below is an example of how to use spacing on a column:
let some_column = iced::widget::column![
iced::widget::text("Hello World!"),
iced::widget::text("Another Hello World!")
].spacing(20)
Wrapping
Rows offer a feature that columns don't, they can wrap their children elements onto new lines. You enable this by calling the .wrap()
method on a row.
Once wrapping is activated, the layout of the row’s children changes. If the available horizontal space fills up, any extra children automatically move to a new row below.
Additionally, children with a width set to Fill
or FillPortion
expand to take up any remaining horizontal space, which can trigger a row break. In contrast, children with fixed or shrink widths continue to be placed side by side until there isn’t enough space, at which point they break onto a new row.