orinium_browser/platform/system/
app.rs1use std::collections::HashMap;
4use std::sync::Arc;
5use winit::application::ApplicationHandler;
6use winit::event::WindowEvent;
7use winit::event_loop::ActiveEventLoop;
8use winit::window::{Window, WindowId};
9
10use crate::browser::{BrowserApp, BrowserCommand};
11use crate::platform::renderer::gpu::GpuRenderer;
12
13pub struct WindowState {
14 pub window: Arc<Window>,
15 pub gpu_renderer: GpuRenderer,
16}
17
18pub struct App {
19 windows: HashMap<WindowId, WindowState>,
20 browser_app: BrowserApp,
21}
22
23impl App {
24 pub fn new(browser_app: BrowserApp) -> Self {
25 Self {
26 windows: HashMap::new(),
27 browser_app,
28 }
29 }
30
31 fn open_new_window(&mut self, event_loop: &ActiveEventLoop, tab_id: usize) {
32 let default_size = self.browser_app.default_window_size();
33 let default_title = self.browser_app.default_window_title();
34 let window = Arc::new(
35 event_loop
36 .create_window(
37 Window::default_attributes()
38 .with_inner_size(winit::dpi::PhysicalSize::new(
39 default_size.0,
40 default_size.1,
41 ))
42 .with_title(&default_title),
43 )
44 .unwrap(),
45 );
46 let window_id = window.id();
47 let scale_factor = window.scale_factor();
48 let gpu_renderer = pollster::block_on(GpuRenderer::new(window.clone(), None)).unwrap();
49
50 self.browser_app.open_window(
51 window_id,
52 (default_size.0 as u32, default_size.1 as u32),
53 default_title,
54 scale_factor,
55 tab_id,
56 );
57
58 let mut state = WindowState {
59 window,
60 gpu_renderer,
61 };
62
63 self.browser_app
64 .apply_draw_commands(window_id, &mut state.gpu_renderer);
65 state.window.request_redraw();
66
67 self.windows.insert(window_id, state);
68 }
69}
70
71impl ApplicationHandler for App {
72 fn resumed(&mut self, event_loop: &ActiveEventLoop) {
73 let default_size = self.browser_app.default_window_size();
74 let default_title = self.browser_app.default_window_title();
75 let window = Arc::new(
76 event_loop
77 .create_window(
78 Window::default_attributes()
79 .with_inner_size(winit::dpi::PhysicalSize::new(
80 default_size.0,
81 default_size.1,
82 ))
83 .with_title(&default_title),
84 )
85 .unwrap(),
86 );
87 let window_id = window.id();
88 let scale_factor = window.scale_factor();
89 let gpu_renderer = pollster::block_on(GpuRenderer::new(window.clone(), None)).unwrap();
90
91 self.browser_app.open_window(
92 window_id,
93 (default_size.0 as u32, default_size.1 as u32),
94 default_title,
95 scale_factor,
96 0,
97 );
98
99 let mut state = WindowState {
100 window,
101 gpu_renderer,
102 };
103
104 self.browser_app
106 .apply_draw_commands(window_id, &mut state.gpu_renderer);
107 state.window.request_redraw();
108
109 self.windows.insert(window_id, state);
110 }
111
112 fn window_event(
113 &mut self,
114 event_loop: &ActiveEventLoop,
115 window_id: WindowId,
116 event: WindowEvent,
117 ) {
118 if !self.windows.contains_key(&window_id) {
119 return;
120 }
121
122 let cmd = {
123 let state = self.windows.get_mut(&window_id).unwrap();
124 self.browser_app
125 .handle_window_event(window_id, event, &mut state.gpu_renderer)
126 };
127
128 match cmd {
129 BrowserCommand::Exit => {
130 self.windows.remove(&window_id);
131 self.browser_app.close_window(window_id);
132 if self.windows.is_empty() {
133 event_loop.exit();
134 }
135 }
136 BrowserCommand::RequestRedraw => {
137 if let Some(state) = self.windows.get(&window_id) {
138 state.window.request_redraw();
139 state
140 .window
141 .set_title(&self.browser_app.window_title(window_id));
142 }
143 }
144 BrowserCommand::RenameWindowTitle => {
145 if let Some(state) = self.windows.get(&window_id) {
146 state
147 .window
148 .set_title(&self.browser_app.window_title(window_id));
149 }
150 }
151 BrowserCommand::OpenNewWindow { tab_id } => {
152 self.open_new_window(event_loop, tab_id);
153 }
154 BrowserCommand::None => {}
155 }
156 }
157}