From 0ef765e060dde3cb4a4ace929895fd5f9b89a9a5 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Mon, 28 Aug 2023 12:35:55 -0500 Subject: [PATCH] move rink over to the new event system --- packages/rink/src/hooks.rs | 134 ++++++++++++++----------- packages/rink/src/widgets/button.rs | 2 +- packages/rink/src/widgets/checkbox.rs | 2 +- packages/rink/src/widgets/number.rs | 2 +- packages/rink/src/widgets/slider.rs | 7 +- packages/rink/src/widgets/text_like.rs | 9 +- 6 files changed, 86 insertions(+), 70 deletions(-) diff --git a/packages/rink/src/hooks.rs b/packages/rink/src/hooks.rs index b6b34458c..f6caf484c 100644 --- a/packages/rink/src/hooks.rs +++ b/packages/rink/src/hooks.rs @@ -2,22 +2,21 @@ use crossterm::event::{ Event as TermEvent, KeyCode as TermKeyCode, KeyModifiers, ModifierKeyCode, MouseButton, MouseEventKind, }; +use dioxus_html::{ + HasFormData, HasKeyboardData, HasWheelData, SerializedFocusData, SerializedKeyboardData, + SerializedMouseData, SerializedWheelData, +}; use dioxus_native_core::prelude::*; use dioxus_native_core::real_dom::NodeImmutable; use rustc_hash::{FxHashMap, FxHashSet}; use dioxus_html::geometry::euclid::{Point2D, Rect, Size2D}; -use dioxus_html::geometry::{ - ClientPoint, Coordinates, ElementPoint, PagePoint, ScreenPoint, WheelDelta, -}; +use dioxus_html::geometry::{ClientPoint, ElementPoint, PagePoint, ScreenPoint, WheelDelta}; use dioxus_html::input_data::keyboard_types::{Code, Key, Location, Modifiers}; use dioxus_html::input_data::{ MouseButton as DioxusMouseButton, MouseButtonSet as DioxusMouseButtons, }; -use dioxus_html::point_interaction::PointData; -use dioxus_html::{ - event_bubbles, prelude::PointInteraction, FocusData, KeyboardData, MouseData, WheelData, -}; +use dioxus_html::{event_bubbles, prelude::PointInteraction}; use std::any::Any; use std::collections::HashMap; use std::{ @@ -42,10 +41,10 @@ pub struct Event { #[derive(Debug, Clone, PartialEq)] pub enum EventData { - Mouse(MouseData), - Keyboard(KeyboardData), - Focus(FocusData), - Wheel(WheelData), + Mouse(SerializedMouseData), + Keyboard(SerializedKeyboardData), + Focus(SerializedFocusData), + Wheel(SerializedWheelData), Form(FormData), } @@ -70,13 +69,23 @@ pub struct FormData { pub files: Option, } +impl HasFormData for FormData { + fn value(&self) -> String { + self.value.clone() + } + + fn values(&self) -> HashMap> { + self.values.clone() + } + + fn as_any(&self) -> &dyn std::any::Any { + self + } +} + impl FormData { fn into_html(self) -> dioxus_html::FormData { - dioxus_html::FormData { - value: self.value, - values: self.values, - files: None, - } + dioxus_html::FormData::new(self) } } @@ -93,9 +102,9 @@ type EventCore = (&'static str, EventData); const MAX_REPEAT_TIME: Duration = Duration::from_millis(100); pub struct InnerInputState { - mouse: Option, - wheel: Option, - last_key_pressed: Option<(KeyboardData, Instant)>, + mouse: Option, + wheel: Option, + last_key_pressed: Option<(SerializedKeyboardData, Instant)>, pub(crate) focus_state: FocusState, // subscribers: Vec>, } @@ -137,12 +146,16 @@ impl InnerInputState { _ => {} } - let new_mouse_data = MouseData::new(PointData::new( - m.trigger_button(), - held_buttons, - m.coordinates(), + let coordinates = m.coordinates(); + let new_mouse_data = SerializedMouseData::new( + m.client_coordinates(), + coordinates.element(), + m.page_coordinates(), + m.screen_coordinates(), m.modifiers(), - )); + held_buttons, + m.trigger_button(), + ); self.mouse = Some(new_mouse_data.clone()); *m = new_mouse_data; @@ -159,7 +172,13 @@ impl InnerInputState { .is_some(); if is_repeating { - *k = KeyboardData::new(k.key(), k.code(), k.location(), true, k.modifiers()); + *k = SerializedKeyboardData::new( + is_repeating, + k.code(), + k.key(), + k.location(), + k.modifiers(), + ); } self.last_key_pressed = Some((k.clone(), Instant::now())); @@ -203,13 +222,13 @@ impl InnerInputState { resolved_events.push(Event { name: "focus", id, - data: EventData::Focus(FocusData {}), + data: EventData::Focus(SerializedFocusData::default()), bubbles: event_bubbles("focus"), }); resolved_events.push(Event { name: "focusin", id, - data: EventData::Focus(FocusData {}), + data: EventData::Focus(SerializedFocusData::default()), bubbles: event_bubbles("focusin"), }); } @@ -217,7 +236,7 @@ impl InnerInputState { resolved_events.push(Event { name: "focusout", id, - data: EventData::Focus(FocusData {}), + data: EventData::Focus(SerializedFocusData::default()), bubbles: event_bubbles("focusout"), }); } @@ -230,7 +249,7 @@ impl InnerInputState { fn resolve_mouse_events( &mut self, - previous_mouse: Option, + previous_mouse: Option, resolved_events: &mut Vec, layout: &Taffy, dom: &mut RealDom, @@ -277,7 +296,10 @@ impl InnerInputState { } } - fn prepare_mouse_data(mouse_data: &MouseData, layout: &Layout) -> MouseData { + fn prepare_mouse_data( + mouse_data: &SerializedMouseData, + layout: &Layout, + ) -> SerializedMouseData { let Point { x, y } = layout.location; let node_origin = ClientPoint::new( layout_to_screen_space(x).into(), @@ -288,19 +310,15 @@ impl InnerInputState { .to_point() .cast_unit(); - let coordinates = Coordinates::new( - mouse_data.screen_coordinates(), + SerializedMouseData::new( mouse_data.client_coordinates(), new_client_coordinates, mouse_data.page_coordinates(), - ); - - MouseData::new(PointData::new( - mouse_data.trigger_button(), - mouse_data.held_buttons(), - coordinates, + mouse_data.screen_coordinates(), mouse_data.modifiers(), - )) + mouse_data.held_buttons(), + mouse_data.trigger_button(), + ) } if let Some(mouse_data) = &self.mouse { @@ -693,17 +711,6 @@ fn get_event(evt: TermEvent) -> Option<(&'static str, EventData)> { // from https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent - // The `page` and `screen` coordinates are inconsistent with the MDN definition, as they are relative to the viewport (client), not the target element/page/screen, respectively. - // todo? - // But then, MDN defines them in terms of pixels, yet crossterm provides only row/column, and it might not be possible to get pixels. So we can't get 100% consistency anyway. - let coordinates = Coordinates::new( - ScreenPoint::new(x, y), - ClientPoint::new(x, y), - // offset x/y are set when the origin of the event is assigned to an element - ElementPoint::new(0., 0.), - PagePoint::new(x, y), - ); - let mut modifiers = Modifiers::empty(); if shift { modifiers.insert(Modifiers::SHIFT); @@ -719,17 +726,24 @@ fn get_event(evt: TermEvent) -> Option<(&'static str, EventData)> { } // held mouse buttons get set later by maintaining state, as crossterm does not provide them - EventData::Mouse(MouseData::new(PointData::new( - button, - DioxusMouseButtons::empty(), - coordinates, + EventData::Mouse(SerializedMouseData::new( + // The `page` and `screen` coordinates are inconsistent with the MDN definition, as they are relative to the viewport (client), not the target element/page/screen, respectively. + // todo? + // But then, MDN defines them in terms of pixels, yet crossterm provides only row/column, and it might not be possible to get pixels. So we can't get 100% consistency anyway. + ClientPoint::new(x, y), + // offset x/y are set when the origin of the event is assigned to an element + ElementPoint::new(0., 0.), + PagePoint::new(x, y), + ScreenPoint::new(x, y), modifiers, - ))) + DioxusMouseButtons::empty(), + button, + )) }; let get_wheel_data = |up| { let y = if up { -1.0 } else { 1.0 }; - EventData::Wheel(WheelData::new(WheelDelta::lines(0., y, 0.))) + EventData::Wheel(SerializedWheelData::new(WheelDelta::lines(0., y, 0.))) }; match m.kind { @@ -754,11 +768,11 @@ fn translate_key_event(event: crossterm::event::KeyEvent) -> Option { let code = guess_code_from_crossterm_key_code(event.code)?; let modifiers = modifiers_from_crossterm_modifiers(event.modifiers); - Some(EventData::Keyboard(KeyboardData::new( - key, - code, - Location::Standard, + Some(EventData::Keyboard(SerializedKeyboardData::new( false, + code, + key, + Location::Standard, modifiers, ))) } diff --git a/packages/rink/src/widgets/button.rs b/packages/rink/src/widgets/button.rs index 523b2392a..d07dd79f0 100644 --- a/packages/rink/src/widgets/button.rs +++ b/packages/rink/src/widgets/button.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use dioxus_html::input_data::keyboard_types::Key; +use dioxus_html::{input_data::keyboard_types::Key, HasKeyboardData}; use dioxus_native_core::{ custom_element::CustomElement, node::OwnedAttributeDiscription, diff --git a/packages/rink/src/widgets/checkbox.rs b/packages/rink/src/widgets/checkbox.rs index fab809ed2..fe878e5b8 100644 --- a/packages/rink/src/widgets/checkbox.rs +++ b/packages/rink/src/widgets/checkbox.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use dioxus_html::input_data::keyboard_types::Key; +use dioxus_html::{input_data::keyboard_types::Key, HasKeyboardData}; use dioxus_native_core::{ custom_element::CustomElement, node::OwnedAttributeDiscription, diff --git a/packages/rink/src/widgets/number.rs b/packages/rink/src/widgets/number.rs index 371c8b41d..c2a71ceac 100644 --- a/packages/rink/src/widgets/number.rs +++ b/packages/rink/src/widgets/number.rs @@ -1,4 +1,4 @@ -use dioxus_html::input_data::keyboard_types::Key; +use dioxus_html::{input_data::keyboard_types::Key, HasKeyboardData}; use dioxus_native_core::{ custom_element::CustomElement, real_dom::{NodeImmutable, RealDom}, diff --git a/packages/rink/src/widgets/slider.rs b/packages/rink/src/widgets/slider.rs index 3af995e09..5cef645cf 100644 --- a/packages/rink/src/widgets/slider.rs +++ b/packages/rink/src/widgets/slider.rs @@ -1,7 +1,8 @@ use std::collections::HashMap; use dioxus_html::{ - input_data::keyboard_types::Key, prelude::PointInteraction, KeyboardData, MouseData, + input_data::keyboard_types::Key, prelude::PointInteraction, HasKeyboardData, + SerializedKeyboardData, SerializedMouseData, }; use dioxus_native_core::{ custom_element::CustomElement, @@ -211,7 +212,7 @@ impl Slider { } } - fn handle_keydown(&mut self, mut root: NodeMut, data: &KeyboardData) { + fn handle_keydown(&mut self, mut root: NodeMut, data: &SerializedKeyboardData) { let key = data.key(); let step = self.step(); @@ -233,7 +234,7 @@ impl Slider { self.write_value(rdom, id); } - fn handle_mousemove(&mut self, mut root: NodeMut, data: &MouseData) { + fn handle_mousemove(&mut self, mut root: NodeMut, data: &SerializedMouseData) { if !data.held_buttons().is_empty() { let id = root.id(); let rdom = root.real_dom_mut(); diff --git a/packages/rink/src/widgets/text_like.rs b/packages/rink/src/widgets/text_like.rs index 5bfebd0ab..e7869600a 100644 --- a/packages/rink/src/widgets/text_like.rs +++ b/packages/rink/src/widgets/text_like.rs @@ -2,7 +2,8 @@ use std::{collections::HashMap, io::stdout}; use crossterm::{cursor::MoveTo, execute}; use dioxus_html::{ - input_data::keyboard_types::Key, prelude::PointInteraction, KeyboardData, MouseData, + input_data::keyboard_types::Key, prelude::PointInteraction, HasKeyboardData, + SerializedKeyboardData, SerializedMouseData, }; use dioxus_native_core::{ custom_element::CustomElement, @@ -186,7 +187,7 @@ impl TextLike { } } - fn handle_keydown(&mut self, mut root: NodeMut, data: &KeyboardData) { + fn handle_keydown(&mut self, mut root: NodeMut, data: &SerializedKeyboardData) { let key = data.key(); let modifiers = data.modifiers(); let code = data.code(); @@ -230,7 +231,7 @@ impl TextLike { } } - fn handle_mousemove(&mut self, mut root: NodeMut, data: &MouseData) { + fn handle_mousemove(&mut self, mut root: NodeMut, data: &SerializedMouseData) { if self.dragging { let id = root.id(); let offset = data.element_coordinates(); @@ -247,7 +248,7 @@ impl TextLike { } } - fn handle_mousedown(&mut self, mut root: NodeMut, data: &MouseData) { + fn handle_mousedown(&mut self, mut root: NodeMut, data: &SerializedMouseData) { let offset = data.element_coordinates(); let mut new = Pos::new(offset.x as usize, offset.y as usize);