use enum_variant_type::EnumVariantType;
use feather_macro::Dispatch;
use guillotiere::euclid::default::Rotation3D;
use guillotiere::euclid::{Point3D, Vector3D};
use winit::dpi::PhysicalPosition;
use winit::event::{DeviceId, TouchPhase};
use crate::{Pixel, PxPoint, PxVector, RelVector};
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[repr(u8)]
pub enum TouchState {
Start = 0,
Move = 1,
End = 2,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[repr(u8)]
pub enum MouseState {
Down = 0,
Up = 1,
DblClick = 2,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[repr(u16)]
pub enum MouseButton {
Left = (1 << 0),
Right = (1 << 1),
Middle = (1 << 2),
Back = (1 << 3),
Forward = (1 << 4),
X1 = (1 << 5),
X2 = (1 << 6),
X3 = (1 << 7),
X4 = (1 << 8),
X5 = (1 << 9),
X6 = (1 << 10),
X7 = (1 << 11),
X8 = (1 << 12),
X9 = (1 << 13),
X10 = (1 << 14),
X11 = (1 << 15),
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[repr(u8)]
pub enum ModifierKeys {
Shift = 1,
Control = 2,
Alt = 4,
Super = 8,
Capslock = 16,
Numlock = 32,
Held = 64,
}
#[derive(Debug, Dispatch, EnumVariantType, Clone)]
#[evt(derive(Clone), module = "raw_event")]
pub enum RawEvent {
Drag, Drop {
device_id: DeviceId,
pos: PhysicalPosition<f32>,
},
Focus {
acquired: bool,
window: std::sync::Arc<winit::window::Window>, },
JoyAxis {
device_id: DeviceId,
value: f64,
axis: u32,
},
JoyButton {
device_id: DeviceId,
down: bool,
button: u32,
},
JoyOrientation {
device_id: DeviceId,
velocity: Vector3D<f32, crate::Pixel>,
rotation: Rotation3D<f32>,
},
Key {
device_id: DeviceId,
physical_key: winit::keyboard::PhysicalKey,
location: winit::keyboard::KeyLocation,
down: bool,
logical_key: winit::keyboard::Key,
modifiers: u8,
},
Mouse {
device_id: DeviceId,
state: MouseState,
pos: PxPoint,
button: MouseButton,
all_buttons: u16,
modifiers: u8,
},
MouseOn {
device_id: DeviceId,
pos: PxPoint,
modifiers: u8,
all_buttons: u16,
},
MouseMove {
device_id: DeviceId,
pos: PxPoint,
modifiers: u8,
all_buttons: u16,
},
MouseOff {
device_id: DeviceId,
modifiers: u8,
all_buttons: u16,
},
MouseScroll {
device_id: DeviceId,
state: TouchState,
pos: PxPoint,
delta: Result<PxVector, RelVector>,
},
Touch {
device_id: DeviceId,
index: u32,
state: TouchState,
pos: Point3D<f32, Pixel>,
angle: Rotation3D<f32>,
pressure: f64,
},
}
static_assertions::const_assert!(size_of::<RawEvent>() == 48);
impl RawEvent {
pub fn kind(&self) -> RawEventKind {
self.into()
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[repr(u64)]
pub enum RawEventKind {
Drag = (1 << 0),
Drop = (1 << 1),
Focus = (1 << 2),
JoyAxis = (1 << 3),
JoyButton = (1 << 4),
JoyOrientation = (1 << 5),
Key = (1 << 6),
Mouse = (1 << 7),
MouseOn = (1 << 8),
MouseMove = (1 << 9),
MouseOff = (1 << 10),
MouseScroll = (1 << 11),
Touch = (1 << 12),
}
impl From<&RawEvent> for RawEventKind {
fn from(value: &RawEvent) -> Self {
match value {
RawEvent::Drag => RawEventKind::Drag,
RawEvent::Drop { .. } => RawEventKind::Drop,
RawEvent::Focus { .. } => RawEventKind::Focus,
RawEvent::JoyAxis { .. } => RawEventKind::JoyAxis,
RawEvent::JoyButton { .. } => RawEventKind::JoyButton,
RawEvent::JoyOrientation { .. } => RawEventKind::JoyOrientation,
RawEvent::Key { .. } => RawEventKind::Key,
RawEvent::Mouse { .. } => RawEventKind::Mouse,
RawEvent::MouseOn { .. } => RawEventKind::MouseOn,
RawEvent::MouseMove { .. } => RawEventKind::MouseMove,
RawEvent::MouseOff { .. } => RawEventKind::MouseOff,
RawEvent::MouseScroll { .. } => RawEventKind::MouseScroll,
RawEvent::Touch { .. } => RawEventKind::Touch,
}
}
}
impl From<TouchPhase> for TouchState {
fn from(value: TouchPhase) -> Self {
match value {
TouchPhase::Started => TouchState::Start,
TouchPhase::Moved => TouchState::Move,
TouchPhase::Ended => TouchState::End,
TouchPhase::Cancelled => TouchState::End,
}
}
}
impl From<winit::event::MouseButton> for MouseButton {
fn from(value: winit::event::MouseButton) -> Self {
use winit::event;
match value {
event::MouseButton::Left => MouseButton::Left,
event::MouseButton::Right => MouseButton::Right,
event::MouseButton::Middle => MouseButton::Middle,
event::MouseButton::Back => MouseButton::Back,
event::MouseButton::Forward => MouseButton::Forward,
event::MouseButton::Other(5) => MouseButton::X1,
event::MouseButton::Other(6) => MouseButton::X2,
event::MouseButton::Other(7) => MouseButton::X3,
event::MouseButton::Other(8) => MouseButton::X4,
event::MouseButton::Other(9) => MouseButton::X5,
event::MouseButton::Other(10) => MouseButton::X6,
event::MouseButton::Other(11) => MouseButton::X7,
event::MouseButton::Other(12) => MouseButton::X8,
event::MouseButton::Other(13) => MouseButton::X9,
event::MouseButton::Other(14) => MouseButton::X10,
event::MouseButton::Other(15) => MouseButton::X11,
event::MouseButton::Other(_) => panic!("Mouse button out of range"),
}
}
}