use std::sync::Arc;
use winit::{
event_loop::EventLoop,
window::WindowBuilder,
window::Window as WinitWindow,
dpi::PhysicalSize,
event::*,
keyboard::*
};
use log::*;
pub struct Window<'a> {
win: Arc<WinitWindow>,
evt_loop: EventLoop<()>,
render_fn: Box<dyn FnMut() + 'a>,
resize_fn: Box<dyn FnMut(&PhysicalSize<u32>) + 'a>
}
impl<'a> Window<'a> {
pub fn from_raw(win: WinitWindow, evt_loop: EventLoop<()>) -> Self {
Self {
win: Arc::new(win),
evt_loop,
render_fn: Box::new(|| {}),
resize_fn: Box::new(|_| {}),
}
}
pub fn new(size: (u32, u32), title: String, resizable: bool) -> Window<'a> {
debug!("Ebb: Creating window");
let event_loop = EventLoop::new().unwrap();
let window = WindowBuilder::new().build(&event_loop).unwrap();
window.set_resizable(resizable);
let _ = window.request_inner_size(PhysicalSize::new(size.0, size.1));
window.set_title(&title);
#[cfg(target_arch = "wasm32")]
{
debug!("Ebb: Using web canvas for window");
let canvas = web_sys::Element::from(window.canvas().unwrap());
canvas.set_attribute("width", &size.0.to_string()).unwrap();
canvas.set_attribute("height", &size.1.to_string()).unwrap();
use winit::platform::web::WindowExtWebSys;
web_sys::window()
.and_then(|win| win.document())
.and_then(|doc| {
let dst = doc.get_element_by_id("ebb-canvas").expect("Cannot find Ebb canvas element");
let canvas = web_sys::Element::from(window.canvas()?);
dst.append_child(&canvas).ok()?;
Some(())
})
.expect("Couldn't append canvas to document body.");
}
#[cfg(not(target_arch = "wasm32"))]
{
debug!("Ebb: Creating native window");
}
debug!("Ebb: Window creation complete");
Window::from_raw(window, event_loop)
}
pub fn run(mut self) {
let _ = self.evt_loop.run(move |event, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == self.win.id() => match event {
WindowEvent::RedrawRequested => {
self.render_fn.as_mut()();
},
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
self.resize_fn.as_mut()(physical_size);
},
_ => {}
},
Event::AboutToWait => {
self.win.request_redraw();
},
_ => {}
}
});
}
pub fn on_render<T: 'a + FnMut()>(&mut self, renderer: T) {
self.render_fn = Box::new(renderer);
}
pub fn on_resize<T:'a + FnMut(&PhysicalSize<u32>)>(&mut self, cbk: T) {
self.resize_fn = Box::new(cbk);
}
pub fn raw_window(&self) -> Arc<WinitWindow> {
self.win.clone()
}
}
#[macro_export]
macro_rules! create_instance {
($window:expr) => {{
let win_clone = $window.raw_window(); ebb::instance::Instance::new(win_clone) }};
}