Переглянути джерело

TUI: use constructor instead of deprecated fields

Reinis Mazeiks 3 роки тому
батько
коміт
9c6cd42ca2
2 змінених файлів з 44 додано та 33 видалено
  1. 7 5
      packages/html/src/events.rs
  2. 37 28
      packages/tui/src/hooks.rs

+ 7 - 5
packages/html/src/events.rs

@@ -9,7 +9,6 @@ pub mod on {
     use crate::input::{
         decode_mouse_button_set, encode_mouse_button_set, MouseButton, MouseButtonSet,
     };
-    use enumset::EnumSet;
     use keyboard_types::Modifiers;
     use std::collections::HashMap;
 
@@ -570,9 +569,12 @@ pub mod on {
     }
 
     impl MouseData {
+        /// Construct MouseData with the specified properties
+        ///
+        /// Note: the current implementation truncates coordinates. In the future, when we change the internal representation, it may also support a fractional part.
         pub fn new(
             coordinates: Coordinates,
-            trigger_button: MouseButton,
+            trigger_button: Option<MouseButton>,
             held_buttons: MouseButtonSet,
             modifiers: Modifiers,
         ) -> Self {
@@ -593,7 +595,7 @@ pub mod on {
                 meta_key,
                 shift_key,
 
-                button: trigger_button.into_web_code(),
+                button: trigger_button.map_or(0, |b| b.into_web_code()),
                 buttons: encode_mouse_button_set(held_buttons),
 
                 client_x,
@@ -670,9 +672,9 @@ pub mod on {
         ///
         // todo the following is kind of bad; should we just return None when the trigger_button is unreliable (and frankly irrelevant)? i guess we would need the event_type here
         /// This is only guaranteed to indicate which button was pressed during events caused by pressing or releasing a button. As such, it is not reliable for events such as mouseenter, mouseleave, mouseover, mouseout, or mousemove. For example, a value of MouseButton::Primary may also indicate that no button was pressed.
-        pub fn trigger_button(&self) -> MouseButton {
+        pub fn trigger_button(&self) -> Option<MouseButton> {
             #[allow(deprecated)]
-            MouseButton::from_web_code(self.button)
+            Some(MouseButton::from_web_code(self.button))
         }
     }
 

+ 37 - 28
packages/tui/src/hooks.rs

@@ -4,6 +4,10 @@ use crossterm::event::{
 use dioxus_core::*;
 use fxhash::{FxHashMap, FxHashSet};
 
+use dioxus_html::geometry::{ClientPoint, Coordinates, ElementPoint, PagePoint, ScreenPoint};
+use dioxus_html::input::keyboard_types::Modifiers;
+use dioxus_html::input::MouseButton as DioxusMouseButton;
+use dioxus_html::input::MouseButtonSet as DioxusMouseButtons;
 use dioxus_html::{on::*, KeyCode};
 use std::{
     any::Any,
@@ -588,40 +592,45 @@ fn get_event(evt: TermEvent) -> Option<(&'static str, EventData)> {
             let ctrl = m.modifiers.contains(KeyModifiers::CONTROL);
             let meta = false;
 
-            let get_mouse_data = |b| {
-                let buttons = match b {
-                    None => 0,
-                    Some(MouseButton::Left) => 1,
-                    Some(MouseButton::Right) => 2,
-                    Some(MouseButton::Middle) => 4,
-                };
-                let button_state = match b {
-                    None => 0,
-                    Some(MouseButton::Left) => 0,
-                    Some(MouseButton::Middle) => 1,
-                    Some(MouseButton::Right) => 2,
+            let get_mouse_data = |crossterm_button: Option<MouseButton>| {
+                let button = crossterm_button.map(|b| match b {
+                    MouseButton::Left => DioxusMouseButton::Primary,
+                    MouseButton::Right => DioxusMouseButton::Secondary,
+                    MouseButton::Middle => DioxusMouseButton::Auxiliary,
+                });
+
+                let button_set = match button {
+                    None => DioxusMouseButtons::empty(),
+                    Some(button) => DioxusMouseButtons::only(button),
                 };
+
                 // from https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent
 
                 // The `offset`, `page` and `screen` coordinates are inconsistent with the MDN definition, as they are relative to the viewport (client), not the target element/page/screen, respectively.
                 // todo?
                 // But then, MDN defines them in terms of pixels, yet crossterm provides only row/column, and it might not be possible to get pixels. So we can't get 100% consistency anyway.
-                EventData::Mouse(MouseData {
-                    alt_key: alt,
-                    button: button_state,
-                    buttons,
-                    client_x: x,
-                    client_y: y,
-                    ctrl_key: ctrl,
-                    meta_key: meta,
-                    offset_x: x,
-                    offset_y: y,
-                    page_x: x,
-                    page_y: y,
-                    screen_x: x,
-                    screen_y: y,
-                    shift_key: shift,
-                })
+                let coordinates = Coordinates::new(
+                    ScreenPoint::new(x, y),
+                    ClientPoint::new(x, y),
+                    ElementPoint::new(x, y),
+                    PagePoint::new(x, y),
+                );
+
+                let mut modifiers = Modifiers::empty();
+                if shift {
+                    modifiers.insert(Modifiers::SHIFT);
+                }
+                if ctrl {
+                    modifiers.insert(Modifiers::CONTROL);
+                }
+                if meta {
+                    modifiers.insert(Modifiers::META);
+                }
+                if alt {
+                    modifiers.insert(Modifiers::ALT);
+                }
+
+                EventData::Mouse(MouseData::new(coordinates, button, button_set, modifiers))
             };
 
             let get_wheel_data = |up| {