summaryrefslogtreecommitdiff
path: root/src/library/heading.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-12-20 14:18:29 +0100
committerLaurenz <laurmaedje@gmail.com>2021-12-21 00:20:24 +0100
commit11565a40b315212474f52eb576a9fd92b11f1132 (patch)
treec6b7afb35103065bc92b407094ca905bb75cfc73 /src/library/heading.rs
parent958f74f77707340f34ee36d09492bdb74523aa2a (diff)
Set Rules Episode IX: The Rise of Testing
Diffstat (limited to 'src/library/heading.rs')
-rw-r--r--src/library/heading.rs63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/library/heading.rs b/src/library/heading.rs
new file mode 100644
index 00000000..c9777577
--- /dev/null
+++ b/src/library/heading.rs
@@ -0,0 +1,63 @@
+use super::prelude::*;
+use super::{FontFamily, TextNode};
+
+/// A section heading.
+#[derive(Debug, Hash)]
+pub struct HeadingNode {
+ /// The node that produces the heading's contents.
+ pub child: PackedNode,
+ /// The logical nesting depth of the section, starting from one. In the
+ /// default style, this controls the text size of the heading.
+ pub level: usize,
+}
+
+#[properties]
+impl HeadingNode {
+ /// The heading's font family.
+ pub const FAMILY: Smart<String> = Smart::Auto;
+ /// The fill color of heading in the text. Just the surrounding text color
+ /// if `auto`.
+ pub const FILL: Smart<Paint> = Smart::Auto;
+}
+
+impl Construct for HeadingNode {
+ fn construct(_: &mut EvalContext, args: &mut Args) -> TypResult<Node> {
+ Ok(Node::block(Self {
+ child: args.expect::<Node>("body")?.into_block(),
+ level: args.named("level")?.unwrap_or(1),
+ }))
+ }
+}
+
+impl Set for HeadingNode {
+ fn set(styles: &mut Styles, args: &mut Args) -> TypResult<()> {
+ styles.set_opt(Self::FAMILY, args.named("family")?);
+ styles.set_opt(Self::FILL, args.named("fill")?);
+ Ok(())
+ }
+}
+
+impl Layout for HeadingNode {
+ fn layout(
+ &self,
+ ctx: &mut LayoutContext,
+ regions: &Regions,
+ ) -> Vec<Constrained<Rc<Frame>>> {
+ let upscale = (1.6 - 0.1 * self.level as f64).max(0.75);
+ ctx.styles.set(TextNode::STRONG, true);
+ ctx.styles.set(TextNode::SIZE, Relative::new(upscale).into());
+
+ if let Smart::Custom(family) = ctx.styles.get_ref(Self::FAMILY) {
+ let list: Vec<_> = std::iter::once(FontFamily::named(family))
+ .chain(ctx.styles.get_ref(TextNode::FAMILY_LIST).iter().cloned())
+ .collect();
+ ctx.styles.set(TextNode::FAMILY_LIST, list);
+ }
+
+ if let Smart::Custom(fill) = ctx.styles.get(Self::FILL) {
+ ctx.styles.set(TextNode::FILL, fill);
+ }
+
+ self.child.layout(ctx, regions)
+ }
+}