Преглед на файлове

Feat: synthetic events wired up (ish)

Jonathan Kelley преди 4 години
родител
ревизия
3087813570
променени са 2 файла, в които са добавени 315 реда и са изтрити 69 реда
  1. 12 17
      examples/webview.rs
  2. 303 52
      packages/core/src/events.rs

+ 12 - 17
examples/webview.rs

@@ -9,24 +9,19 @@
 
 use dioxus::prelude::*;
 
-fn main() {
-    let app = dioxus_webview::new(|ctx| {
+async fn main() {
+    dioxus_webview::launch(|ctx| {
         let (count, set_count) = use_state(ctx, || 0);
 
-        html! {
-            <div>
-                <h1> "Dioxus Desktop Demo" </h1>
-                <p> "Count is {count}"</p>
-                <p> "Count is {count}"</p>
-                <p> "Data is {data}"</p>
-                <button onclick=|_| set_count(count + 1) >
+        ctx.render(rsx! {
+            div {
+                h1 { "Dioxus Desktop Demo" }
+                p { "Count is {count}" }
+                button {
                     "Click to increment"
-                </button>
-             </div>
-        }
-    });
-
-    let f = 10_i32;
-    println!("hello {}", f);
-    app.launch(());
+                    onclick: |_| set_count(count + 1)
+                }
+            }
+        })
+    }).await;
 }

+ 303 - 52
packages/core/src/events.rs

@@ -1,9 +1,9 @@
 //! 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.
 //!
-//! 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;
 
@@ -27,57 +27,308 @@ impl EventTrigger {
 #[derive(Debug)]
 pub enum VirtualEvent {
     // Real events
-    ClipboardEvent(ClipboardEvent),
-    CompositionEvent(CompositionEvent),
-    KeyboardEvent(KeyboardEvent),
-    FocusEvent(FocusEvent),
-    FormEvent(FormEvent),
-    GenericEvent(GenericEvent),
-    MouseEvent(MouseEvent),
-    PointerEvent(PointerEvent),
-    SelectionEvent(SelectionEvent),
-    TouchEvent(TouchEvent),
-    UIEvent(UIEvent),
-    WheelEvent(WheelEvent),
-    MediaEvent(MediaEvent),
-    ImageEvent(ImageEvent),
-    AnimationEvent(AnimationEvent),
-    TransitionEvent(TransitionEvent),
+    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,
 }
 
-// these should reference the underlying event
+pub mod on {
+    #![allow(unused)]
+    use std::ops::Deref;
 
-#[derive(Debug)]
-pub struct ClipboardEvent {}
-#[derive(Debug)]
-pub struct CompositionEvent {}
-#[derive(Debug)]
-pub struct KeyboardEvent {}
-#[derive(Debug)]
-pub struct FocusEvent {}
-#[derive(Debug)]
-pub struct FormEvent {}
-#[derive(Debug)]
-pub struct GenericEvent {}
-#[derive(Debug)]
-pub struct MouseEvent {}
-#[derive(Debug)]
-pub struct PointerEvent {}
-#[derive(Debug)]
-pub struct SelectionEvent {}
-#[derive(Debug)]
-pub struct TouchEvent {}
-#[derive(Debug)]
-pub struct UIEvent {}
-#[derive(Debug)]
-pub struct WheelEvent {}
-#[derive(Debug)]
-pub struct MediaEvent {}
-#[derive(Debug)]
-pub struct ImageEvent {}
-#[derive(Debug)]
-pub struct AnimationEvent {}
-#[derive(Debug)]
-pub struct TransitionEvent {}
+    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!")
+                                }
+                            }),
+                        }
+                    }
+                )*
+            };
+        }
+
+    struct GetModifierKey(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(Box<RawMouseEvent>);
+    impl Deref for MouseEvent {
+        type Target = RawMouseEvent;
+        fn deref(&self) -> &Self::Target {
+            self.0.as_ref()
+        }
+    }
+    #[derive(Debug)]
+    pub struct RawMouseEvent {
+        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,
+        // 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
+    }
+}