From df59d5148ed7d79dc39f872018e24e3b8139f8f8 Mon Sep 17 00:00:00 2001 From: Reinis Mazeiks Date: Sat, 7 May 2022 16:27:34 +0300 Subject: [PATCH] TUI mouse press&release: Replace usage of deprecated fields with accessors --- packages/tui/src/hooks.rs | 49 +++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/packages/tui/src/hooks.rs b/packages/tui/src/hooks.rs index c8d890d83..1dcddf5f4 100644 --- a/packages/tui/src/hooks.rs +++ b/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)),