1use core::marker::PhantomData;
2
3use crate::{
4 DisplayPort, FsTheme, I18n, TouchEvent, UiView, ViewEnvironment, ViewEvent, ViewRedraw,
5 ViewRegistration,
6};
7
8pub struct UiSystem<'text, Display, Root, ViewId, Message, const N: usize>
10where
11 Display: DisplayPort,
12 Root: UiView<'text, ViewId, Message, N>,
13{
14 display: Display,
15 root: Root,
16 theme: FsTheme,
17 i18n: I18n<'text>,
18 registration: ViewRegistration<'text, ViewId, N>,
19 marker: PhantomData<Message>,
20}
21
22impl<'text, Display, Root, ViewId, Message, const N: usize>
23 UiSystem<'text, Display, Root, ViewId, Message, N>
24where
25 Display: DisplayPort,
26 Root: UiView<'text, ViewId, Message, N>,
27{
28 pub fn new(display: Display, root: Root, theme: FsTheme, i18n: I18n<'text>) -> Self {
30 let registration = ViewRegistration::new(display.bounds());
31 let mut system = Self {
32 display,
33 root,
34 theme,
35 i18n,
36 registration,
37 marker: PhantomData,
38 };
39 system.configure_root();
40 system
41 }
42
43 pub fn configure_root(&mut self) {
45 self.registration.clear_children();
46 self.registration.set_frame(self.display.bounds());
47 self.root.configure(&mut self.registration);
48 }
49
50 pub const fn root(&self) -> &Root {
52 &self.root
53 }
54
55 pub fn root_mut(&mut self) -> &mut Root {
57 &mut self.root
58 }
59
60 pub const fn registration(&self) -> &ViewRegistration<'text, ViewId, N> {
62 &self.registration
63 }
64
65 pub fn registration_mut(&mut self) -> &mut ViewRegistration<'text, ViewId, N> {
67 &mut self.registration
68 }
69
70 pub const fn theme(&self) -> &FsTheme {
72 &self.theme
73 }
74
75 pub fn theme_mut(&mut self) -> &mut FsTheme {
77 &mut self.theme
78 }
79
80 pub const fn i18n(&self) -> &I18n<'text> {
82 &self.i18n
83 }
84
85 pub fn i18n_mut(&mut self) -> &mut I18n<'text> {
87 &mut self.i18n
88 }
89
90 pub const fn display(&self) -> &Display {
92 &self.display
93 }
94
95 pub fn display_mut(&mut self) -> &mut Display {
97 &mut self.display
98 }
99
100 pub fn with_display_and_root<R>(&mut self, apply: impl FnOnce(&mut Display, &Root) -> R) -> R {
102 let display = &mut self.display;
103 let root = &self.root;
104 apply(display, root)
105 }
106
107 pub fn with_display_and_root_mut<R>(
109 &mut self,
110 apply: impl FnOnce(&mut Display, &mut Root) -> R,
111 ) -> R {
112 let display = &mut self.display;
113 let root = &mut self.root;
114 apply(display, root)
115 }
116
117 pub fn update(&mut self, dt_ms: u32) -> ViewEvent<Message> {
119 let env = ViewEnvironment {
120 theme: &self.theme,
121 i18n: &self.i18n,
122 };
123 self.root.update(dt_ms, &self.registration, &env)
124 }
125
126 pub fn handle_touch(&mut self, touch: TouchEvent) -> ViewEvent<Message> {
128 let env = ViewEnvironment {
129 theme: &self.theme,
130 i18n: &self.i18n,
131 };
132 self.root.handle_touch(touch, &self.registration, &env)
133 }
134
135 pub fn draw(&mut self) -> Result<(), Display::Error> {
137 let env = ViewEnvironment {
138 theme: &self.theme,
139 i18n: &self.i18n,
140 };
141 self.display.draw_frame(|canvas| {
142 self.root.draw(canvas, &self.registration, &env);
143 })
144 }
145
146 pub fn draw_redraw(&mut self, redraw: ViewRedraw) -> Result<(), Display::Error> {
148 match redraw {
149 ViewRedraw::None => Ok(()),
150 ViewRedraw::Full => self.draw(),
151 ViewRedraw::Dirty(area) => {
152 let env = ViewEnvironment {
153 theme: &self.theme,
154 i18n: &self.i18n,
155 };
156 self.display.draw_dirty(area, |canvas| {
157 self.root.draw(canvas, &self.registration, &env);
158 })
159 }
160 }
161 }
162}