use embedded_graphics::{
draw_target::DrawTarget,
prelude::PixelColor,
primitives::Rectangle,
text::renderer::{CharacterStyle, TextRenderer},
};
use object_chain::{Chain, ChainElement, Link};
use crate::{
parser::Token,
rendering::{cursor::Cursor, TextBoxProperties},
};
pub trait Plugin<'a, C>: Clone
where
C: PixelColor,
{
#[inline]
fn new_line(&mut self) {}
#[inline]
fn next_token(
&mut self,
mut next_token: impl FnMut() -> Option<Token<'a, C>>,
) -> Option<Token<'a, C>> {
next_token()
}
#[inline]
fn render_token(&mut self, token: Token<'a, C>) -> Option<Token<'a, C>> {
Some(token)
}
#[inline]
fn post_render<T, D>(
&mut self,
_draw_target: &mut D,
_character_style: &T,
_text: Option<&str>,
_bounds: Rectangle,
) -> Result<(), D::Error>
where
T: TextRenderer<Color = C>,
D: DrawTarget<Color = C>,
{
Ok(())
}
#[inline]
fn on_start_render<S: CharacterStyle + TextRenderer>(
&mut self,
_cursor: &mut Cursor,
_props: &TextBoxProperties<'_, S>,
) {
}
#[inline]
fn on_rendering_finished(&mut self) {}
}
impl<'a, C> Plugin<'a, C> for super::NoPlugin<C> where C: PixelColor {}
impl<'a, C, P> Plugin<'a, C> for Chain<P>
where
P: Plugin<'a, C>,
C: PixelColor,
Chain<P>: Clone,
{
fn new_line(&mut self) {
self.object.new_line();
}
fn next_token(
&mut self,
next_token: impl FnMut() -> Option<Token<'a, C>>,
) -> Option<Token<'a, C>> {
self.object.next_token(next_token)
}
fn render_token(&mut self, token: Token<'a, C>) -> Option<Token<'a, C>> {
self.object.render_token(token)
}
fn post_render<T, D>(
&mut self,
draw_target: &mut D,
character_style: &T,
text: Option<&str>,
bounds: Rectangle,
) -> Result<(), D::Error>
where
T: TextRenderer<Color = C>,
D: DrawTarget<Color = C>,
{
self.object
.post_render(draw_target, character_style, text, bounds)
}
fn on_start_render<S: CharacterStyle + TextRenderer>(
&mut self,
cursor: &mut Cursor,
props: &TextBoxProperties<'_, S>,
) {
self.object.on_start_render(cursor, props);
}
fn on_rendering_finished(&mut self) {
self.object.on_rendering_finished();
}
}
impl<'a, C, P, CE> Plugin<'a, C> for Link<P, CE>
where
CE: ChainElement + Plugin<'a, C>,
P: Plugin<'a, C>,
C: PixelColor,
Link<P, CE>: Clone,
{
fn new_line(&mut self) {
self.parent.new_line();
self.object.new_line();
}
fn next_token(
&mut self,
mut next_token: impl FnMut() -> Option<Token<'a, C>>,
) -> Option<Token<'a, C>> {
let parent = &mut self.parent;
let next_token = || parent.next_token(&mut next_token);
self.object.next_token(next_token)
}
fn render_token(&mut self, token: Token<'a, C>) -> Option<Token<'a, C>> {
self.parent
.render_token(token)
.and_then(|t| self.object.render_token(t))
}
fn post_render<T, D>(
&mut self,
draw_target: &mut D,
character_style: &T,
text: Option<&str>,
bounds: Rectangle,
) -> Result<(), D::Error>
where
T: TextRenderer<Color = C>,
D: DrawTarget<Color = C>,
{
self.parent
.post_render(draw_target, character_style, text, bounds)?;
self.object
.post_render(draw_target, character_style, text, bounds)
}
fn on_start_render<S: CharacterStyle + TextRenderer>(
&mut self,
cursor: &mut Cursor,
props: &TextBoxProperties<'_, S>,
) {
self.parent.on_start_render(cursor, props);
self.object.on_start_render(cursor, props);
}
fn on_rendering_finished(&mut self) {
self.parent.on_rendering_finished();
self.object.on_rendering_finished();
}
}