From be51cac3d71d5eb49e266d0d2aae6ab945caf560 Mon Sep 17 00:00:00 2001 From: Cory Forsstrom Date: Tue, 14 Sep 2021 09:10:37 -0700 Subject: Add Align::Fill variant --- native/src/layout/flex.rs | 62 +++++++++++++++++++++++++++++++++++++---------- native/src/layout/node.rs | 6 +++++ 2 files changed, 55 insertions(+), 13 deletions(-) (limited to 'native/src/layout') diff --git a/native/src/layout/flex.rs b/native/src/layout/flex.rs index 3d3ff82c..17045e69 100644 --- a/native/src/layout/flex.rs +++ b/native/src/layout/flex.rs @@ -76,7 +76,11 @@ where let max_cross = axis.cross(limits.max()); let mut fill_sum = 0; - let mut cross = axis.cross(limits.min()).max(axis.cross(limits.fill())); + let mut cross = if align_items == Align::Fill { + axis.cross(limits.min()) + } else { + axis.cross(limits.min()).max(axis.cross(limits.fill())) + }; let mut available = axis.main(limits.max()) - total_spacing; let mut nodes: Vec = Vec::with_capacity(items.len()); @@ -89,17 +93,34 @@ where } .fill_factor(); - if fill_factor == 0 { - let (max_width, max_height) = axis.pack(available, max_cross); + let cross_fill_factor = match axis { + Axis::Horizontal => child.height(), + Axis::Vertical => child.width(), + } + .fill_factor(); - let child_limits = - Limits::new(Size::ZERO, Size::new(max_width, max_height)); + if align_items != Align::Fill && fill_factor != 0 { + fill_sum += fill_factor; - let layout = child.layout(renderer, &child_limits); - let size = layout.size(); + continue; + } - available -= axis.main(size); + 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(); + + if align_items != Align::Fill + || cross_fill_factor == 0 && align_items == Align::Fill + { cross = cross.max(axis.cross(size)); + } + + if fill_factor == 0 { + available -= axis.main(size); nodes[i] = layout; } else { @@ -124,11 +145,23 @@ where max_main }; - let (min_main, min_cross) = - axis.pack(min_main, axis.cross(limits.min())); + let (min_main, min_cross) = axis.pack( + min_main, + if align_items == Align::Fill { + cross + } else { + axis.cross(limits.min()) + }, + ); - let (max_main, max_cross) = - axis.pack(max_main, axis.cross(limits.max())); + let (max_main, max_cross) = axis.pack( + max_main, + if align_items == Align::Fill { + cross + } else { + axis.cross(limits.max()) + }, + ); let child_limits = Limits::new( Size::new(min_main, min_cross), @@ -136,7 +169,10 @@ where ); let layout = child.layout(renderer, &child_limits); - cross = cross.max(axis.cross(layout.size())); + + if align_items != Align::Fill { + cross = cross.max(axis.cross(layout.size())); + } nodes[i] = layout; } diff --git a/native/src/layout/node.rs b/native/src/layout/node.rs index d7666f31..bee5e64e 100644 --- a/native/src/layout/node.rs +++ b/native/src/layout/node.rs @@ -56,6 +56,9 @@ impl Node { Align::End => { self.bounds.x += space.width - self.bounds.width; } + Align::Fill => { + self.bounds.width = space.width; + } } match vertical_alignment { @@ -66,6 +69,9 @@ impl Node { Align::End => { self.bounds.y += space.height - self.bounds.height; } + Align::Fill => { + self.bounds.height = space.height; + } } } -- cgit From e89bbe8a79537c650149154cb54038819e0efad7 Mon Sep 17 00:00:00 2001 From: Cory Forsstrom Date: Tue, 14 Sep 2021 10:38:02 -0700 Subject: Calc fill cross and use for all children --- native/src/layout/flex.rs | 84 +++++++++++++++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 29 deletions(-) (limited to 'native/src/layout') diff --git a/native/src/layout/flex.rs b/native/src/layout/flex.rs index 17045e69..2f75fee1 100644 --- a/native/src/layout/flex.rs +++ b/native/src/layout/flex.rs @@ -76,16 +76,38 @@ where let max_cross = axis.cross(limits.max()); let mut fill_sum = 0; - let mut cross = if align_items == Align::Fill { - axis.cross(limits.min()) - } else { - axis.cross(limits.min()).max(axis.cross(limits.fill())) - }; + let mut cross = axis.cross(limits.min()).max(axis.cross(limits.fill())); let mut available = axis.main(limits.max()) - total_spacing; let mut nodes: Vec = Vec::with_capacity(items.len()); nodes.resize(items.len(), Node::default()); + if align_items == Align::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(), @@ -93,35 +115,39 @@ where } .fill_factor(); - let cross_fill_factor = match axis { - Axis::Horizontal => child.height(), - Axis::Vertical => child.width(), - } - .fill_factor(); - - if align_items != Align::Fill && fill_factor != 0 { - fill_sum += fill_factor; - - continue; - } - - let (max_width, max_height) = axis.pack(available, max_cross); + if fill_factor == 0 { + let (min_width, min_height) = axis.pack( + 0.0, + if align_items == Align::Fill { + cross + } else { + 0.0 + }, + ); - let child_limits = - Limits::new(Size::ZERO, Size::new(max_width, max_height)); + let (max_width, max_height) = axis.pack( + available, + if align_items == Align::Fill { + cross + } else { + max_cross + }, + ); - let layout = child.layout(renderer, &child_limits); - let size = layout.size(); + let child_limits = Limits::new( + Size::new(min_width, min_height), + Size::new(max_width, max_height), + ); - if align_items != Align::Fill - || cross_fill_factor == 0 && align_items == Align::Fill - { - cross = cross.max(axis.cross(size)); - } + let layout = child.layout(renderer, &child_limits); + let size = layout.size(); - if fill_factor == 0 { available -= axis.main(size); + if align_items != Align::Fill { + cross = cross.max(axis.cross(size)); + } + nodes[i] = layout; } else { fill_sum += fill_factor; @@ -159,7 +185,7 @@ where if align_items == Align::Fill { cross } else { - axis.cross(limits.max()) + max_cross }, ); -- cgit From 95e4791a1e4611f0db703ac2911f56b391469b5f Mon Sep 17 00:00:00 2001 From: Cory Forsstrom Date: Wed, 15 Sep 2021 11:18:11 -0700 Subject: Improve readability of Align::Fill branching --- native/src/layout/flex.rs | 56 +++++++++++++++++++---------------------------- 1 file changed, 22 insertions(+), 34 deletions(-) (limited to 'native/src/layout') diff --git a/native/src/layout/flex.rs b/native/src/layout/flex.rs index 2f75fee1..52b48fec 100644 --- a/native/src/layout/flex.rs +++ b/native/src/layout/flex.rs @@ -116,23 +116,17 @@ where .fill_factor(); if fill_factor == 0 { - let (min_width, min_height) = axis.pack( - 0.0, - if align_items == Align::Fill { - cross - } else { - 0.0 - }, - ); + let (min_width, min_height) = if align_items == Align::Fill { + axis.pack(0.0, cross) + } else { + axis.pack(0.0, 0.0) + }; - let (max_width, max_height) = axis.pack( - available, - if align_items == Align::Fill { - cross - } else { - max_cross - }, - ); + let (max_width, max_height) = if align_items == Align::Fill { + axis.pack(available, cross) + } else { + axis.pack(available, max_cross) + }; let child_limits = Limits::new( Size::new(min_width, min_height), @@ -171,27 +165,21 @@ where max_main }; - let (min_main, min_cross) = axis.pack( - min_main, - if align_items == Align::Fill { - cross - } else { - axis.cross(limits.min()) - }, - ); + let (min_width, min_height) = if align_items == Align::Fill { + axis.pack(min_main, cross) + } else { + axis.pack(min_main, axis.cross(limits.min())) + }; - let (max_main, max_cross) = axis.pack( - max_main, - if align_items == Align::Fill { - cross - } else { - max_cross - }, - ); + let (max_width, max_height) = if align_items == Align::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); -- cgit From 5fae6e59ffbc5913761df638dc7f0c35b7f43bc9 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 20 Sep 2021 14:33:02 +0700 Subject: Introduce and use `CrossAlign` enum for `Column` and `Row` --- native/src/layout/flex.rs | 30 +++++++++++++++++++----------- native/src/layout/node.rs | 22 +++++++++++----------- 2 files changed, 30 insertions(+), 22 deletions(-) (limited to 'native/src/layout') diff --git a/native/src/layout/flex.rs b/native/src/layout/flex.rs index 52b48fec..dfb5288b 100644 --- a/native/src/layout/flex.rs +++ b/native/src/layout/flex.rs @@ -19,7 +19,7 @@ use crate::{ layout::{Limits, Node}, - Align, Element, Padding, Point, Size, + CrossAlign, Element, Padding, Point, Size, }; /// The main axis of a flex layout. @@ -65,7 +65,7 @@ pub fn resolve( limits: &Limits, padding: Padding, spacing: f32, - align_items: Align, + align_items: CrossAlign, items: &[Element<'_, Message, Renderer>], ) -> Node where @@ -82,7 +82,7 @@ where let mut nodes: Vec = Vec::with_capacity(items.len()); nodes.resize(items.len(), Node::default()); - if align_items == Align::Fill { + if align_items == CrossAlign::Fill { let mut fill_cross = axis.cross(limits.min()); items.iter().for_each(|child| { @@ -116,13 +116,13 @@ where .fill_factor(); if fill_factor == 0 { - let (min_width, min_height) = if align_items == Align::Fill { + let (min_width, min_height) = if align_items == CrossAlign::Fill { axis.pack(0.0, cross) } else { axis.pack(0.0, 0.0) }; - let (max_width, max_height) = if align_items == Align::Fill { + let (max_width, max_height) = if align_items == CrossAlign::Fill { axis.pack(available, cross) } else { axis.pack(available, max_cross) @@ -138,7 +138,7 @@ where available -= axis.main(size); - if align_items != Align::Fill { + if align_items != CrossAlign::Fill { cross = cross.max(axis.cross(size)); } @@ -165,13 +165,13 @@ where max_main }; - let (min_width, min_height) = if align_items == Align::Fill { + let (min_width, min_height) = if align_items == CrossAlign::Fill { axis.pack(min_main, cross) } else { axis.pack(min_main, axis.cross(limits.min())) }; - let (max_width, max_height) = if align_items == Align::Fill { + let (max_width, max_height) = if align_items == CrossAlign::Fill { axis.pack(max_main, cross) } else { axis.pack(max_main, max_cross) @@ -184,7 +184,7 @@ where let layout = child.layout(renderer, &child_limits); - if align_items != Align::Fill { + if align_items != CrossAlign::Fill { cross = cross.max(axis.cross(layout.size())); } @@ -206,10 +206,18 @@ where match axis { Axis::Horizontal => { - node.align(Align::Start, align_items, Size::new(0.0, cross)); + node.align( + CrossAlign::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, + CrossAlign::Start, + Size::new(cross, 0.0), + ); } } diff --git a/native/src/layout/node.rs b/native/src/layout/node.rs index bee5e64e..2239a654 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::{CrossAlign, Point, Rectangle, Size}; /// The bounds of an element and its children. #[derive(Debug, Clone, Default)] @@ -44,32 +44,32 @@ impl Node { /// Aligns the [`Node`] in the given space. pub fn align( &mut self, - horizontal_alignment: Align, - vertical_alignment: Align, + horizontal_alignment: CrossAlign, + vertical_alignment: CrossAlign, space: Size, ) { match horizontal_alignment { - Align::Start => {} - Align::Center => { + CrossAlign::Start => {} + CrossAlign::Center => { self.bounds.x += (space.width - self.bounds.width) / 2.0; } - Align::End => { + CrossAlign::End => { self.bounds.x += space.width - self.bounds.width; } - Align::Fill => { + CrossAlign::Fill => { self.bounds.width = space.width; } } match vertical_alignment { - Align::Start => {} - Align::Center => { + CrossAlign::Start => {} + CrossAlign::Center => { self.bounds.y += (space.height - self.bounds.height) / 2.0; } - Align::End => { + CrossAlign::End => { self.bounds.y += space.height - self.bounds.height; } - Align::Fill => { + CrossAlign::Fill => { self.bounds.height = space.height; } } -- cgit From a0ad3996225601aaa1ebe051cba115374b55c80e Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 20 Sep 2021 15:09:55 +0700 Subject: Refactor alignment types into an `alignment` module --- native/src/layout/flex.rs | 27 ++++++++++++--------------- native/src/layout/node.rs | 22 +++++++++++----------- 2 files changed, 23 insertions(+), 26 deletions(-) (limited to 'native/src/layout') diff --git a/native/src/layout/flex.rs b/native/src/layout/flex.rs index dfb5288b..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}, - CrossAlign, 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( limits: &Limits, padding: Padding, spacing: f32, - align_items: CrossAlign, + align_items: Alignment, items: &[Element<'_, Message, Renderer>], ) -> Node where @@ -82,7 +79,7 @@ where let mut nodes: Vec = Vec::with_capacity(items.len()); nodes.resize(items.len(), Node::default()); - if align_items == CrossAlign::Fill { + if align_items == Alignment::Fill { let mut fill_cross = axis.cross(limits.min()); items.iter().for_each(|child| { @@ -116,13 +113,13 @@ where .fill_factor(); if fill_factor == 0 { - let (min_width, min_height) = if align_items == CrossAlign::Fill { + let (min_width, min_height) = if align_items == Alignment::Fill { axis.pack(0.0, cross) } else { axis.pack(0.0, 0.0) }; - let (max_width, max_height) = if align_items == CrossAlign::Fill { + let (max_width, max_height) = if align_items == Alignment::Fill { axis.pack(available, cross) } else { axis.pack(available, max_cross) @@ -138,7 +135,7 @@ where available -= axis.main(size); - if align_items != CrossAlign::Fill { + if align_items != Alignment::Fill { cross = cross.max(axis.cross(size)); } @@ -165,13 +162,13 @@ where max_main }; - let (min_width, min_height) = if align_items == CrossAlign::Fill { + 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_width, max_height) = if align_items == CrossAlign::Fill { + let (max_width, max_height) = if align_items == Alignment::Fill { axis.pack(max_main, cross) } else { axis.pack(max_main, max_cross) @@ -184,7 +181,7 @@ where let layout = child.layout(renderer, &child_limits); - if align_items != CrossAlign::Fill { + if align_items != Alignment::Fill { cross = cross.max(axis.cross(layout.size())); } @@ -207,7 +204,7 @@ where match axis { Axis::Horizontal => { node.align( - CrossAlign::Start, + Alignment::Start, align_items, Size::new(0.0, cross), ); @@ -215,7 +212,7 @@ where Axis::Vertical => { node.align( align_items, - CrossAlign::Start, + Alignment::Start, Size::new(cross, 0.0), ); } diff --git a/native/src/layout/node.rs b/native/src/layout/node.rs index 2239a654..e9e6058e 100644 --- a/native/src/layout/node.rs +++ b/native/src/layout/node.rs @@ -1,4 +1,4 @@ -use crate::{CrossAlign, Point, Rectangle, Size}; +use crate::{Alignment, Point, Rectangle, Size}; /// The bounds of an element and its children. #[derive(Debug, Clone, Default)] @@ -44,32 +44,32 @@ impl Node { /// Aligns the [`Node`] in the given space. pub fn align( &mut self, - horizontal_alignment: CrossAlign, - vertical_alignment: CrossAlign, + horizontal_alignment: Alignment, + vertical_alignment: Alignment, space: Size, ) { match horizontal_alignment { - CrossAlign::Start => {} - CrossAlign::Center => { + Alignment::Start => {} + Alignment::Center => { self.bounds.x += (space.width - self.bounds.width) / 2.0; } - CrossAlign::End => { + Alignment::End => { self.bounds.x += space.width - self.bounds.width; } - CrossAlign::Fill => { + Alignment::Fill => { self.bounds.width = space.width; } } match vertical_alignment { - CrossAlign::Start => {} - CrossAlign::Center => { + Alignment::Start => {} + Alignment::Center => { self.bounds.y += (space.height - self.bounds.height) / 2.0; } - CrossAlign::End => { + Alignment::End => { self.bounds.y += space.height - self.bounds.height; } - CrossAlign::Fill => { + Alignment::Fill => { self.bounds.height = space.height; } } -- cgit