diff --git a/src/input/crossterm.rs b/src/input/crossterm.rs index 3ee1c7b..cd7d094 100644 --- a/src/input/crossterm.rs +++ b/src/input/crossterm.rs @@ -4,7 +4,7 @@ use crate::crossterm::event::{ }; impl From for Input { - /// Convert [`crossterm::event::Event`] to [`Input`]. + /// Convert [`crossterm::event::Event`] into [`Input`]. fn from(event: Event) -> Self { match event { Event::Key(key) => Self::from(key), @@ -14,18 +14,10 @@ impl From for Input { } } -impl From for Input { - /// Convert [`crossterm::event::KeyEvent`] to [`Input`]. - fn from(key: KeyEvent) -> Self { - if key.kind == KeyEventKind::Release { - // On Windows or when `crossterm::event::PushKeyboardEnhancementFlags` is set, - // key release event can be reported. Ignore it. (#14) - return Self::default(); - } - - let ctrl = key.modifiers.contains(KeyModifiers::CONTROL); - let alt = key.modifiers.contains(KeyModifiers::ALT); - let key = match key.code { +impl From for Key { + /// Convert [`crossterm::event::KeyCode`] into [`Key`]. + fn from(code: KeyCode) -> Self { + match code { KeyCode::Char(c) => Key::Char(c), KeyCode::Backspace => Key::Backspace, KeyCode::Enter => Key::Enter, @@ -42,20 +34,42 @@ impl From for Input { KeyCode::Esc => Key::Esc, KeyCode::F(x) => Key::F(x), _ => Key::Null, - }; + } + } +} + +impl From for Input { + /// Convert [`crossterm::event::KeyEvent`] into [`Input`]. + fn from(key: KeyEvent) -> Self { + if key.kind == KeyEventKind::Release { + // On Windows or when `crossterm::event::PushKeyboardEnhancementFlags` is set, + // key release event can be reported. Ignore it. (#14) + return Self::default(); + } + + let ctrl = key.modifiers.contains(KeyModifiers::CONTROL); + let alt = key.modifiers.contains(KeyModifiers::ALT); + let key = Key::from(key.code); Self { key, ctrl, alt } } } -impl From for Input { - /// Convert [`crossterm::event::MouseEvent`] to [`Input`]. - fn from(mouse: MouseEvent) -> Self { - let key = match mouse.kind { +impl From for Key { + /// Convert [`crossterm::event::MouseEventKind`] into [`Key`]. + fn from(kind: MouseEventKind) -> Self { + match kind { MouseEventKind::ScrollDown => Key::MouseScrollDown, MouseEventKind::ScrollUp => Key::MouseScrollUp, _ => Key::Null, - }; + } + } +} + +impl From for Input { + /// Convert [`crossterm::event::MouseEvent`] into [`Input`]. + fn from(mouse: MouseEvent) -> Self { + let key = Key::from(mouse.kind); let ctrl = mouse.modifiers.contains(KeyModifiers::CONTROL); let alt = mouse.modifiers.contains(KeyModifiers::ALT); Self { key, ctrl, alt } @@ -172,9 +186,9 @@ mod tests { // Regression for https://github.com/rhysd/tui-textarea/issues/14 #[test] fn ignore_key_release_event() { - let mut k = key_event(KeyCode::Char('a'), KeyModifiers::empty()); - k.kind = KeyEventKind::Release; - let want = input(Key::Null, false, false); - assert_eq!(Input::from(k.clone()), want, "{:?} -> {:?}", k, want); + let mut from = key_event(KeyCode::Char('a'), KeyModifiers::empty()); + from.kind = KeyEventKind::Release; + let to = input(Key::Null, false, false); + assert_eq!(Input::from(from), to, "{:?} -> {:?}", from, to); } } diff --git a/src/input/termion.rs b/src/input/termion.rs index 12a23d7..aa2f68f 100644 --- a/src/input/termion.rs +++ b/src/input/termion.rs @@ -2,7 +2,7 @@ use super::{Input, Key}; use termion::event::{Event, Key as KeyEvent, MouseButton, MouseEvent}; impl From for Input { - /// Convert [`termion::event::Event`] to [`Input`]. + /// Convert [`termion::event::Event`] into [`Input`]. fn from(event: Event) -> Self { match event { Event::Key(key) => Self::from(key), @@ -13,7 +13,7 @@ impl From for Input { } impl From for Input { - /// Convert [`termion::event::Key`] to [`Input`]. + /// Convert [`termion::event::Key`] into [`Input`]. fn from(key: KeyEvent) -> Self { let mut ctrl = false; let mut alt = false; @@ -48,13 +48,24 @@ impl From for Input { } } +impl From for Key { + /// Convert [`termion::event::MouseButton`] into [`Key`]. + fn from(button: MouseButton) -> Self { + match button { + MouseButton::WheelUp => Key::MouseScrollUp, + MouseButton::WheelDown => Key::MouseScrollDown, + _ => Key::Null, + } + } +} + impl From for Input { - /// Convert [`termion::event::MouseEvent`] to [`Input`]. + /// Convert [`termion::event::MouseEvent`] into [`Input`]. fn from(mouse: MouseEvent) -> Self { - let key = match mouse { - MouseEvent::Press(MouseButton::WheelUp, ..) => Key::MouseScrollUp, - MouseEvent::Press(MouseButton::WheelDown, ..) => Key::MouseScrollDown, - _ => return Self::default(), + let key = if let MouseEvent::Press(button, ..) = mouse { + Key::from(button) + } else { + Key::Null }; Self { key, diff --git a/src/input/termwiz.rs b/src/input/termwiz.rs index ab5ff1a..ad82891 100644 --- a/src/input/termwiz.rs +++ b/src/input/termwiz.rs @@ -4,7 +4,7 @@ use termwiz::input::{ }; impl From for Input { - /// Convert [`termwiz::input::InputEvent`] to [`Input`]. + /// Convert [`termwiz::input::InputEvent`] into [`Input`]. fn from(input: InputEvent) -> Self { match input { InputEvent::Key(key) => Self::from(key), @@ -15,11 +15,10 @@ impl From for Input { } } -impl From for Input { - /// Convert [`termwiz::input::KeyEvent`] to [`Input`]. - fn from(key: KeyEvent) -> Self { - let KeyEvent { key, modifiers } = key; - let key = match key { +impl From for Key { + /// Convert [`termwiz::input::KeyCode`] into [`Key`]. + fn from(key: KeyCode) -> Self { + match key { KeyCode::Char(c) => Key::Char(c), KeyCode::Backspace => Key::Backspace, KeyCode::Tab => Key::Tab, @@ -36,7 +35,15 @@ impl From for Input { KeyCode::Delete => Key::Delete, KeyCode::Function(x) => Key::F(x), _ => Key::Null, - }; + } + } +} + +impl From for Input { + /// Convert [`termwiz::input::KeyEvent`] into [`Input`]. + fn from(key: KeyEvent) -> Self { + let KeyEvent { key, modifiers } = key; + let key = Key::from(key); let ctrl = modifiers.contains(Modifiers::CTRL); let alt = modifiers.contains(Modifiers::ALT); @@ -45,7 +52,7 @@ impl From for Input { } impl From for Key { - /// Convert [`termwiz::input::MouseButtons`] to [`Key`]. + /// Convert [`termwiz::input::MouseButtons`] into [`Key`]. fn from(buttons: MouseButtons) -> Self { if buttons.contains(MouseButtons::VERT_WHEEL) { if buttons.contains(MouseButtons::WHEEL_POSITIVE) { @@ -60,7 +67,7 @@ impl From for Key { } impl From for Input { - /// Convert [`termwiz::input::MouseEvent`] to [`Input`]. + /// Convert [`termwiz::input::MouseEvent`] into [`Input`]. fn from(mouse: MouseEvent) -> Self { let MouseEvent { mouse_buttons, @@ -76,13 +83,14 @@ impl From for Input { } impl From for Input { - /// Convert [`termwiz::input::PixelMouseEvent`] to [`Input`]. + /// Convert [`termwiz::input::PixelMouseEvent`] into [`Input`]. fn from(mouse: PixelMouseEvent) -> Self { let PixelMouseEvent { mouse_buttons, modifiers, .. } = mouse; + let key = Key::from(mouse_buttons); let ctrl = modifiers.contains(Modifiers::CTRL); let alt = modifiers.contains(Modifiers::ALT);