khora_infra/platform/window/
winit.rs1use khora_core::platform::window::{KhoraWindow, KhoraWindowHandle};
18use raw_window_handle::{
19 DisplayHandle, HandleError, HasDisplayHandle, HasWindowHandle, WindowHandle,
20};
21use std::sync::Arc;
22use winit::{
23 dpi::LogicalSize,
24 error::OsError,
25 event_loop::ActiveEventLoop,
26 window::{Icon, Window},
27};
28
29#[derive(Debug, Clone)]
35pub struct WinitWindow {
36 inner: Arc<Window>,
37}
38
39impl WinitWindow {
40 pub fn winit_window(&self) -> &Window {
42 &self.inner
43 }
44
45 pub fn clone_winit_arc(&self) -> Arc<Window> {
49 Arc::clone(&self.inner)
50 }
51}
52
53pub struct WinitWindowBuilder {
57 title: String,
58 width: u32,
59 height: u32,
60 icon: Option<Icon>,
61}
62
63impl WinitWindowBuilder {
64 pub fn new() -> Self {
66 Self {
67 title: "Khora Engine".to_string(),
68 width: 1024,
69 height: 768,
70 icon: None,
71 }
72 }
73
74 pub fn with_title(mut self, title: impl Into<String>) -> Self {
76 self.title = title.into();
77 self
78 }
79
80 pub fn with_dimensions(mut self, width: u32, height: u32) -> Self {
82 self.width = width;
83 self.height = height;
84 self
85 }
86
87 pub fn with_icon_rgba(mut self, rgba: Vec<u8>, width: u32, height: u32) -> Self {
89 match Icon::from_rgba(rgba, width, height) {
90 Ok(icon) => self.icon = Some(icon),
91 Err(e) => log::warn!("Failed to build window icon: {e}"),
92 }
93 self
94 }
95
96 pub fn build(self, event_loop: &ActiveEventLoop) -> Result<WinitWindow, OsError> {
101 log::info!(
102 "Building window with title: '{}' and size: {}x{}",
103 self.title,
104 self.width,
105 self.height
106 );
107
108 let window_attributes = Window::default_attributes()
109 .with_title(self.title)
110 .with_inner_size(LogicalSize::new(self.width, self.height))
111 .with_window_icon(self.icon)
112 .with_visible(true);
113
114 let window = event_loop.create_window(window_attributes)?;
115
116 log::info!("Winit window created successfully (id: {:?}).", window.id());
117 Ok(WinitWindow {
118 inner: Arc::new(window),
119 })
120 }
121}
122
123impl Default for WinitWindowBuilder {
124 fn default() -> Self {
126 Self::new()
127 }
128}
129
130impl HasWindowHandle for WinitWindow {
131 fn window_handle(&self) -> Result<WindowHandle<'_>, HandleError> {
133 self.inner.window_handle()
134 }
135}
136
137impl HasDisplayHandle for WinitWindow {
138 fn display_handle(&self) -> Result<DisplayHandle<'_>, HandleError> {
140 self.inner.display_handle()
141 }
142}
143
144impl KhoraWindow for WinitWindow {
145 fn inner_size(&self) -> (u32, u32) {
147 let size = self.inner.inner_size();
148 (size.width, size.height)
149 }
150
151 fn scale_factor(&self) -> f64 {
153 self.inner.scale_factor()
154 }
155
156 fn request_redraw(&self) {
158 self.inner.request_redraw();
159 }
160
161 fn clone_handle_arc(&self) -> KhoraWindowHandle {
163 self.inner.clone()
164 }
165
166 fn id(&self) -> u64 {
168 use std::collections::hash_map::DefaultHasher;
169 use std::hash::{Hash, Hasher};
170
171 let mut hasher = DefaultHasher::new();
172 self.inner.id().hash(&mut hasher);
173 hasher.finish()
174 }
175}