From 9c6cd42ca24119358a69653e1934fe0bae9221bc Mon Sep 17 00:00:00 2001 From: Reinis Mazeiks Date: Sat, 7 May 2022 10:49:49 +0300 Subject: [PATCH] TUI: use constructor instead of deprecated fields --- packages/html/src/events.rs | 12 ++++--- packages/tui/src/hooks.rs | 65 +++++++++++++++++++++---------------- 2 files changed, 44 insertions(+), 33 deletions(-) diff --git a/packages/html/src/events.rs b/packages/html/src/events.rs index 4f2507292..fa1791e60 100644 --- a/packages/html/src/events.rs +++ b/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, 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 { #[allow(deprecated)] - MouseButton::from_web_code(self.button) + Some(MouseButton::from_web_code(self.button)) } } diff --git a/packages/tui/src/hooks.rs b/packages/tui/src/hooks.rs index 04d320fcb..722c2598c 100644 --- a/packages/tui/src/hooks.rs +++ b/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| { + 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| {