diff options
| author | Laurenz <laurmaedje@gmail.com> | 2019-11-20 17:28:58 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2019-11-20 17:31:52 +0100 |
| commit | f24e9b44e0ceb19be6f4e16af2d22815e9ccf5b7 (patch) | |
| tree | 9e520ee1f8b802973aa5b568c11fafc42e6426a8 /src/layout/stacked.rs | |
| parent | 1dafe2c2ea0828bb075fdbb0da663967f7b5b2b9 (diff) | |
Refined expansion model 🔛
Diffstat (limited to 'src/layout/stacked.rs')
| -rw-r--r-- | src/layout/stacked.rs | 100 |
1 files changed, 66 insertions, 34 deletions
diff --git a/src/layout/stacked.rs b/src/layout/stacked.rs index b2d07382..cdc35580 100644 --- a/src/layout/stacked.rs +++ b/src/layout/stacked.rs @@ -8,28 +8,31 @@ pub struct StackLayouter { space: usize, hard: bool, - start: Size2D, actions: LayoutActionList, - combined_dimensions: Size2D, + combined_dimensions: Size2D, // <- specialized sub: Subspace, } #[derive(Debug, Clone)] struct Subspace { + origin: Size2D, // <- specialized usable: Size2D, - anchor: Size2D, + anchor: Size2D, // <- generic factor: i32, - dimensions: Size2D, + dimensions: Size2D, // <- generic + space: Option<Size>, } impl Subspace { - fn new(usable: Size2D, axes: LayoutAxes) -> Subspace { + fn new(origin: Size2D, usable: Size2D, axes: LayoutAxes) -> Subspace { Subspace { - usable, + origin, + usable: axes.generalize(usable), anchor: axes.anchor(usable), factor: axes.secondary.axis.factor(), dimensions: Size2D::zero(), + space: None, } } } @@ -41,7 +44,7 @@ impl Subspace { pub struct StackContext { pub spaces: LayoutSpaces, pub axes: LayoutAxes, - pub shrink_to_fit: bool, + pub expand: bool, } impl StackLayouter { @@ -49,7 +52,6 @@ impl StackLayouter { pub fn new(ctx: StackContext) -> StackLayouter { let axes = ctx.axes; let space = ctx.spaces[0]; - let usable = ctx.axes.generalize(space.usable()); StackLayouter { ctx, @@ -57,15 +59,16 @@ impl StackLayouter { space: 0, hard: true, - start: space.start(), actions: LayoutActionList::new(), combined_dimensions: Size2D::zero(), - sub: Subspace::new(usable, axes), + sub: Subspace::new(space.start(), space.usable(), axes), } } pub fn add(&mut self, layout: Layout) -> LayoutResult<()> { + self.layout_space(); + let size = self.ctx.axes.generalize(layout.dimensions); let mut new_dimensions = merge(self.sub.dimensions, size); @@ -81,10 +84,9 @@ impl StackLayouter { let offset = self.sub.dimensions.y; let anchor = self.ctx.axes.anchor(size); - let pos = self.ctx.axes.specialize( - self.start - + (self.sub.anchor - anchor) - + Size2D::with_y(self.combined_dimensions.y + self.sub.factor * offset) + let pos = self.sub.origin + self.ctx.axes.specialize( + (self.sub.anchor - anchor) + + Size2D::with_y(self.combined_dimensions.y + self.sub.factor * offset) ); self.actions.add_layout(pos, layout); @@ -100,19 +102,16 @@ impl StackLayouter { Ok(()) } - pub fn add_space(&mut self, space: Size) { - if self.sub.dimensions.y + space > self.sub.usable.y { - self.finish_space(false); - } else { - self.sub.dimensions.y += space; + pub fn add_space(&mut self, space: Size, soft: bool) { + self.sub.space = Some(space); + if !soft { + self.layout_space(); } } pub fn set_axes(&mut self, axes: LayoutAxes) { if axes != self.ctx.axes { - self.finish_subspace(); - self.ctx.axes = axes; - self.sub = Subspace::new(self.remaining_subspace(), axes); + self.finish_subspace(axes); } } @@ -128,7 +127,7 @@ impl StackLayouter { pub fn remaining(&self) -> LayoutSpaces { let mut spaces = smallvec![LayoutSpace { - dimensions: self.ctx.axes.specialize(self.remaining_subspace()), + dimensions: self.remaining_subspace().1, padding: SizeBox::zero(), }]; @@ -161,13 +160,13 @@ impl StackLayouter { } pub fn finish_space(&mut self, hard: bool) { - self.finish_subspace(); + self.finish_subspace(self.ctx.axes); let space = self.ctx.spaces[self.space]; let actions = std::mem::replace(&mut self.actions, LayoutActionList::new()); self.layouts.add(Layout { - dimensions: match self.ctx.shrink_to_fit { + dimensions: match self.ctx.expand { true => self.combined_dimensions.padded(space.padding), false => space.dimensions, }, @@ -180,27 +179,60 @@ impl StackLayouter { fn start_space(&mut self, space: usize, hard: bool) { self.space = space; - let space = self.ctx.spaces[space]; - let usable = self.ctx.axes.generalize(space.usable()); self.hard = hard; - self.start = space.start(); self.combined_dimensions = Size2D::zero(); - self.sub = Subspace::new(usable, self.ctx.axes); + self.sub = Subspace::new(space.start(), space.usable(), self.ctx.axes); } fn next_space(&self) -> usize { (self.space + 1).min(self.ctx.spaces.len() - 1) } - fn finish_subspace(&mut self) { - let dims = self.ctx.axes.specialize(self.sub.dimensions); - self.combined_dimensions = merge(self.combined_dimensions, dims); + fn finish_subspace(&mut self, new_axes: LayoutAxes) { + if self.ctx.axes.primary.needs_expansion() { + self.sub.dimensions.x = self.sub.usable.x; + } + + if self.ctx.axes.secondary.needs_expansion() { + self.sub.dimensions.y = self.sub.usable.y; + } + + let (new_origin, new_usable) = self.remaining_subspace(); + + let origin = self.sub.origin; + let dimensions = self.ctx.axes.specialize(self.sub.dimensions); + let space = self.ctx.spaces[self.space]; + self.combined_dimensions.max_eq(origin - space.start() + dimensions); + + self.ctx.axes = new_axes; + self.sub = Subspace::new(new_origin, new_usable, new_axes); } - fn remaining_subspace(&self) -> Size2D { - Size2D::new(self.sub.usable.x, self.sub.usable.y - self.sub.dimensions.y) + fn remaining_subspace(&self) -> (Size2D, Size2D) { + let used = self.ctx.axes.specialize(self.sub.usable); + let dimensions = self.ctx.axes.specialize(self.sub.dimensions); + + let new_usable = self.ctx.axes.specialize(Size2D { + x: self.sub.usable.x, + y: self.sub.usable.y - self.sub.dimensions.y, + }); + + let new_origin = self.sub.origin + + Size2D::with_y(self.ctx.axes.specialize(self.sub.dimensions).y); + + (new_origin, new_usable) + } + + fn layout_space(&mut self) { + if let Some(space) = self.sub.space.take() { + if self.sub.dimensions.y + space > self.sub.usable.y { + self.finish_space(false); + } else { + self.sub.dimensions.y += space; + } + } } } |
