lyra-engine/src/input_event.rs

221 lines
8.1 KiB
Rust
Raw Normal View History

2023-03-16 21:47:36 +00:00
use winit::{event::{DeviceId, KeyboardInput, ModifiersState, MouseScrollDelta, TouchPhase, MouseButton, AxisId, Touch, WindowEvent, ElementState}, dpi::PhysicalPosition};
/// Wrapper around events from `winit::WindowEvent` that are specific to input related events.
///
/// The `winit::WindowEvent` enum has many values that are related to inputs.
/// Ex:
/// * winit::WindowEvent::KeyboardInput
/// * winit::WindowEvent::CursorMoved
/// * winit::WindowEvent::CursorEntered
/// * winit::WindowEvent::MouseWheel
/// * winit::WindowEvent::CursorLeft
/// * winit::WindowEvent::MouseInput
/// etc.
///
/// Its easier for these to all be in a single `InputEvent` type enum to check if any input was received.
/// The comments for all the methods were taken from `winit::WindowEvent`
#[derive(Debug, PartialEq, Clone)]
2023-03-16 21:47:36 +00:00
pub enum InputEvent {
/// An event from the keyboard has been received.
KeyboardInput {
device_id: DeviceId,
input: KeyboardInput,
/// If true, the event was generated synthetically by winit in one of the following circumstances:
/// Synthetic key press events are generated for all keys pressed when a window gains focus.
/// Likewise, synthetic key release events are generated for all keys pressed when a window goes out of focus.
/// Currently, this is only functional on X11 and Windows
is_synthetic: bool,
},
/// Change in physical position of a pointing device.
/// This represents raw, unfiltered physical motion.
///
/// This is from winit's `DeviceEvent::MouseMotion`
MouseMotion {
device_id: DeviceId,
delta: (f64, f64),
},
2023-03-16 21:47:36 +00:00
/// The cursor has moved on the window.
CursorMoved {
device_id: DeviceId,
position: PhysicalPosition<f64>,
modifiers: ModifiersState,
},
/// The cursor has entered the window.
CursorEntered {
device_id: DeviceId,
},
/// The cursor has left the window.
CursorLeft {
device_id: DeviceId,
},
/// A mouse wheel movement or touchpad scroll occurred.
MouseWheel {
device_id: DeviceId,
delta: MouseScrollDelta,
phase: TouchPhase,
/// Deprecated in favor of WindowEvent::ModifiersChanged
modifiers: ModifiersState,
},
/// An mouse button press has been received.
MouseInput {
device_id: DeviceId,
state: ElementState,
button: MouseButton,
#[deprecated = "Deprecated in favor of WindowEvent::ModifiersChanged"]
modifiers: ModifiersState,
},
/// Touchpad magnification event with two-finger pinch gesture.
/// Positive delta values indicate magnification (zooming in) and negative delta values indicate shrinking (zooming out).
///
/// Note: Only available on macOS
TouchpadMagnify {
device_id: DeviceId,
delta: f64,
phase: TouchPhase,
},
/// Smart magnification event.
///
/// On a Mac, smart magnification is triggered by a double tap with two fingers
/// on the trackpad and is commonly used to zoom on a certain object
/// (e.g. a paragraph of a PDF) or (sort of like a toggle) to reset any zoom.
/// The gesture is also supported in Safari, Pages, etc.
///
/// The event is general enough that its generating gesture is allowed to vary
/// across platforms. It could also be generated by another device.
///
/// Unfortunatly, neither [Windows](https://support.microsoft.com/en-us/windows/touch-gestures-for-windows-a9d28305-4818-a5df-4e2b-e5590f850741)
/// nor [Wayland](https://wayland.freedesktop.org/libinput/doc/latest/gestures.html)
/// support this gesture or any other gesture with the same effect.
///
/// ## Platform-specific
///
/// - Only available on **macOS 10.8** and later.
SmartMagnify { device_id: DeviceId },
/// Touchpad rotation event with two-finger rotation gesture.
///
/// Positive delta values indicate rotation counterclockwise and
/// negative delta values indicate rotation clockwise.
///
/// ## Platform-specific
///
/// - Only available on **macOS**.
TouchpadRotate {
device_id: DeviceId,
delta: f32,
phase: TouchPhase,
},
/// Touchpad pressure event.
///
/// At the moment, only supported on Apple forcetouch-capable macbooks.
/// The parameters are: pressure level (value between 0 and 1 representing how hard the touchpad
/// is being pressed) and stage (integer representing the click level).
TouchpadPressure {
device_id: DeviceId,
pressure: f32,
stage: i64,
},
/// Motion on some analog axis. May report data redundant to other, more specific events.
AxisMotion {
device_id: DeviceId,
axis: AxisId,
value: f64,
},
/// Touch event has been received
///
/// ## Platform-specific
///
/// - **macOS:** Unsupported.
Touch(Touch),
}
#[derive(Debug, PartialEq)]
pub enum InputEventConversionError<'a> {
FromError(&'a WindowEvent<'a>)
}
impl<'a> TryFrom<&'a WindowEvent<'a>> for InputEvent {
type Error = InputEventConversionError<'a>;
fn try_from(value: &'a WindowEvent<'a>) -> Result<Self, Self::Error> {
match value {
WindowEvent::KeyboardInput { device_id, input, is_synthetic } =>
Ok(InputEvent::KeyboardInput {
device_id: device_id.clone(),
input: input.clone(),
is_synthetic: is_synthetic.clone()
}),
WindowEvent::CursorMoved { device_id, position, modifiers } =>
Ok(InputEvent::CursorMoved {
device_id: device_id.clone(),
position: position.clone(),
modifiers: modifiers.clone()
}),
WindowEvent::CursorEntered { device_id } =>
Ok(InputEvent::CursorEntered {
device_id: device_id.clone()
}),
WindowEvent::CursorLeft { device_id } =>
Ok(InputEvent::CursorLeft {
device_id: device_id.clone()
}),
WindowEvent::MouseWheel { device_id, delta, phase, modifiers } =>
Ok(InputEvent::MouseWheel {
device_id: device_id.clone(),
delta: delta.clone(),
phase: phase.clone(),
modifiers: modifiers.clone()
}),
WindowEvent::MouseInput { device_id, state, button, modifiers } =>
Ok(InputEvent::MouseInput {
device_id: device_id.clone(),
state: state.clone(),
button: button.clone(),
modifiers: modifiers.clone()
}),
WindowEvent::TouchpadMagnify { device_id, delta, phase } =>
Ok(InputEvent::TouchpadMagnify {
device_id: device_id.clone(),
delta: delta.clone(),
phase: phase.clone()
}),
WindowEvent::SmartMagnify { device_id } =>
Ok(InputEvent::SmartMagnify {
device_id: device_id.clone()
}),
WindowEvent::TouchpadRotate { device_id, delta, phase } =>
Ok(InputEvent::TouchpadRotate {
device_id: device_id.clone(),
delta: delta.clone(),
phase: phase.clone()
}),
WindowEvent::TouchpadPressure { device_id, pressure, stage } =>
Ok(InputEvent::TouchpadPressure {
device_id: device_id.clone(),
pressure: pressure.clone(),
stage: stage.clone()
}),
WindowEvent::AxisMotion { device_id, axis, value } =>
Ok(InputEvent::AxisMotion {
device_id: device_id.clone(),
axis: axis.clone(),
value: value.clone()
}),
WindowEvent::Touch(t) => Ok(InputEvent::Touch(t.clone())),
_ => Err(InputEventConversionError::FromError(value))
}
}
}