summaryrefslogtreecommitdiff
path: root/src/layout/stacked.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2019-10-16 22:32:40 +0200
committerLaurenz <laurmaedje@gmail.com>2019-10-16 22:32:40 +0200
commite87a34a4d0bf967427e2443f9f48026d09ccd5db (patch)
treed1163980613526f9b211c710a9bb52b2893f0839 /src/layout/stacked.rs
parent58693486f97ddbb34595efa1a81a4e7b1d3204c9 (diff)
Rearrange layouting contexts ♻
Diffstat (limited to 'src/layout/stacked.rs')
-rw-r--r--src/layout/stacked.rs55
1 files changed, 41 insertions, 14 deletions
diff --git a/src/layout/stacked.rs b/src/layout/stacked.rs
index 3a29f722..0b7bfd4f 100644
--- a/src/layout/stacked.rs
+++ b/src/layout/stacked.rs
@@ -17,10 +17,37 @@ pub struct StackLayouter {
}
/// The context for stack layouting.
+///
+/// See [`LayoutContext`] for details about the fields.
#[derive(Debug, Copy, Clone)]
pub struct StackContext {
+ pub alignment: Alignment,
pub space: LayoutSpace,
- pub extra_space: Option<LayoutSpace>,
+ pub followup_spaces: Option<LayoutSpace>,
+ pub shrink_to_fit: bool,
+}
+
+macro_rules! reuse {
+ ($ctx:expr) => {
+ StackContext {
+ alignment: $ctx.alignment,
+ space: $ctx.space,
+ followup_spaces: $ctx.followup_spaces,
+ shrink_to_fit: $ctx.shrink_to_fit
+ }
+ };
+}
+
+impl StackContext {
+ /// Create a stack context from a generic layout context.
+ pub fn from_layout_ctx(ctx: LayoutContext) -> StackContext {
+ reuse!(ctx)
+ }
+
+ /// Create a stack context from a flex context.
+ pub fn from_flex_ctx(ctx: FlexContext) -> StackContext {
+ reuse!(ctx)
+ }
}
impl StackLayouter {
@@ -33,8 +60,8 @@ impl StackLayouter {
space: ctx.space,
usable: ctx.space.usable(),
- dimensions: start_dimensions(ctx.space),
- cursor: start_cursor(ctx.space),
+ dimensions: start_dimensions(ctx.alignment, ctx.space),
+ cursor: start_cursor(ctx.alignment, ctx.space),
in_extra_space: false,
started: true,
}
@@ -57,7 +84,7 @@ impl StackLayouter {
};
if self.overflows(new_dimensions) {
- if self.ctx.extra_space.is_some() &&
+ if self.ctx.followup_spaces.is_some() &&
!(self.in_extra_space && self.overflows(layout.dimensions))
{
self.finish_layout(true)?;
@@ -70,7 +97,7 @@ impl StackLayouter {
// Determine where to put the box. When we right-align it, we want the
// cursor to point to the top-right corner of the box. Therefore, the
// position has to be moved to the left by the width of the box.
- let position = match self.space.alignment {
+ let position = match self.ctx.alignment {
Alignment::Left => self.cursor,
Alignment::Right => self.cursor - Size2D::with_x(layout.dimensions.x),
Alignment::Center => self.cursor - Size2D::with_x(layout.dimensions.x / 2),
@@ -101,7 +128,7 @@ impl StackLayouter {
let new_dimensions = self.dimensions + Size2D::with_y(space);
if self.overflows(new_dimensions) {
- if self.ctx.extra_space.is_some() {
+ if self.ctx.followup_spaces.is_some() {
self.finish_layout(false)?;
} else {
return Err(LayoutError::NotEnoughSpace("cannot fit space into stack"));
@@ -133,7 +160,7 @@ impl StackLayouter {
pub fn finish_layout(&mut self, start_new_empty: bool) -> LayoutResult<()> {
let actions = std::mem::replace(&mut self.actions, LayoutActionList::new());
self.layouts.add(Layout {
- dimensions: if self.space.shrink_to_fit {
+ dimensions: if self.ctx.shrink_to_fit {
self.dimensions.padded(self.space.padding)
} else {
self.space.dimensions
@@ -152,12 +179,12 @@ impl StackLayouter {
}
pub fn start_new_space(&mut self) -> LayoutResult<()> {
- if let Some(space) = self.ctx.extra_space {
+ if let Some(space) = self.ctx.followup_spaces {
self.started = true;
self.space = space;
self.usable = space.usable();
- self.dimensions = start_dimensions(space);
- self.cursor = start_cursor(space);
+ self.dimensions = start_dimensions(self.ctx.alignment, space);
+ self.cursor = start_cursor(self.ctx.alignment, space);
self.in_extra_space = true;
Ok(())
} else {
@@ -183,19 +210,19 @@ impl StackLayouter {
}
}
-fn start_dimensions(space: LayoutSpace) -> Size2D {
- match space.alignment {
+fn start_dimensions(alignment: Alignment, space: LayoutSpace) -> Size2D {
+ match alignment {
Alignment::Left => Size2D::zero(),
Alignment::Right | Alignment::Center => Size2D::with_x(space.usable().x),
}
}
-fn start_cursor(space: LayoutSpace) -> Size2D {
+fn start_cursor(alignment: Alignment, space: LayoutSpace) -> Size2D {
Size2D {
// If left-align, the cursor points to the top-left corner of
// each box. If we right-align, it points to the top-right
// corner.
- x: match space.alignment {
+ x: match alignment {
Alignment::Left => space.padding.left,
Alignment::Right => space.dimensions.x - space.padding.right,
Alignment::Center => space.padding.left + (space.usable().x / 2),