orinium_browser/platform/system/
app.rs

1//! Manages the application lifecycle, including window creation and event handling.
2
3use 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        // 初回描画
105        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}