summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2019-11-17 14:51:31 +0100
committerLaurenz <laurmaedje@gmail.com>2019-11-17 14:51:31 +0100
commit4d0bdc4ca4cb5e8ca1a70b38a0fc0ec37d9e4857 (patch)
treece30d2b3d3709c2c248e3e8f31696d69c9db0f09 /src
parent1f009b5b95cbc31fb0a05a7f72ee6f5f53ece19a (diff)
Axes updating for flex layouter 📐
Diffstat (limited to 'src')
-rw-r--r--src/layout/flex.rs90
-rw-r--r--src/layout/mod.rs10
-rw-r--r--src/layout/stacked.rs2
3 files changed, 71 insertions, 31 deletions
diff --git a/src/layout/flex.rs b/src/layout/flex.rs
index 286f6a30..3155a13a 100644
--- a/src/layout/flex.rs
+++ b/src/layout/flex.rs
@@ -23,6 +23,11 @@ pub struct FlexLayouter {
stack: StackLayouter,
units: Vec<FlexUnit>,
+ merged_actions: LayoutActionList,
+ merged_dimensions: Size2D,
+ max_left: Size,
+ max_right: Size,
+
usable: Size,
run: FlexRun,
space: Option<Size>,
@@ -54,7 +59,7 @@ enum FlexUnit {
#[derive(Debug, Clone)]
struct FlexRun {
- content: Vec<(Size, Layout)>,
+ content: Vec<(Size, Size, Layout)>,
size: Size2D,
}
@@ -67,12 +72,18 @@ impl FlexLayouter {
shrink_to_fit: ctx.shrink_to_fit,
});
+ let usable = stack.usable().x;
FlexLayouter {
ctx,
units: vec![],
stack,
- usable: stack.usable().x,
+ merged_actions: LayoutActionList::new(),
+ merged_dimensions: Size2D::with_x(usable),
+ max_left: Size::zero(),
+ max_right: usable,
+
+ usable,
run: FlexRun { content: vec![], size: Size2D::zero() },
space: None,
}
@@ -158,27 +169,6 @@ impl FlexLayouter {
Ok(())
}
- /// Finish the current flex run.
- fn finish_run(&mut self) -> LayoutResult<()> {
- let mut actions = LayoutActionList::new();
- for (x, layout) in self.run.content.drain(..) {
- let position = self.ctx.axes.specialize(Size2D::with_x(x));
- actions.add_layout(position, layout);
- }
-
- self.run.size.y += self.ctx.flex_spacing;
-
- self.stack.add(Layout {
- dimensions: self.ctx.axes.specialize(self.run.size),
- actions: actions.into_vec(),
- debug_render: false,
- })?;
-
- self.run.size = Size2D::zero();
-
- Ok(())
- }
-
/// Layout a content box into the current flex run or start a new run if
/// it does not fit.
fn layout_box(&mut self, boxed: Layout) -> LayoutResult<()> {
@@ -204,7 +194,10 @@ impl FlexLayouter {
self.layout_space();
- self.run.content.push((self.run.size.x, boxed));
+ let offset = self.run.size.x;
+ let anchor = self.ctx.axes.primary.anchor(size.x);
+ self.run.content.push((offset, anchor, boxed));
+
self.run.size.x += size.x;
self.run.size.y = crate::size::max(self.run.size.y, size.y);
@@ -220,7 +213,54 @@ impl FlexLayouter {
}
fn layout_set_axes(&mut self, axes: LayoutAxes) {
- // TODO
+ if axes.primary != self.ctx.axes.primary {
+ self.finish_aligned_run();
+ self.usable = match axes.primary.alignment {
+ Alignment::Origin => self.max_right,
+ Alignment::Center => self.max_right - self.max_left,
+ Alignment::End => self.merged_dimensions.x - self.max_left,
+ };
+ }
+
+ if axes.secondary != self.ctx.axes.secondary {
+ self.stack.set_axes(axes);
+ }
+ }
+
+ /// Finish the current flex run.
+ fn finish_run(&mut self) -> LayoutResult<()> {
+ self.finish_aligned_run();
+
+ let actions = std::mem::replace(&mut self.merged_actions, LayoutActionList::new());
+ self.stack.add(Layout {
+ dimensions: self.ctx.axes.specialize(self.merged_dimensions),
+ actions: actions.into_vec(),
+ debug_render: false,
+ })?;
+
+ self.merged_dimensions.y = Size::zero();
+ self.max_left = Size::zero();
+ self.max_right = self.merged_dimensions.x;
+ self.usable = self.merged_dimensions.x;
+
+ Ok(())
+ }
+
+ fn finish_aligned_run(&mut self) -> LayoutResult<()> {
+ let anchor = self.ctx.axes.primary.anchor(self.merged_dimensions.x);
+ let factor = if self.ctx.axes.primary.axis.is_positive() { 1 } else { -1 };
+
+ for (offset, layout_anchor, layout) in self.run.content.drain(..) {
+ let general_position = Size2D::with_x(anchor - layout_anchor + factor * offset);
+ let position = self.ctx.axes.specialize(general_position);
+
+ self.merged_actions.add_layout(position, layout);
+ }
+
+ self.merged_dimensions.y = crate::size::max(self.merged_dimensions.y, self.run.size.y);
+ self.run.size = Size2D::zero();
+
+ Ok(())
}
/// This layouter's context.
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index 9bb91956..420c90bc 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -202,20 +202,20 @@ impl LayoutAxes {
/// the layouting axes, that is:
/// - The x coordinate describes the primary axis instead of the horizontal one.
/// - The y coordinate describes the secondary axis instead of the vertical one.
- pub fn generalize(&self, space: Size2D) -> Size2D {
+ pub fn generalize(&self, size: Size2D) -> Size2D {
if self.primary.axis.is_horizontal() {
- space
+ size
} else {
- Size2D { x: space.y, y: space.x }
+ Size2D { x: size.y, y: size.x }
}
}
/// Returns the specialized version of this generalized Size2D.
/// (Inverse to `generalized`).
- pub fn specialize(&self, space: Size2D) -> Size2D {
+ pub fn specialize(&self, size: Size2D) -> Size2D {
// In fact, generalized is its own inverse. For reasons of clarity
// at the call site, we still have this second function.
- self.generalize(space)
+ self.generalize(size)
}
/// The position of the anchor specified by the two aligned axes
diff --git a/src/layout/stacked.rs b/src/layout/stacked.rs
index 764b8325..77af6f38 100644
--- a/src/layout/stacked.rs
+++ b/src/layout/stacked.rs
@@ -150,7 +150,7 @@ impl StackLayouter {
let factor = if self.ctx.axes.secondary.axis.is_positive() { 1 } else { -1 };
for (offset, layout_anchor, layout) in self.boxes.drain(..) {
- let general_position = anchor - layout_anchor + Size2D::with_y(offset * factor);
+ let general_position = anchor - layout_anchor + Size2D::with_y(factor * offset);
let position = start + self.ctx.axes.specialize(general_position);
self.merged_actions.add_layout(position, layout);