From f8a8a8571756a0b8889f806bc3cf994868d9bfda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 3 Aug 2025 22:16:45 +0200 Subject: [PATCH] Add `align_x` support for `row::Wrapping` --- widget/src/row.rs | 56 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/widget/src/row.rs b/widget/src/row.rs index 7bd8799f..101e51d8 100644 --- a/widget/src/row.rs +++ b/widget/src/row.rs @@ -160,6 +160,7 @@ where Wrapping { row: self, vertical_spacing: None, + align_x: alignment::Horizontal::Left, } } } @@ -368,6 +369,7 @@ pub struct Wrapping< > { row: Row<'a, Message, Theme, Renderer>, vertical_spacing: Option, + align_x: alignment::Horizontal, } impl Wrapping<'_, Message, Theme, Renderer> { @@ -376,6 +378,15 @@ impl Wrapping<'_, Message, Theme, Renderer> { self.vertical_spacing = Some(amount.into().0); self } + + /// Sets the horizontal alignment of the wrapping [`Row`]. + pub fn align_x( + mut self, + align_x: impl Into, + ) -> Self { + self.align_x = align_x.into(); + self + } } impl Widget @@ -423,9 +434,9 @@ where Alignment::End => 1.0, }; - let align = |row_start: std::ops::Range, - row_height: f32, - children: &mut Vec| { + let align_y = |row_start: std::ops::Range, + row_height: f32, + children: &mut Vec| { if align_factor != 0.0 { for node in &mut children[row_start] { let height = node.size().height; @@ -450,7 +461,7 @@ where if x != 0.0 && x + child_size.width > max_width { intrinsic_size.width = intrinsic_size.width.max(x - spacing); - align(row_start..i, row_height, &mut children); + align_y(row_start..i, row_height, &mut children); y += row_height + vertical_spacing; x = 0.0; @@ -473,7 +484,42 @@ where } intrinsic_size.height = y + row_height; - align(row_start..children.len(), row_height, &mut children); + align_y(row_start..children.len(), row_height, &mut children); + + let align_factor = match self.align_x { + alignment::Horizontal::Left => 0.0, + alignment::Horizontal::Center => 2.0, + alignment::Horizontal::Right => 1.0, + }; + + if align_factor != 0.0 { + let total_width = intrinsic_size.width; + + let mut row_start = 0; + + for i in 0..children.len() { + let bounds = children[i].bounds(); + let row_width = bounds.x + bounds.width; + + let next_x = children + .get(i + 1) + .map(|node| node.bounds().x) + .unwrap_or_default(); + + if next_x == 0.0 { + let translation = Vector::new( + (total_width - row_width) / align_factor, + 0.0, + ); + + for node in &mut children[row_start..=i] { + node.translate_mut(translation); + } + + row_start = i + 1; + } + } + } let size = limits.resolve(self.row.width, self.row.height, intrinsic_size);