1use winit::{event, event_loop::EventLoopProxy};
2
3#[cfg(feature = "software")]
4use crate::software::PixelBufferInner;
5
6use crate::{
7 gpu::GPUInner, math::Point2, runner::{CursorIcon, Handle, Runner, RunnerError, WindowEvent}, utils::{ArcMut, ArcRef}
8};
9
10#[derive(Clone, Debug)]
11pub struct Window {
12 pub(crate) inner: ArcRef<WindowInner>,
13}
14
15impl Window {
16 pub(crate) fn new(
17 runner: &mut Runner,
18 parent: Option<&Window>,
19 title: String,
20 size: Point2,
21 pos: Option<Point2>,
22 ) -> Result<Self, WindowError> {
23 let parent_id = if let Some(parent) = parent {
24 Some(parent.inner.wait_borrow().window_id)
25 } else {
26 None
27 };
28
29 let result = runner.internal_new_window(parent_id, title, size, pos);
30 if result.is_err() {
31 return Err(WindowError::RunnerError(result.unwrap_err()));
32 }
33
34 let (window_id, proxy) = result.unwrap();
35 let window_events = runner.get_events_pointer(window_id);
36 let window_pointer = runner.get_window_pointer(window_id);
37
38 if window_events.is_none() || window_pointer.is_none() {
39 return Err(WindowError::WindowNotFound);
40 }
41
42 let window_events = window_events.unwrap();
43 let window_pointer = window_pointer.unwrap();
44
45 let inner = ArcRef::new(WindowInner {
46 window_id,
47 window_events,
48 window_pointer: Some(window_pointer),
49 proxy,
50 graphics: None,
51 size: size.into(),
52
53 #[cfg(feature = "software")]
54 pixelbuffer: None,
55 });
56
57 runner.window_events_attributes.push(inner.clone());
58
59 Ok(Self { inner })
60 }
61
62 pub fn id(&self) -> usize {
67 self.inner.wait_borrow().window_id
68 }
69
70 pub fn size(&self) -> Point2 {
75 self.inner.wait_borrow().size
76 }
77
78 pub fn quit(&self) {
80 let inner = self.inner.wait_borrow();
81
82 _ = inner.proxy.send_event(WindowEvent::Close {
83 ref_id: inner.window_id,
84 });
85 }
86
87 pub fn set_title(&mut self, title: &str) {
89 let inner = self.inner.wait_borrow();
90
91 _ = inner.proxy.send_event(WindowEvent::Title {
92 ref_id: inner.window_id,
93 title: title.to_string(),
94 });
95 }
96
97 pub fn set_cursor(&mut self, cursor: Option<CursorIcon>) {
99 let inner = self.inner.wait_borrow();
100
101 _ = inner.proxy.send_event(WindowEvent::Cursor {
102 ref_id: inner.window_id,
103 cursor,
104 });
105 }
106
107 pub fn set_size(&mut self, size: Point2) {
109 let inner = self.inner.wait_borrow();
110
111 _ = inner.proxy.send_event(WindowEvent::Size {
112 ref_id: inner.window_id,
113 size: size.into(),
114 });
115 }
116
117 pub fn set_position(&mut self, pos: Point2) {
119 let inner = self.inner.wait_borrow();
120
121 _ = inner.proxy.send_event(WindowEvent::Position {
122 ref_id: inner.window_id,
123 pos: pos.into(),
124 });
125 }
126
127 pub fn request_redraw(&mut self) {
129 let inner = self.inner.wait_borrow();
130
131 _ = inner.proxy.send_event(WindowEvent::Redraw {
132 ref_id: inner.window_id,
133 });
134 }
135}
136
137pub struct WindowBuilder<'a> {
138 runner: &'a mut Runner,
139 parent_window: Option<&'a Window>,
140 title: String,
141 size: Point2,
142 pos: Option<Point2>,
143}
144
145impl<'a> WindowBuilder<'a> {
146 pub(crate) fn new(runner: &'a mut Runner, title: &str, size: Point2) -> Self {
147 WindowBuilder {
148 runner,
149 parent_window: None,
150 title: title.to_string(),
151 size,
152 pos: None,
153 }
154 }
155
156 pub fn title(mut self, title: String) -> Self {
158 self.title = title;
159 self
160 }
161
162 pub fn size(mut self, size: Point2) -> Self {
164 self.size = size;
165 self
166 }
167
168 pub fn pos(mut self, pos: Option<Point2>) -> Self {
170 self.pos = pos;
171 self
172 }
173
174 pub fn with_parent_window(mut self, parent: &'a Window) -> Self {
178 self.parent_window = Some(parent);
179 self
180 }
181
182 pub fn build(self) -> Result<Window, WindowError> {
183 Window::new(
184 self.runner,
185 self.parent_window,
186 self.title,
187 self.size,
188 self.pos,
189 )
190 }
191}
192
193pub(crate) struct WindowInner {
194 pub window_id: usize,
195 pub window_events: ArcRef<Vec<event::WindowEvent>>,
196 pub window_pointer: Option<ArcMut<Handle>>,
197 pub proxy: EventLoopProxy<WindowEvent>,
198 pub size: Point2,
199
200 pub(crate) graphics: Option<ArcRef<GPUInner>>,
201
202 #[cfg(feature = "software")]
203 pub(crate) pixelbuffer: Option<ArcRef<PixelBufferInner>>,
204}
205
206impl WindowInner {
207 pub fn process_event(&mut self) {
208 for event in self.window_events.wait_borrow_mut().iter() {
209 match event {
210 event::WindowEvent::CloseRequested => {
211 self.graphics = None;
212 self.window_pointer = None;
213 }
214 event::WindowEvent::Resized(size) => {
215 if let Some(gpu) = &self.graphics {
216 gpu.wait_borrow_mut().resize(*size);
217 }
218
219 #[cfg(feature = "software")]
220 if let Some(softbuffer) = &self.pixelbuffer {
221 _ = softbuffer.wait_borrow_mut().resize(*size);
222 }
223
224 self.size = Point2::from(*size);
225 }
226 _ => {}
227 }
228 }
229 }
230
231 pub fn cycle(&mut self) {
232 if let Some(gpu) = &self.graphics {
233 gpu.wait_borrow_mut().cycle();
234 }
235 }
236}
237
238
239#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
240pub enum RunMode {
241 Poll,
242 ReDraw,
243}
244
245#[derive(Clone, Debug, Eq, Hash, PartialEq)]
246pub enum WindowError {
247 RunnerError(RunnerError),
248 WindowNotFound,
249}