workflow_egui/module/
module.rs1use crate::imports::*;
2
3pub enum ModuleStyle {
4 Mobile,
5 Default,
6}
7
8pub enum ModuleCaps {
12 Desktop,
13 Mobile,
14 WebApp,
15 Extension,
16}
17
18pub trait ModuleT: Downcast {
19 type Context;
20
21 fn name(&self) -> Option<&'static str> {
22 None
23 }
24
25 fn modal(&self) -> bool {
26 false
27 }
28
29 fn secure(&self) -> bool {
30 false
31 }
32
33 fn style(&self) -> ModuleStyle {
34 ModuleStyle::Default
35 }
36
37 fn activate(&mut self, _core: &mut Self::Context) {}
38
39 fn deactivate(&mut self, _core: &mut Self::Context) {}
40
41 fn main(&mut self, _core: &mut Self::Context) {}
42
43 fn render(
44 &mut self,
45 core: &mut Self::Context,
46 ctx: &egui::Context,
47 frame: &mut eframe::Frame,
48 ui: &mut egui::Ui,
49 );
50
51 fn shutdown(&mut self) {}
52}
53
54impl_downcast!(ModuleT assoc Context);
55
56pub struct Inner<T> {
57 pub name: String,
58 pub type_name: String,
59 pub type_id: TypeId,
60 pub module: Rc<RefCell<dyn ModuleT<Context = T>>>,
61}
62
63pub struct Module<T> {
64 pub inner: Rc<Inner<T>>,
65}
66
67impl<T> Clone for Module<T> {
68 fn clone(&self) -> Self {
69 Self {
70 inner: Rc::clone(&self.inner),
71 }
72 }
73}
74
75impl<T> Module<T>
76where
77 T: App + 'static,
78{
79 pub fn any(&self) -> Rc<RefCell<dyn ModuleT<Context = T>>> {
80 Rc::clone(&self.inner.module)
81 }
82
83 pub fn main(&self, core: &mut T) {
84 self.inner.module.borrow_mut().main(core)
85 }
86
87 pub fn activate(&self, core: &mut T) {
88 self.inner.module.borrow_mut().activate(core)
89 }
90
91 pub fn deactivate(&self, core: &mut T) {
92 self.inner.module.borrow_mut().deactivate(core)
93 }
94
95 pub fn render(
96 &self,
97 core: &mut T,
98 ctx: &egui::Context,
99 frame: &mut eframe::Frame,
100 ui: &mut egui::Ui,
101 ) {
102 let mut module = self.inner.module.borrow_mut();
103
104 match module.style() {
105 ModuleStyle::Mobile => {
106 if let Some(text_styles) = core.mobile_text_styles() {
107 ui.style_mut().text_styles = text_styles;
108 }
109 }
110 ModuleStyle::Default => {
111 if let Some(text_styles) = core.default_text_styles() {
112 ui.style_mut().text_styles = text_styles;
113 }
114 }
115 }
116
117 module.render(core, ctx, frame, ui)
118 }
119
120 pub fn name(&self) -> &str {
121 self.inner
122 .module
123 .borrow_mut()
124 .name()
125 .unwrap_or_else(|| self.inner.name.as_str())
126 }
127
128 pub fn modal(&self) -> bool {
129 self.inner.module.borrow_mut().modal()
130 }
131
132 pub fn secure(&self) -> bool {
133 self.inner.module.borrow_mut().secure()
134 }
135
136 pub fn type_id(&self) -> TypeId {
137 self.inner.type_id
138 }
139
140 pub fn as_ref<M>(&self) -> Ref<'_, M>
141 where
142 M: ModuleT + 'static,
143 {
144 Ref::map(self.inner.module.borrow(), |r| {
145 (r).as_any()
146 .downcast_ref::<M>()
147 .expect("unable to downcast section")
148 })
149 }
150
151 pub fn as_mut<M>(&mut self) -> RefMut<'_, M>
152 where
153 M: ModuleT + 'static,
154 {
155 RefMut::map(self.inner.module.borrow_mut(), |r| {
156 (r).as_any_mut()
157 .downcast_mut::<M>()
158 .expect("unable to downcast_mut module")
159 })
160 }
161}
162
163impl<T> std::fmt::Debug for Module<T> {
164 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
165 write!(f, "{}", self.inner.name)
166 }
167}
168
169impl<T> Eq for Module<T> {}
170
171impl<T> PartialEq for Module<T> {
172 fn eq(&self, other: &Self) -> bool {
173 self.inner.type_id == other.inner.type_id
174 }
175}
176
177impl<T, M> From<M> for Module<T>
178where
179 M: ModuleT<Context = T> + 'static,
180 T: App,
181{
182 fn from(section: M) -> Self {
183 let type_name = type_name::<M>().to_string();
184 let name = type_name.split("::").last().unwrap().to_string();
185 let type_id = TypeId::of::<M>();
186 Self {
187 inner: Rc::new(Inner {
188 name,
189 type_name,
190 type_id,
191 module: Rc::new(RefCell::new(section)),
192 }),
193 }
194 }
195}
196
197pub trait HashMapModuleExtension<T, M> {
198 fn insert_typeid(&mut self, value: M)
199 where
200 M: ModuleT<Context = T> + 'static,
201 T: App;
202}
203
204impl<T, M> HashMapModuleExtension<T, M> for AHashMap<TypeId, Module<T>>
205where
206 M: ModuleT<Context = T> + 'static,
207 T: App,
208{
209 fn insert_typeid(&mut self, section: M) {
210 self.insert(TypeId::of::<M>(), Module::<T>::from(section));
211 }
212}