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<WindowEvent> {
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<WindowEvent>)) -> ! {
let window_ptr = self.ptr;
unsafe {
let closure = |c_event: CWindowEvent| {
handler(self, Self::translate_event(c_event));
};
let closure_data: Box<Box<dyn FnMut(CWindowEvent)>> = 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) }
}
}
|