Skip to main content

diene_engine_core/app/
windowing.rs

1//! Thin wrapper around native window creation and access.
2
3use engine_renderer_api::{DisplayHandle, HandleError, HasDisplayHandle, HasWindowHandle, RenderExtent, RenderWindow, WindowHandle};
4use thiserror::Error;
5use winit::{
6    dpi::PhysicalSize,
7    event_loop::ActiveEventLoop,
8    window::{Window as WinitWindow, WindowId},
9};
10
11/// Errors returned by native window operations.
12#[derive(Debug, Error)]
13pub enum WindowError {
14    /// Event loop operation failed.
15    #[error("event loop failed: {0}")]
16    EventLoop(#[from] winit::error::EventLoopError),
17
18    /// Operating system call failed.
19    #[error("operating system call failed: {0}")]
20    Os(#[from] winit::error::OsError),
21}
22
23/// Owns the native window used for presenting rendered frames.
24#[derive(Debug)]
25pub(super) struct Window {
26    inner: WinitWindow,
27}
28
29impl Window {
30    /// Creates a window attached to the active event loop.
31    pub(super) fn create(event_loop: &ActiveEventLoop, title: &str) -> Result<Self, WindowError> {
32        let attributes = WinitWindow::default_attributes().with_title(title);
33        let inner = event_loop.create_window(attributes)?;
34
35        Ok(Self { inner })
36    }
37
38    /// Returns the platform window identifier.
39    pub(super) fn id(&self) -> WindowId {
40        self.inner.id()
41    }
42
43    /// Returns the current drawable size in physical pixels.
44    fn physical_size(&self) -> PhysicalSize<u32> {
45        self.inner.inner_size()
46    }
47
48    /// Requests that the event loop schedule a redraw for this window.
49    pub(super) fn request_redraw(&self) {
50        self.inner.request_redraw();
51    }
52}
53
54impl HasWindowHandle for Window {
55    fn window_handle(&self) -> Result<WindowHandle<'_>, HandleError> {
56        self.inner.window_handle()
57    }
58}
59
60impl HasDisplayHandle for Window {
61    fn display_handle(&self) -> Result<DisplayHandle<'_>, HandleError> {
62        self.inner.display_handle()
63    }
64}
65
66impl RenderWindow for Window {
67    fn size(&self) -> RenderExtent {
68        let size = self.physical_size();
69        RenderExtent::new(size.width, size.height)
70    }
71}