move rink over to the new event system

This commit is contained in:
Evan Almloff 2023-08-28 12:35:55 -05:00
parent 93cbfd0dbc
commit 0ef765e060
6 changed files with 86 additions and 70 deletions

View file

@ -2,22 +2,21 @@ use crossterm::event::{
Event as TermEvent, KeyCode as TermKeyCode, KeyModifiers, ModifierKeyCode, MouseButton, Event as TermEvent, KeyCode as TermKeyCode, KeyModifiers, ModifierKeyCode, MouseButton,
MouseEventKind, MouseEventKind,
}; };
use dioxus_html::{
HasFormData, HasKeyboardData, HasWheelData, SerializedFocusData, SerializedKeyboardData,
SerializedMouseData, SerializedWheelData,
};
use dioxus_native_core::prelude::*; use dioxus_native_core::prelude::*;
use dioxus_native_core::real_dom::NodeImmutable; use dioxus_native_core::real_dom::NodeImmutable;
use rustc_hash::{FxHashMap, FxHashSet}; use rustc_hash::{FxHashMap, FxHashSet};
use dioxus_html::geometry::euclid::{Point2D, Rect, Size2D}; use dioxus_html::geometry::euclid::{Point2D, Rect, Size2D};
use dioxus_html::geometry::{ use dioxus_html::geometry::{ClientPoint, ElementPoint, PagePoint, ScreenPoint, WheelDelta};
ClientPoint, Coordinates, ElementPoint, PagePoint, ScreenPoint, WheelDelta,
};
use dioxus_html::input_data::keyboard_types::{Code, Key, Location, Modifiers}; use dioxus_html::input_data::keyboard_types::{Code, Key, Location, Modifiers};
use dioxus_html::input_data::{ use dioxus_html::input_data::{
MouseButton as DioxusMouseButton, MouseButtonSet as DioxusMouseButtons, MouseButton as DioxusMouseButton, MouseButtonSet as DioxusMouseButtons,
}; };
use dioxus_html::point_interaction::PointData; use dioxus_html::{event_bubbles, prelude::PointInteraction};
use dioxus_html::{
event_bubbles, prelude::PointInteraction, FocusData, KeyboardData, MouseData, WheelData,
};
use std::any::Any; use std::any::Any;
use std::collections::HashMap; use std::collections::HashMap;
use std::{ use std::{
@ -42,10 +41,10 @@ pub struct Event {
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub enum EventData { pub enum EventData {
Mouse(MouseData), Mouse(SerializedMouseData),
Keyboard(KeyboardData), Keyboard(SerializedKeyboardData),
Focus(FocusData), Focus(SerializedFocusData),
Wheel(WheelData), Wheel(SerializedWheelData),
Form(FormData), Form(FormData),
} }
@ -70,13 +69,23 @@ pub struct FormData {
pub files: Option<Files>, pub files: Option<Files>,
} }
impl HasFormData for FormData {
fn value(&self) -> String {
self.value.clone()
}
fn values(&self) -> HashMap<String, Vec<String>> {
self.values.clone()
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
impl FormData { impl FormData {
fn into_html(self) -> dioxus_html::FormData { fn into_html(self) -> dioxus_html::FormData {
dioxus_html::FormData { dioxus_html::FormData::new(self)
value: self.value,
values: self.values,
files: None,
}
} }
} }
@ -93,9 +102,9 @@ type EventCore = (&'static str, EventData);
const MAX_REPEAT_TIME: Duration = Duration::from_millis(100); const MAX_REPEAT_TIME: Duration = Duration::from_millis(100);
pub struct InnerInputState { pub struct InnerInputState {
mouse: Option<MouseData>, mouse: Option<SerializedMouseData>,
wheel: Option<WheelData>, wheel: Option<SerializedWheelData>,
last_key_pressed: Option<(KeyboardData, Instant)>, last_key_pressed: Option<(SerializedKeyboardData, Instant)>,
pub(crate) focus_state: FocusState, pub(crate) focus_state: FocusState,
// subscribers: Vec<Rc<dyn Fn() + 'static>>, // subscribers: Vec<Rc<dyn Fn() + 'static>>,
} }
@ -137,12 +146,16 @@ impl InnerInputState {
_ => {} _ => {}
} }
let new_mouse_data = MouseData::new(PointData::new( let coordinates = m.coordinates();
m.trigger_button(), let new_mouse_data = SerializedMouseData::new(
held_buttons, m.client_coordinates(),
m.coordinates(), coordinates.element(),
m.page_coordinates(),
m.screen_coordinates(),
m.modifiers(), m.modifiers(),
)); held_buttons,
m.trigger_button(),
);
self.mouse = Some(new_mouse_data.clone()); self.mouse = Some(new_mouse_data.clone());
*m = new_mouse_data; *m = new_mouse_data;
@ -159,7 +172,13 @@ impl InnerInputState {
.is_some(); .is_some();
if is_repeating { 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())); self.last_key_pressed = Some((k.clone(), Instant::now()));
@ -203,13 +222,13 @@ impl InnerInputState {
resolved_events.push(Event { resolved_events.push(Event {
name: "focus", name: "focus",
id, id,
data: EventData::Focus(FocusData {}), data: EventData::Focus(SerializedFocusData::default()),
bubbles: event_bubbles("focus"), bubbles: event_bubbles("focus"),
}); });
resolved_events.push(Event { resolved_events.push(Event {
name: "focusin", name: "focusin",
id, id,
data: EventData::Focus(FocusData {}), data: EventData::Focus(SerializedFocusData::default()),
bubbles: event_bubbles("focusin"), bubbles: event_bubbles("focusin"),
}); });
} }
@ -217,7 +236,7 @@ impl InnerInputState {
resolved_events.push(Event { resolved_events.push(Event {
name: "focusout", name: "focusout",
id, id,
data: EventData::Focus(FocusData {}), data: EventData::Focus(SerializedFocusData::default()),
bubbles: event_bubbles("focusout"), bubbles: event_bubbles("focusout"),
}); });
} }
@ -230,7 +249,7 @@ impl InnerInputState {
fn resolve_mouse_events( fn resolve_mouse_events(
&mut self, &mut self,
previous_mouse: Option<MouseData>, previous_mouse: Option<SerializedMouseData>,
resolved_events: &mut Vec<Event>, resolved_events: &mut Vec<Event>,
layout: &Taffy, layout: &Taffy,
dom: &mut RealDom, 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 Point { x, y } = layout.location;
let node_origin = ClientPoint::new( let node_origin = ClientPoint::new(
layout_to_screen_space(x).into(), layout_to_screen_space(x).into(),
@ -288,19 +310,15 @@ impl InnerInputState {
.to_point() .to_point()
.cast_unit(); .cast_unit();
let coordinates = Coordinates::new( SerializedMouseData::new(
mouse_data.screen_coordinates(),
mouse_data.client_coordinates(), mouse_data.client_coordinates(),
new_client_coordinates, new_client_coordinates,
mouse_data.page_coordinates(), mouse_data.page_coordinates(),
); mouse_data.screen_coordinates(),
MouseData::new(PointData::new(
mouse_data.trigger_button(),
mouse_data.held_buttons(),
coordinates,
mouse_data.modifiers(), mouse_data.modifiers(),
)) mouse_data.held_buttons(),
mouse_data.trigger_button(),
)
} }
if let Some(mouse_data) = &self.mouse { 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 // 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(); let mut modifiers = Modifiers::empty();
if shift { if shift {
modifiers.insert(Modifiers::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 // held mouse buttons get set later by maintaining state, as crossterm does not provide them
EventData::Mouse(MouseData::new(PointData::new( EventData::Mouse(SerializedMouseData::new(
button, // 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.
DioxusMouseButtons::empty(), // todo?
coordinates, // 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, modifiers,
))) DioxusMouseButtons::empty(),
button,
))
}; };
let get_wheel_data = |up| { let get_wheel_data = |up| {
let y = if up { -1.0 } else { 1.0 }; 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 { match m.kind {
@ -754,11 +768,11 @@ fn translate_key_event(event: crossterm::event::KeyEvent) -> Option<EventData> {
let code = guess_code_from_crossterm_key_code(event.code)?; let code = guess_code_from_crossterm_key_code(event.code)?;
let modifiers = modifiers_from_crossterm_modifiers(event.modifiers); let modifiers = modifiers_from_crossterm_modifiers(event.modifiers);
Some(EventData::Keyboard(KeyboardData::new( Some(EventData::Keyboard(SerializedKeyboardData::new(
key,
code,
Location::Standard,
false, false,
code,
key,
Location::Standard,
modifiers, modifiers,
))) )))
} }

View file

@ -1,6 +1,6 @@
use std::collections::HashMap; 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::{ use dioxus_native_core::{
custom_element::CustomElement, custom_element::CustomElement,
node::OwnedAttributeDiscription, node::OwnedAttributeDiscription,

View file

@ -1,6 +1,6 @@
use std::collections::HashMap; 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::{ use dioxus_native_core::{
custom_element::CustomElement, custom_element::CustomElement,
node::OwnedAttributeDiscription, node::OwnedAttributeDiscription,

View file

@ -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::{ use dioxus_native_core::{
custom_element::CustomElement, custom_element::CustomElement,
real_dom::{NodeImmutable, RealDom}, real_dom::{NodeImmutable, RealDom},

View file

@ -1,7 +1,8 @@
use std::collections::HashMap; use std::collections::HashMap;
use dioxus_html::{ 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::{ use dioxus_native_core::{
custom_element::CustomElement, 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 key = data.key();
let step = self.step(); let step = self.step();
@ -233,7 +234,7 @@ impl Slider {
self.write_value(rdom, id); 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() { if !data.held_buttons().is_empty() {
let id = root.id(); let id = root.id();
let rdom = root.real_dom_mut(); let rdom = root.real_dom_mut();

View file

@ -2,7 +2,8 @@ use std::{collections::HashMap, io::stdout};
use crossterm::{cursor::MoveTo, execute}; use crossterm::{cursor::MoveTo, execute};
use dioxus_html::{ 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::{ use dioxus_native_core::{
custom_element::CustomElement, custom_element::CustomElement,
@ -186,7 +187,7 @@ impl<C: TextLikeController> TextLike<C> {
} }
} }
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 key = data.key();
let modifiers = data.modifiers(); let modifiers = data.modifiers();
let code = data.code(); let code = data.code();
@ -230,7 +231,7 @@ impl<C: TextLikeController> TextLike<C> {
} }
} }
fn handle_mousemove(&mut self, mut root: NodeMut, data: &MouseData) { fn handle_mousemove(&mut self, mut root: NodeMut, data: &SerializedMouseData) {
if self.dragging { if self.dragging {
let id = root.id(); let id = root.id();
let offset = data.element_coordinates(); let offset = data.element_coordinates();
@ -247,7 +248,7 @@ impl<C: TextLikeController> TextLike<C> {
} }
} }
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 offset = data.element_coordinates();
let mut new = Pos::new(offset.x as usize, offset.y as usize); let mut new = Pos::new(offset.x as usize, offset.y as usize);