summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
authorMartin Haug <mhaug@live.de>2021-06-08 11:05:09 +0200
committerLaurenz <laurmaedje@gmail.com>2021-06-09 22:44:40 +0200
commit29cfef0a6dfef5820bda339d327638e285aaf4d3 (patch)
tree7a2e16b4c97d4259da1eb63deaa716b620feb4df /src/library
parent73fa2eda2c23bd3baeb9e22b99eb0bfb183fc638 (diff)
Add a grid layouter
Diffstat (limited to 'src/library')
-rw-r--r--src/library/grid.rs76
-rw-r--r--src/library/mod.rs3
2 files changed, 79 insertions, 0 deletions
diff --git a/src/library/grid.rs b/src/library/grid.rs
new file mode 100644
index 00000000..0aa1fc9d
--- /dev/null
+++ b/src/library/grid.rs
@@ -0,0 +1,76 @@
+use crate::layout::GridNode;
+
+use super::*;
+
+/// `stack`: Stack children along an axis.
+///
+/// # Positional parameters
+/// - Children: variadic, of type `template`.
+///
+/// # Named parameters
+/// - Column widths: `columns`, of type `Array<GridUnit>`.
+/// - Row widths: `rows`, of type `Array<GridUnit>`.
+/// - Gutter: `gutter-vertical` and `gutter-horizontal` for individual track axis or `gutter` for both, of type `Array<GridUnit>` respectively.
+/// - Stacking direction: `dir`, of type `direction`.
+///
+/// # Return value
+/// A template that arranges its children along the specified grid cells.
+///
+/// # Relevant types and constants
+/// - Type `direction`
+/// - `ltr`
+/// - `rtl`
+/// - `ttb`
+/// - `btt`
+pub fn grid(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
+ let cols = args.eat_named::<GridUnits>(ctx, "columns").unwrap_or_default();
+ let rows = args.eat_named::<GridUnits>(ctx, "rows").unwrap_or_default();
+
+ let gutter = args.eat_named(ctx, "gutter");
+ let gutter_vertical = args
+ .eat_named::<GridUnits>(ctx, "gutter-col")
+ .or_else(|| gutter.clone())
+ .unwrap_or_default();
+ let gutter_horizontal = args
+ .eat_named::<GridUnits>(ctx, "gutter-row")
+ .or(gutter)
+ .unwrap_or_default();
+
+ let dir = args.eat_named(ctx, "dir");
+ let children = args.eat_all::<TemplateValue>(ctx);
+
+ Value::template("grid", move |ctx| {
+ let children =
+ children.iter().map(|child| ctx.exec_template_stack(child).into()).collect();
+ ctx.push(GridNode {
+ dir: dir.unwrap_or_else(|| ctx.state.lang.dir),
+ children,
+ gutter: Gen::new(gutter_vertical.clone(), gutter_horizontal.clone()),
+ tracks: Gen::new(cols.clone(), rows.clone()),
+ })
+ })
+}
+
+/// A list of [`GridUnit`]s.
+#[derive(Default, Debug, Clone, PartialEq, Hash)]
+pub struct GridUnits(pub Vec<TrackSizing>);
+
+impl GridUnits {
+ pub fn get(&self, index: usize) -> TrackSizing {
+ if self.0.is_empty() {
+ TrackSizing::Auto
+ } else {
+ *self.0.get(index).unwrap_or(self.0.last().unwrap())
+ }
+ }
+}
+
+value! {
+ GridUnits: "array of fractional values, lengths, and the `auto` keyword",
+ Value::TrackSizing(value) => Self(vec![value]),
+ Value::Array(values) => Self(values
+ .into_iter()
+ .filter_map(|v| v.cast().ok())
+ .collect()
+ ),
+}
diff --git a/src/library/mod.rs b/src/library/mod.rs
index f9e4f68a..8caddc4c 100644
--- a/src/library/mod.rs
+++ b/src/library/mod.rs
@@ -6,6 +6,7 @@
mod align;
mod basic;
mod font;
+mod grid;
mod image;
mod lang;
mod math;
@@ -20,6 +21,7 @@ pub use self::image::*;
pub use align::*;
pub use basic::*;
pub use font::*;
+pub use grid::*;
pub use lang::*;
pub use math::*;
pub use pad::*;
@@ -47,6 +49,7 @@ pub fn new() -> Scope {
std.def_func("circle", circle);
std.def_func("ellipse", ellipse);
std.def_func("font", font);
+ std.def_func("grid", grid);
std.def_func("h", h);
std.def_func("image", image);
std.def_func("lang", lang);