use alloc::vec::Vec;
use crate::geom::{Point, Size};
pub type TouchId = u64;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum ElementState {
Down,
Up,
}
impl ElementState {
#[inline]
pub const fn is_down(self) -> bool {
matches!(self, ElementState::Down)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum PointerButton {
Left,
Right,
Middle,
Other(u16),
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub struct Modifiers(u8);
impl Modifiers {
pub const NONE: Self = Self(0);
pub const SHIFT: Self = Self(1 << 0);
pub const CTRL: Self = Self(1 << 1);
pub const ALT: Self = Self(1 << 2);
pub const SUPER: Self = Self(1 << 3);
#[inline]
pub const fn contains(self, other: Self) -> bool {
self.0 & other.0 == other.0
}
#[inline]
pub const fn set(self, other: Self, on: bool) -> Self {
Self(if on {
self.0 | other.0
} else {
self.0 & !other.0
})
}
#[inline]
pub const fn is_empty(self) -> bool {
self.0 == 0
}
}
impl core::ops::BitOr for Modifiers {
type Output = Self;
#[inline]
fn bitor(self, rhs: Self) -> Self {
Self(self.0 | rhs.0)
}
}
impl core::ops::BitOrAssign for Modifiers {
#[inline]
fn bitor_assign(&mut self, rhs: Self) {
self.0 |= rhs.0;
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[non_exhaustive]
#[allow(missing_docs)]
pub enum KeyCode {
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
Digit0,
Digit1,
Digit2,
Digit3,
Digit4,
Digit5,
Digit6,
Digit7,
Digit8,
Digit9,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
Escape,
Enter,
Tab,
Space,
Backspace,
Delete,
Insert,
Home,
End,
PageUp,
PageDown,
ArrowUp,
ArrowDown,
ArrowLeft,
ArrowRight,
ShiftLeft,
ShiftRight,
ControlLeft,
ControlRight,
AltLeft,
AltRight,
SuperLeft,
SuperRight,
CapsLock,
NumLock,
ScrollLock,
Minus,
Equal,
IntlBackslash,
BracketLeft,
BracketRight,
Backslash,
Semicolon,
Quote,
Backquote,
Comma,
Period,
Slash,
NumpadEnter,
NumpadAdd,
NumpadSubtract,
NumpadMultiply,
NumpadDivide,
NumpadDecimal,
Numpad0,
Numpad1,
Numpad2,
Numpad3,
Numpad4,
Numpad5,
Numpad6,
Numpad7,
Numpad8,
Numpad9,
Unidentified(u32),
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum InputEvent {
PointerMoved {
position: Point,
},
PointerButton {
button: PointerButton,
state: ElementState,
position: Point,
modifiers: Modifiers,
},
PointerScroll {
delta_x: f32,
delta_y: f32,
position: Point,
},
PointerLeft,
TouchDown {
id: TouchId,
position: Point,
},
TouchMoved {
id: TouchId,
position: Point,
},
TouchUp {
id: TouchId,
position: Point,
cancelled: bool,
},
Key {
code: KeyCode,
state: ElementState,
repeat: bool,
modifiers: Modifiers,
},
Text {
ch: char,
},
SurfaceResized {
size: Size,
scale_factor: f32,
},
CloseRequested,
}
pub trait InputSource {
fn poll(&mut self, out: &mut Vec<InputEvent>);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn modifier_bits() {
let m = Modifiers::NONE | Modifiers::SHIFT | Modifiers::CTRL;
assert!(m.contains(Modifiers::SHIFT));
assert!(m.contains(Modifiers::SHIFT | Modifiers::CTRL));
assert!(!m.contains(Modifiers::ALT));
assert!(!m.is_empty());
assert!(m.set(Modifiers::SHIFT, false).contains(Modifiers::CTRL));
assert!(!m.set(Modifiers::SHIFT, false).contains(Modifiers::SHIFT));
}
#[test]
fn unidentified_keys_keep_their_scancode() {
assert_ne!(KeyCode::Unidentified(30), KeyCode::Unidentified(31));
}
}