#![allow(clippy::trivially_copy_pass_by_ref)]
use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not};
pub use keyboard_types::{Code, KeyState, Location};
pub type KbKey = keyboard_types::Key;
#[non_exhaustive]
#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
pub struct KeyEvent {
pub state: KeyState,
pub key: KbKey,
pub code: Code,
pub location: Location,
pub mods: Modifiers,
pub repeat: bool,
pub is_composing: bool,
}
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
pub struct Modifiers(keyboard_types::Modifiers);
pub trait IntoKey {
fn into_key(self) -> KbKey;
}
impl KeyEvent {
#[doc(hidden)]
pub fn for_test(mods: impl Into<Modifiers>, key: impl IntoKey) -> KeyEvent {
let mods = mods.into();
let key = key.into_key();
KeyEvent {
key,
code: Code::Unidentified,
location: Location::Standard,
state: KeyState::Down,
mods,
is_composing: false,
repeat: false,
}
}
}
impl Modifiers {
pub const ALT: Modifiers = Modifiers(keyboard_types::Modifiers::ALT);
pub const ALT_GRAPH: Modifiers = Modifiers(keyboard_types::Modifiers::ALT_GRAPH);
pub const CAPS_LOCK: Modifiers = Modifiers(keyboard_types::Modifiers::CAPS_LOCK);
pub const CONTROL: Modifiers = Modifiers(keyboard_types::Modifiers::CONTROL);
pub const FN: Modifiers = Modifiers(keyboard_types::Modifiers::FN);
pub const FN_LOCK: Modifiers = Modifiers(keyboard_types::Modifiers::FN_LOCK);
pub const META: Modifiers = Modifiers(keyboard_types::Modifiers::META);
pub const NUM_LOCK: Modifiers = Modifiers(keyboard_types::Modifiers::NUM_LOCK);
pub const SCROLL_LOCK: Modifiers = Modifiers(keyboard_types::Modifiers::SCROLL_LOCK);
pub const SHIFT: Modifiers = Modifiers(keyboard_types::Modifiers::SHIFT);
pub const SYMBOL: Modifiers = Modifiers(keyboard_types::Modifiers::SYMBOL);
pub const SYMBOL_LOCK: Modifiers = Modifiers(keyboard_types::Modifiers::SYMBOL_LOCK);
pub const HYPER: Modifiers = Modifiers(keyboard_types::Modifiers::HYPER);
pub const SUPER: Modifiers = Modifiers(keyboard_types::Modifiers::SUPER);
pub fn raw(&self) -> keyboard_types::Modifiers {
self.0
}
pub fn shift(&self) -> bool {
self.contains(Modifiers::SHIFT)
}
pub fn ctrl(&self) -> bool {
self.contains(Modifiers::CONTROL)
}
pub fn alt(&self) -> bool {
self.contains(Modifiers::ALT)
}
pub fn meta(&self) -> bool {
self.contains(Modifiers::META)
}
pub fn empty() -> Modifiers {
Default::default()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn contains(&self, other: Modifiers) -> bool {
self.0.contains(other.0)
}
pub fn set(&mut self, other: Modifiers, value: bool) {
self.0.set(other.0, value)
}
}
impl BitAnd for Modifiers {
type Output = Self;
fn bitand(self, rhs: Self) -> Self {
Modifiers(self.0 & rhs.0)
}
}
impl BitAndAssign for Modifiers {
fn bitand_assign(&mut self, rhs: Self) {
*self = Modifiers(self.0 & rhs.0)
}
}
impl BitOr for Modifiers {
type Output = Self;
fn bitor(self, rhs: Self) -> Self {
Modifiers(self.0 | rhs.0)
}
}
impl BitOrAssign for Modifiers {
fn bitor_assign(&mut self, rhs: Self) {
*self = Modifiers(self.0 | rhs.0)
}
}
impl BitXor for Modifiers {
type Output = Self;
fn bitxor(self, rhs: Self) -> Self {
Modifiers(self.0 ^ rhs.0)
}
}
impl BitXorAssign for Modifiers {
fn bitxor_assign(&mut self, rhs: Self) {
*self = Modifiers(self.0 ^ rhs.0)
}
}
impl Not for Modifiers {
type Output = Self;
fn not(self) -> Self {
Modifiers(!self.0)
}
}
impl IntoKey for KbKey {
fn into_key(self) -> KbKey {
self
}
}
impl IntoKey for &str {
fn into_key(self) -> KbKey {
KbKey::Character(self.into())
}
}