makepad_platform/os/windows/
windows.rs1use {
2 std::{
3 rc::Rc,
4 cell::RefCell,
5 },
6 crate::{
7 makepad_live_id::*,
8 cx::*,
9 event::*,
10 thread::Signal,
11 os::{
12 windows::{
13 windows_media::CxWindowsMedia,
14 windows_decoding::CxWindowsDecoding,
15 win32_event::*,
16 d3d11::{D3d11Window, D3d11Cx},
17 win32_app::*,
18 },
19 cx_native::EventFlow,
20 },
21 pass::CxPassParent,
22 cx_api::{CxOsApi, CxOsOp},
23 window::CxWindowPool,
24 windows::Win32::Graphics::Direct3D11::ID3D11Device,
25 }
26};
27
28impl Cx {
29
30 pub fn event_loop(cx: Rc<RefCell<Cx >>) {
31
32 cx.borrow_mut().self_ref = Some(cx.clone());
33 cx.borrow_mut().os_type = OsType::Windows;
34
35 let d3d11_cx = Rc::new(RefCell::new(D3d11Cx::new()));
36
37 cx.borrow_mut().os.d3d11_device = Some(d3d11_cx.borrow().device.clone());
39
40 for arg in std::env::args() {
41 if arg == "--stdin-loop" {
42 let mut cx = cx.borrow_mut();
43 cx.in_makepad_studio = true;
44 let mut d3d11_cx = d3d11_cx.borrow_mut();
45 return cx.stdin_event_loop(&mut d3d11_cx);
46 }
47 }
48
49 let d3d11_windows = Rc::new(RefCell::new(Vec::new()));
50
51 init_win32_app_global(Box::new({
52 let cx = cx.clone();
53 move | event | {
54 get_win32_app_global();
55 let mut cx = cx.borrow_mut();
56 let mut d3d11_cx = d3d11_cx.borrow_mut();
57 let mut d3d11_windows = d3d11_windows.borrow_mut();
58 cx.win32_event_callback(event, &mut d3d11_cx, &mut d3d11_windows)
59 }
60 }));
61
62 cx.borrow_mut().call_event_handler(&Event::Construct);
63 cx.borrow_mut().redraw_all();
64 get_win32_app_global().start_signal_poll();
65 Win32App::event_loop();
66 }
67
68 fn win32_event_callback(
69 &mut self,
70 event: Win32Event,
71 d3d11_cx: &mut D3d11Cx,
72 d3d11_windows: &mut Vec<D3d11Window>
73 ) -> EventFlow {
74 if let EventFlow::Exit = self.handle_platform_ops(d3d11_windows, d3d11_cx) {
75 return EventFlow::Exit
76 }
77
78 let mut paint_dirty = false;
79
80 match event {
82 Win32Event::AppGotFocus => { for window in d3d11_windows.iter_mut() {
84 if let Some(main_pass_id) = self.windows[window.window_id].main_pass_id {
85 self.repaint_pass(main_pass_id);
86 }
87 }
88 paint_dirty = true;
89 self.call_event_handler(&Event::AppGotFocus);
90 }
91 Win32Event::AppLostFocus => {
92 self.call_event_handler(&Event::AppLostFocus);
93 }
94 Win32Event::WindowResizeLoopStart(window_id) => {
95 if let Some(window) = d3d11_windows.iter_mut().find( | w | w.window_id == window_id) {
96 window.start_resize();
97 }
98 }
99 Win32Event::WindowResizeLoopStop(window_id) => {
100 if let Some(window) = d3d11_windows.iter_mut().find( | w | w.window_id == window_id) {
101 window.stop_resize();
102 }
103 }
104 Win32Event::WindowGeomChange(re) => { if let Some(window) = d3d11_windows.iter_mut().find( | w | w.window_id == re.window_id) {
107 window.window_geom = re.new_geom.clone();
108 self.windows[re.window_id].window_geom = re.new_geom.clone();
109 if re.old_geom.inner_size != re.new_geom.inner_size {
111
112 if let Some(main_pass_id) = self.windows[re.window_id].main_pass_id {
113 self.redraw_pass_and_child_passes(main_pass_id);
114 }
115 }
116 }
117 self.redraw_all();
119 self.call_event_handler(&Event::WindowGeomChange(re));
120 }
121 Win32Event::WindowClosed(wc) => {
122 let window_id = wc.window_id;
123 self.call_event_handler(&Event::WindowClosed(wc));
124 self.windows[window_id].is_created = false;
126 if let Some(index) = d3d11_windows.iter().position( | w | w.window_id == window_id) {
127 d3d11_windows.remove(index);
128 if d3d11_windows.len() == 0 {
129 self.call_event_handler(&Event::Destruct);
130 return EventFlow::Exit
131 }
132 }
133 }
134 Win32Event::Paint => {
135 if self.new_next_frames.len() != 0 {
136 self.call_next_frame_event(get_win32_app_global().time_now());
137 }
138 if self.need_redrawing() {
139 self.call_draw_event();
140 self.hlsl_compile_shaders(&d3d11_cx);
141 }
142 self.handle_repaint(d3d11_windows, d3d11_cx);
145 }
146 Win32Event::MouseDown(e) => {
147 self.fingers.process_tap_count(
148 e.abs,
149 e.time
150 );
151 self.fingers.mouse_down(e.button);
152 self.call_event_handler(&Event::MouseDown(e.into()))
153 }
154 Win32Event::MouseMove(e) => {
155 self.call_event_handler(&Event::MouseMove(e.into()));
156 self.fingers.cycle_hover_area(live_id!(mouse).into());
157 self.fingers.switch_captures();
158 }
159 Win32Event::MouseUp(e) => {
160
161 let button = e.button;
162 self.call_event_handler(&Event::MouseUp(e.into()));
163 self.fingers.mouse_up(button);
164 self.fingers.cycle_hover_area(live_id!(mouse).into());
165 }
166 Win32Event::Scroll(e) => {
167 self.call_event_handler(&Event::Scroll(e.into()))
168 }
169 Win32Event::WindowDragQuery(e) => {
170 self.call_event_handler(&Event::WindowDragQuery(e))
171 }
172 Win32Event::WindowCloseRequested(e) => {
173 self.call_event_handler(&Event::WindowCloseRequested(e))
174 }
175 Win32Event::TextInput(e) => {
176 self.call_event_handler(&Event::TextInput(e))
177 }
178 Win32Event::Drag(e) => {
179 self.call_event_handler(&Event::Drag(e));
180 self.drag_drop.cycle_drag();
181 },
182 Win32Event::Drop(e) => {
183 self.call_event_handler(&Event::Drop(e));
184 self.drag_drop.cycle_drag();
185 },
186 Win32Event::DragEnd => {
187 self.call_event_handler(&Event::MouseUp(MouseUpEvent {
189 abs: dvec2(-100000.0, -100000.0),
190 button: 0,
191 window_id: CxWindowPool::id_zero(),
192 modifiers: Default::default(),
193 time: 0.0
194 }));
195 self.fingers.mouse_up(0);
196 self.fingers.cycle_hover_area(live_id!(mouse).into());
197 }
198 Win32Event::KeyDown(e) => {
199 self.keyboard.process_key_down(e.clone());
200 self.call_event_handler(&Event::KeyDown(e))
201 }
202 Win32Event::KeyUp(e) => {
203 self.keyboard.process_key_up(e.clone());
204 self.call_event_handler(&Event::KeyUp(e))
205 }
206 Win32Event::TextCopy(e) => {
207 self.call_event_handler(&Event::TextCopy(e))
208 }
209 Win32Event::TextCut(e) => {
210 self.call_event_handler(&Event::TextCut(e))
211 }
212 Win32Event::Timer(e) => {
213 self.call_event_handler(&Event::Timer(e))
214 }
215 Win32Event::Signal => {
216 if Signal::check_and_clear_ui_signal() {
217 self.handle_media_signals();
218 self.call_event_handler(&Event::Signal);
219 }
220 }
221 }
222
223 if self.any_passes_dirty() || self.need_redrawing() || self.new_next_frames.len() != 0 || paint_dirty {
224 EventFlow::Poll
225 } else {
226 EventFlow::Wait
227 }
228
229 }
230
231 pub (crate) fn handle_repaint(&mut self, d3d11_windows: &mut Vec<D3d11Window>, d3d11_cx: &mut D3d11Cx) {
232 let mut passes_todo = Vec::new();
233 self.compute_pass_repaint_order(&mut passes_todo);
234 self.repaint_id += 1;
235 for pass_id in &passes_todo {
236 self.passes[*pass_id].set_time(get_win32_app_global().time_now() as f32);
237 match self.passes[*pass_id].parent.clone() {
238 CxPassParent::Window(window_id) => {
239 if let Some(window) = d3d11_windows.iter_mut().find( | w | w.window_id == window_id) {
240 window.resize_buffers(&d3d11_cx);
242 self.draw_pass_to_window(*pass_id, true, window, d3d11_cx);
243 }
244 }
245 CxPassParent::Pass(_) => {
246 self.draw_pass_to_magic_texture(*pass_id, d3d11_cx);
248 },
249 CxPassParent::None => {
250 self.draw_pass_to_magic_texture(*pass_id, d3d11_cx);
251 }
252 }
253 }
254 }
255
256 pub (crate) fn handle_networking_events(&mut self) {
257 }
258
259 fn handle_platform_ops(&mut self, d3d11_windows: &mut Vec<D3d11Window>, d3d11_cx: &D3d11Cx) -> EventFlow {
260 let mut ret = EventFlow::Poll;
261 while let Some(op) = self.platform_ops.pop() {
262 match op {
263 CxOsOp::CreateWindow(window_id) => {
264 let window = &mut self.windows[window_id];
265 let d3d11_window = D3d11Window::new(
266 window_id,
267 &d3d11_cx,
268 window.create_inner_size.unwrap_or(dvec2(800., 600.)),
269 window.create_position,
270 &window.create_title
271 );
272
273 window.window_geom = d3d11_window.window_geom.clone();
274 d3d11_windows.push(d3d11_window);
275 window.is_created = true;
276 },
277 CxOsOp::CloseWindow(window_id) => {
278 if let Some(index) = d3d11_windows.iter().position( | w | w.window_id == window_id) {
279 self.windows[window_id].is_created = false;
280 d3d11_windows[index].win32_window.close_window();
281 d3d11_windows.remove(index);
282 if d3d11_windows.len() == 0 {
283 ret = EventFlow::Exit
284 }
285 }
286 },
287 CxOsOp::MinimizeWindow(window_id) => {
288 if let Some(window) = d3d11_windows.iter_mut().find( | w | w.window_id == window_id) {
289 window.win32_window.minimize();
290 }
291 },
292 CxOsOp::MaximizeWindow(window_id) => {
293 if let Some(window) = d3d11_windows.iter_mut().find( | w | w.window_id == window_id) {
294 window.win32_window.maximize();
295 }
296 },
297 CxOsOp::RestoreWindow(window_id) => {
298 if let Some(window) = d3d11_windows.iter_mut().find( | w | w.window_id == window_id) {
299 window.win32_window.restore();
300 }
301 },
302 CxOsOp::Quit=>{
303 ret = EventFlow::Exit
304 }
305 CxOsOp::FullscreenWindow(_window_id) => {
306 todo!()
307 },
308 CxOsOp::NormalizeWindow(_window_id) => {
309 todo!()
310 }
311 CxOsOp::SetTopmost(_window_id, _is_topmost) => {
312 todo!()
313 }
314 CxOsOp::ShowClipboardActions(_) => {
315 }
316 CxOsOp::XrStartPresenting => {
317 },
319 CxOsOp::XrStopPresenting => {
320 },
322 CxOsOp::ShowTextIME(_area, _pos) => {
323 }
325 CxOsOp::HideTextIME => {
326 },
328 CxOsOp::SetCursor(cursor) => {
329 get_win32_app_global().set_mouse_cursor(cursor);
330 },
331 CxOsOp::StartTimer {timer_id, interval, repeats} => {
332 get_win32_app_global().start_timer(timer_id, interval, repeats);
333 },
334 CxOsOp::StopTimer(timer_id) => {
335 get_win32_app_global().stop_timer(timer_id);
336 },
337 CxOsOp::StartDragging(dragged_item) => {
338 get_win32_app_global().start_dragging(dragged_item);
339 },
340 CxOsOp::UpdateMacosMenu(_menu) => {
341 },
342 CxOsOp::HttpRequest {request_id: _, request: _} => {
343 },
345 CxOsOp::WebSocketOpen {request_id: _, request: _,} => {
346 }
348 CxOsOp::WebSocketSendBinary {request_id: _, data: _} => {
349 }
351 CxOsOp::WebSocketSendString {request_id: _, data: _} => {
352 },
354 CxOsOp::InitializeVideoDecoding(_, _, _) => todo!(),
355 CxOsOp::DecodeNextVideoChunk(_, _) => todo!(),
356 CxOsOp::FetchNextVideoFrames(_, _) => todo!(),
357 CxOsOp::CleanupVideoDecoding(_) => todo!(),
358 }
359 }
360 ret
361 }
362}
363
364impl CxOsApi for Cx {
365 fn init_cx_os(&mut self) {
366 self.live_expand();
367 self.live_scan_dependencies();
368 self.native_load_dependencies();
369 }
370
371 fn spawn_thread<F>(&mut self, f: F) where F: FnOnce() + Send + 'static {
372 std::thread::spawn(f);
373 }
374}
375
376#[derive(Default)]
377pub struct CxOs {
378 pub (crate) media: CxWindowsMedia,
379 pub (crate) d3d11_device: Option<ID3D11Device>,
380 pub (crate) decoding: CxWindowsDecoding,
381 pub (crate) new_frame_being_rendered: Option<crate::cx_stdin::PresentableDraw>,
382}