diff options
Diffstat (limited to 'native/src/layout')
-rw-r--r-- | native/src/layout/flex.rs | 93 | ||||
-rw-r--r-- | native/src/layout/node.rs | 24 |
2 files changed, 89 insertions, 28 deletions
diff --git a/native/src/layout/flex.rs b/native/src/layout/flex.rs index 3d3ff82c..5fbcbca0 100644 --- a/native/src/layout/flex.rs +++ b/native/src/layout/flex.rs @@ -16,11 +16,8 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - -use crate::{ - layout::{Limits, Node}, - Align, Element, Padding, Point, Size, -}; +use crate::layout::{Limits, Node}; +use crate::{Alignment, Element, Padding, Point, Size}; /// The main axis of a flex layout. #[derive(Debug)] @@ -65,7 +62,7 @@ pub fn resolve<Message, Renderer>( limits: &Limits, padding: Padding, spacing: f32, - align_items: Align, + align_items: Alignment, items: &[Element<'_, Message, Renderer>], ) -> Node where @@ -82,6 +79,32 @@ where let mut nodes: Vec<Node> = Vec::with_capacity(items.len()); nodes.resize(items.len(), Node::default()); + if align_items == Alignment::Fill { + let mut fill_cross = axis.cross(limits.min()); + + items.iter().for_each(|child| { + let cross_fill_factor = match axis { + Axis::Horizontal => child.height(), + Axis::Vertical => child.width(), + } + .fill_factor(); + + if cross_fill_factor == 0 { + let (max_width, max_height) = axis.pack(available, max_cross); + + let child_limits = + Limits::new(Size::ZERO, Size::new(max_width, max_height)); + + let layout = child.layout(renderer, &child_limits); + let size = layout.size(); + + fill_cross = fill_cross.max(axis.cross(size)); + } + }); + + cross = fill_cross; + } + for (i, child) in items.iter().enumerate() { let fill_factor = match axis { Axis::Horizontal => child.width(), @@ -90,16 +113,31 @@ where .fill_factor(); if fill_factor == 0 { - let (max_width, max_height) = axis.pack(available, max_cross); + let (min_width, min_height) = if align_items == Alignment::Fill { + axis.pack(0.0, cross) + } else { + axis.pack(0.0, 0.0) + }; - let child_limits = - Limits::new(Size::ZERO, Size::new(max_width, max_height)); + let (max_width, max_height) = if align_items == Alignment::Fill { + axis.pack(available, cross) + } else { + axis.pack(available, max_cross) + }; + + let child_limits = Limits::new( + Size::new(min_width, min_height), + Size::new(max_width, max_height), + ); let layout = child.layout(renderer, &child_limits); let size = layout.size(); available -= axis.main(size); - cross = cross.max(axis.cross(size)); + + if align_items != Alignment::Fill { + cross = cross.max(axis.cross(size)); + } nodes[i] = layout; } else { @@ -124,19 +162,28 @@ where max_main }; - let (min_main, min_cross) = - axis.pack(min_main, axis.cross(limits.min())); + let (min_width, min_height) = if align_items == Alignment::Fill { + axis.pack(min_main, cross) + } else { + axis.pack(min_main, axis.cross(limits.min())) + }; - let (max_main, max_cross) = - axis.pack(max_main, axis.cross(limits.max())); + let (max_width, max_height) = if align_items == Alignment::Fill { + axis.pack(max_main, cross) + } else { + axis.pack(max_main, max_cross) + }; let child_limits = Limits::new( - Size::new(min_main, min_cross), - Size::new(max_main, max_cross), + Size::new(min_width, min_height), + Size::new(max_width, max_height), ); let layout = child.layout(renderer, &child_limits); - cross = cross.max(axis.cross(layout.size())); + + if align_items != Alignment::Fill { + cross = cross.max(axis.cross(layout.size())); + } nodes[i] = layout; } @@ -156,10 +203,18 @@ where match axis { Axis::Horizontal => { - node.align(Align::Start, align_items, Size::new(0.0, cross)); + node.align( + Alignment::Start, + align_items, + Size::new(0.0, cross), + ); } Axis::Vertical => { - node.align(align_items, Align::Start, Size::new(cross, 0.0)); + node.align( + align_items, + Alignment::Start, + Size::new(cross, 0.0), + ); } } diff --git a/native/src/layout/node.rs b/native/src/layout/node.rs index d7666f31..e9e6058e 100644 --- a/native/src/layout/node.rs +++ b/native/src/layout/node.rs @@ -1,4 +1,4 @@ -use crate::{Align, Point, Rectangle, Size}; +use crate::{Alignment, Point, Rectangle, Size}; /// The bounds of an element and its children. #[derive(Debug, Clone, Default)] @@ -44,28 +44,34 @@ impl Node { /// Aligns the [`Node`] in the given space. pub fn align( &mut self, - horizontal_alignment: Align, - vertical_alignment: Align, + horizontal_alignment: Alignment, + vertical_alignment: Alignment, space: Size, ) { match horizontal_alignment { - Align::Start => {} - Align::Center => { + Alignment::Start => {} + Alignment::Center => { self.bounds.x += (space.width - self.bounds.width) / 2.0; } - Align::End => { + Alignment::End => { self.bounds.x += space.width - self.bounds.width; } + Alignment::Fill => { + self.bounds.width = space.width; + } } match vertical_alignment { - Align::Start => {} - Align::Center => { + Alignment::Start => {} + Alignment::Center => { self.bounds.y += (space.height - self.bounds.height) / 2.0; } - Align::End => { + Alignment::End => { self.bounds.y += space.height - self.bounds.height; } + Alignment::Fill => { + self.bounds.height = space.height; + } } } |