diff options
Diffstat (limited to 'src/layout/stacked.rs')
| -rw-r--r-- | src/layout/stacked.rs | 263 |
1 files changed, 0 insertions, 263 deletions
diff --git a/src/layout/stacked.rs b/src/layout/stacked.rs deleted file mode 100644 index 2e128a5f..00000000 --- a/src/layout/stacked.rs +++ /dev/null @@ -1,263 +0,0 @@ -use smallvec::smallvec; -use super::*; - -#[derive(Debug, Clone)] -pub struct StackLayouter { - ctx: StackContext, - layouts: MultiLayout, - - space: Space, - sub: Subspace, -} - -#[derive(Debug, Clone)] -struct Space { - index: usize, - hard: bool, - actions: LayoutActionList, - combined_dimensions: Size2D, -} - -impl Space { - fn new(index: usize, hard: bool) -> Space { - Space { - index, - hard, - actions: LayoutActionList::new(), - combined_dimensions: Size2D::zero(), - } - } -} - -#[derive(Debug, Clone)] -struct Subspace { - origin: Size2D, - anchor: Size2D, - factor: i32, - - boxes: Vec<(Size, Size, Layout)>, - - usable: Size2D, - dimensions: Size2D, - - space: SpaceState, -} - -impl Subspace { - fn new(origin: Size2D, usable: Size2D, axes: LayoutAxes) -> Subspace { - Subspace { - origin, - anchor: axes.anchor(usable), - factor: axes.secondary.axis.factor(), - boxes: vec![], - usable: axes.generalize(usable), - dimensions: Size2D::zero(), - space: SpaceState::Forbidden, - } - } -} - -/// The context for stack layouting. -/// -/// See [`LayoutContext`] for details about the fields. -#[derive(Debug, Clone)] -pub struct StackContext { - pub spaces: LayoutSpaces, - pub axes: LayoutAxes, - pub expand: bool, -} - -impl StackLayouter { - /// Create a new stack layouter. - pub fn new(ctx: StackContext) -> StackLayouter { - let axes = ctx.axes; - let space = ctx.spaces[0]; - - StackLayouter { - ctx, - layouts: MultiLayout::new(), - space: Space::new(0, true), - sub: Subspace::new(space.start(), space.usable(), axes), - } - } - - pub fn add(&mut self, layout: Layout) -> LayoutResult<()> { - if let SpaceState::Soft(space) = self.sub.space { - self.add_space(space, SpaceKind::Hard); - } - - let size = self.ctx.axes.generalize(layout.dimensions); - - let mut new_dimensions = Size2D { - x: crate::size::max(self.sub.dimensions.x, size.x), - y: self.sub.dimensions.y + size.y - }; - - while !self.sub.usable.fits(new_dimensions) { - if self.space_is_last() && self.space_is_empty() { - Err(LayoutError::NotEnoughSpace("failed to add box to stack"))?; - } - - self.finish_space(true); - new_dimensions = size; - } - - let offset = self.sub.dimensions.y; - let anchor = self.ctx.axes.primary.anchor(size.x); - - self.sub.boxes.push((offset, anchor, layout)); - self.sub.dimensions = new_dimensions; - self.sub.space = SpaceState::Allowed; - - Ok(()) - } - - pub fn add_multiple(&mut self, layouts: MultiLayout) -> LayoutResult<()> { - for layout in layouts { - self.add(layout)?; - } - Ok(()) - } - - pub fn add_space(&mut self, space: Size, kind: SpaceKind) { - if kind == SpaceKind::Soft { - if self.sub.space != SpaceState::Forbidden { - self.sub.space = SpaceState::Soft(space); - } - } else { - if self.sub.dimensions.y + space > self.sub.usable.y { - self.sub.dimensions.y = self.sub.usable.y; - } else { - self.sub.dimensions.y += space; - } - - if kind == SpaceKind::Hard { - self.sub.space = SpaceState::Forbidden; - } - } - } - - pub fn set_axes(&mut self, axes: LayoutAxes) { - if axes != self.ctx.axes { - self.finish_subspace(); - let (origin, usable) = self.remaining_subspace(); - self.ctx.axes = axes; - self.sub = Subspace::new(origin, usable, axes); - } - } - - pub fn set_spaces(&mut self, spaces: LayoutSpaces, replace_empty: bool) { - if replace_empty && self.space_is_empty() { - self.ctx.spaces = spaces; - self.start_space(0, self.space.hard); - } else { - self.ctx.spaces.truncate(self.space.index + 1); - self.ctx.spaces.extend(spaces); - } - } - - pub fn remaining(&self) -> LayoutSpaces { - let mut spaces = smallvec![LayoutSpace { - dimensions: self.remaining_subspace().1, - padding: SizeBox::zero(), - }]; - - for space in &self.ctx.spaces[self.next_space()..] { - spaces.push(space.usable_space()); - } - - spaces - } - - pub fn primary_usable(&self) -> Size { - self.sub.usable.x - } - - pub fn space_is_empty(&self) -> bool { - self.space.combined_dimensions == Size2D::zero() - && self.space.actions.is_empty() - && self.sub.dimensions == Size2D::zero() - } - - pub fn space_is_last(&self) -> bool { - self.space.index == self.ctx.spaces.len() - 1 - } - - pub fn finish(mut self) -> MultiLayout { - if self.space.hard || !self.space_is_empty() { - self.finish_space(false); - } - self.layouts - } - - pub fn finish_space(&mut self, hard: bool) { - self.finish_subspace(); - - let space = self.ctx.spaces[self.space.index]; - - self.layouts.add(Layout { - dimensions: match self.ctx.expand { - true => space.dimensions, - false => self.space.combined_dimensions.padded(space.padding), - }, - actions: self.space.actions.to_vec(), - debug_render: true, - }); - - self.start_space(self.next_space(), hard); - } - - fn start_space(&mut self, space: usize, hard: bool) { - self.space = Space::new(space, hard); - - let space = self.ctx.spaces[space]; - self.sub = Subspace::new(space.start(), space.usable(), self.ctx.axes); - } - - fn next_space(&self) -> usize { - (self.space.index + 1).min(self.ctx.spaces.len() - 1) - } - - fn finish_subspace(&mut self) { - let factor = self.ctx.axes.secondary.axis.factor(); - let anchor = - self.ctx.axes.anchor(self.sub.usable) - - self.ctx.axes.anchor(Size2D::with_y(self.sub.dimensions.y)); - - for (offset, layout_anchor, layout) in self.sub.boxes.drain(..) { - let pos = self.sub.origin - + self.ctx.axes.specialize( - anchor + Size2D::new(-layout_anchor, factor * offset) - ); - - self.space.actions.add_layout(pos, layout); - } - - 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 space = self.ctx.spaces[self.space.index]; - let origin = self.sub.origin; - let dimensions = self.ctx.axes.specialize(self.sub.dimensions); - self.space.combined_dimensions.max_eq(origin - space.start() + dimensions); - } - - fn remaining_subspace(&self) -> (Size2D, Size2D) { - let new_origin = self.sub.origin + match self.ctx.axes.secondary.axis.is_positive() { - true => self.ctx.axes.specialize(Size2D::with_y(self.sub.dimensions.y)), - false => Size2D::zero(), - }; - - let new_usable = self.ctx.axes.specialize(Size2D { - x: self.sub.usable.x, - y: self.sub.usable.y - self.sub.dimensions.y - self.sub.space.soft_or_zero(), - }); - - (new_origin, new_usable) - } -} |
