use core::marker::PhantomData;
use crate::{
DisplayPort, FsTheme, I18n, TouchEvent, UiView, ViewEnvironment, ViewEvent, ViewRedraw,
ViewRegistration,
};
pub struct UiSystem<'text, Display, Root, ViewId, Message, const N: usize>
where
Display: DisplayPort,
Root: UiView<'text, ViewId, Message, N>,
{
display: Display,
root: Root,
theme: FsTheme,
i18n: I18n<'text>,
registration: ViewRegistration<'text, ViewId, N>,
marker: PhantomData<Message>,
}
impl<'text, Display, Root, ViewId, Message, const N: usize>
UiSystem<'text, Display, Root, ViewId, Message, N>
where
Display: DisplayPort,
Root: UiView<'text, ViewId, Message, N>,
{
pub fn new(display: Display, root: Root, theme: FsTheme, i18n: I18n<'text>) -> Self {
let registration = ViewRegistration::new(display.bounds());
let mut system = Self {
display,
root,
theme,
i18n,
registration,
marker: PhantomData,
};
system.configure_root();
system
}
pub fn configure_root(&mut self) {
self.registration.clear_children();
self.registration.set_frame(self.display.bounds());
self.root.configure(&mut self.registration);
}
pub const fn root(&self) -> &Root {
&self.root
}
pub fn root_mut(&mut self) -> &mut Root {
&mut self.root
}
pub const fn registration(&self) -> &ViewRegistration<'text, ViewId, N> {
&self.registration
}
pub fn registration_mut(&mut self) -> &mut ViewRegistration<'text, ViewId, N> {
&mut self.registration
}
pub const fn theme(&self) -> &FsTheme {
&self.theme
}
pub fn theme_mut(&mut self) -> &mut FsTheme {
&mut self.theme
}
pub const fn i18n(&self) -> &I18n<'text> {
&self.i18n
}
pub fn i18n_mut(&mut self) -> &mut I18n<'text> {
&mut self.i18n
}
pub const fn display(&self) -> &Display {
&self.display
}
pub fn display_mut(&mut self) -> &mut Display {
&mut self.display
}
pub fn with_display_and_root<R>(&mut self, apply: impl FnOnce(&mut Display, &Root) -> R) -> R {
let display = &mut self.display;
let root = &self.root;
apply(display, root)
}
pub fn with_display_and_root_mut<R>(
&mut self,
apply: impl FnOnce(&mut Display, &mut Root) -> R,
) -> R {
let display = &mut self.display;
let root = &mut self.root;
apply(display, root)
}
pub fn update(&mut self, dt_ms: u32) -> ViewEvent<Message> {
let env = ViewEnvironment {
theme: &self.theme,
i18n: &self.i18n,
};
self.root.update(dt_ms, &self.registration, &env)
}
pub fn handle_touch(&mut self, touch: TouchEvent) -> ViewEvent<Message> {
let env = ViewEnvironment {
theme: &self.theme,
i18n: &self.i18n,
};
self.root.handle_touch(touch, &self.registration, &env)
}
pub fn draw(&mut self) -> Result<(), Display::Error> {
let env = ViewEnvironment {
theme: &self.theme,
i18n: &self.i18n,
};
self.display.draw_frame(|canvas| {
self.root.draw(canvas, &self.registration, &env);
})
}
pub fn draw_redraw(&mut self, redraw: ViewRedraw) -> Result<(), Display::Error> {
match redraw {
ViewRedraw::None => Ok(()),
ViewRedraw::Full => self.draw(),
ViewRedraw::Dirty(area) => {
let env = ViewEnvironment {
theme: &self.theme,
i18n: &self.i18n,
};
self.display.draw_dirty(area, |canvas| {
self.root.draw(canvas, &self.registration, &env);
})
}
}
}
}