use bevy::{
input::keyboard::KeyCode,
prelude::{Deref, DerefMut, Resource},
reflect::{Enum, Reflect},
};
use std::{collections::VecDeque, fmt};
use keyseq::Modifiers;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Reflect)]
pub struct KeyChord(pub Modifiers, pub KeyCode);
impl fmt::Display for KeyChord {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use KeyCode::*;
self.0.fmt(f)?;
if !self.0.is_empty() {
f.write_str("-")?;
}
let key_repr = match self.1 {
Semicolon => ";",
Period => ".",
Equal => "=",
Slash => "/",
Minus => "-",
BracketLeft => "[",
BracketRight => "]",
Quote => "'",
Backquote => "`",
key_code => {
let mut key = key_code.variant_name();
key = key.strip_prefix("Key").unwrap_or(key);
key = key.strip_prefix("Digit").unwrap_or(key);
return f.write_str(key);
}
};
f.write_str(key_repr)
}
}
impl From<(Modifiers, KeyCode)> for KeyChord {
#[inline(always)]
fn from((mods, key): (Modifiers, KeyCode)) -> Self {
KeyChord(mods, key)
}
}
impl From<KeyCode> for KeyChord {
#[inline(always)]
fn from(key: KeyCode) -> Self {
KeyChord(Modifiers::empty(), key)
}
}
pub(crate) fn is_modifier(key: KeyCode) -> bool {
matches!(
key,
KeyCode::ControlLeft
| KeyCode::ControlRight
| KeyCode::ShiftLeft
| KeyCode::ShiftRight
| KeyCode::AltLeft
| KeyCode::AltRight
| KeyCode::SuperLeft
| KeyCode::SuperRight
)
}
#[derive(Resource, Debug, Deref, DerefMut, Default)]
pub struct KeyChordQueue(pub VecDeque<KeyChord>);