Implement alignment support for table::column

This commit is contained in:
Héctor Ramón Jiménez 2025-07-16 04:06:38 +02:00
parent 1e89439aff
commit 6e71c7dd6f
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
3 changed files with 67 additions and 18 deletions

View file

@ -52,22 +52,22 @@ impl Node {
/// Aligns the [`Node`] in the given space. /// Aligns the [`Node`] in the given space.
pub fn align( pub fn align(
mut self, mut self,
horizontal_alignment: Alignment, align_x: Alignment,
vertical_alignment: Alignment, align_y: Alignment,
space: Size, space: Size,
) -> Self { ) -> Self {
self.align_mut(horizontal_alignment, vertical_alignment, space); self.align_mut(align_x, align_y, space);
self self
} }
/// Mutable reference version of [`Self::align`]. /// Mutable reference version of [`Self::align`].
pub fn align_mut( pub fn align_mut(
&mut self, &mut self,
horizontal_alignment: Alignment, align_x: Alignment,
vertical_alignment: Alignment, align_y: Alignment,
space: Size, space: Size,
) { ) {
match horizontal_alignment { match align_x {
Alignment::Start => {} Alignment::Start => {}
Alignment::Center => { Alignment::Center => {
self.bounds.x += (space.width - self.bounds.width) / 2.0; self.bounds.x += (space.width - self.bounds.width) / 2.0;
@ -77,7 +77,7 @@ impl Node {
} }
} }
match vertical_alignment { match align_y {
Alignment::Start => {} Alignment::Start => {}
Alignment::Center => { Alignment::Center => {
self.bounds.y += (space.height - self.bounds.height) / 2.0; self.bounds.y += (space.height - self.bounds.height) / 2.0;

View file

@ -4,7 +4,7 @@ use iced::widget::{
center_x, center_y, column, container, row, scrollable, slider, table, center_x, center_y, column, container, row, scrollable, slider, table,
text, tooltip, text, tooltip,
}; };
use iced::{Center, Element, Font, Theme}; use iced::{Center, Element, Fill, Font, Right, Theme};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application(Table::new, Table::update, Table::view) iced::application(Table::new, Table::update, Table::view)
@ -59,7 +59,9 @@ impl Table {
} else { } else {
text::default text::default
}) })
}), })
.align_x(Right)
.align_y(Center),
table::column(bold("Price"), |event: &Event| { table::column(bold("Price"), |event: &Event| {
if event.price > 0.0 { if event.price > 0.0 {
text!("${:.2}", event.price).style( text!("${:.2}", event.price).style(
@ -70,9 +72,11 @@ impl Table {
}, },
) )
} else { } else {
text("Free").style(text::success) text("Free").style(text::success).width(Fill).center()
} }
}), })
.align_x(Right)
.align_y(Center),
table::column(bold("Rating"), |event: &Event| { table::column(bold("Rating"), |event: &Event| {
text!("{:.2}", event.rating).style(if event.rating > 4.7 { text!("{:.2}", event.rating).style(if event.rating > 4.7 {
text::success text::success
@ -81,7 +85,9 @@ impl Table {
} else { } else {
text::default text::default
}) })
}), })
.align_x(Right)
.align_y(Center),
]; ];
table(columns, &self.events) table(columns, &self.events)

View file

