1+ mod sb_window;
2+
13use std:: num:: NonZeroU32 ;
4+ pub use sb_window:: SoftbufferWindow ;
5+
26use std:: rc:: Rc ;
37
48use softbuffer:: Surface ;
@@ -7,9 +11,12 @@ use winit::dpi::PhysicalSize;
711use winit:: error:: EventLoopError ;
812use winit:: event:: WindowEvent ;
913use winit:: event_loop:: { ActiveEventLoop , ControlFlow , EventLoop } ;
10- use winit:: window:: { Window , WindowId } ;
14+ use winit:: window:: { Window } ;
15+
16+ pub type RawWindow = Option < Rc < Window > > ;
17+ pub type RawSurface = Option < Surface < Rc < Window > , Rc < Window > > > ;
1118
12- /// Contains a few potential properties to set for a SoftbufferWindow when it is created.
19+ /// Simple struct that holds some properties (size, title) for windows
1320pub struct WindowProperties {
1421 /// Initial width
1522 pub width : u32 ,
@@ -20,6 +27,7 @@ pub struct WindowProperties {
2027}
2128
2229impl Default for WindowProperties {
30+ /// Creates an 800x600 window named "Softbuffer Window"
2331 fn default ( ) -> WindowProperties {
2432 WindowProperties {
2533 width : 800 ,
@@ -29,118 +37,74 @@ impl Default for WindowProperties {
2937 }
3038}
3139
32- /// Wrapper for Softbuffer and a Winit window
33- pub struct SoftbufferWindow {
34- window : Option < Rc < Window > > ,
35- loop_fn : Option < Box < dyn FnMut ( & mut SoftbufferWindow , WindowEvent ) > > ,
36- surface : Option < Surface < Rc < Window > , Rc < Window > > > ,
37- properties : WindowProperties ,
40+ /// Shorthand to run a struct that implements `ApplicationHandler`
41+ pub fn run < A : ApplicationHandler < ( ) > > ( window : & mut A ) -> Result < ( ) , EventLoopError > {
42+ let event_loop = EventLoop :: new ( ) ?;
43+ event_loop. set_control_flow ( ControlFlow :: Poll ) ;
44+ event_loop. run_app ( window)
3845}
3946
40- impl ApplicationHandler for SoftbufferWindow {
41- fn resumed ( & mut self , event_loop : & ActiveEventLoop ) {
42- let window = {
43- let window = event_loop. create_window (
44- Window :: default_attributes ( )
45- . with_title ( self . properties . title )
46- . with_inner_size ( PhysicalSize :: new (
47- self . properties . width ,
48- self . properties . height ,
49- ) ) ,
50- ) ;
51- Rc :: new ( window. unwrap ( ) )
52- } ;
53- let context = softbuffer:: Context :: new ( window. clone ( ) ) . unwrap ( ) ;
54- self . window = Some ( window. clone ( ) ) ;
55- self . surface = Some ( Surface :: new ( & context, window. clone ( ) ) . unwrap ( ) ) ;
56- }
57-
58- fn window_event ( & mut self , event_loop : & ActiveEventLoop , _id : WindowId , event : WindowEvent ) {
59- // Automatic event handling
60- match event {
61- WindowEvent :: CloseRequested => {
62- event_loop. exit ( ) ;
63- }
64- WindowEvent :: Resized ( size) => {
65- self . surface
66- . as_mut ( )
67- . unwrap ( )
68- . resize (
69- NonZeroU32 :: new ( size. width ) . unwrap ( ) ,
70- NonZeroU32 :: new ( size. height ) . unwrap ( ) ,
71- )
72- . unwrap ( ) ;
73- }
74- _ => ( ) ,
75- }
76-
77- let is_redraw_requested = event == WindowEvent :: RedrawRequested ;
78-
79- // User event handling
80- if self . loop_fn . is_some ( ) {
81- let mut loop_fn = self . loop_fn . take ( ) . unwrap ( ) ;
82- loop_fn ( self , event) ;
83- self . loop_fn = Some ( loop_fn) ;
84- }
85-
86- // Displays buffer automatically if event is RedrawRequested
87- if is_redraw_requested {
88- self . surface
89- . as_mut ( )
90- . unwrap ( )
91- . buffer_mut ( )
92- . unwrap ( )
93- . present ( )
94- . unwrap ( ) ;
95- self . window . as_ref ( ) . unwrap ( ) . request_redraw ( ) ;
96- }
97- }
47+ /// Initialises and returns a new RawWindow and RawSurface given an `ActiveEventLoop` and `WindowProperties`.
48+ /// For instance, implementation within `ApplicationHandler::resumed` may look like:
49+ /// ```rust
50+ /// //...
51+ /// fn resumed(&mut self, event_loop: &ActiveEventLoop) {
52+ /// (self.window, self.surface) = init(event_loop, &self.properties);
53+ /// }
54+ /// //...
55+ /// ```
56+ pub fn init ( event_loop : & ActiveEventLoop , properties : & WindowProperties ) -> ( RawWindow , RawSurface ) {
57+ let window = {
58+ let window = event_loop. create_window (
59+ Window :: default_attributes ( )
60+ . with_title ( properties. title )
61+ . with_inner_size ( PhysicalSize :: new (
62+ properties. width ,
63+ properties. height ,
64+ ) ) ,
65+ ) ;
66+ Rc :: new ( window. unwrap ( ) )
67+ } ;
68+ let context = softbuffer:: Context :: new ( window. clone ( ) ) . unwrap ( ) ;
69+ let window : RawWindow = Some ( window. clone ( ) ) ;
70+ let surface : RawSurface = Some ( Surface :: new ( & context, window. clone ( ) . unwrap ( ) ) . unwrap ( ) ) ;
71+ ( window, surface)
9872}
9973
100- impl SoftbufferWindow {
101- /// Creates a new SoftbufferWindow.
102- /// Example usage:
103- /// ```rust
104- /// let window = SoftbufferWindow::new(WindowProperties::default());
105- /// ```
106- pub fn new ( properties : WindowProperties ) -> Self {
107- SoftbufferWindow {
108- window : None ,
109- loop_fn : None ,
110- surface : None ,
111- properties,
112- }
113- }
114-
115- /// Runs a SoftbufferWindow event loop.
116- /// To handle events, you need winit's `WindowEvent` enum.
117- /// Example usage:
118- /// ```rust
119- /// window.run(move |window, event| {
120- /// match event {
121- /// WindowEvent::RedrawRequested => (),
122- /// _ => ()
123- /// }
124- /// });
125- /// ```
126- pub fn run (
127- & mut self ,
128- event_fn : impl FnMut ( & mut SoftbufferWindow , WindowEvent ) + ' static ,
129- ) -> Result < ( ) , EventLoopError > {
130- self . loop_fn = Some ( Box :: new ( event_fn) ) ;
131- let event_loop = EventLoop :: new ( ) . unwrap ( ) ;
132- event_loop. set_control_flow ( ControlFlow :: Poll ) ;
133- event_loop. run_app ( self )
74+ /// Shorthand to listen for and handle WindowEvent::CloseRequested by closing windows
75+ pub fn close ( event_loop : & ActiveEventLoop , event : & WindowEvent ) {
76+ if let WindowEvent :: CloseRequested = event {
77+ event_loop. exit ( ) ;
13478 }
79+ }
13580
136- /// Returns the size of a window as a tuple
137- pub fn inner_size ( & mut self ) -> ( usize , usize ) {
138- let size = self . window . clone ( ) . unwrap ( ) . inner_size ( ) ;
139- ( size. width as usize , size. height as usize )
81+ /// Shorthand to listen for and handle WindowEvent::Resized by resizing a buffer
82+ pub fn resize ( event : & WindowEvent , surface : & mut RawSurface ) {
83+ if let WindowEvent :: Resized ( size) = event {
84+ surface
85+ . as_mut ( )
86+ . unwrap ( )
87+ . resize (
88+ NonZeroU32 :: new ( size. width ) . unwrap ( ) ,
89+ NonZeroU32 :: new ( size. height ) . unwrap ( ) ,
90+ )
91+ . unwrap ( ) ;
14092 }
93+ }
14194
142- /// Gets a mutable reference to the buffer
143- pub fn buffer_mut ( & mut self ) -> softbuffer:: Buffer < ' _ , Rc < Window > , Rc < Window > > {
144- self . surface . as_mut ( ) . unwrap ( ) . buffer_mut ( ) . unwrap ( )
145- }
95+ /// Redraws a RawSurface. Call this on `Window::RedrawRequested`.
96+ pub fn redraw ( window : & mut RawWindow , surface : & mut RawSurface ) {
97+ surface
98+ . as_mut ( )
99+ . unwrap ( )
100+ . buffer_mut ( )
101+ . unwrap ( )
102+ . present ( )
103+ . unwrap ( ) ;
104+ window. as_ref ( ) . unwrap ( ) . request_redraw ( ) ;
146105}
106+
107+ /// Gets a mutable reference to a buffer from a `RawSurface`
108+ pub fn buffer_mut ( surface : & mut RawSurface ) -> softbuffer:: Buffer < ' _ , Rc < Window > , Rc < Window > > {
109+ surface. as_mut ( ) . unwrap ( ) . buffer_mut ( ) . unwrap ( )
110+ }
0 commit comments