summaryrefslogtreecommitdiff
path: root/src/library/stack.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-12-30 11:37:11 +0100
committerLaurenz <laurmaedje@gmail.com>2021-12-30 12:00:12 +0100
commitf5dcb84e36a38182218c7f907b861b12d2bd2c1c (patch)
tree1fce04fb53d2ad5b61f5f3151e43d80e2684e579 /src/library/stack.rs
parentfef55025177ea4f248e61b68fab365bfbc0e47fb (diff)
Make clippy a bit happier
Diffstat (limited to 'src/library/stack.rs')
-rw-r--r--src/library/stack.rs111
1 files changed, 58 insertions, 53 deletions
diff --git a/src/library/stack.rs b/src/library/stack.rs
index dfe5e245..d7748378 100644
--- a/src/library/stack.rs
+++ b/src/library/stack.rs
@@ -1,33 +1,15 @@
//! Side-by-side layout of nodes along an axis.
-use std::fmt::{self, Debug, Formatter};
-
use super::prelude::*;
use super::{AlignNode, SpacingKind, SpacingNode};
/// `stack`: Stack children along an axis.
pub fn stack(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
- let dir = args.named("dir")?.unwrap_or(Dir::TTB);
- let spacing = args.named("spacing")?;
-
- let mut children = vec![];
- let mut deferred = None;
-
- // Build the list of stack children.
- for child in args.all() {
- match child {
- StackChild::Spacing(_) => deferred = None,
- StackChild::Node(_) => {
- if let Some(v) = deferred {
- children.push(StackChild::spacing(v));
- }
- deferred = spacing;
- }
- }
- children.push(child);
- }
-
- Ok(Value::block(StackNode { dir, children }))
+ Ok(Value::block(StackNode {
+ dir: args.named("dir")?.unwrap_or(Dir::TTB),
+ spacing: args.named("spacing")?,
+ children: args.all().collect(),
+ }))
}
/// A node that stacks its children.
@@ -35,6 +17,8 @@ pub fn stack(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
pub struct StackNode {
/// The stacking direction.
pub dir: Dir,
+ /// The spacing between non-spacing children.
+ pub spacing: Option<SpacingKind>,
/// The children to be stacked.
pub children: Vec<StackChild>,
}
@@ -45,7 +29,7 @@ impl Layout for StackNode {
ctx: &mut LayoutContext,
regions: &Regions,
) -> Vec<Constrained<Rc<Frame>>> {
- StackLayouter::new(self, regions).layout(ctx)
+ StackLayouter::new(self, regions.clone()).layout(ctx)
}
}
@@ -58,9 +42,8 @@ pub enum StackChild {
Node(PackedNode),
}
-impl StackChild {
- /// Create a spacing node from a spacing kind.
- pub fn spacing(kind: SpacingKind) -> Self {
+impl From<SpacingKind> for StackChild {
+ fn from(kind: SpacingKind) -> Self {
Self::Spacing(SpacingNode { kind, styles: Styles::new() })
}
}
@@ -77,23 +60,27 @@ impl Debug for StackChild {
castable! {
StackChild,
Expected: "linear, fractional or template",
- Value::Length(v) => Self::spacing(SpacingKind::Linear(v.into())),
- Value::Relative(v) => Self::spacing(SpacingKind::Linear(v.into())),
- Value::Linear(v) => Self::spacing(SpacingKind::Linear(v)),
- Value::Fractional(v) => Self::spacing(SpacingKind::Fractional(v)),
+ Value::Length(v) => SpacingKind::Linear(v.into()).into(),
+ Value::Relative(v) => SpacingKind::Linear(v.into()).into(),
+ Value::Linear(v) => SpacingKind::Linear(v).into(),
+ Value::Fractional(v) => SpacingKind::Fractional(v).into(),
Value::Node(v) => Self::Node(v.into_block()),
}
/// Performs stack layout.
struct StackLayouter<'a> {
- /// The stack node to layout.
- stack: &'a StackNode,
- /// The axis of the block direction.
+ /// The flow node to layout.
+ children: &'a [StackChild],
+ /// The stacking direction.
+ dir: Dir,
+ /// The axis of the stacking direction.
axis: SpecAxis,
- /// Whether the stack should expand to fill the region.
- expand: Spec<bool>,
+ /// The spacing between non-spacing children.
+ spacing: Option<SpacingKind>,
/// The regions to layout children into.
regions: Regions,
+ /// Whether the stack should expand to fill the region.
+ expand: Spec<bool>,
/// The full size of `regions.current` that was available before we started
/// subtracting.
full: Size,
@@ -119,21 +106,23 @@ enum StackItem {
impl<'a> StackLayouter<'a> {
/// Create a new stack layouter.
- fn new(stack: &'a StackNode, regions: &Regions) -> Self {
- let axis = stack.dir.axis();
+ fn new(stack: &'a StackNode, mut regions: Regions) -> Self {
+ let dir = stack.dir;
+ let axis = dir.axis();
let expand = regions.expand;
let full = regions.current;
// Disable expansion along the block axis for children.
- let mut regions = regions.clone();
regions.expand.set(axis, false);
Self {
- stack,
+ children: &stack.children,
+ dir,
axis,
+ spacing: stack.spacing,
+ regions,
expand,
full,
- regions,
used: Gen::zero(),
fr: Fractional::zero(),
items: vec![],
@@ -143,21 +132,26 @@ impl<'a> StackLayouter<'a> {
/// Layout all children.
fn layout(mut self, ctx: &mut LayoutContext) -> Vec<Constrained<Rc<Frame>>> {
- for child in &self.stack.children {
+ // Spacing to insert before the next node.
+ let mut deferred = None;
+
+ for child in self.children {
match child {
- StackChild::Spacing(node) => match node.kind {
- SpacingKind::Linear(v) => self.layout_absolute(v),
- SpacingKind::Fractional(v) => {
- self.items.push(StackItem::Fractional(v));
- self.fr += v;
- }
- },
+ StackChild::Spacing(node) => {
+ self.layout_spacing(node.kind);
+ deferred = None;
+ }
StackChild::Node(node) => {
+ if let Some(kind) = deferred {
+ self.layout_spacing(kind);
+ }
+
if self.regions.is_full() {
self.finish_region();
}
self.layout_node(ctx, node);
+ deferred = self.spacing;
}
}
}
@@ -166,6 +160,17 @@ impl<'a> StackLayouter<'a> {
self.finished
}
+ /// Layout spacing.
+ fn layout_spacing(&mut self, spacing: SpacingKind) {
+ match spacing {
+ SpacingKind::Linear(v) => self.layout_absolute(v),
+ SpacingKind::Fractional(v) => {
+ self.items.push(StackItem::Fractional(v));
+ self.fr += v;
+ }
+ }
+ }
+
/// Layout absolute spacing.
fn layout_absolute(&mut self, amount: Linear) {
// Resolve the linear, limiting it to the remaining available space.
@@ -183,7 +188,7 @@ impl<'a> StackLayouter<'a> {
let align = node
.downcast::<AlignNode>()
.and_then(|node| node.aligns.get(self.axis))
- .unwrap_or(self.stack.dir.start().into());
+ .unwrap_or(self.dir.start().into());
let frames = node.layout(ctx, &self.regions);
let len = frames.len();
@@ -218,7 +223,7 @@ impl<'a> StackLayouter<'a> {
let mut output = Frame::new(size);
let mut cursor = Length::zero();
- let mut ruler: Align = self.stack.dir.start().into();
+ let mut ruler: Align = self.dir.start().into();
// Place all frames.
for item in self.items.drain(..) {
@@ -230,7 +235,7 @@ impl<'a> StackLayouter<'a> {
cursor += v.resolve(self.fr, remaining);
}
StackItem::Frame(frame, align) => {
- if self.stack.dir.is_positive() {
+ if self.dir.is_positive() {
ruler = ruler.max(align);
} else {
ruler = ruler.min(align);
@@ -240,7 +245,7 @@ impl<'a> StackLayouter<'a> {
let parent = size.get(self.axis);
let child = frame.size.get(self.axis);
let block = ruler.resolve(parent - self.used.main)
- + if self.stack.dir.is_positive() {
+ + if self.dir.is_positive() {
cursor
} else {
self.used.main - child - cursor