Merge pull request #940 from Demonthos/make-widgets-cross-framework

This commit is contained in:
Jonathan Kelley authored and GitHub committed 2023-07-11 20:47:01 -07:00
commit f4b3be1b13
44 files changed
+3232 -1185

No files matched your search

+82 -73
View File
@@ -13,7 +13,9 @@ use dioxus_html::geometry::{
use dioxus_html::input_data::keyboard_types::{Code, Key, Location, Modifiers};
use dioxus_html::input_data::MouseButtonSet as DioxusMouseButtons;
use dioxus_html::input_data::{MouseButton as DioxusMouseButton, MouseButtonSet};
use dioxus_html::{event_bubbles, EventData, FocusData, KeyboardData, MouseData, WheelData};
use dioxus_html::{event_bubbles, FocusData, KeyboardData, MouseData, WheelData};
use std::any::Any;
use std::collections::HashMap;
use std::{
cell::{RefCell, RefMut},
rc::Rc,
@@ -24,15 +26,64 @@ use taffy::{prelude::Layout, Taffy};
use crate::focus::{Focus, Focused};
use crate::layout::TaffyLayout;
use crate::{layout_to_screen_space, FocusState};
use crate::{get_abs_layout, layout_to_screen_space, FocusState};
pub(crate) struct Event {
#[derive(Debug, Clone, PartialEq)]
pub struct Event {
pub id: NodeId,
pub name: &'static str,
pub data: Rc<EventData>,
pub data: EventData,
pub bubbles: bool,
}
#[derive(Debug, Clone, PartialEq)]
pub enum EventData {
Mouse(MouseData),
Keyboard(KeyboardData),
Focus(FocusData),
Wheel(WheelData),
Form(FormData),
}
impl EventData {
pub fn into_any(self) -> Rc<dyn Any> {
match self {
EventData::Mouse(m) => Rc::new(m),
EventData::Keyboard(k) => Rc::new(k),
EventData::Focus(f) => Rc::new(f),
EventData::Wheel(w) => Rc::new(w),
EventData::Form(f) => Rc::new(f.into_html()),
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct FormData {
pub value: String,
pub values: HashMap<String, Vec<String>>,
pub files: Option<Files>,
}
impl FormData {
fn into_html(self) -> dioxus_html::FormData {
dioxus_html::FormData {
value: self.value,
values: self.values,
files: None,
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct Files {
files: FxHashMap<String, File>,
}
#[derive(Clone, Debug, PartialEq)]
pub struct File {}
type EventCore = (&'static str, EventData);
const MAX_REPEAT_TIME: Duration = Duration::from_millis(100);
@@ -148,13 +199,13 @@ impl InnerInputState {
resolved_events.push(Event {
name: "focus",
id,
data: Rc::new(EventData::Focus(FocusData {})),
data: EventData::Focus(FocusData {}),
bubbles: event_bubbles("focus"),
});
resolved_events.push(Event {
name: "focusin",
id,
data: Rc::new(EventData::Focus(FocusData {})),
data: EventData::Focus(FocusData {}),
bubbles: event_bubbles("focusin"),
});
}
@@ -162,7 +213,7 @@ impl InnerInputState {
resolved_events.push(Event {
name: "focusout",
id,
data: Rc::new(EventData::Focus(FocusData {})),
data: EventData::Focus(FocusData {}),
bubbles: event_bubbles("focusout"),
});
}
@@ -198,7 +249,7 @@ impl InnerInputState {
fn try_create_event(
name: &'static str,
data: Rc<EventData>,
data: EventData,
will_bubble: &mut FxHashSet<NodeId>,
resolved_events: &mut Vec<Event>,
node: NodeRef,
@@ -273,7 +324,7 @@ impl InnerInputState {
if old_pos != Some(new_pos) {
let mut will_bubble = FxHashSet::default();
for node in dom.get_listening_sorted("mousemove") {
let node_layout = get_abs_layout(node, dom, layout);
let node_layout = get_abs_layout(node, layout);
let previously_contained = old_pos
.filter(|pos| layout_contains_point(&node_layout, *pos))
.is_some();
@@ -282,10 +333,7 @@ impl InnerInputState {
if currently_contains && previously_contained {
try_create_event(
"mousemove",
Rc::new(EventData::Mouse(prepare_mouse_data(
mouse_data,
&node_layout,
))),
EventData::Mouse(prepare_mouse_data(mouse_data, &node_layout)),
&mut will_bubble,
resolved_events,
node,
@@ -300,7 +348,7 @@ impl InnerInputState {
// mouseenter
let mut will_bubble = FxHashSet::default();
for node in dom.get_listening_sorted("mouseenter") {
let node_layout = get_abs_layout(node, dom, layout);
let node_layout = get_abs_layout(node, layout);
let previously_contained = old_pos
.filter(|pos| layout_contains_point(&node_layout, *pos))
.is_some();
@@ -309,7 +357,7 @@ impl InnerInputState {
if currently_contains && !previously_contained {
try_create_event(
"mouseenter",
Rc::new(dioxus_html::EventData::Mouse(mouse_data.clone())),
EventData::Mouse(mouse_data.clone()),
&mut will_bubble,
resolved_events,
node,
@@ -323,7 +371,7 @@ impl InnerInputState {
// mouseover
let mut will_bubble = FxHashSet::default();
for node in dom.get_listening_sorted("mouseover") {
let node_layout = get_abs_layout(node, dom, layout);
let node_layout = get_abs_layout(node, layout);
let previously_contained = old_pos
.filter(|pos| layout_contains_point(&node_layout, *pos))
.is_some();
@@ -332,10 +380,7 @@ impl InnerInputState {
if currently_contains && !previously_contained {
try_create_event(
"mouseover",
Rc::new(EventData::Mouse(prepare_mouse_data(
mouse_data,
&node_layout,
))),
EventData::Mouse(prepare_mouse_data(mouse_data, &node_layout)),
&mut will_bubble,
resolved_events,
node,
@@ -349,16 +394,13 @@ impl InnerInputState {
if was_pressed {
let mut will_bubble = FxHashSet::default();
for node in dom.get_listening_sorted("mousedown") {
let node_layout = get_abs_layout(node, dom, layout);
let node_layout = get_abs_layout(node, layout);
let currently_contains = layout_contains_point(&node_layout, new_pos);
if currently_contains {
try_create_event(
"mousedown",
Rc::new(EventData::Mouse(prepare_mouse_data(
mouse_data,
&node_layout,
))),
EventData::Mouse(prepare_mouse_data(mouse_data, &node_layout)),
&mut will_bubble,
resolved_events,
node,
@@ -373,16 +415,13 @@ impl InnerInputState {
if was_released {
let mut will_bubble = FxHashSet::default();
for node in dom.get_listening_sorted("mouseup") {
let node_layout = get_abs_layout(node, dom, layout);
let node_layout = get_abs_layout(node, layout);
let currently_contains = layout_contains_point(&node_layout, new_pos);
if currently_contains {
try_create_event(
"mouseup",
Rc::new(EventData::Mouse(prepare_mouse_data(
mouse_data,
&node_layout,
))),
EventData::Mouse(prepare_mouse_data(mouse_data, &node_layout)),
&mut will_bubble,
resolved_events,
node,
@@ -398,16 +437,13 @@ impl InnerInputState {
if mouse_data.trigger_button() == Some(DioxusMouseButton::Primary) && was_released {
let mut will_bubble = FxHashSet::default();
for node in dom.get_listening_sorted("click") {
let node_layout = get_abs_layout(node, dom, layout);
let node_layout = get_abs_layout(node, layout);
let currently_contains = layout_contains_point(&node_layout, new_pos);
if currently_contains {
try_create_event(
"click",
Rc::new(EventData::Mouse(prepare_mouse_data(
mouse_data,
&node_layout,
))),
EventData::Mouse(prepare_mouse_data(mouse_data, &node_layout)),
&mut will_bubble,
resolved_events,
node,
@@ -424,16 +460,13 @@ impl InnerInputState {
{
let mut will_bubble = FxHashSet::default();
for node in dom.get_listening_sorted("contextmenu") {
let node_layout = get_abs_layout(node, dom, layout);
let node_layout = get_abs_layout(node, layout);
let currently_contains = layout_contains_point(&node_layout, new_pos);
if currently_contains {
try_create_event(
"contextmenu",
Rc::new(EventData::Mouse(prepare_mouse_data(
mouse_data,
&node_layout,
))),
EventData::Mouse(prepare_mouse_data(mouse_data, &node_layout)),
&mut will_bubble,
resolved_events,
node,
@@ -450,14 +483,14 @@ impl InnerInputState {
if was_scrolled {
let mut will_bubble = FxHashSet::default();
for node in dom.get_listening_sorted("wheel") {
let node_layout = get_abs_layout(node, dom, layout);
let node_layout = get_abs_layout(node, layout);
let currently_contains = layout_contains_point(&node_layout, new_pos);
if currently_contains {
try_create_event(
"wheel",
Rc::new(EventData::Wheel(w.clone())),
EventData::Wheel(w.clone()),
&mut will_bubble,
resolved_events,
node,
@@ -473,7 +506,7 @@ impl InnerInputState {
// mouseleave
let mut will_bubble = FxHashSet::default();
for node in dom.get_listening_sorted("mouseleave") {
let node_layout = get_abs_layout(node, dom, layout);
let node_layout = get_abs_layout(node, layout);
let previously_contained = old_pos
.filter(|pos| layout_contains_point(&node_layout, *pos))
.is_some();
@@ -482,10 +515,7 @@ impl InnerInputState {
if !currently_contains && previously_contained {
try_create_event(
"mouseleave",
Rc::new(EventData::Mouse(prepare_mouse_data(
mouse_data,
&node_layout,
))),
EventData::Mouse(prepare_mouse_data(mouse_data, &node_layout)),
&mut will_bubble,
resolved_events,
node,
@@ -499,7 +529,7 @@ impl InnerInputState {
// mouseout
let mut will_bubble = FxHashSet::default();
for node in dom.get_listening_sorted("mouseout") {
let node_layout = get_abs_layout(node, dom, layout);
let node_layout = get_abs_layout(node, layout);
let previously_contained = old_pos
.filter(|pos| layout_contains_point(&node_layout, *pos))
.is_some();
@@ -508,10 +538,7 @@ impl InnerInputState {
if !currently_contains && previously_contained {
try_create_event(
"mouseout",
Rc::new(EventData::Mouse(prepare_mouse_data(
mouse_data,
&node_layout,
))),
EventData::Mouse(prepare_mouse_data(mouse_data, &node_layout)),
&mut will_bubble,
resolved_events,
node,
@@ -546,24 +573,6 @@ impl InnerInputState {
// }
}
fn get_abs_layout(node: NodeRef, dom: &RealDom, taffy: &Taffy) -> Layout {
let mut node_layout = *taffy
.layout(node.get::<TaffyLayout>().unwrap().node.unwrap())
.unwrap();
let mut current = node;
while let Some(parent) = current.parent_id() {
let parent = dom.get(parent).unwrap();
current = parent;
let parent_layout = taffy
.layout(parent.get::<TaffyLayout>().unwrap().node.unwrap())
.unwrap();
node_layout.location.x += parent_layout.location.x;
node_layout.location.y += parent_layout.location.y;
}
node_layout
}
pub struct RinkInputHandler {
state: Rc<RefCell<InnerInputState>>,
queued_events: Rc<RefCell<Vec<EventCore>>>,
@@ -628,12 +637,12 @@ impl RinkInputHandler {
})
.map(|evt| (evt.0, evt.1));
let mut hm: FxHashMap<&'static str, Vec<Rc<EventData>>> = FxHashMap::default();
let mut hm: FxHashMap<&'static str, Vec<EventData>> = FxHashMap::default();
for (event, data) in events {
if let Some(v) = hm.get_mut(event) {
v.push(Rc::new(data));
v.push(data);
} else {
hm.insert(event, vec![Rc::new(data)]);
hm.insert(event, vec![data]);
}
}
for (event, datas) in hm {