Evan Almloff hace 3 años
padre
commit
a03ab3edfb
Se han modificado 2 ficheros con 48 adiciones y 21 borrados
  1. 3 3
      examples/keys.rs
  2. 45 18
      src/hooks.rs

+ 3 - 3
examples/keys.rs

@@ -8,7 +8,7 @@ fn main() {
 }
 
 fn app(cx: Scope) -> Element {
-    let (key, set_key) = use_state(&cx, || KeyCode::Space);
+    let (key, set_key) = use_state(&cx, || "".to_string());
     let (mouse, set_mouse) = use_state(&cx, || (0, 0));
     let (count, set_count) = use_state(&cx, || 0);
     let (buttons, set_buttons) = use_state(&cx, || 0);
@@ -30,7 +30,7 @@ fn app(cx: Scope) -> Element {
                     KeyCode::DownArrow => set_count(count - 10),
                     _ => {},
                 }
-                set_key(evt.key_code);
+                set_key(format!("{:?} repeating: {:?}", evt.key, evt.repeat));
             },
             onwheel: move |evt: WheelEvent| {
                 set_count(count + evt.data.delta_y as i64);
@@ -49,7 +49,7 @@ fn app(cx: Scope) -> Element {
             },
 
             "count: {count:?}",
-            "key: {key:?}",
+            "key: {key}",
             "mouse buttons: {buttons:b}",
             "mouse pos: {mouse:?}",
             "mouse button pressed: {mouse_clicked}"

+ 45 - 18
src/hooks.rs

@@ -72,7 +72,7 @@ impl EventData {
 const MAX_REPEAT_TIME: Duration = Duration::from_millis(100);
 
 pub struct InnerInputState {
-    mouse: Option<MouseData>,
+    mouse: Option<(MouseData, Vec<u16>)>,
     wheel: Option<WheelData>,
     last_key_pressed: Option<(KeyboardData, Instant)>,
     screen: Option<(u16, u16)>,
@@ -93,26 +93,53 @@ impl InnerInputState {
     // stores current input state and transforms events based on that state
     fn apply_event(&mut self, evt: &mut EventCore) {
         match evt.1 {
+            // limitations: only two buttons may be held at once
             EventData::Mouse(ref mut m) => match &mut self.mouse {
                 Some(state) => {
-                    *state = clone_mouse_data(m);
-                    // crossterm always outputs the left mouse button on mouse up
-                    // let mut buttons = state.buttons;
-                    // *state = clone_mouse_data(m);
-                    // match evt.0 {
-                    //     "mouseup" => {
-                    //         buttons &= !m.buttons;
-                    //     }
-                    //     "mousedown" => {
-                    //         buttons |= m.buttons;
-                    //     }
-                    //     _ => (),
-                    // }
-                    // state.buttons = buttons;
-                    // m.buttons = buttons;
+                    let mut buttons = state.0.buttons;
+                    state.0 = clone_mouse_data(m);
+                    match evt.0 {
+                        // this code only runs when there are no buttons down
+                        "mouseup" => {
+                            buttons = 0;
+                            state.1 = Vec::new();
+                        }
+                        "mousedown" => {
+                            if state.1.contains(&m.buttons) {
+                                // if we already pressed a button and there is another button released the button crossterm sends is the button remaining
+                                if state.1.len() > 1 {
+                                    state.1 = vec![m.buttons];
+                                }
+                                // otherwise some other button was pressed. In testing it was consistantly this mapping
+                                else {
+                                    match m.buttons {
+                                        0x01 => state.1.push(0x02),
+                                        0x02 => state.1.push(0x01),
+                                        0x04 => state.1.push(0x01),
+                                        _ => (),
+                                    }
+                                }
+                            } else {
+                                state.1.push(m.buttons);
+                            }
+
+                            buttons = state.1.iter().copied().reduce(|a, b| a | b).unwrap();
+                        }
+                        _ => (),
+                    }
+                    state.0.buttons = buttons;
+                    m.buttons = buttons;
+                    // println!("{buttons}")
                 }
                 None => {
-                    self.mouse = Some(clone_mouse_data(m));
+                    self.mouse = Some((
+                        clone_mouse_data(m),
+                        if m.buttons == 0 {
+                            Vec::new()
+                        } else {
+                            vec![m.buttons]
+                        },
+                    ));
                 }
             },
             EventData::Wheel(ref w) => self.wheel = Some(clone_wheel_data(w)),
@@ -152,7 +179,7 @@ pub struct RinkInputHandler {
 
 impl RinkInputHandler {
     /// global context that handles events
-    /// limitations: GUI key modifier is never detected, key up events are not detected, and mouse up events are not specific to a key
+    /// limitations: GUI key modifier is never detected, key up events are not detected, and only two mouse buttons may be pressed at once
     pub fn new(
         mut receiver: UnboundedReceiver<TermEvent>,
         cx: &ScopeState,