Files
dioxus/packages/core/src/events.rs
T

335 lines
8.3 KiB
Rust

//! Virtual Events
//! This module provides a wrapping of platform-specific events with a list of events easier to work with.
//! 3rd party renderers are responsible for forming this virtual events from events.
//! The goal here is to provide a consistent event interface across all renderer types.
//!
//! also... websys is kinda bad for rust-analyzer so we coerce for you automatically :)
use crate::innerlude::ScopeIdx;
#[derive(Debug)]
pub struct EventTrigger {
pub component_id: ScopeIdx,
pub listener_id: usize,
pub event: VirtualEvent,
}
impl EventTrigger {
pub fn new(event: VirtualEvent, scope: ScopeIdx, id: usize) -> Self {
Self {
component_id: scope,
listener_id: id,
event,
}
}
}
#[derive(Debug)]
pub enum VirtualEvent {
// Real events
ClipboardEvent(on::ClipboardEvent),
CompositionEvent(on::CompositionEvent),
KeyboardEvent(on::KeyboardEvent),
FocusEvent(on::FocusEvent),
FormEvent(on::FormEvent),
GenericEvent(on::GenericEvent),
SelectionEvent(on::SelectionEvent),
TouchEvent(on::TouchEvent),
UIEvent(on::UIEvent),
WheelEvent(on::WheelEvent),
MediaEvent(on::MediaEvent),
AnimationEvent(on::AnimationEvent),
TransitionEvent(on::TransitionEvent),
ToggleEvent(on::ToggleEvent),
// TODO these events are particularly heavy, so we box them
MouseEvent(on::MouseEvent),
PointerEvent(on::PointerEvent),
// todo
// ImageEvent(event_data::ImageEvent),
OtherEvent,
}
pub mod on {
#![allow(unused)]
use std::ops::Deref;
use crate::{
builder::ElementBuilder,
context::NodeCtx,
innerlude::{Attribute, Listener, VNode},
};
use super::VirtualEvent;
macro_rules! event_builder {
(
$eventdata:ident;
$(
$(#[$attr:meta])*
$name:ident
)* ) => {
$(
$(#[$attr])*
pub fn $name<'a>(
c: &'_ NodeCtx<'a>,
callback: impl Fn($eventdata) + 'a,
) -> Listener<'a> {
Listener {
event: stringify!($name),
id: *c.idx.borrow(),
scope: c.scope,
callback: c.bump.alloc(move |evt: VirtualEvent| match evt {
VirtualEvent::$eventdata(event) => callback(event),
_ => {
unreachable!("Downcasted VirtualEvent to wrong event type - this is a bug!")
}
}),
}
}
)*
};
}
pub struct GetModifierKey(pub Box<dyn Fn(usize) -> bool>);
impl std::fmt::Debug for GetModifierKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// just skip for now
Ok(())
}
}
// DOMDataTransfer clipboardData
#[derive(Debug)]
pub struct ClipboardEvent {}
event_builder! {
ClipboardEvent;
copy cut paste
}
// string data
#[derive(Debug)]
pub struct CompositionEvent {
data: String,
}
event_builder! {
ClipboardEvent;
compositionend compositionstart compositionupdate
}
#[derive(Debug)]
pub struct KeyboardEvent {
char_code: usize,
ctrl_key: bool,
key: String,
key_code: usize,
locale: String,
location: usize,
meta_key: bool,
repeat: bool,
shift_key: bool,
which: usize,
get_modifier_state: GetModifierKey,
}
event_builder! {
KeyboardEvent;
keydown keypress keyup
}
#[derive(Debug)]
pub struct FocusEvent {/* DOMEventTarget relatedTarget */}
event_builder! {
FocusEvent;
focus blur
}
#[derive(Debug)]
pub struct FormEvent {}
event_builder! {
FormEvent;
change input invalid reset submit
}
#[derive(Debug)]
pub struct GenericEvent {/* Error Load */}
event_builder! {
GenericEvent;
}
#[derive(Debug)]
pub struct MouseEvent(pub Box<RawMouseEvent>);
impl Deref for MouseEvent {
type Target = RawMouseEvent;
fn deref(&self) -> &Self::Target {
self.0.as_ref()
}
}
#[derive(Debug)]
pub struct RawMouseEvent {
pub alt_key: bool,
pub button: i32,
pub buttons: i32,
pub client_x: i32,
pub client_y: i32,
pub ctrl_key: bool,
pub meta_key: bool,
pub page_x: i32,
pub page_y: i32,
pub screen_x: i32,
pub screen_y: i32,
pub shift_key: bool,
pub get_modifier_state: GetModifierKey,
// relatedTarget: DOMEventTarget,
}
event_builder! {
MouseEvent;
click contextmenu doubleclick drag dragend dragenter dragexit
dragleave dragover dragstart drop mousedown mouseenter mouseleave
mousemove mouseout mouseover mouseup
}
#[derive(Debug)]
pub struct PointerEvent(Box<RawPointerEvent>);
impl Deref for PointerEvent {
type Target = RawPointerEvent;
fn deref(&self) -> &Self::Target {
self.0.as_ref()
}
}
#[derive(Debug)]
pub struct RawPointerEvent {
// Mouse only
alt_key: bool,
button: usize,
buttons: usize,
client_x: i32,
client_y: i32,
ctrl_key: bool,
meta_key: bool,
page_x: i32,
page_y: i32,
screen_x: i32,
screen_y: i32,
shift_key: bool,
get_modifier_state: GetModifierKey,
// Pointer-specific
pointer_id: usize,
width: usize,
height: usize,
pressure: usize,
tangential_pressure: usize,
tilt_x: i32,
tilt_y: i32,
twist: i32,
pointer_type: String,
is_primary: bool,
}
event_builder! {
PointerEvent;
pointerdown pointermove pointerup pointercancel gotpointercapture
lostpointercapture pointerenter pointerleave pointerover pointerout
}
#[derive(Debug)]
pub struct SelectionEvent {}
event_builder! {
SelectionEvent;
select
}
#[derive(Debug)]
pub struct TouchEvent {
alt_key: bool,
ctrl_key: bool,
meta_key: bool,
shift_key: bool,
get_modifier_state: GetModifierKey,
//
// changedTouches: DOMTouchList,
// todo
// targetTouches: DOMTouchList,
// touches: DOMTouchList,
// getModifierState(key): boolean
}
event_builder! {
TouchEvent;
touchcancel touchend touchmove touchstart
}
#[derive(Debug)]
pub struct UIEvent {
// DOMAbstractView view
detail: i32,
}
event_builder! {
UIEvent;
scroll
}
#[derive(Debug)]
pub struct WheelEvent {
delta_mode: i32,
delta_x: i32,
delta_y: i32,
delta_z: i32,
}
event_builder! {
WheelEvent;
wheel
}
#[derive(Debug)]
pub struct MediaEvent {}
event_builder! {
MediaEvent;
abort canplay canplaythrough durationchange emptied encrypted
ended error loadeddata loadedmetadata loadstart pause play
playing progress ratechange seeked seeking stalled suspend
timeupdate volumechange waiting
}
// todo!
// imageevent clashes with media event
// might need to derive this e manually
//
// #[derive(Debug)]
// pub struct ImageEvent {}
// event_builder! {
// ImageEvent;
// load error
// }
#[derive(Debug)]
pub struct AnimationEvent {
animation_name: String,
pseudo_element: String,
elapsed_time: f32,
}
event_builder! {
AnimationEvent;
animationstart animationend animationiteration
}
#[derive(Debug)]
pub struct TransitionEvent {
property_name: String,
pseudo_element: String,
elapsed_time: f32,
}
event_builder! {
TransitionEvent;
transitionend
}
#[derive(Debug)]
pub struct ToggleEvent {}
event_builder! {
ToggleEvent;
toggle
}
}