From 37d354cf7fdee5a423436899b20e77aab0629b05 Mon Sep 17 00:00:00 2001 From: Ryan Goldstein Date: Sat, 9 Mar 2019 21:54:29 -0500 Subject: [PATCH] Get to a state where a canvas is spawned --- examples/window.rs | 6 +- src/event_loop.rs | 2 +- src/platform_impl/stdweb/mod.rs | 119 ++++++++++++++++++-------------- 3 files changed, 75 insertions(+), 52 deletions(-) diff --git a/examples/window.rs b/examples/window.rs index 3d5c7cf7..b33b5984 100644 --- a/examples/window.rs +++ b/examples/window.rs @@ -1,4 +1,7 @@ extern crate winit; +#[macro_use] +extern crate stdweb; + use winit::window::WindowBuilder; use winit::event::{Event, WindowEvent}; use winit::event_loop::{EventLoop, ControlFlow}; @@ -10,9 +13,10 @@ fn main() { .with_title("A fantastic window!") .build(&event_loop) .unwrap(); + console!(log, "Built window!"); event_loop.run(|event, _, control_flow| { - println!("{:?}", event); + console!(log, format!("{:?}", event)); match event { Event::WindowEvent { diff --git a/src/event_loop.rs b/src/event_loop.rs index ca217f7c..44cc8b90 100644 --- a/src/event_loop.rs +++ b/src/event_loop.rs @@ -139,7 +139,7 @@ impl EventLoop { /// /// [`ControlFlow`]: ./enum.ControlFlow.html #[inline] - pub fn run(self, event_handler: F) -> ! + pub fn run(self, event_handler: F) // TODO: this needs to be ! where F: 'static + FnMut(Event, &EventLoopWindowTarget, &mut ControlFlow) { self.event_loop.run(event_handler) diff --git a/src/platform_impl/stdweb/mod.rs b/src/platform_impl/stdweb/mod.rs index cea168da..2eda4318 100644 --- a/src/platform_impl/stdweb/mod.rs +++ b/src/platform_impl/stdweb/mod.rs @@ -41,7 +41,8 @@ pub struct MonitorHandle; impl MonitorHandle { pub fn get_hidpi_factor(&self) -> f64 { - unimplemented!(); + // TODO + 1.0 } pub fn get_position(&self) -> PhysicalPosition { @@ -71,8 +72,42 @@ pub struct Window { } impl Window { - pub fn new(target: &EventLoopWindowTarget, window: WindowAttributes, platform: PlatformSpecificWindowBuilderAttributes) -> Result { - unimplemented!(); + pub fn new(target: &EventLoopWindowTarget, attr: WindowAttributes, + _: PlatformSpecificWindowBuilderAttributes) -> Result { + let element = document() + .create_element("canvas") + .map_err(|_| CreationError::OsError("Failed to create canvas element".to_owned()))?; + let canvas: CanvasElement = element.try_into() + .map_err(|_| CreationError::OsError("Failed to create canvas element".to_owned()))?; + document().body() + .ok_or_else(|| CreationError::OsError("Failed to find body node".to_owned()))? + .append_child(&canvas); + let window = Window { canvas }; + if let Some(dimensions) = attr.dimensions { + window.set_inner_size(dimensions); + } else { + window.set_inner_size(LogicalSize { + width: 1024.0, + height: 768.0, + }) + } + // TODO: most of these are no-op, but should they stay here just in case? + window.set_min_dimensions(attr.min_dimensions); + window.set_max_dimensions(attr.max_dimensions); + window.set_resizable(attr.resizable); + window.set_title(&attr.title); + window.set_maximized(attr.maximized); + if attr.visible { + window.show(); + } else { + window.hide(); + } + //window.set_transparent(attr.transparent); + window.set_decorations(attr.decorations); + window.set_always_on_top(attr.always_on_top); + window.set_window_icon(attr.window_icon); + target.register_window(&window); + Ok(window) } pub fn set_title(&self, title: &str) { @@ -88,8 +123,7 @@ impl Window { } pub fn request_redraw(&self) { - // TODO: what does this mean - unimplemented!(); + // TODO: what does this mean? If it's a 'present'-style call then it's not necessary } pub fn get_position(&self) -> Option { @@ -106,7 +140,6 @@ impl Window { pub fn set_position(&self, position: LogicalPosition) { // TODO: use CSS? - unimplemented!(); } #[inline] @@ -148,7 +181,8 @@ impl Window { #[inline] pub fn get_hidpi_factor(&self) -> f64 { - unimplemented!(); + // TODO + 1.0 } #[inline] @@ -199,13 +233,13 @@ impl Window { #[inline] pub fn set_cursor_position(&self, position: LogicalPosition) -> Result<(), String> { // TODO: pointer capture - unimplemented!(); + Ok(()) } #[inline] pub fn grab_cursor(&self, grab: bool) -> Result<(), String> { // TODO: pointer capture - unimplemented!(); + Ok(()) } #[inline] @@ -217,13 +251,11 @@ impl Window { #[inline] pub fn set_maximized(&self, maximized: bool) { // TODO: should there be a maximization / fullscreen API? - unimplemented!(); } #[inline] pub fn set_fullscreen(&self, monitor: Option) { // TODO: should there be a maximization / fullscreen API? - unimplemented!(); } #[inline] @@ -239,12 +271,11 @@ impl Window { #[inline] pub fn set_window_icon(&self, window_icon: Option) { // TODO: should this set the favicon? - unimplemented!(); } #[inline] pub fn set_ime_spot(&self, position: LogicalPosition) { - unimplemented!(); + // TODO: what is this? } #[inline] @@ -271,18 +302,8 @@ impl Window { } } -fn new_rootelw() -> RootELW { - RootELW { - p: EventLoopWindowTarget { - _phantom: PhantomData - }, - _marker: PhantomData - } -} - pub struct EventLoop { - window_target: RootELW, - data: Rc>>, + elw: RootELW, } #[derive(Clone)] @@ -291,9 +312,23 @@ struct EventLoopData { control: ControlFlow, } +pub struct EventLoopWindowTarget { + data: Rc>>, +} + impl EventLoop { pub fn new() -> Self { - unimplemented!(); + EventLoop { + elw: RootELW { + p: EventLoopWindowTarget { + data: Rc::new(RefCell::new(EventLoopData { + events: VecDeque::new(), + control: ControlFlow::Poll + })) + }, + _marker: PhantomData + } + } } pub fn get_available_monitors(&self) -> VecDequeIter { @@ -304,7 +339,7 @@ impl EventLoop { MonitorHandle } - pub fn run(mut self, event_handler: F) -> ! + pub fn run(mut self, event_handler: F) where F: 'static + FnMut(Event, &RootELW, &mut ControlFlow) { // TODO: Create event handlers for the JS events @@ -313,39 +348,26 @@ impl EventLoop { // TODO: file dropping, PathBuf isn't useful for web let document = &document(); - self.add_event(document, |mut data, event: BlurEvent| { + self.elw.p.add_event(document, |mut data, event: BlurEvent| { }); - self.add_event(document, |mut data, event: FocusEvent| { + self.elw.p.add_event(document, |mut data, event: FocusEvent| { }); - // TODO: what to do after attaching events - unimplemented!(); + stdweb::event_loop(); // TODO: this is only necessary for stdweb emscripten, should it be here? } pub fn create_proxy(&self) -> EventLoopProxy { EventLoopProxy { - data: self.data.clone() + data: self.elw.p.data.clone() } } pub fn window_target(&self) -> &RootELW { - &self.window_target - } - - // Apply all enqueued events - fn apply_events(&mut self, mut event_handler: F, start: StartCause) - where F: 'static + FnMut(Event, &RootELW, &mut ControlFlow) { - // TODO: how to handle ControlFlow::Exit? - let mut data = self.data.borrow_mut(); - let mut control = data.control.clone(); - let events = &mut data.events; - event_handler(Event::NewEvents(start), &new_rootelw(), &mut control); - for event in events.drain(..) { - event_handler(event, &new_rootelw(), &mut control); - } - event_handler(Event::EventsCleared, &new_rootelw(), &mut control) + &self.elw } +} +impl EventLoopWindowTarget { fn register_window(&self, other: &Window) { let canvas = &other.canvas; @@ -442,6 +464,7 @@ impl EventLoop { }); } + fn add_event(&self, target: &impl IEventTarget, mut handler: F) where E: ConcreteEvent, F: FnMut(RefMut>, E) + 'static { let data = self.data.clone(); @@ -664,10 +687,6 @@ impl EventLoopProxy { } } -pub struct EventLoopWindowTarget { - _phantom: PhantomData -} - #[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct PlatformSpecificWindowBuilderAttributes;