use super::key::KeyModifiers;
use crate::grid::Pos;
pub type PhysicalPos = ixy::Pos<u32>;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum MouseButton {
Left,
Right,
Middle,
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[non_exhaustive]
pub enum MouseEventKind {
Down(MouseButton),
Up(MouseButton),
Drag(MouseButton),
Moved,
Scroll {
dx: f32,
dy: f32,
},
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[non_exhaustive]
pub struct MouseEvent {
pub kind: MouseEventKind,
pub position: Pos,
pub pixel_position: Option<PhysicalPos>,
pub modifiers: KeyModifiers,
}
impl MouseEvent {
#[must_use]
pub const fn new(kind: MouseEventKind, position: Pos, modifiers: KeyModifiers) -> Self {
Self {
kind,
position,
pixel_position: None,
modifiers,
}
}
#[must_use]
pub const fn with_pixel_position(
kind: MouseEventKind,
position: Pos,
modifiers: KeyModifiers,
pixel_position: PhysicalPos,
) -> Self {
Self {
kind,
position,
pixel_position: Some(pixel_position),
modifiers,
}
}
}
#[cfg(test)]
mod tests {
use super::super::Event;
use super::*;
#[test]
fn test_mouse_event_no_pixel_position() {
let mouse_event = MouseEvent {
kind: MouseEventKind::Down(MouseButton::Left),
position: Pos { x: 10, y: 5 },
pixel_position: None,
modifiers: KeyModifiers::NONE,
};
assert!(mouse_event.pixel_position.is_none());
assert!(matches!(Event::Mouse(mouse_event), Event::Mouse(_)));
}
#[test]
fn test_mouse_event_with_pixel_position() {
let mouse_event = MouseEvent {
kind: MouseEventKind::Moved,
position: Pos { x: 3, y: 2 },
pixel_position: Some(PhysicalPos { x: 55, y: 38 }),
modifiers: KeyModifiers::NONE,
};
let px = mouse_event.pixel_position.unwrap();
assert_eq!(px.x, 55);
assert_eq!(px.y, 38);
assert_ne!(px.x, u32::from(mouse_event.position.x));
}
#[test]
fn test_mouse_event_new_has_no_pixel_position() {
let mouse_event = MouseEvent::new(
MouseEventKind::Down(MouseButton::Left),
Pos { x: 10, y: 5 },
KeyModifiers::NONE,
);
assert_eq!(mouse_event.kind, MouseEventKind::Down(MouseButton::Left));
assert_eq!(mouse_event.position, Pos { x: 10, y: 5 });
assert!(mouse_event.pixel_position.is_none());
}
#[test]
fn test_mouse_event_with_pixel_position_constructor() {
let mouse_event = MouseEvent::with_pixel_position(
MouseEventKind::Moved,
Pos { x: 3, y: 2 },
KeyModifiers::NONE,
PhysicalPos { x: 55, y: 38 },
);
assert_eq!(
mouse_event.pixel_position,
Some(PhysicalPos { x: 55, y: 38 })
);
}
#[test]
fn test_physical_pos_is_copy() {
let p = PhysicalPos { x: 10, y: 20 };
let q = p; assert_eq!(p, q);
}
}