workflow_egui/frame/core.rs
1use crate::frame::app::App;
2use crate::imports::*;
3
4pub struct Core<T>
5where
6 T: App,
7{
8 app: Box<T>,
9
10 is_shutdown_pending: bool,
11 _settings_storage_requested: bool,
12 _last_settings_storage_request: Instant,
13
14 #[allow(dead_code)]
15 runtime: Runtime,
16 events: ApplicationEventsChannel,
17}
18
19impl<T> Core<T>
20where
21 T: App,
22{
23 /// Core initialization
24 pub fn try_new(
25 cc: &eframe::CreationContext<'_>,
26 runtime: Runtime,
27 app_creator: crate::frame::AppCreator<T>,
28 ) -> Result<Self> {
29 let mut app = app_creator(cc, runtime.clone())?;
30 app.init(&runtime, cc);
31
32 let events = runtime.events().clone();
33
34 Ok(Self {
35 runtime,
36 app,
37 is_shutdown_pending: false,
38 _settings_storage_requested: false,
39 _last_settings_storage_request: Instant::now(),
40 events,
41 })
42 }
43}
44
45impl<T> eframe::App for Core<T>
46where
47 T: App,
48{
49 #[cfg(not(target_arch = "wasm32"))]
50 fn on_exit(&mut self, _gl: Option<&eframe::glow::Context>) {
51 self.is_shutdown_pending = true;
52 Runtime::halt();
53 println!("bye!");
54 }
55
56 fn clear_color(&self, _visuals: &egui::Visuals) -> [f32; 4] {
57 egui::Rgba::TRANSPARENT.to_array()
58 }
59
60 /// Called each time the UI needs repainting, which may be many times per second.
61 /// Put your widgets into a `SidePanel`, `TopPanel`, `CentralPanel`, `Window` or `Area`.
62 fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
63 log_info!("--- update ---");
64
65 for event in self.events.iter() {
66 if let Err(err) = self.handle_events(event.clone(), ctx, frame) {
67 log_error!("error processing wallet runtime event: {}", err);
68 }
69 }
70
71 if self.is_shutdown_pending {
72 return;
73 }
74
75 ctx.input(|input| {
76 input.events.iter().for_each(|event| {
77 if let egui::Event::Key {
78 key,
79 pressed,
80 modifiers,
81 repeat,
82 // TODO - propagate
83 physical_key: _,
84 // ..
85 } = event
86 {
87 self.handle_keyboard_events(*key, *pressed, modifiers, *repeat);
88 }
89 });
90 });
91
92 if let Some(device) = self.app.device() {
93 device.set_screen_size(&ctx.screen_rect())
94 }
95
96 self.render(ctx, frame);
97
98 // #[cfg(not(target_arch = "wasm32"))]
99 // if let Some(screenshot) = self.screenshot.clone() {
100 // self.handle_screenshot(ctx, screenshot);
101 // }
102 }
103}
104
105impl<T> Core<T>
106where
107 T: App,
108{
109 fn render(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
110 self.app.render(ctx, frame);
111 }
112
113 // #[cfg(not(target_arch = "wasm32"))]
114 // fn handle_screenshot(&mut self, ctx: &Context, screenshot: Arc<ColorImage>) {
115 // match rfd::FileDialog::new().save_file() {
116 // Some(mut path) => {
117 // path.set_extension("png");
118 // let screen_rect = ctx.screen_rect();
119 // let pixels_per_point = ctx.pixels_per_point();
120 // let screenshot = screenshot.clone();
121 // let sender = self.sender();
122 // std::thread::Builder::new()
123 // .name("screenshot".to_string())
124 // .spawn(move || {
125 // let image = screenshot.region(&screen_rect, Some(pixels_per_point));
126 // image::save_buffer(
127 // &path,
128 // image.as_raw(),
129 // image.width() as u32,
130 // image.height() as u32,
131 // image::ColorType::Rgba8,
132 // )
133 // .unwrap();
134
135 // sender
136 // .try_send(Events::Notify {
137 // user_notification: UserNotification::success(format!(
138 // "Capture saved to\n{}",
139 // path.to_string_lossy()
140 // ))
141 // .as_toast(),
142 // })
143 // .unwrap()
144 // })
145 // .expect("Unable to spawn screenshot thread");
146 // self.screenshot.take();
147 // }
148 // None => {
149 // self.screenshot.take();
150 // }
151 // }
152 // }
153
154 pub fn handle_events(
155 &mut self,
156 event: RuntimeEvent,
157 ctx: &egui::Context,
158 _frame: &mut eframe::Frame,
159 ) -> Result<()> {
160 // log_info!("--- event: {:?}", event);
161 if matches!(event, RuntimeEvent::Exit) {
162 self.is_shutdown_pending = true;
163 }
164
165 self.app.handle_event(ctx, event);
166
167 Ok(())
168 }
169
170 fn handle_keyboard_events(
171 &mut self,
172 key: egui::Key,
173 pressed: bool,
174 modifiers: &egui::Modifiers,
175 _repeat: bool,
176 ) {
177 self.app
178 .handle_keyboard_events(key, pressed, modifiers, false);
179 }
180
181 // pub fn apply_mobile_style(&self, ui: &mut Ui) {
182 // ui.style_mut().text_styles = self.mobile_style.text_styles.clone();
183 // }
184
185 // pub fn apply_default_style(&self, ui: &mut Ui) {
186 // ui.style_mut().text_styles = self.default_style.text_styles.clone();
187 // }
188}