use bitflags::bitflags;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
pub type AxisId = u32;
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct ButtonId(pub u32);
impl From<ButtonId> for u32 {
fn from(val: ButtonId) -> Self {
val.0
}
}
pub use crate::DeviceId;
#[derive(Clone, Debug, PartialEq)]
pub enum Event {
Dummy,
Added,
Removed,
MouseButton {
button: MouseButton,
state: ElementState,
},
MouseMotion {
delta: (f64, f64),
},
MouseWheel {
delta: MouseScrollDelta,
},
Motion {
axis: AxisId,
value: f64,
},
Button {
button: ButtonId,
state: ElementState,
},
Key(KeyboardInput),
Text {
codepoint: char,
},
}
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum ElementState {
Pressed,
Released,
Repeated,
Unknown,
}
impl Default for ElementState {
fn default() -> Self {
Self::Unknown
}
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct KeyboardInput {
pub scancode: ScanCode,
pub state: ElementState,
pub virtual_keycode: Option<VirtualKeyCode>,
}
impl KeyboardInput {
pub fn is_key_pressed(&self, key_code: VirtualKeyCode) -> bool {
self.virtual_keycode == Some(key_code) && self.state == ElementState::Pressed
}
pub fn is_key_released(&self, key_code: VirtualKeyCode) -> bool {
self.virtual_keycode == Some(key_code) && self.state == ElementState::Released
}
pub fn is_key_repeated(&self, key_code: VirtualKeyCode) -> bool {
self.virtual_keycode == Some(key_code) && self.state == ElementState::Repeated
}
pub fn is_key_triggered(&self, key_code: VirtualKeyCode) -> bool {
self.virtual_keycode == Some(key_code)
&& (self.state == ElementState::Pressed || self.state == ElementState::Repeated)
}
}
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum TouchPhase {
Started,
Moved,
Ended,
Cancelled,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Touch {
pub device_id: DeviceId,
pub phase: TouchPhase,
pub location: PhysicalPosition<f64>,
pub force: Option<Force>,
pub id: u64,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Force {
Calibrated {
force: f64,
max_possible_force: f64,
altitude_angle: Option<f64>,
},
Normalized(f64),
}
impl Force {
pub fn normalized(&self) -> f64 {
match self {
Force::Calibrated {
force,
max_possible_force,
altitude_angle,
} => {
let force = match altitude_angle {
Some(altitude_angle) => force / altitude_angle.sin(),
None => *force,
};
force / max_possible_force
}
Force::Normalized(force) => *force,
}
}
}
pub type ScanCode = u32;
bitflags! {
#[derive(Default)]
pub struct ModifiersState: u32 {
const SHIFT = 0b100;
const LSHIFT = 0b010;
const RSHIFT = 0b001;
const CTRL = 0b100 << 3;
const LCTRL = 0b010 << 3;
const RCTRL = 0b001 << 3;
const ALT = 0b100 << 6;
const LALT = 0b010 << 6;
const RALT = 0b001 << 6;
const LOGO = 0b100 << 9;
const LLOGO = 0b010 << 9;
const RLOGO = 0b001 << 9;
}
}
impl ModifiersState {
pub fn shift(&self) -> bool {
self.intersects(Self::SHIFT)
}
pub fn ctrl(&self) -> bool {
self.intersects(Self::CTRL)
}
pub fn alt(&self) -> bool {
self.intersects(Self::ALT)
}
pub fn logo(&self) -> bool {
self.intersects(Self::LOGO)
}
}
#[cfg(feature = "serde")]
mod modifiers_serde {
use super::ModifiersState;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[derive(Default, Serialize, Deserialize)]
#[serde(default)]
#[serde(rename = "ModifiersState")]
pub struct ModifiersStateSerialize {
pub shift: bool,
pub ctrl: bool,
pub alt: bool,
pub logo: bool,
}
impl Serialize for ModifiersState {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let s = ModifiersStateSerialize {
shift: self.shift(),
ctrl: self.ctrl(),
alt: self.alt(),
logo: self.logo(),
};
s.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for ModifiersState {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let ModifiersStateSerialize {
shift,
ctrl,
alt,
logo,
} = ModifiersStateSerialize::deserialize(deserializer)?;
let mut m = ModifiersState::empty();
m.set(ModifiersState::SHIFT, shift);
m.set(ModifiersState::CTRL, ctrl);
m.set(ModifiersState::ALT, alt);
m.set(ModifiersState::LOGO, logo);
Ok(m)
}
}
}
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum MouseButton {
Left,
Right,
Middle,
Other(u8),
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum MouseScrollDelta {
LineDelta(f32, f32),
PixelDelta(PhysicalPosition<f64>),
}
#[derive(Debug, Copy, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct PhysicalPosition<P> {
pub x: P,
pub y: P,
}
impl<P> PhysicalPosition<P> {
#[inline]
pub const fn new(x: P, y: P) -> Self {
PhysicalPosition { x, y }
}
}
#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)]
#[repr(u32)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum VirtualKeyCode {
Key1,
Key2,
Key3,
Key4,
Key5,
Key6,
Key7,
Key8,
Key9,
Key0,
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,
Escape,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
F13,
F14,
F15,
F16,
F17,
F18,
F19,
F20,
F21,
F22,
F23,
F24,
Snapshot,
Scroll,
Pause,
Insert,
Home,
Delete,
End,
PageDown,
PageUp,
Left,
Up,
Right,
Down,
Back,
Return,
Space,
Compose,
Caret,
Numlock,
Numpad0,
Numpad1,
Numpad2,
Numpad3,
Numpad4,
Numpad5,
Numpad6,
Numpad7,
Numpad8,
Numpad9,
NumpadComma,
NumpadEnter,
NumpadEquals,
NumpadSubtract,
AbntC1,
AbntC2,
Apostrophe,
Apps,
At,
Ax,
Backslash,
Calculator,
Capital,
Colon,
Comma,
Convert,
Decimal,
Divide,
Equals,
Grave,
Kana,
Kanji,
LAlt,
LBracket,
LControl,
LShift,
LWin,
Mail,
MediaSelect,
MediaStop,
Minus,
Multiply,
Mute,
MyComputer,
NavigateForward,
NavigateBackward,
NextTrack,
NoConvert,
OEM102,
Period,
PlayPause,
Plus, Power,
PrevTrack,
RAlt,
RBracket,
RControl,
RShift,
RWin,
Semicolon,
Slash,
Sleep,
Stop,
Sysrq,
Tab,
Underline,
Unlabeled,
VolumeDown,
VolumeUp,
Wake,
WebBack,
WebFavorites,
WebForward,
WebHome,
WebRefresh,
WebSearch,
WebStop,
Yen,
Copy,
Paste,
Cut,
}