From 4640585fbdf72df993dbed46799844aa78996cce Mon Sep 17 00:00:00 2001 From: Martin Haug Date: Sat, 4 Jun 2022 12:57:45 +0200 Subject: First iteration of outline items --- src/model/layout.rs | 11 ++++++++++- src/model/styles.rs | 28 +++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) (limited to 'src/model') diff --git a/src/model/layout.rs b/src/model/layout.rs index b0247258..b4151c04 100644 --- a/src/model/layout.rs +++ b/src/model/layout.rs @@ -232,7 +232,16 @@ impl Layout for LayoutNode { let at = ctx.pins.cursor(); let entry = StyleEntry::Barrier(Barrier::new(node.id())); - let result = node.0.layout(ctx, regions, entry.chain(&styles)); + let mut result = node.0.layout(ctx, regions, entry.chain(&styles)); + + if let Some(role) = styles.role() { + result = result.map(|mut frames| { + for frame in frames.iter_mut() { + Arc::make_mut(frame).apply_role(role); + } + frames + }); + } let fresh = ctx.pins.from(at); let dirty = ctx.pins.dirty.get(); diff --git a/src/model/styles.rs b/src/model/styles.rs index 9e723171..7db2df42 100644 --- a/src/model/styles.rs +++ b/src/model/styles.rs @@ -5,6 +5,7 @@ use std::marker::PhantomData; use super::{Barrier, Content, Key, Property, Recipe, Selector, Show, Target}; use crate::diag::TypResult; +use crate::frame::Role; use crate::library::text::{FontFamily, TextNode}; use crate::util::ReadableTypeId; use crate::Context; @@ -36,6 +37,13 @@ impl StyleMap { styles } + /// Create a style map from a single role. + pub fn with_role(role: Role) -> Self { + let mut styles = Self::new(); + styles.push(StyleEntry::Role(role)); + styles + } + /// Set an inner value for a style property. /// /// If the property needs folding and the value is already contained in the @@ -170,6 +178,8 @@ pub enum StyleEntry { Property(Property), /// A show rule recipe. Recipe(Recipe), + /// A semantic role. + Role(Role), /// A barrier for scoped styles. Barrier(Barrier), /// Guards against recursive show rules. @@ -229,6 +239,7 @@ impl Debug for StyleEntry { match self { Self::Property(property) => property.fmt(f)?, Self::Recipe(recipe) => recipe.fmt(f)?, + Self::Role(role) => role.fmt(f)?, Self::Barrier(barrier) => barrier.fmt(f)?, Self::Guard(sel) => write!(f, "Guard against {sel:?}")?, Self::Unguard(sel) => write!(f, "Unguard against {sel:?}")?, @@ -324,8 +335,23 @@ impl<'a> StyleChain<'a> { Ok(realized) } + /// Retrieve the current role + pub fn role(self) -> Option { + let mut depth = 0; + + for entry in self.entries() { + match *entry { + StyleEntry::Role(role) => return Some(role), + StyleEntry::Barrier(_) if depth == 1 => return None, + StyleEntry::Barrier(_) => depth += 1, + _ => {} + } + } + None + } + /// Whether the recipe identified by the selector is guarded. - fn guarded(&self, sel: Selector) -> bool { + fn guarded(self, sel: Selector) -> bool { for entry in self.entries() { match *entry { StyleEntry::Guard(s) if s == sel => return true, -- cgit v1.2.3