aboutsummaryrefslogtreecommitdiff
path: root/src/input/systems.rs
diff options
context:
space:
mode:
authorLibravatar Silas Bartha <silas@exvacuum.dev>2024-12-20 08:02:55 -0500
committerLibravatar Silas Bartha <silas@exvacuum.dev>2024-12-20 08:02:55 -0500
commit652a17e0f90a045b99a80044be313e23b9529005 (patch)
tree0fec702d8a143cc67c1845eb4214aba5ee0d1d7d /src/input/systems.rs
parent87172fd904a9d461b10438be7dc55660e7ced680 (diff)
parent39e8be3872232d929c4ccaa1b595bf61d656b2fe (diff)
Merge branch 'wip'
Diffstat (limited to 'src/input/systems.rs')
-rw-r--r--src/input/systems.rs306
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,
+ },
+ }
+}