1
0
Эх сурвалжийг харах

fix absolute position for mouse events

Evan Almloff 3 жил өмнө
parent
commit
1d699b0b6e
1 өөрчлөгдсөн 50 нэмэгдсэн , 34 устгасан
  1. 50 34
      packages/tui/src/hooks.rs

+ 50 - 34
packages/tui/src/hooks.rs

@@ -256,16 +256,16 @@ 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 = layout.layout(node.state.layout.node.unwrap()).unwrap();
+                        let node_layout = get_abs_layout(node, dom, layout);
                         let previously_contained = old_pos
-                            .filter(|pos| layout_contains_point(node_layout, *pos))
+                            .filter(|pos| layout_contains_point(&node_layout, *pos))
                             .is_some();
-                        let currently_contains = layout_contains_point(node_layout, new_pos);
+                        let currently_contains = layout_contains_point(&node_layout, new_pos);
 
                         if currently_contains && previously_contained {
                             try_create_event(
                                 "mousemove",
-                                Arc::new(prepare_mouse_data(mouse_data, node_layout)),
+                                Arc::new(prepare_mouse_data(mouse_data, &node_layout)),
                                 &mut will_bubble,
                                 resolved_events,
                                 node,
@@ -280,11 +280,11 @@ impl InnerInputState {
                 // mouseenter
                 let mut will_bubble = FxHashSet::default();
                 for node in dom.get_listening_sorted("mouseenter") {
-                    let node_layout = layout.layout(node.state.layout.node.unwrap()).unwrap();
+                    let node_layout = get_abs_layout(node, dom, layout);
                     let previously_contained = old_pos
-                        .filter(|pos| layout_contains_point(node_layout, *pos))
+                        .filter(|pos| layout_contains_point(&node_layout, *pos))
                         .is_some();
-                    let currently_contains = layout_contains_point(node_layout, new_pos);
+                    let currently_contains = layout_contains_point(&node_layout, new_pos);
 
                     if currently_contains && !previously_contained {
                         try_create_event(
@@ -303,16 +303,16 @@ impl InnerInputState {
                 // mouseover
                 let mut will_bubble = FxHashSet::default();
                 for node in dom.get_listening_sorted("mouseover") {
-                    let node_layout = layout.layout(node.state.layout.node.unwrap()).unwrap();
+                    let node_layout = get_abs_layout(node, dom, layout);
                     let previously_contained = old_pos
-                        .filter(|pos| layout_contains_point(node_layout, *pos))
+                        .filter(|pos| layout_contains_point(&node_layout, *pos))
                         .is_some();
-                    let currently_contains = layout_contains_point(node_layout, new_pos);
+                    let currently_contains = layout_contains_point(&node_layout, new_pos);
 
                     if currently_contains && !previously_contained {
                         try_create_event(
                             "mouseover",
-                            Arc::new(prepare_mouse_data(mouse_data, node_layout)),
+                            Arc::new(prepare_mouse_data(mouse_data, &node_layout)),
                             &mut will_bubble,
                             resolved_events,
                             node,
@@ -326,13 +326,13 @@ impl InnerInputState {
             if was_pressed {
                 let mut will_bubble = FxHashSet::default();
                 for node in dom.get_listening_sorted("mousedown") {
-                    let node_layout = layout.layout(node.state.layout.node.unwrap()).unwrap();
-                    let currently_contains = layout_contains_point(node_layout, new_pos);
+                    let node_layout = get_abs_layout(node, dom, layout);
+                    let currently_contains = layout_contains_point(&node_layout, new_pos);
 
                     if currently_contains {
                         try_create_event(
                             "mousedown",
-                            Arc::new(prepare_mouse_data(mouse_data, node_layout)),
+                            Arc::new(prepare_mouse_data(mouse_data, &node_layout)),
                             &mut will_bubble,
                             resolved_events,
                             node,
@@ -347,13 +347,13 @@ impl InnerInputState {
                 if was_released {
                     let mut will_bubble = FxHashSet::default();
                     for node in dom.get_listening_sorted("mouseup") {
-                        let node_layout = layout.layout(node.state.layout.node.unwrap()).unwrap();
-                        let currently_contains = layout_contains_point(node_layout, new_pos);
+                        let node_layout = get_abs_layout(node, dom, layout);
+                        let currently_contains = layout_contains_point(&node_layout, new_pos);
 
                         if currently_contains {
                             try_create_event(
                                 "mouseup",
-                                Arc::new(prepare_mouse_data(mouse_data, node_layout)),
+                                Arc::new(prepare_mouse_data(mouse_data, &node_layout)),
                                 &mut will_bubble,
                                 resolved_events,
                                 node,
@@ -369,13 +369,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 = layout.layout(node.state.layout.node.unwrap()).unwrap();
-                        let currently_contains = layout_contains_point(node_layout, new_pos);
+                        let node_layout = get_abs_layout(node, dom, layout);
+                        let currently_contains = layout_contains_point(&node_layout, new_pos);
 
                         if currently_contains {
                             try_create_event(
                                 "click",
-                                Arc::new(prepare_mouse_data(mouse_data, node_layout)),
+                                Arc::new(prepare_mouse_data(mouse_data, &node_layout)),
                                 &mut will_bubble,
                                 resolved_events,
                                 node,
@@ -392,13 +392,13 @@ impl InnerInputState {
                 {
                     let mut will_bubble = FxHashSet::default();
                     for node in dom.get_listening_sorted("contextmenu") {
-                        let node_layout = layout.layout(node.state.layout.node.unwrap()).unwrap();
-                        let currently_contains = layout_contains_point(node_layout, new_pos);
+                        let node_layout = get_abs_layout(node, dom, layout);
+                        let currently_contains = layout_contains_point(&node_layout, new_pos);
 
                         if currently_contains {
                             try_create_event(
                                 "contextmenu",
-                                Arc::new(prepare_mouse_data(mouse_data, node_layout)),
+                                Arc::new(prepare_mouse_data(mouse_data, &node_layout)),
                                 &mut will_bubble,
                                 resolved_events,
                                 node,
@@ -415,9 +415,9 @@ impl InnerInputState {
                     if wheel_delta != 0.0 {
                         let mut will_bubble = FxHashSet::default();
                         for node in dom.get_listening_sorted("wheel") {
-                            let node_layout =
-                                layout.layout(node.state.layout.node.unwrap()).unwrap();
-                            let currently_contains = layout_contains_point(node_layout, new_pos);
+                            let node_layout = get_abs_layout(node, dom, layout);
+
+                            let currently_contains = layout_contains_point(&node_layout, new_pos);
 
                             if currently_contains {
                                 try_create_event(
@@ -438,16 +438,16 @@ impl InnerInputState {
                 // mouseleave
                 let mut will_bubble = FxHashSet::default();
                 for node in dom.get_listening_sorted("mouseleave") {
-                    let node_layout = layout.layout(node.state.layout.node.unwrap()).unwrap();
+                    let node_layout = get_abs_layout(node, dom, layout);
                     let previously_contained = old_pos
-                        .filter(|pos| layout_contains_point(node_layout, *pos))
+                        .filter(|pos| layout_contains_point(&node_layout, *pos))
                         .is_some();
-                    let currently_contains = layout_contains_point(node_layout, new_pos);
+                    let currently_contains = layout_contains_point(&node_layout, new_pos);
 
                     if !currently_contains && previously_contained {
                         try_create_event(
                             "mouseleave",
-                            Arc::new(prepare_mouse_data(mouse_data, node_layout)),
+                            Arc::new(prepare_mouse_data(mouse_data, &node_layout)),
                             &mut will_bubble,
                             resolved_events,
                             node,
@@ -461,16 +461,16 @@ impl InnerInputState {
                 // mouseout
                 let mut will_bubble = FxHashSet::default();
                 for node in dom.get_listening_sorted("mouseout") {
-                    let node_layout = layout.layout(node.state.layout.node.unwrap()).unwrap();
+                    let node_layout = get_abs_layout(node, dom, layout);
                     let previously_contained = old_pos
-                        .filter(|pos| layout_contains_point(node_layout, *pos))
+                        .filter(|pos| layout_contains_point(&node_layout, *pos))
                         .is_some();
-                    let currently_contains = layout_contains_point(node_layout, new_pos);
+                    let currently_contains = layout_contains_point(&node_layout, new_pos);
 
                     if !currently_contains && previously_contained {
                         try_create_event(
                             "mouseout",
-                            Arc::new(prepare_mouse_data(mouse_data, node_layout)),
+                            Arc::new(prepare_mouse_data(mouse_data, &node_layout)),
                             &mut will_bubble,
                             resolved_events,
                             node,
@@ -487,6 +487,22 @@ impl InnerInputState {
     // }
 }
 
+fn get_abs_layout(node: &Node, dom: &Dom, taffy: &Taffy) -> Layout {
+    let mut node_layout = taffy
+        .layout(node.state.layout.node.unwrap())
+        .unwrap()
+        .clone();
+    let mut current = node;
+    while let Some(parent_id) = current.parent {
+        let parent = &dom[parent_id];
+        current = parent;
+        let parent_layout = taffy.layout(parent.state.layout.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>>>,