From cb6bc86e1e692ac8bbd20fecb46cdad033f4ac2c Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Thu, 30 May 2024 12:37:32 +0200 Subject: [PATCH] feat(flex-row): align_items, justify_items, justify_content, and min_item_width --- src/widget/flex_row/layout.rs | 32 +++++++++++++++++++++++++------- src/widget/flex_row/widget.rs | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/src/widget/flex_row/layout.rs b/src/widget/flex_row/layout.rs index cf80548..d781e4f 100644 --- a/src/widget/flex_row/layout.rs +++ b/src/widget/flex_row/layout.rs @@ -10,6 +10,7 @@ use taffy::style::{AlignItems, Dimension, Display, Style}; use taffy::style_helpers::length; use taffy::{AlignContent, TaffyTree}; +#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_lines)] pub fn resolve( renderer: &Renderer, @@ -18,10 +19,12 @@ pub fn resolve( padding: Padding, column_spacing: f32, row_spacing: f32, + min_item_width: Option, + justify_items: Option, + align_items: Option, justify_content: Option, tree: &mut [Tree], ) -> Node { - let limits = limits.shrink(padding); let max_size = limits.max(); let mut leafs = Vec::with_capacity(items.len()); @@ -44,6 +47,8 @@ pub fn resolve( height: Dimension::Auto, }, + align_items, + justify_items, justify_content, padding: Rect { @@ -57,20 +62,31 @@ pub fn resolve( }; for (child, tree) in items.iter().zip(tree.iter_mut()) { - // Calculate the dimensions of the item. let child_widget = child.as_widget(); - let child_node = child_widget.layout(tree, renderer, &limits); + let child_node = child_widget.layout(tree, renderer, limits); let size = child_node.size(); nodes.push(child_node); let c_size = child_widget.size(); - let (width, justify_self) = match c_size.width { - Length::Fill | Length::FillPortion(_) => (Dimension::Auto, Some(AlignItems::Stretch)), - _ => (length(size.width), None), + let (width, flex_grow, justify_self) = match c_size.width { + Length::Fill | Length::FillPortion(_) => { + (Dimension::Auto, 1.0, Some(AlignItems::Stretch)) + } + _ => (length(size.width), 0.0, None), }; let child_style = Style { + flex_grow, + + min_size: taffy::geometry::Size { + width: match min_item_width { + Some(width) => length(size.width.min(width)), + None => Dimension::Auto, + }, + height: Dimension::Auto, + }, + size: taffy::geometry::Size { width, height: match c_size.height { @@ -78,7 +94,9 @@ pub fn resolve( _ => length(size.height), }, }, + justify_self, + ..Style::default() }; @@ -149,5 +167,5 @@ pub fn resolve( height: flex_layout.content_size.height, }; - Node::with_children(size.expand(padding), nodes) + Node::with_children(size, nodes) } diff --git a/src/widget/flex_row/widget.rs b/src/widget/flex_row/widget.rs index 2394d07..b89397f 100644 --- a/src/widget/flex_row/widget.rs +++ b/src/widget/flex_row/widget.rs @@ -25,8 +25,17 @@ pub struct FlexRow<'a, Message> { row_spacing: u16, /// Sets the width. width: Length, + /// Sets minimum width of items that grow. + #[setters(into)] + min_item_width: Option, /// Sets the max width max_width: f32, + /// Defines how content will be aligned horizontally. + #[setters(skip)] + align_items: Option, + /// Defines how content will be aligned vertically. + #[setters(skip)] + justify_items: Option, /// Defines how the content will be justified. #[setters(into)] justify_content: Option, @@ -40,11 +49,34 @@ impl<'a, Message> FlexRow<'a, Message> { column_spacing: 4, row_spacing: 4, width: Length::Shrink, + min_item_width: None, max_width: f32::INFINITY, + align_items: None, + justify_items: None, justify_content: None, } } + /// Defines how content will be aligned horizontally. + pub fn align_items(mut self, alignment: iced::Alignment) -> Self { + self.align_items = Some(match alignment { + iced::Alignment::Center => taffy::AlignItems::Center, + iced::Alignment::Start => taffy::AlignItems::Start, + iced::Alignment::End => taffy::AlignItems::End, + }); + self + } + + /// Defines how content will be aligned vertically. + pub fn justify_items(mut self, alignment: iced::Alignment) -> Self { + self.justify_items = Some(match alignment { + iced::Alignment::Center => taffy::AlignItems::Center, + iced::Alignment::Start => taffy::AlignItems::Start, + iced::Alignment::End => taffy::AlignItems::End, + }); + self + } + /// Sets the space between each column and row. pub const fn spacing(mut self, spacing: u16) -> Self { self.column_spacing = spacing; @@ -87,6 +119,9 @@ impl<'a, Message: 'static + Clone> Widget self.padding, f32::from(self.column_spacing), f32::from(self.row_spacing), + self.min_item_width, + self.align_items, + self.justify_items, self.justify_content, &mut tree.children, )