From 1d699b0b6ea0cbe9609aaf02a24ac5683d922eed Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Mon, 13 Jun 2022 19:42:03 -0500 Subject: [PATCH] fix absolute position for mouse events --- packages/tui/src/hooks.rs | 84 +++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 34 deletions(-) diff --git a/packages/tui/src/hooks.rs b/packages/tui/src/hooks.rs index 3a1646fdf..98102c5ba 100644 --- a/packages/tui/src/hooks.rs +++ b/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>, queued_events: Rc>>,