Create the outline of event input and handler calls

This commit is contained in:
Ryan Goldstein 2019-02-26 13:36:48 -05:00
parent f44e98ddc9
commit c088f8bd03
2 changed files with 97 additions and 25 deletions

View file

@ -111,6 +111,8 @@ extern crate parking_lot;
extern crate percent_encoding; extern crate percent_encoding;
#[cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))] #[cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))]
extern crate smithay_client_toolkit as sctk; extern crate smithay_client_toolkit as sctk;
#[cfg(feature = "stdweb")]
extern crate stdweb;
pub mod dpi; pub mod dpi;
pub mod event; pub mod event;

View file

@ -1,14 +1,18 @@
use dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize}; use dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize};
use event::Event; use event::{Event, StartCause};
use event_loop::{ControlFlow, EventLoopWindowTarget as RootELW, EventLoopClosed}; use event_loop::{ControlFlow, EventLoopWindowTarget as RootELW, EventLoopClosed};
use icon::Icon; use icon::Icon;
use monitor::{MonitorHandle as RootMH}; use monitor::{MonitorHandle as RootMH};
use window::{CreationError, MouseCursor, WindowAttributes}; use window::{CreationError, MouseCursor, WindowAttributes};
use stdweb::{ use stdweb::{
traits::*,
web::{
document, document,
web::html_element::CanvasElement event::*,
html_element::CanvasElement,
}
}; };
use std::cell::Cell; use std::cell::{RefCell, RefMut};
use std::collections::VecDeque; use std::collections::VecDeque;
use std::collections::vec_deque::IntoIter as VecDequeIter; use std::collections::vec_deque::IntoIter as VecDequeIter;
use std::marker::PhantomData; use std::marker::PhantomData;
@ -59,7 +63,6 @@ impl WindowId {
pub struct Window { pub struct Window {
canvas: CanvasElement, canvas: CanvasElement,
monitors: VecDeque<MonitorHandle>
} }
impl Window { impl Window {
@ -86,7 +89,7 @@ impl Window {
} }
pub fn get_position(&self) -> Option<LogicalPosition> { pub fn get_position(&self) -> Option<LogicalPosition> {
let bounds = canvas.get_bouding_client_rect(); let bounds = self.canvas.get_bounding_client_rect();
Some(LogicalPosition { Some(LogicalPosition {
x: bounds.get_x(), x: bounds.get_x(),
y: bounds.get_y(), y: bounds.get_y(),
@ -105,23 +108,23 @@ impl Window {
#[inline] #[inline]
pub fn get_inner_size(&self) -> Option<LogicalSize> { pub fn get_inner_size(&self) -> Option<LogicalSize> {
Some(LogicalSize { Some(LogicalSize {
x: self.canvas.width() as f64 width: self.canvas.width() as f64,
y: self.canvas.height() as f64 height: self.canvas.height() as f64
}) })
} }
#[inline] #[inline]
pub fn get_outer_size(&self) -> Option<LogicalSize> { pub fn get_outer_size(&self) -> Option<LogicalSize> {
Some(LogicalSize { Some(LogicalSize {
x: self.canvas.width() as f64 width: self.canvas.width() as f64,
y: self.canvas.height() as f64 height: self.canvas.height() as f64
}) })
} }
#[inline] #[inline]
pub fn set_inner_size(&self, size: LogicalSize) { pub fn set_inner_size(&self, size: LogicalSize) {
self.canvas.set_width(size.x as u32); self.canvas.set_width(size.width as u32);
self.canvas.set_height(size.y as u32); self.canvas.set_height(size.height as u32);
} }
#[inline] #[inline]
@ -185,7 +188,7 @@ impl Window {
MouseCursor::ColResize => "col-resize", MouseCursor::ColResize => "col-resize",
MouseCursor::RowResize => "row-resize", MouseCursor::RowResize => "row-resize",
}; };
self.canvas.set_attribute("cursor", text); self.canvas.set_attribute("cursor", text)
.expect("Setting the cursor on the canvas"); .expect("Setting the cursor on the canvas");
} }
@ -249,7 +252,7 @@ impl Window {
#[inline] #[inline]
pub fn get_available_monitors(&self) -> VecDequeIter<MonitorHandle> { pub fn get_available_monitors(&self) -> VecDequeIter<MonitorHandle> {
self.monitors.iter() VecDeque::new().into_iter()
} }
#[inline] #[inline]
@ -259,25 +262,28 @@ impl Window {
#[inline] #[inline]
pub fn id(&self) -> WindowId { pub fn id(&self) -> WindowId {
WindowId::dummy() // TODO ?
unsafe { WindowId::dummy() }
} }
} }
fn new_rootelw<T>() -> RootELW<T> { fn new_rootelw<T>() -> RootELW<T> {
RootELW { RootELW {
p: EventLoopWindowTarget, p: EventLoopWindowTarget {
_phantom: PhantomData
},
_marker: PhantomData _marker: PhantomData
} }
} }
pub struct EventLoop<T> { pub struct EventLoop<T: 'static> {
window_target: RootELW<T>, window_target: RootELW<T>,
monitors: VecDeque<MonitorHandle>, data: Rc<RefCell<EventLoopData<T>>>,
data: Rc<Cell<EventLoopData>>,
} }
struct EventLoopData { #[derive(Clone)]
events: VecDeque<T>, struct EventLoopData<T> {
events: VecDeque<Event<T>>,
control: ControlFlow, control: ControlFlow,
} }
@ -287,7 +293,7 @@ impl<T> EventLoop<T> {
} }
pub fn get_available_monitors(&self) -> VecDequeIter<MonitorHandle> { pub fn get_available_monitors(&self) -> VecDequeIter<MonitorHandle> {
self.monitors.iter() VecDeque::new().into_iter()
} }
pub fn get_primary_monitor(&self) -> MonitorHandle { pub fn get_primary_monitor(&self) -> MonitorHandle {
@ -299,23 +305,87 @@ impl<T> EventLoop<T> {
{ {
// TODO: Create event handlers for the JS events // TODO: Create event handlers for the JS events
// TODO: how to handle request redraw? // TODO: how to handle request redraw?
// TODO: onclose (stdweb PR)
// TODO: file dropping, PathBuf isn't useful for web
let document = &document();
self.add_event(document, |data, event: BlurEvent| {
});
self.add_event(document, |data, event: FocusEvent| {
});
// TODO: what to do after attaching events
unimplemented!(); unimplemented!();
} }
pub fn create_proxy(&self) -> EventLoopProxy<T> { pub fn create_proxy(&self) -> EventLoopProxy<T> {
EventLoopProxy { EventLoopProxy {
events: self.window_target.p.events.clone() data: self.data.clone()
} }
} }
pub fn window_target(&self) -> &RootELW<T> { pub fn window_target(&self) -> &RootELW<T> {
&self.window_target &self.window_target
} }
// Apply all enqueued events
fn apply_events<F>(&mut self, mut event_handler: F, start: StartCause)
where F: 'static + FnMut(Event<T>, &RootELW<T>, &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)
} }
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] fn register_window(&self, other: &Window) {
let canvas = &other.canvas;
self.add_event(canvas, |data, event: KeyDownEvent| {
// TODO: received character
// TODO: keyboard input
});
self.add_event(canvas, |data, event: KeyUpEvent| {
// TODO: keyboard input
});
self.add_event(canvas, |data, _: PointerOutEvent| {
// TODO
});
self.add_event(canvas, |data, _: PointerOverEvent| {
// TODO
});
self.add_event(canvas, |data, event: PointerMoveEvent| {
// TODO: mouse move
});
self.add_event(canvas, |data, event: PointerUpEvent| {
// TODO: mouse pointers
});
self.add_event(canvas, |data, event: PointerDownEvent| {
// TODO: mouse pointers
});
}
fn add_event<E, F>(&self, target: &impl IEventTarget, mut handler: F)
where E: ConcreteEvent, F: FnMut(RefMut<EventLoopData<T>>, E) + 'static {
let data = self.data.clone();
target.add_event_listener(move |event: E| {
event.prevent_default();
event.stop_propagation();
event.cancel_bubble();
handler(data.borrow_mut(), event);
});
}
}
#[derive(Clone)]
pub struct EventLoopProxy<T> { pub struct EventLoopProxy<T> {
data: EventLoopData data: Rc<RefCell<EventLoopData<T>>>
} }
impl<T> EventLoopProxy<T> { impl<T> EventLoopProxy<T> {