200 lines
5.3 KiB
Rust
200 lines
5.3 KiB
Rust
use std::rc::Rc;
|
||
|
||
use clay_layout::{
|
||
Declaration, fit, grow,
|
||
layout::{
|
||
Alignment, LayoutAlignmentX, LayoutAlignmentY,
|
||
LayoutDirection::{self, TopToBottom},
|
||
Padding,
|
||
},
|
||
text::{TextConfig, TextElementConfig},
|
||
};
|
||
use libopenbirch::node::NodeEnum;
|
||
|
||
use super::{Document, State};
|
||
|
||
pub struct Line {
|
||
pub segments: Vec<LineSegment>,
|
||
}
|
||
|
||
impl From<String> for Line {
|
||
fn from(value: String) -> Self {
|
||
Line {
|
||
segments: vec![LineSegment::Text(value, 20)],
|
||
}
|
||
}
|
||
}
|
||
|
||
impl Line {
|
||
pub fn draw<'a>(&'a mut self, clay: &'a clay_layout::Clay, theme: &Theme, state: &'a State) {
|
||
for segment in self.segments.iter_mut() {
|
||
segment.draw(clay, theme, state);
|
||
}
|
||
}
|
||
}
|
||
|
||
pub struct Theme {
|
||
pub text_color: clay_layout::color::Color,
|
||
pub text_font: u16,
|
||
pub math_color: clay_layout::color::Color,
|
||
pub math_font: u16,
|
||
}
|
||
|
||
pub enum LineSegment {
|
||
Text(String, u16),
|
||
// Link(String, Link),
|
||
Math(String, Rc<NodeEnum>, u16),
|
||
}
|
||
|
||
impl LineSegment {
|
||
pub fn draw<'a>(&'a mut self, clay: &'a clay_layout::Clay, theme: &'a Theme, state: &'a State) {
|
||
match self {
|
||
LineSegment::Text(text, font_size) => clay.text(
|
||
text.as_str(),
|
||
TextConfig::new()
|
||
.font_id(theme.text_font)
|
||
.font_size(*font_size)
|
||
.color(theme.text_color)
|
||
.end(),
|
||
),
|
||
LineSegment::Math(_source, node_enum, font_size) => {
|
||
draw_math_enum(node_enum.clone(), clay, theme, *font_size, state);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
fn draw_binary(
|
||
symbol: &'static str,
|
||
left: Rc<NodeEnum>,
|
||
right: Rc<NodeEnum>,
|
||
font_size: u16,
|
||
clay: &clay_layout::Clay,
|
||
theme: &Theme,
|
||
state: &State,
|
||
) {
|
||
clay.with(
|
||
&Declaration::new()
|
||
.layout()
|
||
.direction(LayoutDirection::LeftToRight)
|
||
.width(fit!(0.))
|
||
.height(fit!(0.))
|
||
.child_alignment(Alignment::new(
|
||
LayoutAlignmentX::Center,
|
||
LayoutAlignmentY::Center,
|
||
))
|
||
.padding(Padding::new(2, 2, 3, 3))
|
||
.end(),
|
||
|clay| {
|
||
// Left side
|
||
draw_math_enum(left, clay, theme, font_size, state);
|
||
// add symbol
|
||
clay.text(
|
||
symbol,
|
||
TextConfig::new()
|
||
.color(theme.math_color)
|
||
.font_size(font_size)
|
||
.font_id(theme.math_font)
|
||
.end(),
|
||
);
|
||
// Right side
|
||
draw_math_enum(right, clay, theme, font_size, state);
|
||
},
|
||
)
|
||
}
|
||
|
||
fn draw_math_enum<'a>(
|
||
node: Rc<NodeEnum>,
|
||
clay: &'a clay_layout::Clay,
|
||
theme: &'a Theme,
|
||
font_size: u16,
|
||
state: &'a State,
|
||
) {
|
||
match node.as_ref() {
|
||
NodeEnum::Constant(constant) => {
|
||
let str = std::mem::ManuallyDrop::new(constant.get_value().to_string());
|
||
clay.text(
|
||
str.as_str(),
|
||
TextConfig::new()
|
||
.color(theme.math_color)
|
||
.font_size(font_size)
|
||
.font_id(theme.math_font)
|
||
.end(),
|
||
)
|
||
}
|
||
NodeEnum::Add(add) => draw_binary(
|
||
" + ",
|
||
add.get_left(),
|
||
add.get_right(),
|
||
font_size,
|
||
clay,
|
||
theme,
|
||
state,
|
||
),
|
||
|
||
NodeEnum::Subtract(sub) => draw_binary(
|
||
" - ",
|
||
sub.get_left(),
|
||
sub.get_right(),
|
||
font_size,
|
||
clay,
|
||
theme,
|
||
state,
|
||
),
|
||
|
||
NodeEnum::Multiply(mul) => draw_binary(
|
||
"× ",
|
||
mul.get_left(),
|
||
mul.get_right(),
|
||
font_size,
|
||
clay,
|
||
theme,
|
||
state,
|
||
),
|
||
|
||
NodeEnum::Assign(assign) => draw_binary(
|
||
" := ",
|
||
assign.get_left(),
|
||
assign.get_right(),
|
||
font_size,
|
||
clay,
|
||
theme,
|
||
state,
|
||
),
|
||
|
||
NodeEnum::Divide(divide) => clay.with(
|
||
&Declaration::new()
|
||
.layout()
|
||
.direction(TopToBottom)
|
||
.width(fit!(0.))
|
||
.height(fit!(0.))
|
||
.child_alignment(Alignment::new(
|
||
LayoutAlignmentX::Center,
|
||
LayoutAlignmentY::Center,
|
||
))
|
||
.padding(Padding::new(4, 4, 2, 2))
|
||
.end(),
|
||
|clay| {
|
||
// Left side
|
||
draw_math_enum(divide.get_left(), clay, theme, font_size, state);
|
||
// Seperator bar
|
||
clay.with(
|
||
&Declaration::new()
|
||
.layout()
|
||
.width(grow!(0.))
|
||
.height(fit!(1.))
|
||
.end()
|
||
.background_color(theme.math_color),
|
||
|_| {},
|
||
);
|
||
// Right side
|
||
draw_math_enum(divide.get_right(), clay, theme, font_size, state);
|
||
},
|
||
),
|
||
NodeEnum::Symbol(symbol) => todo!(),
|
||
NodeEnum::Function(function) => todo!(),
|
||
NodeEnum::Call(call) => todo!(),
|
||
|
||
NodeEnum::Empty(empty) => {}
|
||
}
|
||
}
|