diff options
| author | Laurenz <laurmaedje@gmail.com> | 2019-10-16 22:32:40 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2019-10-16 22:32:40 +0200 |
| commit | e87a34a4d0bf967427e2443f9f48026d09ccd5db (patch) | |
| tree | d1163980613526f9b211c710a9bb52b2893f0839 /src/layout/stacked.rs | |
| parent | 58693486f97ddbb34595efa1a81a4e7b1d3204c9 (diff) | |
Rearrange layouting contexts ♻
Diffstat (limited to 'src/layout/stacked.rs')
| -rw-r--r-- | src/layout/stacked.rs | 55 |
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), |
