summaryrefslogtreecommitdiff
path: root/src/layout/flex.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2019-10-13 12:08:07 +0200
committerLaurenz <laurmaedje@gmail.com>2019-10-13 12:08:07 +0200
commit463e4ebd8234da5e28700e9b22b6ef5f0dfef56f (patch)
tree01f3961d6996de3ee8f9819c2792f6ee8c2a3c3d /src/layout/flex.rs
parent6f22e4f13c42f06b686a01fbdd28a0163e88ae77 (diff)
Refactor layout types 🚧
Diffstat (limited to 'src/layout/flex.rs')
-rw-r--r--src/layout/flex.rs140
1 files changed, 58 insertions, 82 deletions
diff --git a/src/layout/flex.rs b/src/layout/flex.rs
index 75674e8f..68d39004 100644
--- a/src/layout/flex.rs
+++ b/src/layout/flex.rs
@@ -4,109 +4,85 @@ use crate::size::{Size, Size2D};
use super::*;
-/// A flex layout consists of a yet unarranged list of boxes.
-#[derive(Debug, Clone)]
-pub struct FlexLayout {
- /// The sublayouts composing this layout.
- pub units: Vec<FlexUnit>,
+
+/// Finishes a flex layout by justifying the positions of the individual boxes.
+#[derive(Debug)]
+pub struct FlexLayouter {
+ ctx: FlexContext,
+ units: Vec<FlexUnit>,
+
+ actions: LayoutActionList,
+ dimensions: Size2D,
+ usable: Size2D,
+ cursor: Size2D,
+
+ line_content: Vec<(Size2D, Layout)>,
+ line_metrics: Size2D,
+ last_glue: Option<Layout>,
+}
+
+/// The context for flex layouting.
+#[derive(Debug, Copy, Clone)]
+pub struct FlexContext {
+ /// The space to layout the boxes in.
+ pub space: LayoutSpace,
+ /// The flex spacing between two lines of boxes.
+ pub flex_spacing: Size,
}
/// A unit in a flex layout.
#[derive(Debug, Clone)]
-pub enum FlexUnit {
+enum FlexUnit {
/// A content unit to be arranged flexibly.
- Boxed(BoxLayout),
+ Boxed(Layout),
/// A unit which acts as glue between two [`FlexUnit::Boxed`] units and
/// is only present if there was no flow break in between the two surrounding boxes.
- Glue(BoxLayout),
+ Glue(Layout),
}
-impl FlexLayout {
- /// Create a new flex layout.
- pub fn new() -> FlexLayout {
- FlexLayout {
+impl FlexLayouter {
+ /// Create a new flex layouter.
+ pub fn new(ctx: FlexContext) -> FlexLayouter {
+ FlexLayouter {
+ ctx,
units: vec![],
+
+ actions: LayoutActionList::new(),
+ dimensions: match ctx.space.alignment {
+ Alignment::Left => Size2D::zero(),
+ Alignment::Right => Size2D::with_x(ctx.space.usable().x),
+ },
+ usable: ctx.space.usable(),
+ cursor: Size2D::new(ctx.space.padding.left, ctx.space.padding.top),
+
+ line_content: vec![],
+ line_metrics: Size2D::zero(),
+ last_glue: None,
}
}
- /// Create a new flex layout containing just one box.
- pub fn from_box(boxed: BoxLayout) -> FlexLayout {
- FlexLayout {
- units: vec![FlexUnit::Boxed(boxed)],
- }
+ /// Get a reference to this layouter's context.
+ pub fn ctx(&self) -> &FlexContext {
+ &self.ctx
}
/// Add a sublayout.
- pub fn add_box(&mut self, layout: BoxLayout) {
+ pub fn add(&mut self, layout: Layout) {
self.units.push(FlexUnit::Boxed(layout));
}
/// Add a glue layout which can be replaced by a line break.
- pub fn add_glue(&mut self, glue: BoxLayout) {
+ pub fn add_glue(&mut self, glue: Layout) {
self.units.push(FlexUnit::Glue(glue));
}
- /// Add all sublayouts of another flex layout.
- pub fn add_flexible(&mut self, layout: FlexLayout) {
- self.units.extend(layout.units);
- }
-
/// Whether this layouter contains any items.
pub fn is_empty(&self) -> bool {
self.units.is_empty()
}
/// Compute the justified layout.
- pub fn finish(self, ctx: FlexContext) -> LayoutResult<BoxLayout> {
- FlexFinisher::new(self, ctx).finish()
- }
-}
-
-/// The context for flex layouting.
-#[derive(Debug, Copy, Clone)]
-pub struct FlexContext {
- /// The space to layout the boxes in.
- pub space: LayoutSpace,
- /// The flex spacing between two lines of boxes.
- pub flex_spacing: Size,
-}
-
-/// Finishes a flex layout by justifying the positions of the individual boxes.
-#[derive(Debug)]
-struct FlexFinisher {
- units: Vec<FlexUnit>,
- ctx: FlexContext,
- actions: LayoutActionList,
- dimensions: Size2D,
- usable: Size2D,
- cursor: Size2D,
- line_metrics: Size2D,
- line_content: Vec<(Size2D, BoxLayout)>,
- glue: Option<BoxLayout>,
-}
-
-impl FlexFinisher {
- /// Create the finisher from the layout.
- fn new(layout: FlexLayout, ctx: FlexContext) -> FlexFinisher {
- let space = ctx.space;
- FlexFinisher {
- units: layout.units,
- ctx,
- actions: LayoutActionList::new(),
- dimensions: match ctx.space.alignment {
- Alignment::Left => Size2D::zero(),
- Alignment::Right => Size2D::with_x(space.usable().x),
- },
- usable: space.usable(),
- cursor: Size2D::new(space.padding.left, space.padding.top),
- line_metrics: Size2D::zero(),
- line_content: vec![],
- glue: None,
- }
- }
-
- /// Finish the flex layout into the justified box layout.
- fn finish(mut self) -> LayoutResult<BoxLayout> {
+ pub fn finish(mut self) -> LayoutResult<Layout> {
// Move the units out of the layout.
let units = self.units;
self.units = vec![];
@@ -122,7 +98,7 @@ impl FlexFinisher {
// Flush everything to get the correct dimensions.
self.newline();
- Ok(BoxLayout {
+ Ok(Layout {
dimensions: if self.ctx.space.shrink_to_fit {
self.dimensions.padded(self.ctx.space.padding)
} else {
@@ -134,8 +110,8 @@ impl FlexFinisher {
}
/// Layout the box.
- fn boxed(&mut self, boxed: BoxLayout) -> LayoutResult<()> {
- let last_glue_x = self.glue.as_ref()
+ fn boxed(&mut self, boxed: Layout) -> LayoutResult<()> {
+ let last_glue_x = self.last_glue.as_ref()
.map(|g| g.dimensions.x)
.unwrap_or(Size::zero());
@@ -147,7 +123,7 @@ impl FlexFinisher {
}
self.newline();
- } else if let Some(glue) = self.glue.take() {
+ } else if let Some(glue) = self.last_glue.take() {
self.append(glue);
}
@@ -157,15 +133,15 @@ impl FlexFinisher {
}
/// Layout the glue.
- fn glue(&mut self, glue: BoxLayout) {
- if let Some(glue) = self.glue.take() {
+ fn glue(&mut self, glue: Layout) {
+ if let Some(glue) = self.last_glue.take() {
self.append(glue);
}
- self.glue = Some(glue);
+ self.last_glue = Some(glue);
}
/// Append a box to the layout without checking anything.
- fn append(&mut self, layout: BoxLayout) {
+ fn append(&mut self, layout: Layout) {
let dim = layout.dimensions;
self.line_content.push((self.cursor, layout));