Merge pull request #940 from Demonthos/make-widgets-cross-framework
This commit is contained in:
44 files changed
+3232
-1185
No files matched your search
+82
-73
@@ -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 {
|
||||
|
||||
Reference in new issue
Block a user