diff options
Diffstat (limited to 'src/layout/flex.rs')
| -rw-r--r-- | src/layout/flex.rs | 132 |
1 files changed, 68 insertions, 64 deletions
diff --git a/src/layout/flex.rs b/src/layout/flex.rs index 64d48c7d..2f219640 100644 --- a/src/layout/flex.rs +++ b/src/layout/flex.rs @@ -2,13 +2,13 @@ use super::*; #[derive(Debug, Clone)] pub struct FlexLayouter { - stack: StackLayouter, - axes: LayoutAxes, flex_spacing: Size, + stack: StackLayouter, units: Vec<FlexUnit>, line: FlexLine, + part: PartialLine, } #[derive(Debug, Clone)] @@ -24,7 +24,6 @@ struct FlexLine { usable: Size, actions: LayoutActionList, combined_dimensions: Size2D, - part: PartialLine, } impl FlexLine { @@ -33,7 +32,6 @@ impl FlexLine { usable, actions: LayoutActionList::new(), combined_dimensions: Size2D::zero(), - part: PartialLine::new(usable), } } } @@ -44,6 +42,7 @@ struct PartialLine { content: Vec<(Size, Layout)>, dimensions: Size2D, space: Option<Size>, + last_was_space: bool, } impl PartialLine { @@ -53,6 +52,7 @@ impl PartialLine { content: vec![], dimensions: Size2D::zero(), space: None, + last_was_space: false, } } } @@ -80,13 +80,13 @@ impl FlexLayouter { let usable = stack.primary_usable(); FlexLayouter { - stack, - axes: ctx.axes, flex_spacing: ctx.flex_spacing, + stack, units: vec![], - line: FlexLine::new(usable) + line: FlexLine::new(usable), + part: PartialLine::new(usable), } } @@ -105,7 +105,7 @@ impl FlexLayouter { } pub fn add_primary_space(&mut self, space: Size, soft: bool) { - self.units.push(FlexUnit::Space(space, soft)); + self.units.push(FlexUnit::Space(space, soft)) } pub fn add_secondary_space(&mut self, space: Size, soft: bool) -> LayoutResult<()> { @@ -122,7 +122,7 @@ impl FlexLayouter { pub fn set_spaces(&mut self, spaces: LayoutSpaces, replace_empty: bool) { if replace_empty && self.run_is_empty() && self.stack.space_is_empty() { self.stack.set_spaces(spaces, true); - self.start_run(); + self.start_line(); } else { self.stack.set_spaces(spaces, false); } @@ -142,7 +142,6 @@ impl FlexLayouter { Ok((flex_spaces, Some(stack_spaces))) } - } pub fn run_is_empty(&self) -> bool { @@ -162,7 +161,9 @@ impl FlexLayouter { if !self.run_is_empty() { self.finish_run()?; } - Ok(self.stack.finish_space(hard)) + + self.stack.finish_space(hard); + Ok(self.start_line()) } pub fn finish_run(&mut self) -> LayoutResult<Size2D> { @@ -172,7 +173,7 @@ impl FlexLayouter { FlexUnit::Boxed(boxed) => self.layout_box(boxed)?, FlexUnit::Space(space, soft) => self.layout_space(space, soft), FlexUnit::SetAxes(axes) => self.layout_set_axes(axes), - FlexUnit::Break => self.layout_break(), + FlexUnit::Break => { self.finish_line()?; }, } } @@ -183,77 +184,91 @@ impl FlexLayouter { self.finish_partial_line(); self.stack.add(Layout { - dimensions: self.axes.specialize(self.line.combined_dimensions), - actions: self.line.actions.into_vec(), + dimensions: self.axes.specialize(Size2D { + x: self.line.usable, + y: self.line.combined_dimensions.y + self.flex_spacing, + }), + actions: self.line.actions.to_vec(), debug_render: false, })?; let remaining = self.axes.specialize(Size2D { - x: self.line.usable - self.line.combined_dimensions.x, + x: self.part.usable + - self.part.dimensions.x + - self.part.space.unwrap_or(Size::zero()), y: self.line.combined_dimensions.y, }); - self.line = FlexLine::new(self.stack.primary_usable()); + self.start_line(); Ok(remaining) } - fn finish_partial_line(&mut self) { - let part = self.line.part; + fn start_line(&mut self) { + let usable = self.stack.primary_usable(); + self.line = FlexLine::new(usable); + self.part = PartialLine::new(usable); + } + fn finish_partial_line(&mut self) { let factor = self.axes.primary.axis.factor(); let anchor = self.axes.primary.anchor(self.line.usable) - - self.axes.primary.anchor(part.dimensions.x); + - self.axes.primary.anchor(self.part.dimensions.x); - for (offset, layout) in part.content { + for (offset, layout) in self.part.content.drain(..) { let pos = self.axes.specialize(Size2D::with_x(anchor + factor * offset)); self.line.actions.add_layout(pos, layout); } - self.line.combined_dimensions.x.max_eq(part.dimensions.x); - self.line.part = PartialLine::new(self.line.usable - part.dimensions.x); - } - - fn start_run(&mut self) { - let usable = self.stack.primary_usable(); - self.line = FlexLine::new(usable); + self.line.combined_dimensions.x = anchor + factor * self.part.dimensions.x; + self.line.combined_dimensions.y.max_eq(self.part.dimensions.x); } fn layout_box(&mut self, boxed: Layout) -> LayoutResult<()> { let size = self.axes.generalize(boxed.dimensions); - if size.x > self.size_left() { - self.space = None; + let new_dimension = self.part.dimensions.x + + self.part.space.unwrap_or(Size::zero()); + + if new_dimension > self.part.usable { self.finish_line()?; - while size.x > self.usable { + while size.x > self.line.usable { if self.stack.space_is_last() { - Err(LayoutError::NotEnoughSpace("cannot fix box into flex run"))?; + Err(LayoutError::NotEnoughSpace("failed to add box to flex run"))?; } - self.finish_space(true); - self.total_usable = self.stack.primary_usable(); - self.usable = self.total_usable; + self.stack.finish_space(true); } } - self.layout_space(); + if let Some(space) = self.part.space.take() { + self.layout_space(space, false); + } - let offset = self.run.size.x; - self.run.content.push((offset, boxed)); + let offset = self.part.dimensions.x; + self.part.content.push((offset, boxed)); - self.run.size.x += size.x; - self.run.size.y = crate::size::max(self.run.size.y, size.y); + self.part.dimensions.x += size.x; + self.part.dimensions.y.max_eq(size.y); + self.part.last_was_space = false; Ok(()) } fn layout_space(&mut self, space: Size, soft: bool) { - if let Some(space) = self.space.take() { - if self.run.size.x > Size::zero() && self.run.size.x + space <= self.usable { - self.run.size.x += space; + if soft { + if !self.part.last_was_space { + self.part.space = Some(space); + } + } else { + if self.part.dimensions.x + space > self.part.usable { + self.part.dimensions.x = self.part.usable; + } else { + self.part.dimensions.x += space; } + self.part.last_was_space = true; } } @@ -261,19 +276,17 @@ impl FlexLayouter { if axes.primary != self.axes.primary { self.finish_partial_line(); - // self.usable = match axes.primary.alignment { - // Alignment::Origin => - // if self.max_extent == Size::zero() { - // self.total_usable - // } else { - // Size::zero() - // }, - // Alignment::Center => crate::size::max( - // self.total_usable - 2 * self.max_extent, - // Size::zero() - // ), - // Alignment::End => self.total_usable - self.max_extent, - // }; + let extent = self.line.combined_dimensions.x; + let usable = self.line.usable; + + let new_usable = match axes.primary.alignment { + Alignment::Origin if extent == Size::zero() => usable, + Alignment::Center if extent < usable / 2 => usable - 2 * extent, + Alignment::End => usable - extent, + _ => Size::zero(), + }; + + self.part = PartialLine::new(new_usable); } if axes.secondary != self.axes.secondary { @@ -282,13 +295,4 @@ impl FlexLayouter { self.axes = axes; } - - fn layout_break(&mut self) { - - } - - fn size_left(&self) -> Size { - let space = self.space.unwrap_or(Size::zero()); - self.usable - (self.run.size.x + space) - } } |