@ -1,11 +1,13 @@
#![allow(missing_docs, missing_debug_implementations)] #![allow(missing_docs, missing_debug_implementations)]
use crate::core; use crate::core;
use crate::core::alignment;
use crate::core::layout; use crate::core::layout;
use crate::core::mouse; use crate::core::mouse;
use crate::core::renderer; use crate::core::renderer;
use crate::core::widget; use crate::core::widget;
use crate::core::{ use crate::core::{
Background, Element, Layout, Length, Pixels, Rectangle, Size, Widget, Alignment, Background, Element, Layout, Length, Pixels, Rectangle, Size,
Widget,
}; };
pub fn table<'a, R, T, Message, Theme, Renderer>( pub fn table<'a, R, T, Message, Theme, Renderer>(
@ -33,6 +35,8 @@ where
header: header.into(), header: header.into(),
view: Box::new(move |data| view(data).into()), view: Box::new(move |data| view(data).into()),
width: Length::Shrink, width: Length::Shrink,
align_x: alignment::Horizontal::Left,
align_y: alignment::Vertical::Top,
} }
} }
@ -40,7 +44,7 @@ pub struct Table<'a, Message, Theme = crate::Theme, Renderer = crate::Renderer>
where where
Theme: Catalog, Theme: Catalog,
{ {
columns: Vec<Length>, columns: Vec<Column_>,
cells: Vec<Element<'a, Message, Theme, Renderer>>, cells: Vec<Element<'a, Message, Theme, Renderer>>,
width: Length, width: Length,
height: Length, height: Length,
@ -51,6 +55,12 @@ where
class: Theme::Class<'a>, class: Theme::Class<'a>,
} }
struct Column_ {
width: Length,
align_x: alignment::Horizontal,
align_y: alignment::Vertical,
}
impl<'a, Message, Theme, Renderer> Table<'a, Message, Theme, Renderer> impl<'a, Message, Theme, Renderer> Table<'a, Message, Theme, Renderer>
where where
Theme: Catalog, Theme: Catalog,
@ -88,13 +98,17 @@ where
width = width.enclose(column.width); width = width.enclose(column.width);
column.width Column_ {
width: column.width,
align_x: column.align_x,
align_y: column.align_y,
}
}) })
.collect(); .collect();
if width == Length::Shrink { if width == Length::Shrink {
if let Some(first) = columns.first_mut() { if let Some(first) = columns.first_mut() {
*first = Length::Fill; first.width = Length::Fill;
} }
} }
@ -225,7 +239,7 @@ where
let column = i / rows; let column = i / rows;
let row = i % rows; let row = i % rows;
let width = self.columns[column]; let width = self.columns[column].width;
let size = cell.as_widget().size(); let size = cell.as_widget().size();
if row == 0 { if row == 0 {
@ -307,7 +321,7 @@ where
let size = cell.as_widget().size(); let size = cell.as_widget().size();
let width = self.columns[column]; let width = self.columns[column].width;
let width_factor = width.fill_factor(); let width_factor = width.fill_factor();
if row == 0 { if row == 0 {
@ -387,7 +401,16 @@ where
} }
} }
let Column_ {
align_x, align_y, ..
} = &self.columns[column];
cell.move_to_mut((x, y)); cell.move_to_mut((x, y));
cell.align_mut(
Alignment::from(*align_x),
Alignment::from(*align_y),
Size::new(metrics.columns[column], metrics.rows[row]),
);
y += metrics.rows[row] + spacing_y; y += metrics.rows[row] + spacing_y;
} }
@ -505,6 +528,8 @@ pub struct Column<
header: Element<'a, Message, Theme, Renderer>, header: Element<'a, Message, Theme, Renderer>,
view: Box<dyn Fn(T) -> Element<'a, Message, Theme, Renderer> + 'a>, view: Box<dyn Fn(T) -> Element<'a, Message, Theme, Renderer> + 'a>,
width: Length, width: Length,
align_x: alignment::Horizontal,
align_y: alignment::Vertical,
} }
impl<'a, T, Message, Theme, Renderer> Column<'a, T, Message, Theme, Renderer> { impl<'a, T, Message, Theme, Renderer> Column<'a, T, Message, Theme, Renderer> {
@ -512,6 +537,24 @@ impl<'a, T, Message, Theme, Renderer> Column<'a, T, Message, Theme, Renderer> {
self.width = width.into(); self.width = width.into();
self self
} }
/// Sets the alignment for the horizontal axis of the [`Column`].
pub fn align_x(
mut self,
alignment: impl Into<alignment::Horizontal>,
) -> Self {
self.align_x = alignment.into();
self
}
/// Sets the alignment for the vertical axis of the [`Column`].
pub fn align_y(
mut self,
alignment: impl Into<alignment::Vertical>,
) -> Self {
self.align_y = alignment.into();
self
}
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]