Преглед на файлове

TUI mouse press&release: Replace usage of deprecated fields with accessors

Reinis Mazeiks преди 3 години
родител
ревизия
df59d5148e
променени са 1 файла, в които са добавени 31 реда и са изтрити 18 реда
  1. 31 18
      packages/tui/src/hooks.rs

+ 31 - 18
packages/tui/src/hooks.rs

@@ -4,6 +4,7 @@ use crossterm::event::{
 use dioxus_core::*;
 use fxhash::{FxHashMap, FxHashSet};
 
+use dioxus_html::geometry::euclid::{Point2D, Rect, Size2D};
 use dioxus_html::geometry::{ClientPoint, Coordinates, ElementPoint, PagePoint, ScreenPoint};
 use dioxus_html::input::keyboard_types::Modifiers;
 use dioxus_html::input::MouseButtonSet as DioxusMouseButtons;
@@ -16,7 +17,7 @@ use std::{
     sync::Arc,
     time::{Duration, Instant},
 };
-use stretch2::geometry::Point;
+use stretch2::geometry::{Point, Size};
 use stretch2::{prelude::Layout, Stretch};
 
 use crate::{Dom, Node};
@@ -177,11 +178,12 @@ impl InnerInputState {
         layout: &Stretch,
         dom: &mut Dom,
     ) {
-        fn layout_contains_point(layout: &Layout, point: (i32, i32)) -> bool {
-            layout.location.x as i32 <= point.0
-                && layout.location.x as i32 + layout.size.width as i32 >= point.0
-                && layout.location.y as i32 <= point.1
-                && layout.location.y as i32 + layout.size.height as i32 >= point.1
+        fn layout_contains_point(layout: &Layout, point: ScreenPoint) -> bool {
+            let Point { x, y } = layout.location;
+            let Size { width, height } = layout.size;
+
+            let layout_rect = Rect::new(Point2D::new(x, y), Size2D::new(width, height));
+            layout_rect.contains(point.cast())
         }
 
         fn try_create_event(
@@ -233,14 +235,19 @@ impl InnerInputState {
         }
 
         if let Some(mouse_data) = &self.mouse {
-            let new_pos = (mouse_data.screen_x, mouse_data.screen_y);
-            let old_pos = previous_mouse.as_ref().map(|m| (m.screen_x, m.screen_y));
-            // the a mouse button is pressed if a button was not down and is now down
-            let pressed =
-                (mouse_data.buttons & !previous_mouse.as_ref().map(|m| m.buttons).unwrap_or(0)) > 0;
-            // the a mouse button is pressed if a button was down and is now not down
-            let released =
-                (!mouse_data.buttons & previous_mouse.map(|m| m.buttons).unwrap_or(0)) > 0;
+            let new_pos = mouse_data.screen_coordinates();
+            let old_pos = previous_mouse.as_ref().map(|m| m.screen_coordinates());
+
+            // a mouse button is pressed if a button was not down and is now down
+            let previous_buttons = previous_mouse
+                .map_or(MouseButtonSet::empty(), |previous_data| {
+                    previous_data.held_buttons()
+                });
+            let was_pressed = !(mouse_data.held_buttons() - previous_buttons).is_empty();
+
+            // a mouse button is released if a button was down and is now not down
+            let was_released = !(previous_buttons - mouse_data.held_buttons()).is_empty();
+
             let wheel_delta = self.wheel.as_ref().map_or(0.0, |w| w.delta_y);
             let wheel_data = &self.wheel;
 
@@ -316,7 +323,7 @@ impl InnerInputState {
             }
 
             // mousedown
-            if pressed {
+            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();
@@ -342,7 +349,7 @@ impl InnerInputState {
                     let node_layout = layout.layout(node.state.layout.node.unwrap()).unwrap();
                     let currently_contains = layout_contains_point(node_layout, new_pos);
 
-                    if currently_contains && released {
+                    if currently_contains && was_released {
                         try_create_event(
                             "mouseup",
                             Arc::new(prepare_mouse_data(mouse_data, node_layout)),
@@ -362,7 +369,10 @@ impl InnerInputState {
                     let node_layout = layout.layout(node.state.layout.node.unwrap()).unwrap();
                     let currently_contains = layout_contains_point(node_layout, new_pos);
 
-                    if currently_contains && released && mouse_data.button == 0 {
+                    if currently_contains
+                        && was_released
+                        && mouse_data.trigger_button() == Some(DioxusMouseButton::Primary)
+                    {
                         try_create_event(
                             "click",
                             Arc::new(prepare_mouse_data(mouse_data, node_layout)),
@@ -382,7 +392,10 @@ impl InnerInputState {
                     let node_layout = layout.layout(node.state.layout.node.unwrap()).unwrap();
                     let currently_contains = layout_contains_point(node_layout, new_pos);
 
-                    if currently_contains && released && mouse_data.button == 2 {
+                    if currently_contains
+                        && was_released
+                        && mouse_data.trigger_button() == Some(DioxusMouseButton::Secondary)
+                    {
                         try_create_event(
                             "contextmenu",
                             Arc::new(prepare_mouse_data(mouse_data, node_layout)),