diff options
| author | Laurenz <laurmaedje@gmail.com> | 2019-10-17 12:55:34 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2019-10-17 12:55:34 +0200 |
| commit | 1987e5861cf2c033e3a540a5ef7c0f7106016929 (patch) | |
| tree | dcbf2d32c88d394e63b60e7473b2f6ba79fc83e3 /src/layout | |
| parent | f22f9513aea21408ebf6febd01912e630e9ad5e6 (diff) | |
Create basic box and line-break functions 📦
Diffstat (limited to 'src/layout')
| -rw-r--r-- | src/layout/flex.rs | 43 | ||||
| -rw-r--r-- | src/layout/tree.rs | 11 |
2 files changed, 32 insertions, 22 deletions
diff --git a/src/layout/flex.rs b/src/layout/flex.rs index 39c16aef..a6f2e091 100644 --- a/src/layout/flex.rs +++ b/src/layout/flex.rs @@ -73,6 +73,8 @@ enum FlexUnit { /// is only present if there was no flow break in between the two /// surrounding boxes. Glue(Size2D), + /// A forced break of the current flex run. + Break, } #[derive(Debug, Clone)] @@ -114,6 +116,11 @@ impl FlexLayouter { self.units.push(FlexUnit::Glue(glue)); } + /// Add a forced line break. + pub fn add_break(&mut self) { + self.units.push(FlexUnit::Break); + } + /// Compute the justified layout. /// /// The layouter is not consumed by this to prevent ownership problems @@ -127,6 +134,7 @@ impl FlexLayouter { match unit { FlexUnit::Boxed(boxed) => self.layout_box(boxed)?, FlexUnit::Glue(glue) => self.layout_glue(glue), + FlexUnit::Break => self.layout_break()?, } } @@ -157,14 +165,12 @@ impl FlexLayouter { } self.finish_run()?; - } else { - // Only add the glue if we did not move to a new line. - self.flush_glue(); } + self.flush_glue(); + let dimensions = boxed.dimensions; self.run.content.push((self.run.size.x, boxed)); - self.grow_run(dimensions); Ok(()) @@ -174,20 +180,12 @@ impl FlexLayouter { self.cached_glue = Some(glue); } - fn flush_glue(&mut self) { - if let Some(glue) = self.cached_glue.take() { - let new_line_width = self.run.size.x + glue.x; - if !self.overflows_line(new_line_width) { - self.grow_run(glue); - } - } - } - - fn grow_run(&mut self, dimensions: Size2D) { - self.run.size.x += dimensions.x; - self.run.size.y = crate::size::max(self.run.size.y, dimensions.y); + fn layout_break(&mut self) -> LayoutResult<()> { + self.cached_glue = None; + self.finish_run() } + /// Finish the current flex run. fn finish_run(&mut self) -> LayoutResult<()> { self.run.size.y += self.ctx.flex_spacing; @@ -208,6 +206,19 @@ impl FlexLayouter { Ok(()) } + fn flush_glue(&mut self) { + if let Some(glue) = self.cached_glue.take() { + if self.run.size.x > Size::zero() && !self.overflows_line(self.run.size.x + glue.x) { + self.grow_run(glue); + } + } + } + + fn grow_run(&mut self, dimensions: Size2D) { + self.run.size.x += dimensions.x; + self.run.size.y = crate::size::max(self.run.size.y, dimensions.y); + } + /// Whether this layouter contains any items. pub fn is_empty(&self) -> bool { self.units.is_empty() diff --git a/src/layout/tree.rs b/src/layout/tree.rs index bd4adb8a..2c904369 100644 --- a/src/layout/tree.rs +++ b/src/layout/tree.rs @@ -88,6 +88,7 @@ impl<'a, 'p> TreeLayouter<'a, 'p> { fn layout_func(&mut self, func: &FuncCall) -> LayoutResult<()> { // Finish the current flex layout on a copy to find out how // much space would be remaining if we finished. + let mut lookahead_stack = self.stack.clone(); let layouts = self.flex.clone().finish()?; lookahead_stack.add_many(layouts)?; @@ -106,9 +107,7 @@ impl<'a, 'p> TreeLayouter<'a, 'p> { for command in commands { match command { - Command::Layout(tree) => { - self.layout(tree)?; - } + Command::Layout(tree) => self.layout(tree)?, Command::Add(layout) => { self.finish_flex()?; @@ -130,15 +129,15 @@ impl<'a, 'p> TreeLayouter<'a, 'p> { self.start_new_flex(); } - Command::SetStyle(style) => { - *self.style.to_mut() = style; - } + Command::SetStyle(style) => *self.style.to_mut() = style, Command::FinishLayout => { self.finish_flex()?; self.stack.finish_layout(true)?; self.start_new_flex(); } + + Command::FinishFlexRun => self.flex.add_break(), } } |
