retroglyph_core/event/
mouse.rs1use super::key::KeyModifiers;
4use crate::grid::Pos;
5
6pub type PhysicalPos = ixy::Pos<u32>;
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
14#[non_exhaustive]
15pub enum MouseButton {
17 Left,
19 Right,
21 Middle,
23}
24
25#[derive(Debug, Clone, Copy, PartialEq)]
26#[non_exhaustive]
27pub enum MouseEventKind {
31 Down(MouseButton),
33 Up(MouseButton),
35 Drag(MouseButton),
37 Moved,
39 Scroll {
46 dx: f32,
48 dy: f32,
50 },
51}
52
53#[derive(Debug, Clone, Copy, PartialEq)]
54#[non_exhaustive]
55pub struct MouseEvent {
60 pub kind: MouseEventKind,
62 pub position: Pos,
64 pub pixel_position: Option<PhysicalPos>,
69 pub modifiers: KeyModifiers,
71}
72
73impl MouseEvent {
74 #[must_use]
76 pub const fn new(kind: MouseEventKind, position: Pos, modifiers: KeyModifiers) -> Self {
77 Self {
78 kind,
79 position,
80 pixel_position: None,
81 modifiers,
82 }
83 }
84
85 #[must_use]
88 pub const fn with_pixel_position(
89 kind: MouseEventKind,
90 position: Pos,
91 modifiers: KeyModifiers,
92 pixel_position: PhysicalPos,
93 ) -> Self {
94 Self {
95 kind,
96 position,
97 pixel_position: Some(pixel_position),
98 modifiers,
99 }
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 use super::super::Event;
106 use super::*;
107
108 #[test]
109 fn test_mouse_event_no_pixel_position() {
110 let mouse_event = MouseEvent {
111 kind: MouseEventKind::Down(MouseButton::Left),
112 position: Pos { x: 10, y: 5 },
113 pixel_position: None,
114 modifiers: KeyModifiers::NONE,
115 };
116 assert!(mouse_event.pixel_position.is_none());
117 assert!(matches!(Event::Mouse(mouse_event), Event::Mouse(_)));
118 }
119
120 #[test]
121 fn test_mouse_event_with_pixel_position() {
122 let mouse_event = MouseEvent {
123 kind: MouseEventKind::Moved,
124 position: Pos { x: 3, y: 2 },
125 pixel_position: Some(PhysicalPos { x: 55, y: 38 }),
126 modifiers: KeyModifiers::NONE,
127 };
128 let px = mouse_event.pixel_position.unwrap();
129 assert_eq!(px.x, 55);
130 assert_eq!(px.y, 38);
131 assert_ne!(px.x, u32::from(mouse_event.position.x));
133 }
134
135 #[test]
136 fn test_mouse_event_new_has_no_pixel_position() {
137 let mouse_event = MouseEvent::new(
138 MouseEventKind::Down(MouseButton::Left),
139 Pos { x: 10, y: 5 },
140 KeyModifiers::NONE,
141 );
142 assert_eq!(mouse_event.kind, MouseEventKind::Down(MouseButton::Left));
143 assert_eq!(mouse_event.position, Pos { x: 10, y: 5 });
144 assert!(mouse_event.pixel_position.is_none());
145 }
146
147 #[test]
148 fn test_mouse_event_with_pixel_position_constructor() {
149 let mouse_event = MouseEvent::with_pixel_position(
150 MouseEventKind::Moved,
151 Pos { x: 3, y: 2 },
152 KeyModifiers::NONE,
153 PhysicalPos { x: 55, y: 38 },
154 );
155 assert_eq!(
156 mouse_event.pixel_position,
157 Some(PhysicalPos { x: 55, y: 38 })
158 );
159 }
160
161 #[test]
162 fn test_physical_pos_is_copy() {
163 let p = PhysicalPos { x: 10, y: 20 };
164 let q = p; assert_eq!(p, q);
166 }
167}