1#[cfg(feature = "dh")]
2use b3_display_handler::{HasWindowHandler, WindowHandler};
3use dpi::{LogicalSize, PhysicalPosition, PhysicalSize, Position, Size};
4
5use crate::{
6 platform::{WindowApi, Wrapper},
7 platform_impl::WindowImpl,
8 ActiveApplication,
9 ContextOwner,
10};
11
12#[derive(Debug, Default, PartialEq, Eq, Clone, Copy)]
14pub struct WindowOptions {
15 pub titled: bool,
17 pub minimizable: bool,
19 pub closable: bool,
21 pub resizable: bool,
23 pub draggable: bool,
25 pub fullscreen: bool,
27 pub borderless: bool,
29}
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
33pub enum InitMode {
34 Default,
36 Minimized,
38 Maximized,
40 Fullscreen,
42}
43
44impl Default for InitMode {
45 fn default() -> Self { Self::Default }
46}
47
48pub type WindowId = usize;
50
51#[derive(Debug)]
53pub struct Window(WindowImpl);
54
55impl Window {
56 pub fn builder() -> WindowBuilder { WindowBuilder::new() }
58
59 fn new(
60 ctx: &impl ContextOwner,
61 mode: InitMode,
62 options: Option<WindowOptions>,
63 size: Option<Size>,
64 ) -> Self {
65 Self(WindowImpl::new(ctx, mode, options, size))
66 }
67
68 pub fn set_title<S>(&mut self, title: S)
73 where
74 S: Into<String>,
75 {
76 self.0.set_title(title.into());
77 }
78
79 pub fn title(&self) -> String { self.0.title() }
81
82 pub fn id(&self) -> WindowId { self.0.id() }
84
85 pub fn set_options(&mut self, options: WindowOptions) { self.0.set_options(options); }
90
91 pub fn options(&self) -> WindowOptions { self.0.options() }
93
94 pub fn show(&mut self, app: &ActiveApplication) { self.0.show(app); }
99
100 pub fn show_modal(&mut self, app: &ActiveApplication) { self.0.show_modal(app); }
105
106 pub fn toggle_fullscreen(&mut self) { self.0.toggle_fullscreen(); }
108
109 pub fn is_fullscreen(&self) -> bool { self.0.is_fullscreen() }
111
112 pub fn set_frame_size(&mut self, size: Size) { self.0.set_frame_size(size); }
117
118 pub fn frame_size(&self) -> PhysicalSize<u32> { self.0.frame_size() }
120
121 pub fn set_position(&mut self, position: Position) { self.0.set_position(position); }
126
127 pub fn position(&self) -> PhysicalPosition<i32> { self.0.position() }
129
130 pub fn set_min_size(&mut self, min_size: Size) { self.0.set_min_size(min_size); }
135
136 pub fn min_size(&self) -> PhysicalSize<u32> { self.0.min_size() }
138
139 pub fn set_max_size(&mut self, max_size: Size) { self.0.set_max_size(max_size); }
144
145 pub fn max_size(&self) -> PhysicalSize<u32> { self.0.max_size() }
147
148 pub fn maximize(&mut self) { self.0.maximize() }
150
151 pub fn is_maximized(&self) -> bool { self.0.is_maximized() }
153
154 pub fn content_size(&self) -> PhysicalSize<u32> { self.0.content_size() }
156
157 pub fn is_visible(&self) -> bool { self.0.is_visible() }
159
160 pub fn close(&mut self) { self.0.close(); }
162
163 pub fn minimize(&mut self) { self.0.minimize(); }
165
166 pub fn is_minimized(&self) -> bool { self.0.is_minimized() }
168
169 pub fn restore(&mut self) { self.0.restore(); }
171
172 pub fn scale_factor(&self) -> f64 { self.0.scale_factor() }
174}
175
176impl Wrapper<WindowImpl> for Window {
177 #[inline]
178 fn get_impl(&self) -> &WindowImpl { &self.0 }
179
180 #[inline]
181 fn get_impl_mut(&mut self) -> &mut WindowImpl { &mut self.0 }
182}
183
184#[cfg(feature = "dh")]
185impl HasWindowHandler for Window {
186 fn window_handler(&self) -> WindowHandler { self.0.window_handler() }
187}
188
189#[derive(Default)]
191pub struct WindowBuilder {
192 title: Option<String>,
193 mode: InitMode,
194 flags: Option<WindowOptions>,
195 size: Option<Size>,
196}
197
198impl WindowBuilder {
199 #[inline]
200 fn new() -> Self {
201 Self {
202 ..Default::default()
203 }
204 }
205
206 pub fn with_title<S>(mut self, title: S) -> WindowBuilder
211 where
212 S: Into<String>,
213 {
214 self.title = Some(title.into());
215 self
216 }
217
218 pub fn with_init_mode(mut self, mode: InitMode) -> WindowBuilder {
223 self.mode = mode;
224 self
225 }
226
227 pub fn with_size(mut self, size: Size) -> WindowBuilder {
232 self.size = Some(size);
233 self
234 }
235
236 pub fn with_logical_size<S>(mut self, size: S) -> WindowBuilder
241 where
242 S: Into<LogicalSize<f64>>,
243 {
244 self.size = Some(Size::Logical(size.into()));
245 self
246 }
247
248 pub fn with_physical_size<S>(mut self, size: S) -> WindowBuilder
253 where
254 S: Into<PhysicalSize<u32>>,
255 {
256 self.size = Some(Size::Physical(size.into()));
257 self
258 }
259
260 pub fn with_options(mut self, options: WindowOptions) -> WindowBuilder {
265 self.flags = Some(options);
266 self
267 }
268
269 pub fn build(self, ctx: &impl ContextOwner) -> Window {
274 let mut window = Window::new(ctx, self.mode, self.flags, self.size);
275
276 if let Some(title) = self.title {
277 window.set_title(title);
278 }
279
280 window
281 }
282}
283
284impl Drop for Window {
285 fn drop(&mut self) { self.close(); }
286}