summaryrefslogtreecommitdiff
path: root/src/layout/stacked.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2019-11-20 17:28:58 +0100
committerLaurenz <laurmaedje@gmail.com>2019-11-20 17:31:52 +0100
commitf24e9b44e0ceb19be6f4e16af2d22815e9ccf5b7 (patch)
tree9e520ee1f8b802973aa5b568c11fafc42e6426a8 /src/layout/stacked.rs
parent1dafe2c2ea0828bb075fdbb0da663967f7b5b2b9 (diff)
Refined expansion model 🔛
Diffstat (limited to 'src/layout/stacked.rs')
-rw-r--r--src/layout/stacked.rs100
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;
+ }
+ }
}
}