From d9598066c2679d9d0b9ca0ce1d3f26110a238cd2 Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Thu, 4 Mar 2021 18:40:05 -0500 Subject: [PATCH] Feat: yeet, synthetic somewhat wired up --- packages/core-macro/src/rsxt.rs | 7 +++-- packages/core/src/events.rs | 30 ++++++++++---------- packages/core/src/hooks.rs | 1 - packages/core/src/nodebuilder.rs | 14 +++++----- packages/web/examples/infer.rs | 25 +++++++++++++++++ packages/web/examples/rsxt.rs | 1 + packages/web/src/interpreter.rs | 48 +++++++++++++++++--------------- 7 files changed, 79 insertions(+), 47 deletions(-) create mode 100644 packages/web/examples/infer.rs diff --git a/packages/core-macro/src/rsxt.rs b/packages/core-macro/src/rsxt.rs index 719a7828c..61be92ef4 100644 --- a/packages/core-macro/src/rsxt.rs +++ b/packages/core-macro/src/rsxt.rs @@ -342,6 +342,7 @@ impl Parse for Attr { impl ToTokens for ToToksCtx<&Attr> { fn to_tokens(&self, tokens: &mut TokenStream2) { let name = self.inner.name.to_string(); + let nameident = &self.inner.name; let mut attr_stream = TokenStream2::new(); match &self.inner.ty { AttrType::Value(value) => { @@ -352,13 +353,15 @@ impl ToTokens for ToToksCtx<&Attr> { } AttrType::Event(event) => { tokens.append_all(quote! { - .on(#name, #event) + .add_listener(dioxus::events::on::#nameident(ctx, #event)) }); + // .on(#name, #event) } AttrType::Tok(exp) => { tokens.append_all(quote! { - .on(#name, #exp) + .add_listener(dioxus::events::on::#nameident(ctx, #exp)) }); + // .on(#name, #exp) } } } diff --git a/packages/core/src/events.rs b/packages/core/src/events.rs index 7ea61dc29..6bd71bd4b 100644 --- a/packages/core/src/events.rs +++ b/packages/core/src/events.rs @@ -93,7 +93,7 @@ pub mod on { }; } - struct GetModifierKey(Box bool>); + pub struct GetModifierKey(pub Box bool>); impl std::fmt::Debug for GetModifierKey { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { // just skip for now @@ -159,7 +159,7 @@ pub mod on { } #[derive(Debug)] - pub struct MouseEvent(Box); + pub struct MouseEvent(pub Box); impl Deref for MouseEvent { type Target = RawMouseEvent; fn deref(&self) -> &Self::Target { @@ -168,19 +168,19 @@ pub mod on { } #[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, + 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! { diff --git a/packages/core/src/hooks.rs b/packages/core/src/hooks.rs index 427b22df8..3bd36db23 100644 --- a/packages/core/src/hooks.rs +++ b/packages/core/src/hooks.rs @@ -178,7 +178,6 @@ mod use_reducer_def { use super::*; use crate::prelude::*; use bumpalo::Bump; - enum Actions { Incr, Decr, diff --git a/packages/core/src/nodebuilder.rs b/packages/core/src/nodebuilder.rs index 7d9cbff33..6cba5f135 100644 --- a/packages/core/src/nodebuilder.rs +++ b/packages/core/src/nodebuilder.rs @@ -339,18 +339,18 @@ where /// }) /// .finish(); /// ``` - #[inline] pub fn on(mut self, event: &'static str, callback: impl Fn(VirtualEvent) + 'a) -> Self { - // todo: - // increment listner id from nodectx ref - // add listener attrs here instead of later? - - self.listeners.push(Listener { + let listener = Listener { event, callback: self.ctx.bump.alloc(callback), id: *self.ctx.idx.borrow(), scope: self.ctx.scope, - }); + }; + self.add_listener(listener) + } + + pub fn add_listener(mut self, listener: Listener<'a>) -> Self { + self.listeners.push(listener); // bump the context id forward *self.ctx.idx.borrow_mut() += 1; diff --git a/packages/web/examples/infer.rs b/packages/web/examples/infer.rs new file mode 100644 index 000000000..4382ba75d --- /dev/null +++ b/packages/web/examples/infer.rs @@ -0,0 +1,25 @@ +use dioxus_core::{events::on::MouseEvent, prelude::*}; +use dioxus_web::WebsysRenderer; + +fn main() { + // Setup logging + wasm_logger::init(wasm_logger::Config::new(log::Level::Debug)); + console_error_panic_hook::set_once(); + + wasm_bindgen_futures::spawn_local(WebsysRenderer::start(Example)); +} + +static Example: FC<()> = |ctx, _props| { + let handler = move |evt: MouseEvent| { + // Awesome! + // We get type inference with events + dbg!(evt.alt_key); + }; + + ctx.render(rsx! { + button { + "Hello" + onclick: {handler} + } + }) +}; diff --git a/packages/web/examples/rsxt.rs b/packages/web/examples/rsxt.rs index bc6e2276d..4cb05c598 100644 --- a/packages/web/examples/rsxt.rs +++ b/packages/web/examples/rsxt.rs @@ -16,6 +16,7 @@ fn main() { static Example: FC<()> = |ctx, props| { let (name, set_name) = use_state(&ctx, || "...?"); + ctx.render(rsx! { div { diff --git a/packages/web/src/interpreter.rs b/packages/web/src/interpreter.rs index 69652d7b9..6f4888ab2 100644 --- a/packages/web/src/interpreter.rs +++ b/packages/web/src/interpreter.rs @@ -1,7 +1,7 @@ -use std::{borrow::Borrow, fmt::Debug, sync::Arc}; +use std::{borrow::Borrow, convert::TryInto, fmt::Debug, sync::Arc}; use dioxus_core::{ - events::{EventTrigger, MouseEvent, VirtualEvent}, + events::{EventTrigger, VirtualEvent}, patch::Edit, prelude::ScopeIdx, }; @@ -481,30 +481,34 @@ impl PatchMachine { Edit::RemoveKnown => {} } } - - // // 24 - // pub fn save_template(&mut self, id: CacheId) { - // let template = self.stack.top(); - // let t = template.clone_node_with_deep(true).unwrap(); - // // self.templates.insert(id, t); - // } - - // // 25 - // pub fn push_template(&mut self, id: CacheId) { - // let template = self.get_template(id).unwrap(); - // let t = template.clone_node_with_deep(true).unwrap(); - // self.stack.push(t); - // } - - // pub fn has_template(&self, id: CacheId) -> bool { - // todo!() - // // self.templates.contains_key(&id) - // } } fn virtual_event_from_websys_event(event: &web_sys::Event) -> VirtualEvent { + use dioxus_core::events::on::*; match event.type_().as_str() { - "click" => VirtualEvent::MouseEvent(MouseEvent {}), + "click" | "contextmenu" | "doubleclick" | "drag" | "dragend" | "dragenter" | "dragexit" + | "dragleave" | "dragover" | "dragstart" | "drop" | "mousedown" | "mouseenter" + | "mouseleave" | "mousemove" | "mouseout" | "mouseover" | "mouseup" => { + let evt: web_sys::MouseEvent = event.clone().dyn_into().unwrap(); + VirtualEvent::MouseEvent(MouseEvent(Box::new(RawMouseEvent { + alt_key: evt.alt_key(), + button: evt.button() as i32, + buttons: evt.buttons() as i32, + client_x: evt.client_x(), + client_y: evt.client_y(), + ctrl_key: evt.ctrl_key(), + meta_key: evt.meta_key(), + page_x: evt.page_x(), + page_y: evt.page_y(), + screen_x: evt.screen_x(), + screen_y: evt.screen_y(), + shift_key: evt.shift_key(), + get_modifier_state: GetModifierKey(Box::new(|f| { + // evt.get_modifier_state(f) + todo!("This is not yet implemented properly, sorry :("); + })), + }))) + } _ => VirtualEvent::OtherEvent, } }