lambda_platform/winit/
mod.rs1use winit::{
4 dpi::{
5 LogicalSize,
6 PhysicalSize,
7 },
8 event::Event,
9 event_loop::{
10 ControlFlow,
11 EventLoop,
12 EventLoopBuilder,
13 EventLoopProxy,
14 EventLoopWindowTarget,
15 },
16 monitor::MonitorHandle,
17 window::{
18 Window,
19 WindowBuilder,
20 },
21};
22
23pub mod winit_exports {
26 pub use winit::{
27 event::{
28 ElementState,
29 Event,
30 MouseButton,
31 VirtualKeyCode,
32 WindowEvent,
33 },
34 event_loop::{
35 ControlFlow,
36 EventLoop,
37 EventLoopProxy,
38 EventLoopWindowTarget,
39 },
40 };
41}
42
43pub struct LoopBuilder;
45
46impl LoopBuilder {
47 pub fn new() -> Self {
48 return Self;
49 }
50
51 pub fn build<Events: 'static + std::fmt::Debug>(self) -> Loop<Events> {
52 let event_loop = EventLoopBuilder::<Events>::with_user_event().build();
53 return Loop { event_loop };
54 }
55}
56
57pub struct Loop<E: 'static + std::fmt::Debug> {
59 event_loop: EventLoop<E>,
60}
61
62pub struct WindowProperties {
64 pub name: String,
65 pub dimensions: (u32, u32),
66 pub monitor_handle: MonitorHandle,
67}
68
69#[derive(Clone, Copy)]
71pub struct WindowSize {
72 pub width: u32,
73 pub height: u32,
74 pub logical: LogicalSize<u32>,
75 pub physical: PhysicalSize<u32>,
76}
77
78pub struct WindowHandle {
79 pub window_handle: Window,
80 pub size: WindowSize,
81 pub monitor_handle: MonitorHandle,
82}
83
84pub struct WindowHandleBuilder {
86 window_handle: Option<Window>,
87 size: WindowSize,
88 monitor_handle: Option<MonitorHandle>,
89}
90
91impl WindowHandleBuilder {
92 pub fn new() -> Self {
94 let logical: LogicalSize<u32> = [0, 0].into();
96 let physical = logical.to_physical(1.0);
97 let size = WindowSize {
98 width: 0,
99 height: 0,
100 logical,
101 physical,
102 };
103
104 return Self {
105 window_handle: None,
106 size,
107 monitor_handle: None,
108 };
109 }
110
111 fn with_window_size(
113 mut self,
114 window_size: (u32, u32),
115 scale_factor: f64,
116 ) -> Self {
117 let logical: LogicalSize<u32> = window_size.into();
118 let physical: PhysicalSize<u32> = logical.to_physical(scale_factor);
119 let (width, height) = window_size;
120
121 let window_size = WindowSize {
122 width,
123 height,
124 logical,
125 physical,
126 };
127
128 self.size = window_size;
129 return self;
130 }
131
132 pub fn with_window_properties<E: 'static + std::fmt::Debug>(
134 mut self,
135 window_properties: WindowProperties,
136 lambda_loop: &Loop<E>,
137 ) -> Self {
138 let WindowProperties {
139 name,
140 dimensions,
141 monitor_handle,
142 } = window_properties;
143
144 self = self.with_window_size(dimensions, monitor_handle.scale_factor());
146
147 let window_handle = WindowBuilder::new()
148 .with_title(name)
149 .with_inner_size(self.size.logical)
150 .build(&lambda_loop.event_loop)
151 .expect("Failed creation of window handle");
152
153 self.monitor_handle = Some(monitor_handle);
154 self.window_handle = Some(window_handle);
155 return self;
156 }
157
158 pub fn build(self) -> WindowHandle {
160 return WindowHandle {
161 monitor_handle: self
162 .monitor_handle
163 .expect("Unable to find a MonitorHandle."),
164 size: self.size,
165 window_handle: self.window_handle.expect("Unable to find WindowHandle."),
166 };
167 }
168}
169
170pub struct LoopPublisher<E: 'static> {
172 winit_proxy: EventLoopProxy<E>,
173}
174
175impl<E: 'static + std::fmt::Debug> LoopPublisher<E> {
176 #[inline]
178 pub fn new(lambda_loop: &Loop<E>) -> Self {
179 let winit_proxy = lambda_loop.event_loop.create_proxy();
180 return LoopPublisher { winit_proxy };
181 }
182
183 #[inline]
185 pub fn publish_event(&self, event: E) {
186 self
187 .winit_proxy
188 .send_event(event)
189 .expect("Failed to send event");
190 }
191}
192
193impl<E: 'static + std::fmt::Debug> Loop<E> {
194 pub fn create_event_publisher(&mut self) -> LoopPublisher<E> {
196 return LoopPublisher::new(&self);
197 }
198
199 pub fn get_primary_monitor(&self) -> Option<MonitorHandle> {
201 return self.event_loop.primary_monitor();
202 }
203
204 pub fn get_all_monitors(&self) -> impl Iterator<Item = MonitorHandle> {
206 return self.event_loop.available_monitors();
207 }
208
209 pub fn get_any_available_monitors(&self) -> Option<MonitorHandle> {
211 return self.event_loop.available_monitors().next();
212 }
213
214 pub fn run_forever<Callback>(self, callback: Callback)
216 where
217 Callback: 'static
218 + FnMut(Event<E>, &EventLoopWindowTarget<E>, &mut ControlFlow) -> (),
219 {
220 self.event_loop.run(callback);
221 }
222}