diff options
author | Silas Bartha <silas@exvacuum.dev> | 2024-12-20 08:02:55 -0500 |
---|---|---|
committer | Silas Bartha <silas@exvacuum.dev> | 2024-12-20 08:02:55 -0500 |
commit | 652a17e0f90a045b99a80044be313e23b9529005 (patch) | |
tree | 0fec702d8a143cc67c1845eb4214aba5ee0d1d7d /src/input/systems.rs | |
parent | 87172fd904a9d461b10438be7dc55660e7ced680 (diff) | |
parent | 39e8be3872232d929c4ccaa1b595bf61d656b2fe (diff) |
Merge branch 'wip'
Diffstat (limited to 'src/input/systems.rs')
-rw-r--r-- | src/input/systems.rs | 306 |
1 files changed, 290 insertions, 16 deletions
diff --git a/src/input/systems.rs b/src/input/systems.rs index 9be9f25..e851977 100644 --- a/src/input/systems.rs +++ b/src/input/systems.rs @@ -1,12 +1,21 @@ use std::cmp::Ordering; -use bevy::prelude::*; -use crossterm::event::{read, Event, KeyEvent, KeyEventKind}; +use bevy::{ + input::{keyboard::KeyboardInput, ButtonState}, + prelude::*, +}; +use crossterm::event::{read, Event, KeyEvent, KeyEventKind, MediaKeyCode, ModifierKeyCode}; +use smol_str::SmolStr; -use super::{events::TerminalInputEvent, resources::{EventQueue, TerminalInput}}; +use super::{ + components::DummyWindow, + events::TerminalInputEvent, + resources::EventQueue, +}; /// Initializes event queue and thread -pub fn setup_input(event_queue: Res<EventQueue>) { +pub fn setup_input(mut commands: Commands, event_queue: Res<EventQueue>) { + commands.spawn(DummyWindow); let event_queue = event_queue.0.clone(); std::thread::spawn(move || { loop { @@ -26,30 +35,295 @@ pub fn setup_input(event_queue: Res<EventQueue>) { /// Reads events from queue and broadcasts corresponding `TerminalInputEvent`s pub fn input_handling( event_queue: Res<EventQueue>, - mut input: ResMut<TerminalInput>, - mut event_writer: EventWriter<TerminalInputEvent>, + dummy_window_query: Query<Entity, With<DummyWindow>>, + mut terminal_event_writer: EventWriter<TerminalInputEvent>, + mut key_event_writer: EventWriter<KeyboardInput>, ) { - input.clear_just_released(); - input.clear_just_pressed(); let mut event_queue = event_queue.0.lock().unwrap(); let mut key_events = Vec::<KeyEvent>::new(); while let Some(event) = event_queue.pop() { if let Event::Key(event) = event { key_events.push(event); } - event_writer.send(TerminalInputEvent(event)); + terminal_event_writer.send(TerminalInputEvent(event)); } key_events.sort_by(|&a, &b| a.kind.partial_cmp(&b.kind).unwrap_or(Ordering::Equal)); + let window = dummy_window_query.single(); for event in key_events { - match event.kind { - KeyEventKind::Press => { - input.press(event.code); - } - KeyEventKind::Release => { - input.release(event.code); + if let Some(key_code) = crossterm_keycode_to_bevy_keycode(event.code) { + if let Some(logical_key) = crossterm_keycode_to_bevy_key(event.code) { + match event.kind { + KeyEventKind::Press | KeyEventKind::Repeat => { + // input.press(event.code); + key_event_writer.send(KeyboardInput { + key_code, + logical_key, + state: ButtonState::Pressed, + window, + }); + } + KeyEventKind::Release => { + key_event_writer.send(KeyboardInput { + key_code, + logical_key, + state: ButtonState::Released, + window, + }); + } + } } - _ => (), } } } + +fn crossterm_keycode_to_bevy_keycode( + crossterm_keycode: crossterm::event::KeyCode, +) -> Option<bevy::input::keyboard::KeyCode> { + use bevy::input::keyboard::KeyCode as BKey; + use crossterm::event::KeyCode as CKey; + match crossterm_keycode { + CKey::Backspace => Some(BKey::Backspace), + CKey::Enter => Some(BKey::Enter), + CKey::Left => Some(BKey::ArrowLeft), + CKey::Right => Some(BKey::ArrowRight), + CKey::Up => Some(BKey::ArrowUp), + CKey::Down => Some(BKey::ArrowDown), + CKey::Home => Some(BKey::Home), + CKey::End => Some(BKey::End), + CKey::PageUp => Some(BKey::PageUp), + CKey::PageDown => Some(BKey::PageDown), + CKey::Tab | CKey::BackTab => Some(BKey::Tab), + CKey::Delete => Some(BKey::Delete), + CKey::Insert => Some(BKey::Insert), + CKey::F(num) => match num { + 1 => Some(BKey::F1), + 2 => Some(BKey::F2), + 3 => Some(BKey::F3), + 4 => Some(BKey::F4), + 5 => Some(BKey::F5), + 6 => Some(BKey::F6), + 7 => Some(BKey::F7), + 8 => Some(BKey::F8), + 9 => Some(BKey::F9), + 10 => Some(BKey::F10), + 11 => Some(BKey::F11), + 12 => Some(BKey::F12), + 13 => Some(BKey::F13), + 14 => Some(BKey::F14), + 15 => Some(BKey::F15), + 16 => Some(BKey::F16), + 17 => Some(BKey::F17), + 18 => Some(BKey::F18), + 19 => Some(BKey::F19), + 20 => Some(BKey::F20), + 21 => Some(BKey::F21), + 22 => Some(BKey::F22), + 23 => Some(BKey::F23), + 24 => Some(BKey::F24), + 25 => Some(BKey::F25), + 26 => Some(BKey::F26), + 27 => Some(BKey::F27), + 28 => Some(BKey::F28), + 29 => Some(BKey::F29), + 30 => Some(BKey::F30), + 31 => Some(BKey::F31), + 32 => Some(BKey::F32), + 33 => Some(BKey::F33), + 34 => Some(BKey::F34), + 35 => Some(BKey::F35), + _ => None, + }, + CKey::Char(c) => match c { + '1' | '!' => Some(BKey::Digit1), + '2' | '@' => Some(BKey::Digit2), + '3' | '#' => Some(BKey::Digit3), + '4' | '$' => Some(BKey::Digit4), + '5' | '%' => Some(BKey::Digit5), + '6' | '^' => Some(BKey::Digit5), + '7' | '&' => Some(BKey::Digit7), + '8' | '*' => Some(BKey::Digit8), + '9' | '(' => Some(BKey::Digit9), + '0' | ')' => Some(BKey::Digit0), + '-' | '_' => Some(BKey::Minus), + '=' | '+' => Some(BKey::Equal), + '`' | '~' => Some(BKey::Backquote), + 'q' | 'Q' => Some(BKey::KeyQ), + 'w' | 'W' => Some(BKey::KeyW), + 'e' | 'E' => Some(BKey::KeyE), + 'r' | 'R' => Some(BKey::KeyR), + 't' | 'T' => Some(BKey::KeyT), + 'y' | 'Y' => Some(BKey::KeyY), + 'u' | 'U' => Some(BKey::KeyU), + 'i' | 'I' => Some(BKey::KeyI), + 'o' | 'O' => Some(BKey::KeyO), + 'p' | 'P' => Some(BKey::KeyP), + '[' | '{' => Some(BKey::BracketLeft), + ']' | '}' => Some(BKey::BracketRight), + 'a' | 'A' => Some(BKey::KeyA), + 's' | 'S' => Some(BKey::KeyS), + 'd' | 'D' => Some(BKey::KeyD), + 'f' | 'F' => Some(BKey::KeyF), + 'g' | 'G' => Some(BKey::KeyG), + 'h' | 'H' => Some(BKey::KeyH), + 'j' | 'J' => Some(BKey::KeyJ), + 'k' | 'K' => Some(BKey::KeyK), + 'l' | 'L' => Some(BKey::KeyL), + ';' | ':' => Some(BKey::Semicolon), + '\'' | '"' => Some(BKey::Slash), + 'z' | 'Z' => Some(BKey::KeyZ), + 'x' | 'X' => Some(BKey::KeyX), + 'c' | 'C' => Some(BKey::KeyC), + 'v' | 'V' => Some(BKey::KeyV), + 'b' | 'B' => Some(BKey::KeyB), + 'n' | 'N' => Some(BKey::KeyN), + 'm' | 'M' => Some(BKey::KeyM), + ',' | '<' => Some(BKey::Comma), + '.' | '>' => Some(BKey::Period), + '/' | '?' => Some(BKey::Slash), + ' ' => Some(BKey::Space), + _ => None, + }, + CKey::Null => None, + CKey::Esc => Some(BKey::Escape), + CKey::CapsLock => Some(BKey::CapsLock), + CKey::ScrollLock => Some(BKey::ScrollLock), + CKey::NumLock => Some(BKey::NumLock), + CKey::PrintScreen => Some(BKey::PrintScreen), + CKey::Pause => Some(BKey::Pause), + CKey::Menu => Some(BKey::ContextMenu), + CKey::KeypadBegin => None, + CKey::Media(media) => match media { + MediaKeyCode::Play => Some(BKey::MediaPlayPause), + MediaKeyCode::Pause => Some(BKey::Pause), + MediaKeyCode::PlayPause => Some(BKey::MediaPlayPause), + MediaKeyCode::Reverse => None, + MediaKeyCode::Stop => Some(BKey::MediaStop), + MediaKeyCode::FastForward => Some(BKey::MediaTrackNext), + MediaKeyCode::Rewind => Some(BKey::MediaTrackPrevious), + MediaKeyCode::TrackNext => Some(BKey::MediaTrackNext), + MediaKeyCode::TrackPrevious => Some(BKey::MediaTrackPrevious), + MediaKeyCode::Record => None, + MediaKeyCode::LowerVolume => Some(BKey::AudioVolumeDown), + MediaKeyCode::RaiseVolume => Some(BKey::AudioVolumeUp), + MediaKeyCode::MuteVolume => Some(BKey::AudioVolumeMute), + }, + CKey::Modifier(modifier) => match modifier { + ModifierKeyCode::LeftShift => Some(BKey::ShiftLeft), + ModifierKeyCode::LeftControl => Some(BKey::ControlLeft), + ModifierKeyCode::LeftAlt => Some(BKey::AltLeft), + ModifierKeyCode::LeftSuper => Some(BKey::SuperLeft), + ModifierKeyCode::LeftHyper => Some(BKey::Hyper), + ModifierKeyCode::LeftMeta => Some(BKey::Meta), + ModifierKeyCode::RightShift => Some(BKey::ShiftRight), + ModifierKeyCode::RightControl => Some(BKey::ControlRight), + ModifierKeyCode::RightAlt => Some(BKey::AltLeft), + ModifierKeyCode::RightSuper => Some(BKey::SuperRight), + ModifierKeyCode::RightHyper => Some(BKey::Hyper), + ModifierKeyCode::RightMeta => Some(BKey::Meta), + ModifierKeyCode::IsoLevel3Shift => None, + ModifierKeyCode::IsoLevel5Shift => None, + }, + } +} + +fn crossterm_keycode_to_bevy_key( + crossterm_keycode: crossterm::event::KeyCode, +) -> Option<bevy::input::keyboard::Key> { + use bevy::input::keyboard::Key as BKey; + use crossterm::event::KeyCode as CKey; + match crossterm_keycode { + CKey::Backspace => Some(BKey::Backspace), + CKey::Enter => Some(BKey::Enter), + CKey::Left => Some(BKey::ArrowLeft), + CKey::Right => Some(BKey::ArrowRight), + CKey::Up => Some(BKey::ArrowUp), + CKey::Down => Some(BKey::ArrowDown), + CKey::Home => Some(BKey::Home), + CKey::End => Some(BKey::End), + CKey::PageUp => Some(BKey::PageUp), + CKey::PageDown => Some(BKey::PageDown), + CKey::Tab | CKey::BackTab => Some(BKey::Tab), + CKey::Delete => Some(BKey::Delete), + CKey::Insert => Some(BKey::Insert), + CKey::F(num) => match num { + 1 => Some(BKey::F1), + 2 => Some(BKey::F2), + 3 => Some(BKey::F3), + 4 => Some(BKey::F4), + 5 => Some(BKey::F5), + 6 => Some(BKey::F6), + 7 => Some(BKey::F7), + 8 => Some(BKey::F8), + 9 => Some(BKey::F9), + 10 => Some(BKey::F10), + 11 => Some(BKey::F11), + 12 => Some(BKey::F12), + 13 => Some(BKey::F13), + 14 => Some(BKey::F14), + 15 => Some(BKey::F15), + 16 => Some(BKey::F16), + 17 => Some(BKey::F17), + 18 => Some(BKey::F18), + 19 => Some(BKey::F19), + 20 => Some(BKey::F20), + 21 => Some(BKey::F21), + 22 => Some(BKey::F22), + 23 => Some(BKey::F23), + 24 => Some(BKey::F24), + 25 => Some(BKey::F25), + 26 => Some(BKey::F26), + 27 => Some(BKey::F27), + 28 => Some(BKey::F28), + 29 => Some(BKey::F29), + 30 => Some(BKey::F30), + 31 => Some(BKey::F31), + 32 => Some(BKey::F32), + 33 => Some(BKey::F33), + 34 => Some(BKey::F34), + 35 => Some(BKey::F35), + _ => None, + }, + CKey::Char(c) => Some(BKey::Character(SmolStr::from(c.encode_utf8(&mut [0;4])))), + CKey::Null => None, + CKey::Esc => Some(BKey::Escape), + CKey::CapsLock => Some(BKey::CapsLock), + CKey::ScrollLock => Some(BKey::ScrollLock), + CKey::NumLock => Some(BKey::NumLock), + CKey::PrintScreen => Some(BKey::PrintScreen), + CKey::Pause => Some(BKey::Pause), + CKey::Menu => Some(BKey::ContextMenu), + CKey::KeypadBegin => None, + CKey::Media(media) => match media { + MediaKeyCode::Play => Some(BKey::MediaPlayPause), + MediaKeyCode::Pause => Some(BKey::Pause), + MediaKeyCode::PlayPause => Some(BKey::MediaPlayPause), + MediaKeyCode::Reverse => None, + MediaKeyCode::Stop => Some(BKey::MediaStop), + MediaKeyCode::FastForward => Some(BKey::MediaTrackNext), + MediaKeyCode::Rewind => Some(BKey::MediaTrackPrevious), + MediaKeyCode::TrackNext => Some(BKey::MediaTrackNext), + MediaKeyCode::TrackPrevious => Some(BKey::MediaTrackPrevious), + MediaKeyCode::Record => None, + MediaKeyCode::LowerVolume => Some(BKey::AudioVolumeDown), + MediaKeyCode::RaiseVolume => Some(BKey::AudioVolumeUp), + MediaKeyCode::MuteVolume => Some(BKey::AudioVolumeMute), + }, + CKey::Modifier(modifier) => match modifier { + ModifierKeyCode::LeftShift => Some(BKey::Shift), + ModifierKeyCode::LeftControl => Some(BKey::Control), + ModifierKeyCode::LeftAlt => Some(BKey::Alt), + ModifierKeyCode::LeftSuper => Some(BKey::Super), + ModifierKeyCode::LeftHyper => Some(BKey::Hyper), + ModifierKeyCode::LeftMeta => Some(BKey::Meta), + ModifierKeyCode::RightShift => Some(BKey::Shift), + ModifierKeyCode::RightControl => Some(BKey::Control), + ModifierKeyCode::RightAlt => Some(BKey::Alt), + ModifierKeyCode::RightSuper => Some(BKey::Super), + ModifierKeyCode::RightHyper => Some(BKey::Hyper), + ModifierKeyCode::RightMeta => Some(BKey::Meta), + ModifierKeyCode::IsoLevel3Shift => Some(BKey::AltGraph), + ModifierKeyCode::IsoLevel5Shift => None, + }, + } +} |