use std::ffi::{c_void, CString}; use std::ops::ControlFlow; use crate::{CWindowConfig, CWindowEvent}; #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct WindowConfig { pub title: String, pub default_width: u32, pub default_height: u32, pub default_x: u32, pub default_y: u32, pub visible: bool, pub borderless_fullscreen: bool, } pub struct Window { pub(crate) ptr: *mut (), } pub enum WindowEvent { Other = 1, CloseRequest, ScaleFactorChange, Resume, RedrawRequest, } impl Drop for Window { fn drop(&mut self) { unsafe { crate::destroy_window(self.ptr) } } } impl Window { pub fn new(config: WindowConfig) -> Self { let title = CString::new(config.title.as_bytes()).unwrap(); let config = CWindowConfig { default_width: config.default_width, default_height: config.default_height, default_x: config.default_x, default_y: config.default_y, visible: config.visible, borderless_fullscreen: config.borderless_fullscreen, title: title.as_ptr(), }; let window = unsafe { crate::create_window(config) }; Self { ptr: window } } pub fn set_visible(&mut self, visible: bool) { unsafe { crate::set_visible(self.ptr, visible) } } pub fn set_title(&mut self, title: &str) { let string = CString::new(title.to_string().as_bytes()).unwrap(); let bytes = string.as_ptr(); unsafe { crate::set_title(self.ptr, bytes) } } pub fn resize(&mut self, width: u32, height: u32) { unsafe { crate::resize_window(self.ptr, width, height) } } pub fn set_fullscreen(&mut self, fullscreen: bool) { unsafe { crate::set_fullscreen(self.ptr, fullscreen) } } fn translate_event(event: CWindowEvent) -> Option { let event = match event { CWindowEvent::AboutToWait => return None, CWindowEvent::Other => WindowEvent::Other, CWindowEvent::CloseRequest => WindowEvent::CloseRequest, CWindowEvent::ScaleFactorChange => WindowEvent::ScaleFactorChange, CWindowEvent::Resume => WindowEvent::Resume, CWindowEvent::RedrawRequest => WindowEvent::RedrawRequest, }; Some(event) } pub fn wait_for_event(&self) { unsafe { crate::wait_for_event(self.ptr) } } pub fn pop_event(&self) -> bool { unsafe { crate::pop_event(self.ptr) } } pub fn wait_for_resume(&mut self) { unsafe { crate::wait_for_resume(self.ptr) } } pub fn run(&mut self, mut handler: impl FnMut(&mut Window, Option)) -> ! { let window_ptr = self.ptr; unsafe { let closure = |c_event: CWindowEvent| { handler(self, Self::translate_event(c_event)); }; let closure_data: Box> = Box::new(Box::new(closure)); crate::set_event_handler(window_ptr, Box::into_raw(closure_data) as *mut _); } loop { if !self.pop_event() { unsafe { crate::run_event_handler(window_ptr, CWindowEvent::AboutToWait) }; } } } pub fn request_redraw(&mut self) { unsafe { crate::request_redraw(self.ptr) } } }