1pub struct App {
2 window: Option<std::sync::Arc<winit::window::Window>>,
3 pixels: Option<pixels::Pixels<'static>>,
4 title: String,
5 width: u32,
6 height: u32,
7 resizable: bool,
8 fullscreen: bool,
9 draw_fn: Option<Box<dyn FnMut(&mut crate::canvas::Canvas)>>,
10}
11
12impl App {
13 pub fn new(title: &str, width: u32, height: u32, resizable: bool, fullscreen: bool) -> Self {
14 Self {
15 window: None,
16 pixels: None,
17 title: title.to_string(),
18 width,
19 height,
20 resizable,
21 fullscreen,
22 draw_fn: None,
23 }
24 }
25
26 pub fn on_draw(&mut self, f: impl FnMut(&mut crate::canvas::Canvas) + 'static) -> &mut Self {
27 self.draw_fn = Some(Box::new(f));
28 self
29 }
30
31 pub fn run(mut self) {
32 let event_loop = winit::event_loop::EventLoop::new().unwrap();
33 event_loop.run_app(&mut self).unwrap();
34 }
35}
36
37impl winit::application::ApplicationHandler for App {
38 fn resumed(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) {
39 let attributes = winit::window::Window::default_attributes()
40 .with_title(self.title.clone())
41 .with_resizable(self.resizable)
42 .with_inner_size(winit::dpi::PhysicalSize::new(self.width, self.height))
43 .with_fullscreen(
44 if self.fullscreen {
45 Some(winit::window::Fullscreen::Borderless(None))
46 }
47 else {
48 None
49 }
50 );
51
52 let window = std::sync::Arc::new(event_loop.create_window(attributes).expect("Failed to create window"));
53
54 let surface_texture = pixels::SurfaceTexture::new(self.width, self.height, window.clone());
55 let pixels = pixels::Pixels::new(self.width, self.height, surface_texture).unwrap();
56
57 self.pixels = Some(pixels);
58 self.window = Some(window);
59 self.window.as_ref().unwrap().request_redraw();
60 }
61
62 fn window_event(
63 &mut self,
64 event_loop: &winit::event_loop::ActiveEventLoop,
65 window_id: winit::window::WindowId,
66 event: winit::event::WindowEvent,
67 )
68 {
69 if let Some(window) = &self.window {
70 if window.id() == window_id {
71 match event {
72 winit::event::WindowEvent::CloseRequested => {
73 event_loop.exit();
74 },
75 winit::event::WindowEvent::RedrawRequested => {
76 if let (Some(pixels), Some(draw_fn)) = (self.pixels.as_mut(), self.draw_fn.as_mut()) {
77 let mut canvas = crate::canvas::Canvas::new(pixels.frame_mut(), self.width, self.height);
78 draw_fn(&mut canvas);
79 pixels.render().unwrap();
80 }
81 self.window.as_ref().unwrap().request_redraw();
82 }
83 _ => {}
84 }
85 }
86 }
87 }
88}