summaryrefslogtreecommitdiff
path: root/src/library/stack.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-11-17 17:09:19 +0100
committerLaurenz <laurmaedje@gmail.com>2021-11-17 17:09:19 +0100
commit89f2e71852e96062ea9b756bf92fbf4e894871b1 (patch)
tree836099ebd17adf30a24fc62464dfdd3d9c248480 /src/library/stack.rs
parent9a800daa82833c57eee04e92c701ca9a05a67d3b (diff)
Align node
Diffstat (limited to 'src/library/stack.rs')
-rw-r--r--src/library/stack.rs36
1 files changed, 24 insertions, 12 deletions
diff --git a/src/library/stack.rs b/src/library/stack.rs
index 61406e8e..7ac7e6ee 100644
--- a/src/library/stack.rs
+++ b/src/library/stack.rs
@@ -1,7 +1,7 @@
use std::fmt::{self, Debug, Formatter};
use super::prelude::*;
-use super::Spacing;
+use super::{AlignNode, Spacing};
/// `stack`: Stack children along an axis.
pub fn stack(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
@@ -118,7 +118,7 @@ enum StackItem {
/// Fractional spacing between other items.
Fractional(Fractional),
/// A layouted child node.
- Frame(Rc<Frame>),
+ Frame(Rc<Frame>, Align),
}
impl<'a> StackLayouter<'a> {
@@ -176,6 +176,12 @@ impl<'a> StackLayouter<'a> {
/// Layout a node.
fn layout_node(&mut self, ctx: &mut LayoutContext, node: &PackedNode) {
+ // Align nodes' block-axis alignment is respected by the stack node.
+ let align = node
+ .downcast::<AlignNode>()
+ .and_then(|node| node.aligns.get(self.axis))
+ .unwrap_or(self.stack.dir.start().into());
+
let frames = node.layout(ctx, &self.regions);
let len = frames.len();
for (i, frame) in frames.into_iter().enumerate() {
@@ -184,7 +190,7 @@ impl<'a> StackLayouter<'a> {
self.used.block += size.block;
self.used.inline.set_max(size.inline);
*self.regions.current.get_mut(self.axis) -= size.block;
- self.items.push(StackItem::Frame(frame.item));
+ self.items.push(StackItem::Frame(frame.item, align));
if i + 1 < len {
self.finish_region();
@@ -204,29 +210,35 @@ impl<'a> StackLayouter<'a> {
// Expand fully if there are fr spacings.
let full = self.full.get(self.axis);
+ let remaining = full - self.used.block;
if self.fr.get() > 0.0 && full.is_finite() {
+ self.used.block = full;
size.set(self.axis, full);
}
let mut output = Frame::new(size, size.h);
let mut before = Length::zero();
+ let mut ruler: Align = self.stack.dir.start().into();
// Place all frames.
for item in self.items.drain(..) {
match item {
StackItem::Absolute(v) => before += v,
- StackItem::Fractional(v) => {
- let remaining = self.full.get(self.axis) - self.used.block;
- before += v.resolve(self.fr, remaining)
- }
- StackItem::Frame(frame) => {
+ StackItem::Fractional(v) => before += v.resolve(self.fr, remaining),
+ StackItem::Frame(frame, align) => {
+ ruler = ruler.max(align);
+
+ // Align along the block axis.
let parent = size.get(self.axis);
let child = frame.size.get(self.axis);
- let block = if self.stack.dir.is_positive() {
- before
+ let block = ruler.resolve(if self.stack.dir.is_positive() {
+ let after = self.used.block - before;
+ before .. parent - after
} else {
- parent - (before + child)
- };
+ let before_with_self = before + child;
+ let after = self.used.block - before_with_self;
+ after .. parent - before_with_self
+ });
before += child;