summaryrefslogtreecommitdiff
path: root/src/library/columns.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-12-28 13:37:02 +0100
committerLaurenz <laurmaedje@gmail.com>2021-12-28 13:41:26 +0100
commitbd304b99e5d2d23027d90eaae871fdd3bdd12f5d (patch)
treea6814a4ba90764dcb1de3d55fa6e95d7a71dc14a /src/library/columns.rs
parent9624ad635bd8adb0e421c37c63c7310ecc71a708 (diff)
Tidying
Diffstat (limited to 'src/library/columns.rs')
-rw-r--r--src/library/columns.rs62
1 files changed, 26 insertions, 36 deletions
diff --git a/src/library/columns.rs b/src/library/columns.rs
index 25d6da9d..df55fb52 100644
--- a/src/library/columns.rs
+++ b/src/library/columns.rs
@@ -1,7 +1,9 @@
+//! Multi-column layouts.
+
use super::prelude::*;
use super::ParNode;
-/// `columns`: Stack children along an axis.
+/// `columns`: Set content into multiple columns.
pub fn columns(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let columns = args.expect("column count")?;
let gutter = args.named("gutter")?.unwrap_or(Relative::new(0.04).into());
@@ -36,6 +38,8 @@ impl Layout for ColumnsNode {
ctx: &mut LayoutContext,
regions: &Regions,
) -> Vec<Constrained<Rc<Frame>>> {
+ let columns = self.columns.get();
+
// Separating the infinite space into infinite columns does not make
// much sense. Note that this line assumes that no infinitely wide
// region will follow if the first region's width is finite.
@@ -51,21 +55,15 @@ impl Layout for ColumnsNode {
// `region.backlog` and `regions.last`.
let mut sizes = vec![];
- let columns = self.columns.get();
-
for (current, base) in regions
.iter()
- .take(1 + regions.backlog.len() + if regions.last.is_some() { 1 } else { 0 })
+ .take(1 + regions.backlog.len() + regions.last.iter().len())
{
let gutter = self.gutter.resolve(base.x);
+ let width = (current.x - gutter * (columns - 1) as f64) / columns as f64;
+ let size = Size::new(width, current.y);
gutters.push(gutter);
- let size = Size::new(
- (current.x - gutter * (columns - 1) as f64) / columns as f64,
- current.y,
- );
- for _ in 0 .. columns {
- sizes.push(size);
- }
+ sizes.extend(std::iter::repeat(size).take(columns));
}
let first = sizes.remove(0);
@@ -76,24 +74,22 @@ impl Layout for ColumnsNode {
);
// Retrieve elements for the last region from the vectors.
- let last_gutter = if regions.last.is_some() {
+ let last_gutter = regions.last.map(|_| {
let gutter = gutters.pop().unwrap();
let size = sizes.drain(sizes.len() - columns ..).next().unwrap();
pod.last = Some(size);
- Some(gutter)
- } else {
- None
- };
+ gutter
+ });
pod.backlog = sizes.into_iter();
+ let mut finished = vec![];
let mut frames = self.child.layout(ctx, &pod).into_iter();
let dir = ctx.styles.get(ParNode::DIR);
-
- let mut finished = vec![];
let total_regions = (frames.len() as f32 / columns as f32).ceil() as usize;
+ // Stitch together the columns for each region.
for ((current, base), gutter) in regions
.iter()
.take(total_regions)
@@ -103,41 +99,35 @@ impl Layout for ColumnsNode {
// Otherwise its the maximum column height for the frame. In that
// case, the frame is first created with zero height and then
// resized.
- let mut height = if regions.expand.y { current.y } else { Length::zero() };
- let mut frame = Frame::new(Spec::new(regions.current.x, height));
-
+ let height = if regions.expand.y { current.y } else { Length::zero() };
+ let mut output = Frame::new(Spec::new(regions.current.x, height));
let mut cursor = Length::zero();
for _ in 0 .. columns {
- let child_frame = match frames.next() {
+ let frame = match frames.next() {
Some(frame) => frame.item,
None => break,
};
- let width = child_frame.size.x;
-
if !regions.expand.y {
- height.set_max(child_frame.size.y);
+ output.size.y.set_max(frame.size.y);
}
- frame.push_frame(
- Point::with_x(if dir.is_positive() {
- cursor
- } else {
- regions.current.x - cursor - width
- }),
- child_frame,
- );
+ let width = frame.size.x;
+ let x = if dir.is_positive() {
+ cursor
+ } else {
+ regions.current.x - cursor - width
+ };
+ output.push_frame(Point::with_x(x), frame);
cursor += width + gutter;
}
- frame.size.y = height;
-
let mut cts = Constraints::new(regions.expand);
cts.base = base.map(Some);
cts.exact = current.map(Some);
- finished.push(frame.constrain(cts));
+ finished.push(output.constrain(cts));
}
finished