summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2019-10-13 12:36:45 +0200
committerLaurenz <laurmaedje@gmail.com>2019-10-13 12:36:45 +0200
commite2d17aa9d9491b339e6200c97b52f7ade51fa1d8 (patch)
tree95dfa729cc6cbe44ecbf5135f87a3dd8bb70200a /src
parent463e4ebd8234da5e28700e9b22b6ef5f0dfef56f (diff)
Move functions to command-based architecture ✈
Diffstat (limited to 'src')
-rw-r--r--src/func.rs20
-rw-r--r--src/layout/mod.rs31
-rw-r--r--src/layout/stacked.rs12
-rw-r--r--src/library/align.rs14
-rw-r--r--src/library/mod.rs2
-rw-r--r--src/library/styles.rs34
6 files changed, 66 insertions, 47 deletions
diff --git a/src/func.rs b/src/func.rs
index a7044b6e..14dd5beb 100644
--- a/src/func.rs
+++ b/src/func.rs
@@ -37,20 +37,20 @@ impl PartialEq for dyn Function {
/// A sequence of commands requested for execution by a function.
#[derive(Debug)]
-pub struct FuncCommands {
- pub commands: Vec<Command>
+pub struct FuncCommands<'a> {
+ pub commands: Vec<Command<'a>>
}
-impl FuncCommands {
+impl<'a> FuncCommands<'a> {
/// Create an empty command list.
- pub fn new() -> FuncCommands {
+ pub fn new() -> FuncCommands<'a> {
FuncCommands {
commands: vec![],
}
}
/// Add a command to the sequence.
- pub fn add_command(&mut self, command: Command) {
+ pub fn add(&mut self, command: Command<'a>) {
self.commands.push(command);
}
@@ -60,9 +60,9 @@ impl FuncCommands {
}
}
-impl IntoIterator for FuncCommands {
- type Item = Command;
- type IntoIter = std::vec::IntoIter<Command>;
+impl<'a> IntoIterator for FuncCommands<'a> {
+ type Item = Command<'a>;
+ type IntoIter = std::vec::IntoIter<Command<'a>>;
fn into_iter(self) -> Self::IntoIter {
self.commands.into_iter()
@@ -71,8 +71,8 @@ impl IntoIterator for FuncCommands {
/// Commands requested for execution by functions.
#[derive(Debug)]
-pub enum Command {
- Layout(SyntaxTree),
+pub enum Command<'a> {
+ Layout(&'a SyntaxTree),
Add(Layout),
AddMany(MultiLayout),
ToggleStyleClass(FontClass),
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index 19543389..1bd11e14 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -81,6 +81,15 @@ impl MultiLayout {
}
}
+impl IntoIterator for MultiLayout {
+ type Item = Layout;
+ type IntoIter = std::vec::IntoIter<Layout>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ self.layouts.into_iter()
+ }
+}
+
/// The context for layouting.
#[derive(Copy, Clone)]
pub struct LayoutContext<'a, 'p> {
@@ -122,13 +131,14 @@ pub enum Alignment {
}
pub fn layout_tree(tree: &SyntaxTree, ctx: LayoutContext) -> LayoutResult<MultiLayout> {
- Layouter::new(tree, ctx).layout()
+ let mut layouter = Layouter::new(ctx);
+ layouter.layout(tree)?;
+ layouter.finish()
}
/// Transforms a syntax tree into a box layout.
struct Layouter<'a, 'p> {
ctx: LayoutContext<'a, 'p>,
- tree: &'a SyntaxTree,
stack_layouter: StackLayouter,
flex_layouter: FlexLayouter,
style: Cow<'a, TextStyle>,
@@ -136,10 +146,9 @@ struct Layouter<'a, 'p> {
impl<'a, 'p> Layouter<'a, 'p> {
/// Create a new layouter.
- fn new(tree: &'a SyntaxTree, ctx: LayoutContext<'a, 'p>) -> Layouter<'a, 'p> {
+ fn new(ctx: LayoutContext<'a, 'p>) -> Layouter<'a, 'p> {
Layouter {
ctx,
- tree,
stack_layouter: StackLayouter::new(StackContext { space: ctx.space }),
flex_layouter: FlexLayouter::new(FlexContext {
space: LayoutSpace {
@@ -155,9 +164,9 @@ impl<'a, 'p> Layouter<'a, 'p> {
}
/// Layout the tree into a box.
- fn layout(mut self) -> LayoutResult<MultiLayout> {
+ fn layout(&mut self, tree: &SyntaxTree) -> LayoutResult<()> {
// Walk all nodes and layout them.
- for node in &self.tree.nodes {
+ for node in &tree.nodes {
match node {
// Layout a single piece of text.
Node::Text(text) => self.layout_text(text, false)?,
@@ -190,6 +199,10 @@ impl<'a, 'p> Layouter<'a, 'p> {
}
}
+ Ok(())
+ }
+
+ fn finish(mut self) -> LayoutResult<MultiLayout> {
// If there are remainings, add them to the layout.
if !self.flex_layouter.is_empty() {
self.layout_flex()?;
@@ -254,9 +267,9 @@ impl<'a, 'p> Layouter<'a, 'p> {
for command in commands {
match command {
- Command::Layout(tree) => unimplemented!(),
- Command::Add(layout) => unimplemented!(),
- Command::AddMany(layouts) => unimplemented!(),
+ Command::Layout(tree) => self.layout(tree)?,
+ Command::Add(layout) => self.stack_layouter.add_box(layout)?,
+ Command::AddMany(layouts) => self.stack_layouter.add_many(layouts)?,
Command::ToggleStyleClass(class) => self.style.to_mut().toggle_class(class),
}
}
diff --git a/src/layout/stacked.rs b/src/layout/stacked.rs
index 78eb0058..312681ac 100644
--- a/src/layout/stacked.rs
+++ b/src/layout/stacked.rs
@@ -72,9 +72,17 @@ impl StackLayouter {
Ok(())
}
+ /// Add multiple sublayouts.
+ pub fn add_many(&mut self, layouts: MultiLayout) -> LayoutResult<()> {
+ for layout in layouts {
+ self.add_box(layout)?;
+ }
+ Ok(())
+ }
+
/// Add a sublayout at an absolute position.
- pub fn add_box_absolute(&mut self, position: Size2D, layout: Layout) -> LayoutResult<()> {
- Ok(self.actions.add_box(position, layout))
+ pub fn add_box_absolute(&mut self, position: Size2D, layout: Layout) {
+ self.actions.add_box(position, layout);
}
/// Add space in between two boxes.
diff --git a/src/library/align.rs b/src/library/align.rs
index b1e41abb..099daf88 100644
--- a/src/library/align.rs
+++ b/src/library/align.rs
@@ -38,13 +38,15 @@ impl Function for AlignFunc {
Ok(AlignFunc { alignment, body })
}
- fn layout(&self, ctx: LayoutContext) -> LayoutResult<FuncCommands> {
+ fn layout(&self, mut ctx: LayoutContext) -> LayoutResult<FuncCommands> {
if let Some(body) = &self.body {
- // // Override the previous alignment and do the layouting.
- // ctx.space.alignment = self.alignment;
- // layout(body, ctx)
- // .map(|l| Some(Layout::Boxed(l)))
- Ok(FuncCommands::new())
+ ctx.space.alignment = self.alignment;
+ let layouts = layout_tree(body, ctx)?;
+
+ let mut commands = FuncCommands::new();
+ commands.add(Command::AddMany(layouts));
+
+ Ok(commands)
} else {
unimplemented!("context-modifying align func")
}
diff --git a/src/library/mod.rs b/src/library/mod.rs
index acbd11db..848ba847 100644
--- a/src/library/mod.rs
+++ b/src/library/mod.rs
@@ -9,7 +9,7 @@ mod styles;
pub mod prelude {
pub use crate::syntax::{SyntaxTree, FuncHeader, Expression};
pub use crate::parsing::{parse, ParseContext, ParseResult, ParseError};
- pub use crate::layout::{layout_tree, layout_text, MultiLayout, Layout, LayoutContext};
+ pub use crate::layout::{layout_tree, LayoutContext, MultiLayout, Layout};
pub use crate::layout::{LayoutResult, LayoutError};
pub use crate::func::{Function, Command, FuncCommands};
diff --git a/src/library/styles.rs b/src/library/styles.rs
index 28cc0e48..85ae4789 100644
--- a/src/library/styles.rs
+++ b/src/library/styles.rs
@@ -1,13 +1,15 @@
//! Basic style functions: bold, italic, monospace.
use super::prelude::*;
-// use toddle::query::FontClass;
-
+use toddle::query::FontClass;
macro_rules! style_func {
- ($(#[$outer:meta])* pub struct $struct:ident { $name:expr },
- $style:ident => $style_change:block) => {
+ (
+ $(#[$outer:meta])*
+ pub struct $struct:ident { $name:expr },
+ $style:ident => $class:ident
+ ) => {
$(#[$outer])*
#[derive(Debug, PartialEq)]
pub struct $struct { body: SyntaxTree }
@@ -27,20 +29,14 @@ macro_rules! style_func {
}
}
- fn layout(&self, ctx: LayoutContext) -> LayoutResult<FuncCommands> {
- // // Change the context.
- // let mut $style = ctx.style.clone();
- // $style_change
+ fn layout(&self, _: LayoutContext) -> LayoutResult<FuncCommands> {
+ let mut commands = FuncCommands::new();
- // // Create a box and put it into a flex layout.
- // let boxed = layout(&self.body, LayoutContext {
- // style: &$style,
- // .. ctx
- // })?;
- // let flex = FlexLayout::from_box(boxed);
+ commands.add(Command::ToggleStyleClass(FontClass::$class));
+ commands.add(Command::Layout(&self.body));
+ commands.add(Command::ToggleStyleClass(FontClass::$class));
- // Ok(Some(Layout::Flex(flex)))
- Ok(FuncCommands::new())
+ Ok(commands)
}
}
};
@@ -49,17 +45,17 @@ macro_rules! style_func {
style_func! {
/// Typesets text in bold.
pub struct BoldFunc { "bold" },
- style => { style.toggle_class(FontClass::Bold) }
+ style => Bold
}
style_func! {
/// Typesets text in italics.
pub struct ItalicFunc { "italic" },
- style => { style.toggle_class(FontClass::Italic) }
+ style => Italic
}
style_func! {
/// Typesets text in monospace.
pub struct MonospaceFunc { "mono" },
- style => { style.toggle_class(FontClass::Monospace) }
+ style => Monospace
}