Move multi-dir support in stack layouter 🍁

This commit is contained in:
Laurenz 2020-10-06 14:20:28 +02:00
parent c6a6870978
commit ef410f6877

View File

@ -80,7 +80,7 @@ impl StackLayouter {
// Add the box to the vector and remember that spacings are allowed // Add the box to the vector and remember that spacings are allowed
// again. // again.
self.space.layouts.push((self.ctx.dirs, aligns, layout)); self.space.layouts.push((layout, aligns));
self.space.last_spacing = LastSpacing::None; self.space.last_spacing = LastSpacing::None;
} }
@ -96,9 +96,8 @@ impl StackLayouter {
let size = Size::new(0.0, spacing); let size = Size::new(0.0, spacing);
self.update_metrics(size); self.update_metrics(size);
self.space.layouts.push(( self.space.layouts.push((
self.ctx.dirs,
Gen2::default(),
BoxLayout::new(size.specialized(self.ctx.dirs)), BoxLayout::new(size.specialized(self.ctx.dirs)),
Gen2::default(),
)); ));
self.space.last_spacing = LastSpacing::Hard; self.space.last_spacing = LastSpacing::Hard;
@ -227,6 +226,7 @@ impl StackLayouter {
/// Finish active current space and start a new one. /// Finish active current space and start a new one.
pub fn finish_space(&mut self, hard: bool) { pub fn finish_space(&mut self, hard: bool) {
let dirs = self.ctx.dirs;
let space = self.ctx.spaces[self.space.index]; let space = self.ctx.spaces[self.space.index];
// ------------------------------------------------------------------ // // ------------------------------------------------------------------ //
@ -259,7 +259,7 @@ impl StackLayouter {
y1: start.y + self.space.size.height, y1: start.y + self.space.size.height,
}; };
for &(dirs, _, ref layout) in &self.space.layouts { for (layout, _) in &self.space.layouts {
// First, we store the bounds calculated so far (which were reduced // First, we store the bounds calculated so far (which were reduced
// by the predecessors of this layout) as the initial bounding box // by the predecessors of this layout) as the initial bounding box
// of this layout. // of this layout.
@ -280,32 +280,16 @@ impl StackLayouter {
// The `x` field stores the maximal cross-axis extent in one // The `x` field stores the maximal cross-axis extent in one
// axis-aligned run, while the `y` fields stores the accumulated // axis-aligned run, while the `y` fields stores the accumulated
// main-axis extent. // main-axis extent.
let mut extent = Size::ZERO; let mut main_extent = 0.0;
let mut rotation = SpecAxis::Vertical; for (child, bound) in self.space.layouts.iter().zip(&mut bounds).rev() {
for (bound, entry) in bounds.iter_mut().zip(&self.space.layouts).rev() {
let &(dirs, _, ref layout) = entry;
// When the axes are rotated, the maximal cross-axis size
// (`extent.x`) dictates how much main-axis extent the whole run
// had. This value is thus stored in `extent.y`. The cross-axis
// extent is reset for this new axis-aligned run.
if rotation != dirs.main.axis() {
extent.height = extent.width;
extent.width = 0.0;
rotation = dirs.main.axis();
}
// We reduce the bounding box of this layout at its end by the // We reduce the bounding box of this layout at its end by the
// accumulated main-axis extent of all layouts we have seen so far, // accumulated main-axis extent of all layouts we have seen so far
// which are the layouts after this one since we iterate reversed. // (which are the layouts after this one since we iterate reversed).
*bound.get_mut(dirs.main.side(GenAlign::End)) -= *bound.get_mut(dirs.main.side(GenAlign::End)) -=
dirs.main.factor() * extent.height; dirs.main.factor() * main_extent;
// Then, we add this layout's main-axis extent to the accumulator. // And then, we include this layout's main-axis extent.
let size = layout.size.generalized(dirs); main_extent += child.0.size.get(dirs.main.axis());
extent.width = extent.width.max(size.width);
extent.height += size.height;
} }
// ------------------------------------------------------------------ // // ------------------------------------------------------------------ //
@ -314,8 +298,8 @@ impl StackLayouter {
let mut layout = BoxLayout::new(size); let mut layout = BoxLayout::new(size);
let layouts = std::mem::take(&mut self.space.layouts); let children = std::mem::take(&mut self.space.layouts);
for ((dirs, aligns, child), bound) in layouts.into_iter().zip(bounds) { for ((child, aligns), bound) in children.into_iter().zip(bounds) {
let size = child.size.specialized(dirs); let size = child.size.specialized(dirs);
// The space in which this layout is aligned is given by the // The space in which this layout is aligned is given by the
@ -353,7 +337,7 @@ struct Space {
/// Whether to include a layout for this space even if it would be empty. /// Whether to include a layout for this space even if it would be empty.
hard: bool, hard: bool,
/// The so-far accumulated layouts. /// The so-far accumulated layouts.
layouts: Vec<(Gen2<Dir>, Gen2<GenAlign>, BoxLayout)>, layouts: Vec<(BoxLayout, Gen2<GenAlign>)>,
/// The specialized size of this space. /// The specialized size of this space.
size: Size, size: Size,
/// The specialized remaining space. /// The specialized remaining space.