trait based event system

This commit is contained in:
Evan Almloff committed 2023-08-25 17:02:48 -05:00
1 parent a72718134b
commit 299b123446
28 files changed
+2407 -734

No files matched your search

+291 -124
View File
@@ -1,12 +1,12 @@
use crate::events::HasKeyboardData;
use crate::events::{
AnimationData, CompositionData, KeyboardData, MouseData, PointerData, TouchData,
AnimationData, CompositionData, HasTouchData, KeyboardData, MouseData, PointerData, TouchData,
TransitionData, WheelData,
};
use crate::input_data::decode_key_location;
use crate::point_interaction::PointData;
use crate::{DragData, MountedData};
use crate::geometry::{ClientPoint, ElementPoint, PagePoint, ScreenPoint};
use crate::input_data::{decode_key_location, decode_mouse_button_set, MouseButton};
use crate::prelude::*;
use keyboard_types::{Code, Key, Modifiers};
use std::convert::TryInto;
use std::str::FromStr;
use wasm_bindgen::{JsCast, JsValue};
use web_sys::{
@@ -20,7 +20,7 @@ macro_rules! uncheck_convert {
#[inline]
fn from(e: Event) -> Self {
let e: $t = e.unchecked_into();
Self::from(&e)
Self::from(e)
}
}
@@ -28,7 +28,7 @@ macro_rules! uncheck_convert {
#[inline]
fn from(e: &Event) -> Self {
let e: &$t = e.unchecked_ref();
Self::from(e)
Self::from(e.clone())
}
}
};
@@ -38,152 +38,283 @@ macro_rules! uncheck_convert {
}
uncheck_convert![
CompositionEvent => CompositionData,
KeyboardEvent => KeyboardData,
MouseEvent => MouseData,
MouseEvent => DragData,
TouchEvent => TouchData,
PointerEvent => PointerData,
WheelEvent => WheelData,
AnimationEvent => AnimationData,
TransitionEvent => TransitionData,
web_sys::CompositionEvent => CompositionData,
web_sys::KeyboardEvent => KeyboardData,
web_sys::MouseEvent => MouseData,
web_sys::TouchEvent => TouchData,
web_sys::PointerEvent => PointerData,
web_sys::WheelEvent => WheelData,
web_sys::AnimationEvent => AnimationData,
web_sys::TransitionEvent => TransitionData,
web_sys::MouseEvent => DragData,
web_sys::FocusEvent => FocusData,
];
impl From<&CompositionEvent> for CompositionData {
fn from(e: &CompositionEvent) -> Self {
Self {
data: e.data().unwrap_or_default(),
}
impl HasCompositionData for CompositionEvent {
fn data(&self) -> std::string::String {
self.data().unwrap_or_default()
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
impl From<&KeyboardEvent> for KeyboardData {
fn from(e: &KeyboardEvent) -> Self {
impl HasKeyboardData for KeyboardEvent {
fn key(&self) -> Key {
Key::from_str(self.key().as_str()).unwrap_or(Key::Unidentified)
}
fn code(&self) -> Code {
Code::from_str(self.code().as_str()).unwrap_or(Code::Unidentified)
}
fn modifiers(&self) -> Modifiers {
let mut modifiers = Modifiers::empty();
if e.alt_key() {
if self.alt_key() {
modifiers.insert(Modifiers::ALT);
}
if e.ctrl_key() {
if self.ctrl_key() {
modifiers.insert(Modifiers::CONTROL);
}
if e.meta_key() {
if self.meta_key() {
modifiers.insert(Modifiers::META);
}
if e.shift_key() {
if self.shift_key() {
modifiers.insert(Modifiers::SHIFT);
}
Self::new(
Key::from_str(&e.key()).expect("could not parse key"),
Code::from_str(&e.code()).expect("could not parse code"),
decode_key_location(
e.location()
.try_into()
.expect("could not convert location to u32"),
),
e.repeat(),
modifiers,
modifiers
}
fn location(&self) -> keyboard_types::Location {
decode_key_location(self.location() as usize)
}
fn is_auto_repeating(&self) -> bool {
self.repeat()
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
impl HasDragData for MouseEvent {}
impl PointInteraction for MouseEvent {
fn client_coordinates(&self) -> ClientPoint {
ClientPoint::new(self.client_x().into(), self.client_y().into())
}
fn element_coordinates(&self) -> ElementPoint {
ElementPoint::new(self.offset_x().into(), self.offset_y().into())
}
fn page_coordinates(&self) -> PagePoint {
PagePoint::new(self.page_x().into(), self.page_y().into())
}
fn screen_coordinates(&self) -> ScreenPoint {
ScreenPoint::new(self.screen_x().into(), self.screen_y().into())
}
fn modifiers(&self) -> Modifiers {
let mut modifiers = Modifiers::empty();
if self.alt_key() {
modifiers.insert(Modifiers::ALT);
}
if self.ctrl_key() {
modifiers.insert(Modifiers::CONTROL);
}
if self.meta_key() {
modifiers.insert(Modifiers::META);
}
if self.shift_key() {
modifiers.insert(Modifiers::SHIFT);
}
modifiers
}
fn held_buttons(&self) -> crate::input_data::MouseButtonSet {
decode_mouse_button_set(self.buttons())
}
fn trigger_button(&self) -> Option<MouseButton> {
Some(MouseButton::from_web_code(self.button()))
}
}
impl HasMouseData for MouseEvent {
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
impl HasTouchData for TouchEvent {
fn alt_key(&self) -> bool {
self.alt_key()
}
fn ctrl_key(&self) -> bool {
self.ctrl_key()
}
fn meta_key(&self) -> bool {
self.meta_key()
}
fn shift_key(&self) -> bool {
self.shift_key()
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
impl HasPointerData for PointerEvent {
fn pointer_id(&self) -> i32 {
self.pointer_id()
}
fn width(&self) -> i32 {
self.width()
}
fn height(&self) -> i32 {
self.height()
}
fn pressure(&self) -> f32 {
self.pressure()
}
fn tangential_pressure(&self) -> f32 {
self.tangential_pressure()
}
fn tilt_x(&self) -> i32 {
self.tilt_x()
}
fn tilt_y(&self) -> i32 {
self.tilt_y()
}
fn twist(&self) -> i32 {
self.twist()
}
fn pointer_type(&self) -> String {
self.pointer_type()
}
fn is_primary(&self) -> bool {
self.is_primary()
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
impl PointInteraction for PointerEvent {
fn client_coordinates(&self) -> ClientPoint {
ClientPoint::new(self.client_x().into(), self.client_y().into())
}
fn screen_coordinates(&self) -> ScreenPoint {
ScreenPoint::new(self.screen_x().into(), self.screen_y().into())
}
fn element_coordinates(&self) -> ElementPoint {
ElementPoint::new(self.offset_x().into(), self.offset_y().into())
}
fn page_coordinates(&self) -> PagePoint {
PagePoint::new(self.page_x().into(), self.page_y().into())
}
fn modifiers(&self) -> Modifiers {
let mut modifiers = Modifiers::empty();
if self.alt_key() {
modifiers.insert(Modifiers::ALT);
}
if self.ctrl_key() {
modifiers.insert(Modifiers::CONTROL);
}
if self.meta_key() {
modifiers.insert(Modifiers::META);
}
if self.shift_key() {
modifiers.insert(Modifiers::SHIFT);
}
modifiers
}
fn held_buttons(&self) -> crate::input_data::MouseButtonSet {
decode_mouse_button_set(self.buttons())
}
fn trigger_button(&self) -> Option<MouseButton> {
Some(MouseButton::from_web_code(self.button()))
}
}
impl HasWheelData for WheelEvent {
fn delta(&self) -> crate::geometry::WheelDelta {
crate::geometry::WheelDelta::from_web_attributes(
self.delta_mode(),
self.delta_x(),
self.delta_y(),
self.delta_z(),
)
}
}
impl From<&MouseEvent> for MouseData {
fn from(e: &MouseEvent) -> Self {
Self::new(PointData {
button: e.button(),
buttons: e.buttons(),
meta_key: e.meta_key(),
alt_key: e.alt_key(),
ctrl_key: e.ctrl_key(),
shift_key: e.shift_key(),
client_x: e.client_x(),
client_y: e.client_y(),
screen_x: e.screen_x(),
screen_y: e.screen_y(),
offset_x: e.offset_x(),
offset_y: e.offset_y(),
page_x: e.page_x(),
page_y: e.page_y(),
})
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
impl From<&MouseEvent> for DragData {
fn from(value: &MouseEvent) -> Self {
Self {
mouse: MouseData::from(value),
}
impl HasAnimationData for AnimationEvent {
fn animation_name(&self) -> String {
self.animation_name()
}
fn pseudo_element(&self) -> String {
self.pseudo_element()
}
fn elapsed_time(&self) -> f32 {
self.elapsed_time()
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
impl From<&TouchEvent> for TouchData {
fn from(e: &TouchEvent) -> Self {
Self {
alt_key: e.alt_key(),
ctrl_key: e.ctrl_key(),
meta_key: e.meta_key(),
shift_key: e.shift_key(),
}
impl HasTransitionData for TransitionEvent {
fn elapsed_time(&self) -> f32 {
self.elapsed_time()
}
}
impl From<&PointerEvent> for PointerData {
fn from(e: &PointerEvent) -> Self {
Self::new(
PointData {
button: e.button(),
buttons: e.buttons(),
meta_key: e.meta_key(),
alt_key: e.alt_key(),
ctrl_key: e.ctrl_key(),
shift_key: e.shift_key(),
client_x: e.client_x(),
client_y: e.client_y(),
screen_x: e.screen_x(),
screen_y: e.screen_y(),
offset_x: e.offset_x(),
offset_y: e.offset_y(),
page_x: e.page_x(),
page_y: e.page_y(),
},
e.pointer_id(),
e.width(),
e.height(),
e.pressure(),
e.tangential_pressure(),
e.tilt_x(),
e.tilt_y(),
e.twist(),
e.pointer_type(),
e.is_primary(),
)
fn property_name(&self) -> String {
self.property_name()
}
}
impl From<&WheelEvent> for WheelData {
fn from(e: &WheelEvent) -> Self {
WheelData::from_web_attributes(e.delta_mode(), e.delta_x(), e.delta_y(), e.delta_z())
fn pseudo_element(&self) -> String {
self.pseudo_element()
}
}
impl From<&AnimationEvent> for AnimationData {
fn from(e: &AnimationEvent) -> Self {
Self {
elapsed_time: e.elapsed_time(),
animation_name: e.animation_name(),
pseudo_element: e.pseudo_element(),
}
}
}
impl From<&TransitionEvent> for TransitionData {
fn from(e: &TransitionEvent) -> Self {
Self {
elapsed_time: e.elapsed_time(),
property_name: e.property_name(),
pseudo_element: e.pseudo_element(),
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
@@ -209,8 +340,8 @@ impl crate::RenderedElementBacking for web_sys::Element {
Box::pin(async { result })
}
fn get_raw_element(&self) -> crate::MountedResult<&dyn std::any::Any> {
Ok(self)
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn scroll_to(
@@ -254,3 +385,39 @@ impl std::fmt::Display for FocusError {
}
impl std::error::Error for FocusError {}
impl HasClipboardData for Event {
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
impl From<&Event> for ClipboardData {
fn from(e: &Event) -> Self {
ClipboardData::new(e.clone())
}
}
impl HasFocusData for web_sys::FocusEvent {
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
impl HasToggleData for web_sys::Event {
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
impl HasSelectionData for web_sys::Event {
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
impl HasMediaData for web_sys::Event {
fn as_any(&self) -> &dyn std::any::Any {
self
}
}