diff options
| author | Laurenz <laurmaedje@gmail.com> | 2019-12-30 22:28:56 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2019-12-30 22:28:56 +0100 |
| commit | 269f069a4d721a986807293ef71be1348bfae3d4 (patch) | |
| tree | 31b737c4ff2aead3eb5e2673828595bb26622032 /src/layout/stack.rs | |
| parent | b8620121a692df6313eeb5ccf7baf89c1e364116 (diff) | |
Simple line layouter 🧾
Diffstat (limited to 'src/layout/stack.rs')
| -rw-r--r-- | src/layout/stack.rs | 100 |
1 files changed, 37 insertions, 63 deletions
diff --git a/src/layout/stack.rs b/src/layout/stack.rs index 3c659d8a..e0562672 100644 --- a/src/layout/stack.rs +++ b/src/layout/stack.rs @@ -1,11 +1,9 @@ use smallvec::smallvec; +use crate::size::ValueBox; use super::*; /// The stack layouter stack boxes onto each other along the secondary layouting /// axis. -/// -/// The boxes are aligned along both axes according to their requested -/// alignment. #[derive(Debug, Clone)] pub struct StackLayouter { /// The context for layouting. @@ -42,30 +40,21 @@ struct Space { index: usize, /// Whether to add the layout for this space even if it would be empty. hard: bool, - /// The so-far accumulated subspaces. + /// The so-far accumulated layouts. layouts: Vec<(LayoutAxes, Layout)>, - /// The specialized size of this subspace. + /// The specialized size of this space. size: Size2D, /// The specialized remaining space. usable: Size2D, /// The specialized extra-needed dimensions to affect the size at all. extra: Size2D, - /// Dictates the valid alignments for new boxes in this space. - rulers: Rulers, + /// The rulers of a space dictate which alignments for new boxes are still + /// allowed and which require a new space to be started. + rulers: ValueBox<Alignment>, /// The last added spacing if the last added thing was spacing. last_spacing: LastSpacing, } -/// The rulers of a space dictate which alignments for new boxes are still -/// allowed and which require a new space to be started. -#[derive(Debug, Clone)] -struct Rulers { - top: Alignment, - bottom: Alignment, - left: Alignment, - right: Alignment, -} - impl StackLayouter { /// Create a new stack layouter. pub fn new(ctx: StackContext) -> StackLayouter { @@ -157,26 +146,6 @@ impl StackLayouter { } } - /// Update the rulers to account for the new layout. Returns true if a - /// space break is necessary. - fn update_rulers(&mut self, alignment: LayoutAlignment) -> bool { - let axes = self.ctx.axes; - let allowed = self.alignment_allowed(axes.primary, alignment.primary) - && self.alignment_allowed(axes.secondary, alignment.secondary); - - if allowed { - *self.space.rulers.get(axes.secondary) = alignment.secondary; - } - - allowed - } - - /// Whether the given alignment is still allowed according to the rulers. - fn alignment_allowed(&mut self, direction: Direction, alignment: Alignment) -> bool { - alignment >= *self.space.rulers.get(direction) - && alignment <= self.space.rulers.get(direction.inv()).inv() - } - /// Update the size metrics to reflect that a layout or spacing with the /// given generalized dimensions has been added. fn update_metrics(&mut self, dimensions: Size2D) { @@ -196,10 +165,31 @@ impl StackLayouter { *self.space.usable.get_secondary_mut(axes) -= dimensions.y; } + /// Update the rulers to account for the new layout. Returns true if a + /// space break is necessary. + fn update_rulers(&mut self, alignment: LayoutAlignment) -> bool { + let allowed = self.is_fitting_alignment(alignment); + if allowed { + *self.space.rulers.get_mut(self.ctx.axes.secondary, Origin) + = alignment.secondary; + } + allowed + } + + /// Whether a layout with the given alignment can still be layouted in the + /// active space. + pub fn is_fitting_alignment(&mut self, alignment: LayoutAlignment) -> bool { + self.is_fitting_axis(self.ctx.axes.primary, alignment.primary) + && self.is_fitting_axis(self.ctx.axes.secondary, alignment.secondary) + } + + /// Whether the given alignment is still allowed according to the rulers. + fn is_fitting_axis(&mut self, direction: Direction, alignment: Alignment) -> bool { + alignment >= *self.space.rulers.get_mut(direction, Origin) + && alignment <= self.space.rulers.get_mut(direction, End).inv() + } + /// Change the layouting axes used by this layouter. - /// - /// This starts a new subspace (if the axes are actually different from the - /// current ones). pub fn set_axes(&mut self, axes: LayoutAxes) { // Forget the spacing because it is not relevant anymore. if axes.secondary != self.ctx.axes.secondary { @@ -227,9 +217,7 @@ impl StackLayouter { /// The remaining unpadded, unexpanding spaces. If a multi-layout is laid /// out into these spaces, it will fit into this stack. pub fn remaining(&self) -> LayoutSpaces { - let dimensions = self.space.usable - - Size2D::with_y(self.space.last_spacing.soft_or_zero()) - .specialized(self.ctx.axes); + let dimensions = self.usable(); let mut spaces = smallvec