feat(flex-row): align_items, justify_items, justify_content, and min_item_width

This commit is contained in:
Michael Aaron Murphy 2024-05-30 12:37:32 +02:00 committed by Michael Murphy
parent 289db87373
commit cb6bc86e1e
2 changed files with 60 additions and 7 deletions

View file

@ -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<Message>(
renderer: &Renderer,
@ -18,10 +19,12 @@ pub fn resolve<Message>(
padding: Padding,
column_spacing: f32,
row_spacing: f32,
min_item_width: Option<f32>,
justify_items: Option<AlignItems>,
align_items: Option<AlignItems>,
justify_content: Option<AlignContent>,
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<Message>(
height: Dimension::Auto,
},
align_items,
justify_items,
justify_content,
padding: Rect {
@ -57,20 +62,31 @@ pub fn resolve<Message>(
};
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<Message>(
_ => length(size.height),
},
},
justify_self,
..Style::default()
};
@ -149,5 +167,5 @@ pub fn resolve<Message>(
height: flex_layout.content_size.height,
};
Node::with_children(size.expand(padding), nodes)
Node::with_children(size, nodes)
}

View file

@ -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<f32>,
/// Sets the max width
max_width: f32,
/// Defines how content will be aligned horizontally.
#[setters(skip)]
align_items: Option<taffy::AlignItems>,
/// Defines how content will be aligned vertically.
#[setters(skip)]
justify_items: Option<taffy::AlignItems>,
/// Defines how the content will be justified.
#[setters(into)]
justify_content: Option<crate::widget::JustifyContent>,
@ -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<Message, crate::Theme, Renderer>
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,
)