1use crate::geometry::Point;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
8pub enum Event {
9 MouseMove {
11 position: Point,
13 },
14 MouseDown {
16 position: Point,
18 button: MouseButton,
20 },
21 MouseUp {
23 position: Point,
25 button: MouseButton,
27 },
28 Scroll {
30 delta_x: f32,
32 delta_y: f32,
34 },
35 KeyDown {
37 key: Key,
39 #[serde(default)]
41 modifiers: crate::shortcut::Modifiers,
42 },
43 KeyUp {
45 key: Key,
47 #[serde(default)]
49 modifiers: crate::shortcut::Modifiers,
50 },
51 TextInput {
53 text: String,
55 },
56 FocusIn,
58 FocusOut,
60 MouseEnter,
62 MouseLeave,
64 Resize {
66 width: f32,
68 height: f32,
70 },
71 TouchStart {
74 id: TouchId,
76 position: Point,
78 pressure: f32,
80 },
81 TouchMove {
83 id: TouchId,
85 position: Point,
87 pressure: f32,
89 },
90 TouchEnd {
92 id: TouchId,
94 position: Point,
96 },
97 TouchCancel {
99 id: TouchId,
101 },
102 PointerDown {
105 pointer_id: PointerId,
107 pointer_type: PointerType,
109 position: Point,
111 pressure: f32,
113 is_primary: bool,
115 button: Option<MouseButton>,
117 },
118 PointerMove {
120 pointer_id: PointerId,
122 pointer_type: PointerType,
124 position: Point,
126 pressure: f32,
128 is_primary: bool,
130 },
131 PointerUp {
133 pointer_id: PointerId,
135 pointer_type: PointerType,
137 position: Point,
139 is_primary: bool,
141 button: Option<MouseButton>,
143 },
144 PointerCancel {
146 pointer_id: PointerId,
148 },
149 PointerEnter {
151 pointer_id: PointerId,
153 pointer_type: PointerType,
155 },
156 PointerLeave {
158 pointer_id: PointerId,
160 pointer_type: PointerType,
162 },
163 GesturePinch {
166 scale: f32,
168 center: Point,
170 state: GestureState,
172 },
173 GestureRotate {
175 angle: f32,
177 center: Point,
179 state: GestureState,
181 },
182 GesturePan {
184 delta: Point,
186 velocity: Point,
188 state: GestureState,
190 },
191 GestureLongPress {
193 position: Point,
195 },
196 GestureTap {
198 position: Point,
200 count: u8,
202 },
203}
204
205#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
207pub struct TouchId(pub u32);
208
209#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
211pub struct PointerId(pub u32);
212
213#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
215pub enum PointerType {
216 #[default]
218 Mouse,
219 Touch,
221 Pen,
223}
224
225#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
227pub enum GestureState {
228 #[default]
230 Started,
231 Changed,
233 Ended,
235 Cancelled,
237}
238
239#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
241pub enum MouseButton {
242 Left,
244 Right,
246 Middle,
248 Button4,
250 Button5,
252}
253
254#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
256pub enum Key {
257 A,
260 B,
262 C,
264 D,
266 E,
268 F,
270 G,
272 H,
274 I,
276 J,
278 K,
280 L,
282 M,
284 N,
286 O,
288 P,
290 Q,
292 R,
294 S,
296 T,
298 U,
300 V,
302 W,
304 X,
306 Y,
308 Z,
310
311 Num0,
314 Num1,
316 Num2,
318 Num3,
320 Num4,
322 Num5,
324 Num6,
326 Num7,
328 Num8,
330 Num9,
332
333 F1,
336 F2,
338 F3,
340 F4,
342 F5,
344 F6,
346 F7,
348 F8,
350 F9,
352 F10,
354 F11,
356 F12,
358
359 Enter,
362 Escape,
364 Backspace,
366 Tab,
368 Space,
370 Delete,
372 Insert,
374 Home,
376 End,
378 PageUp,
380 PageDown,
382
383 Up,
386 Down,
388 Left,
390 Right,
392
393 ShiftLeft,
396 ShiftRight,
398 ControlLeft,
400 ControlRight,
402 AltLeft,
404 AltRight,
406 MetaLeft,
408 MetaRight,
410
411 Minus,
414 Equal,
416 BracketLeft,
418 BracketRight,
420 Backslash,
422 Semicolon,
424 Quote,
426 Grave,
428 Comma,
430 Period,
432 Slash,
434}
435
436impl Event {
437 #[must_use]
439 pub const fn key_down(key: Key) -> Self {
440 Self::KeyDown {
441 key,
442 modifiers: crate::shortcut::Modifiers::NONE,
443 }
444 }
445
446 #[must_use]
448 pub const fn key_up(key: Key) -> Self {
449 Self::KeyUp {
450 key,
451 modifiers: crate::shortcut::Modifiers::NONE,
452 }
453 }
454
455 #[must_use]
457 pub const fn is_mouse(&self) -> bool {
458 matches!(
459 self,
460 Self::MouseMove { .. }
461 | Self::MouseDown { .. }
462 | Self::MouseUp { .. }
463 | Self::MouseEnter
464 | Self::MouseLeave
465 )
466 }
467
468 #[must_use]
470 pub const fn is_keyboard(&self) -> bool {
471 matches!(
472 self,
473 Self::KeyDown { .. } | Self::KeyUp { .. } | Self::TextInput { .. }
474 )
475 }
476
477 #[must_use]
479 pub const fn is_focus(&self) -> bool {
480 matches!(self, Self::FocusIn | Self::FocusOut)
481 }
482
483 #[must_use]
485 pub const fn is_touch(&self) -> bool {
486 matches!(
487 self,
488 Self::TouchStart { .. }
489 | Self::TouchMove { .. }
490 | Self::TouchEnd { .. }
491 | Self::TouchCancel { .. }
492 )
493 }
494
495 #[must_use]
497 pub const fn is_pointer(&self) -> bool {
498 matches!(
499 self,
500 Self::PointerDown { .. }
501 | Self::PointerMove { .. }
502 | Self::PointerUp { .. }
503 | Self::PointerCancel { .. }
504 | Self::PointerEnter { .. }
505 | Self::PointerLeave { .. }
506 )
507 }
508
509 #[must_use]
511 pub const fn is_gesture(&self) -> bool {
512 matches!(
513 self,
514 Self::GesturePinch { .. }
515 | Self::GestureRotate { .. }
516 | Self::GesturePan { .. }
517 | Self::GestureLongPress { .. }
518 | Self::GestureTap { .. }
519 )
520 }
521
522 #[must_use]
524 pub const fn position(&self) -> Option<Point> {
525 match self {
526 Self::MouseMove { position }
527 | Self::MouseDown { position, .. }
528 | Self::MouseUp { position, .. }
529 | Self::TouchStart { position, .. }
530 | Self::TouchMove { position, .. }
531 | Self::TouchEnd { position, .. }
532 | Self::PointerDown { position, .. }
533 | Self::PointerMove { position, .. }
534 | Self::PointerUp { position, .. }
535 | Self::GestureLongPress { position }
536 | Self::GestureTap { position, .. } => Some(*position),
537 Self::GesturePinch { center, .. } | Self::GestureRotate { center, .. } => Some(*center),
538 _ => None,
539 }
540 }
541
542 #[must_use]
544 pub const fn touch_id(&self) -> Option<TouchId> {
545 match self {
546 Self::TouchStart { id, .. }
547 | Self::TouchMove { id, .. }
548 | Self::TouchEnd { id, .. }
549 | Self::TouchCancel { id } => Some(*id),
550 _ => None,
551 }
552 }
553
554 #[must_use]
556 pub const fn pointer_id(&self) -> Option<PointerId> {
557 match self {
558 Self::PointerDown { pointer_id, .. }
559 | Self::PointerMove { pointer_id, .. }
560 | Self::PointerUp { pointer_id, .. }
561 | Self::PointerCancel { pointer_id }
562 | Self::PointerEnter { pointer_id, .. }
563 | Self::PointerLeave { pointer_id, .. } => Some(*pointer_id),
564 _ => None,
565 }
566 }
567
568 #[must_use]
570 pub const fn pointer_type(&self) -> Option<PointerType> {
571 match self {
572 Self::PointerDown { pointer_type, .. }
573 | Self::PointerMove { pointer_type, .. }
574 | Self::PointerUp { pointer_type, .. }
575 | Self::PointerEnter { pointer_type, .. }
576 | Self::PointerLeave { pointer_type, .. } => Some(*pointer_type),
577 _ => None,
578 }
579 }
580
581 #[must_use]
583 pub const fn pressure(&self) -> Option<f32> {
584 match self {
585 Self::TouchStart { pressure, .. }
586 | Self::TouchMove { pressure, .. }
587 | Self::PointerDown { pressure, .. }
588 | Self::PointerMove { pressure, .. } => Some(*pressure),
589 _ => None,
590 }
591 }
592
593 #[must_use]
595 pub const fn gesture_state(&self) -> Option<GestureState> {
596 match self {
597 Self::GesturePinch { state, .. }
598 | Self::GestureRotate { state, .. }
599 | Self::GesturePan { state, .. } => Some(*state),
600 _ => None,
601 }
602 }
603}
604
605impl TouchId {
606 #[must_use]
608 pub const fn new(id: u32) -> Self {
609 Self(id)
610 }
611}
612
613impl PointerId {
614 #[must_use]
616 pub const fn new(id: u32) -> Self {
617 Self(id)
618 }
619}
620
621impl PointerType {
622 #[must_use]
624 pub const fn is_mouse(&self) -> bool {
625 matches!(self, Self::Mouse)
626 }
627
628 #[must_use]
630 pub const fn is_touch(&self) -> bool {
631 matches!(self, Self::Touch)
632 }
633
634 #[must_use]
636 pub const fn is_pen(&self) -> bool {
637 matches!(self, Self::Pen)
638 }
639}
640
641impl GestureState {
642 #[must_use]
644 pub const fn is_start(&self) -> bool {
645 matches!(self, Self::Started)
646 }
647
648 #[must_use]
650 pub const fn is_active(&self) -> bool {
651 matches!(self, Self::Started | Self::Changed)
652 }
653
654 #[must_use]
656 pub const fn is_end(&self) -> bool {
657 matches!(self, Self::Ended | Self::Cancelled)
658 }
659}
660
661#[cfg(test)]
662#[allow(clippy::unwrap_used, clippy::disallowed_methods)]
663mod tests {
664 use super::*;
665
666 #[test]
667 fn test_event_is_mouse() {
668 assert!(Event::MouseMove {
669 position: Point::ORIGIN
670 }
671 .is_mouse());
672 assert!(Event::MouseEnter.is_mouse());
673 assert!(!Event::key_down(Key::Enter).is_mouse());
674 }
675
676 #[test]
677 fn test_event_is_keyboard() {
678 assert!(Event::key_down(Key::A).is_keyboard());
679 assert!(Event::TextInput {
680 text: "x".to_string()
681 }
682 .is_keyboard());
683 assert!(!Event::MouseMove {
684 position: Point::ORIGIN
685 }
686 .is_keyboard());
687 }
688
689 #[test]
690 fn test_event_is_focus() {
691 assert!(Event::FocusIn.is_focus());
692 assert!(Event::FocusOut.is_focus());
693 assert!(!Event::key_down(Key::Tab).is_focus());
694 }
695
696 #[test]
697 fn test_event_position() {
698 let pos = Point::new(100.0, 200.0);
699 assert_eq!(Event::MouseMove { position: pos }.position(), Some(pos));
700 assert_eq!(
701 Event::MouseDown {
702 position: pos,
703 button: MouseButton::Left
704 }
705 .position(),
706 Some(pos)
707 );
708 assert_eq!(Event::FocusIn.position(), None);
709 }
710
711 #[test]
712 fn test_event_mouse_up_position() {
713 let pos = Point::new(50.0, 75.0);
714 let event = Event::MouseUp {
715 position: pos,
716 button: MouseButton::Right,
717 };
718 assert_eq!(event.position(), Some(pos));
719 assert!(event.is_mouse());
720 }
721
722 #[test]
723 fn test_event_scroll() {
724 let event = Event::Scroll {
725 delta_x: 10.0,
726 delta_y: -5.0,
727 };
728 assert!(!event.is_mouse());
729 assert!(!event.is_keyboard());
730 assert!(event.position().is_none());
731 }
732
733 #[test]
734 fn test_event_resize() {
735 let event = Event::Resize {
736 width: 800.0,
737 height: 600.0,
738 };
739 assert!(!event.is_mouse());
740 assert!(!event.is_keyboard());
741 assert!(!event.is_focus());
742 }
743
744 #[test]
745 fn test_event_key_up() {
746 let event = Event::key_up(Key::Space);
747 assert!(event.is_keyboard());
748 assert!(!event.is_mouse());
749 }
750
751 #[test]
752 fn test_mouse_button_equality() {
753 assert_eq!(MouseButton::Left, MouseButton::Left);
754 assert_ne!(MouseButton::Left, MouseButton::Right);
755 }
756
757 #[test]
758 fn test_key_equality() {
759 assert_eq!(Key::Enter, Key::Enter);
760 assert_ne!(Key::Enter, Key::Space);
761 }
762
763 #[test]
764 fn test_event_mouse_leave() {
765 let event = Event::MouseLeave;
766 assert!(event.is_mouse());
767 assert!(event.position().is_none());
768 }
769
770 #[test]
772 fn test_touch_start() {
773 let event = Event::TouchStart {
774 id: TouchId::new(1),
775 position: Point::new(100.0, 200.0),
776 pressure: 0.8,
777 };
778 assert!(event.is_touch());
779 assert!(!event.is_mouse());
780 assert!(!event.is_pointer());
781 assert_eq!(event.touch_id(), Some(TouchId(1)));
782 assert_eq!(event.position(), Some(Point::new(100.0, 200.0)));
783 assert_eq!(event.pressure(), Some(0.8));
784 }
785
786 #[test]
787 fn test_touch_move() {
788 let event = Event::TouchMove {
789 id: TouchId::new(2),
790 position: Point::new(150.0, 250.0),
791 pressure: 0.5,
792 };
793 assert!(event.is_touch());
794 assert_eq!(event.touch_id(), Some(TouchId(2)));
795 assert_eq!(event.position(), Some(Point::new(150.0, 250.0)));
796 assert_eq!(event.pressure(), Some(0.5));
797 }
798
799 #[test]
800 fn test_touch_end() {
801 let event = Event::TouchEnd {
802 id: TouchId::new(3),
803 position: Point::new(200.0, 300.0),
804 };
805 assert!(event.is_touch());
806 assert_eq!(event.touch_id(), Some(TouchId(3)));
807 assert_eq!(event.position(), Some(Point::new(200.0, 300.0)));
808 assert!(event.pressure().is_none());
809 }
810
811 #[test]
812 fn test_touch_cancel() {
813 let event = Event::TouchCancel {
814 id: TouchId::new(4),
815 };
816 assert!(event.is_touch());
817 assert_eq!(event.touch_id(), Some(TouchId(4)));
818 assert!(event.position().is_none());
819 }
820
821 #[test]
822 fn test_touch_id_creation() {
823 let id = TouchId::new(42);
824 assert_eq!(id.0, 42);
825 let default_id = TouchId::default();
826 assert_eq!(default_id.0, 0);
827 }
828
829 #[test]
831 fn test_pointer_down() {
832 let event = Event::PointerDown {
833 pointer_id: PointerId::new(1),
834 pointer_type: PointerType::Touch,
835 position: Point::new(100.0, 200.0),
836 pressure: 0.7,
837 is_primary: true,
838 button: None,
839 };
840 assert!(event.is_pointer());
841 assert!(!event.is_touch());
842 assert!(!event.is_mouse());
843 assert_eq!(event.pointer_id(), Some(PointerId(1)));
844 assert_eq!(event.pointer_type(), Some(PointerType::Touch));
845 assert_eq!(event.position(), Some(Point::new(100.0, 200.0)));
846 assert_eq!(event.pressure(), Some(0.7));
847 }
848
849 #[test]
850 fn test_pointer_down_with_mouse_button() {
851 let event = Event::PointerDown {
852 pointer_id: PointerId::new(1),
853 pointer_type: PointerType::Mouse,
854 position: Point::new(50.0, 75.0),
855 pressure: 0.5,
856 is_primary: true,
857 button: Some(MouseButton::Left),
858 };
859 assert!(event.is_pointer());
860 assert_eq!(event.pointer_type(), Some(PointerType::Mouse));
861 }
862
863 #[test]
864 fn test_pointer_move() {
865 let event = Event::PointerMove {
866 pointer_id: PointerId::new(2),
867 pointer_type: PointerType::Pen,
868 position: Point::new(150.0, 250.0),
869 pressure: 0.9,
870 is_primary: false,
871 };
872 assert!(event.is_pointer());
873 assert_eq!(event.pointer_id(), Some(PointerId(2)));
874 assert_eq!(event.pointer_type(), Some(PointerType::Pen));
875 assert_eq!(event.pressure(), Some(0.9));
876 }
877
878 #[test]
879 fn test_pointer_up() {
880 let event = Event::PointerUp {
881 pointer_id: PointerId::new(3),
882 pointer_type: PointerType::Mouse,
883 position: Point::new(200.0, 300.0),
884 is_primary: true,
885 button: Some(MouseButton::Right),
886 };
887 assert!(event.is_pointer());
888 assert_eq!(event.pointer_id(), Some(PointerId(3)));
889 assert!(event.pressure().is_none());
890 }
891
892 #[test]
893 fn test_pointer_cancel() {
894 let event = Event::PointerCancel {
895 pointer_id: PointerId::new(4),
896 };
897 assert!(event.is_pointer());
898 assert_eq!(event.pointer_id(), Some(PointerId(4)));
899 assert!(event.pointer_type().is_none());
900 assert!(event.position().is_none());
901 }
902
903 #[test]
904 fn test_pointer_enter() {
905 let event = Event::PointerEnter {
906 pointer_id: PointerId::new(5),
907 pointer_type: PointerType::Mouse,
908 };
909 assert!(event.is_pointer());
910 assert_eq!(event.pointer_id(), Some(PointerId(5)));
911 assert_eq!(event.pointer_type(), Some(PointerType::Mouse));
912 assert!(event.position().is_none());
913 }
914
915 #[test]
916 fn test_pointer_leave() {
917 let event = Event::PointerLeave {
918 pointer_id: PointerId::new(6),
919 pointer_type: PointerType::Touch,
920 };
921 assert!(event.is_pointer());
922 assert_eq!(event.pointer_id(), Some(PointerId(6)));
923 assert_eq!(event.pointer_type(), Some(PointerType::Touch));
924 }
925
926 #[test]
927 fn test_pointer_id_creation() {
928 let id = PointerId::new(99);
929 assert_eq!(id.0, 99);
930 let default_id = PointerId::default();
931 assert_eq!(default_id.0, 0);
932 }
933
934 #[test]
935 fn test_pointer_type_helpers() {
936 assert!(PointerType::Mouse.is_mouse());
937 assert!(!PointerType::Mouse.is_touch());
938 assert!(!PointerType::Mouse.is_pen());
939
940 assert!(!PointerType::Touch.is_mouse());
941 assert!(PointerType::Touch.is_touch());
942 assert!(!PointerType::Touch.is_pen());
943
944 assert!(!PointerType::Pen.is_mouse());
945 assert!(!PointerType::Pen.is_touch());
946 assert!(PointerType::Pen.is_pen());
947 }
948
949 #[test]
950 fn test_pointer_type_default() {
951 let default = PointerType::default();
952 assert_eq!(default, PointerType::Mouse);
953 }
954
955 #[test]
957 fn test_gesture_pinch() {
958 let event = Event::GesturePinch {
959 scale: 1.5,
960 center: Point::new(200.0, 200.0),
961 state: GestureState::Changed,
962 };
963 assert!(event.is_gesture());
964 assert!(!event.is_touch());
965 assert!(!event.is_pointer());
966 assert_eq!(event.gesture_state(), Some(GestureState::Changed));
967 assert_eq!(event.position(), Some(Point::new(200.0, 200.0)));
968 }
969
970 #[test]
971 fn test_gesture_rotate() {
972 let event = Event::GestureRotate {
973 angle: std::f32::consts::PI / 4.0,
974 center: Point::new(150.0, 150.0),
975 state: GestureState::Started,
976 };
977 assert!(event.is_gesture());
978 assert_eq!(event.gesture_state(), Some(GestureState::Started));
979 assert_eq!(event.position(), Some(Point::new(150.0, 150.0)));
980 }
981
982 #[test]
983 fn test_gesture_pan() {
984 let event = Event::GesturePan {
985 delta: Point::new(10.0, -5.0),
986 velocity: Point::new(100.0, -50.0),
987 state: GestureState::Ended,
988 };
989 assert!(event.is_gesture());
990 assert_eq!(event.gesture_state(), Some(GestureState::Ended));
991 assert!(event.position().is_none());
992 }
993
994 #[test]
995 fn test_gesture_long_press() {
996 let event = Event::GestureLongPress {
997 position: Point::new(100.0, 100.0),
998 };
999 assert!(event.is_gesture());
1000 assert_eq!(event.position(), Some(Point::new(100.0, 100.0)));
1001 assert!(event.gesture_state().is_none());
1002 }
1003
1004 #[test]
1005 fn test_gesture_tap() {
1006 let single_tap = Event::GestureTap {
1007 position: Point::new(50.0, 50.0),
1008 count: 1,
1009 };
1010 assert!(single_tap.is_gesture());
1011 assert_eq!(single_tap.position(), Some(Point::new(50.0, 50.0)));
1012
1013 let double_tap = Event::GestureTap {
1014 position: Point::new(50.0, 50.0),
1015 count: 2,
1016 };
1017 assert!(double_tap.is_gesture());
1018 }
1019
1020 #[test]
1021 fn test_gesture_state_helpers() {
1022 assert!(GestureState::Started.is_start());
1023 assert!(GestureState::Started.is_active());
1024 assert!(!GestureState::Started.is_end());
1025
1026 assert!(!GestureState::Changed.is_start());
1027 assert!(GestureState::Changed.is_active());
1028 assert!(!GestureState::Changed.is_end());
1029
1030 assert!(!GestureState::Ended.is_start());
1031 assert!(!GestureState::Ended.is_active());
1032 assert!(GestureState::Ended.is_end());
1033
1034 assert!(!GestureState::Cancelled.is_start());
1035 assert!(!GestureState::Cancelled.is_active());
1036 assert!(GestureState::Cancelled.is_end());
1037 }
1038
1039 #[test]
1040 fn test_gesture_state_default() {
1041 let default = GestureState::default();
1042 assert_eq!(default, GestureState::Started);
1043 }
1044
1045 #[test]
1047 fn test_event_category_exclusivity() {
1048 let touch = Event::TouchStart {
1049 id: TouchId::new(1),
1050 position: Point::ORIGIN,
1051 pressure: 0.5,
1052 };
1053 assert!(touch.is_touch());
1054 assert!(!touch.is_pointer());
1055 assert!(!touch.is_gesture());
1056 assert!(!touch.is_mouse());
1057
1058 let pointer = Event::PointerDown {
1059 pointer_id: PointerId::new(1),
1060 pointer_type: PointerType::Touch,
1061 position: Point::ORIGIN,
1062 pressure: 0.5,
1063 is_primary: true,
1064 button: None,
1065 };
1066 assert!(!pointer.is_touch());
1067 assert!(pointer.is_pointer());
1068 assert!(!pointer.is_gesture());
1069 assert!(!pointer.is_mouse());
1070
1071 let gesture = Event::GesturePinch {
1072 scale: 1.0,
1073 center: Point::ORIGIN,
1074 state: GestureState::Started,
1075 };
1076 assert!(!gesture.is_touch());
1077 assert!(!gesture.is_pointer());
1078 assert!(gesture.is_gesture());
1079 assert!(!gesture.is_mouse());
1080 }
1081
1082 #[test]
1083 fn test_mouse_event_has_no_touch_or_pointer_id() {
1084 let mouse = Event::MouseDown {
1085 position: Point::ORIGIN,
1086 button: MouseButton::Left,
1087 };
1088 assert!(mouse.touch_id().is_none());
1089 assert!(mouse.pointer_id().is_none());
1090 assert!(mouse.pointer_type().is_none());
1091 assert!(mouse.pressure().is_none());
1092 assert!(mouse.gesture_state().is_none());
1093 }
1094
1095 #[test]
1096 fn test_serialization_roundtrip() {
1097 let events = vec![
1098 Event::TouchStart {
1099 id: TouchId::new(1),
1100 position: Point::new(100.0, 200.0),
1101 pressure: 0.8,
1102 },
1103 Event::PointerDown {
1104 pointer_id: PointerId::new(2),
1105 pointer_type: PointerType::Pen,
1106 position: Point::new(50.0, 75.0),
1107 pressure: 0.6,
1108 is_primary: true,
1109 button: None,
1110 },
1111 Event::GesturePinch {
1112 scale: 2.0,
1113 center: Point::new(200.0, 200.0),
1114 state: GestureState::Changed,
1115 },
1116 ];
1117
1118 for event in events {
1119 let json = serde_json::to_string(&event).unwrap();
1120 let deserialized: Event = serde_json::from_str(&json).unwrap();
1121 assert_eq!(event, deserialized);
1122 }
1123 }
1124
1125 #[test]
1128 fn test_mouse_button_all_variants() {
1129 let buttons = [
1130 MouseButton::Left,
1131 MouseButton::Right,
1132 MouseButton::Middle,
1133 MouseButton::Button4,
1134 MouseButton::Button5,
1135 ];
1136 for button in &buttons {
1137 let event = Event::MouseDown {
1138 position: Point::ORIGIN,
1139 button: *button,
1140 };
1141 assert!(event.is_mouse());
1142 }
1143 }
1144
1145 #[test]
1146 fn test_mouse_button_debug() {
1147 assert_eq!(format!("{:?}", MouseButton::Left), "Left");
1148 assert_eq!(format!("{:?}", MouseButton::Middle), "Middle");
1149 }
1150
1151 #[test]
1152 fn test_key_letters() {
1153 let letters = [
1154 Key::A,
1155 Key::B,
1156 Key::C,
1157 Key::D,
1158 Key::E,
1159 Key::F,
1160 Key::G,
1161 Key::H,
1162 Key::I,
1163 Key::J,
1164 Key::K,
1165 Key::L,
1166 Key::M,
1167 Key::N,
1168 Key::O,
1169 Key::P,
1170 Key::Q,
1171 Key::R,
1172 Key::S,
1173 Key::T,
1174 Key::U,
1175 Key::V,
1176 Key::W,
1177 Key::X,
1178 Key::Y,
1179 Key::Z,
1180 ];
1181 for key in &letters {
1182 let event = Event::key_down(*key);
1183 assert!(event.is_keyboard());
1184 }
1185 }
1186
1187 #[test]
1188 fn test_key_numbers() {
1189 let numbers = [
1190 Key::Num0,
1191 Key::Num1,
1192 Key::Num2,
1193 Key::Num3,
1194 Key::Num4,
1195 Key::Num5,
1196 Key::Num6,
1197 Key::Num7,
1198 Key::Num8,
1199 Key::Num9,
1200 ];
1201 for key in &numbers {
1202 let event = Event::key_down(*key);
1203 assert!(event.is_keyboard());
1204 }
1205 }
1206
1207 #[test]
1208 fn test_key_function_keys() {
1209 let function_keys = [
1210 Key::F1,
1211 Key::F2,
1212 Key::F3,
1213 Key::F4,
1214 Key::F5,
1215 Key::F6,
1216 Key::F7,
1217 Key::F8,
1218 Key::F9,
1219 Key::F10,
1220 Key::F11,
1221 Key::F12,
1222 ];
1223 for key in &function_keys {
1224 let event = Event::key_down(*key);
1225 assert!(event.is_keyboard());
1226 }
1227 }
1228
1229 #[test]
1230 fn test_key_control_keys() {
1231 let control_keys = [
1232 Key::Enter,
1233 Key::Escape,
1234 Key::Backspace,
1235 Key::Tab,
1236 Key::Space,
1237 Key::Delete,
1238 Key::Insert,
1239 Key::Home,
1240 Key::End,
1241 Key::PageUp,
1242 Key::PageDown,
1243 ];
1244 for key in &control_keys {
1245 let event = Event::key_down(*key);
1246 assert!(event.is_keyboard());
1247 }
1248 }
1249
1250 #[test]
1251 fn test_key_arrow_keys() {
1252 let arrows = [Key::Up, Key::Down, Key::Left, Key::Right];
1253 for key in &arrows {
1254 let event = Event::key_down(*key);
1255 assert!(event.is_keyboard());
1256 }
1257 }
1258
1259 #[test]
1260 fn test_key_modifiers() {
1261 let modifiers = [
1262 Key::ShiftLeft,
1263 Key::ShiftRight,
1264 Key::ControlLeft,
1265 Key::ControlRight,
1266 Key::AltLeft,
1267 Key::AltRight,
1268 Key::MetaLeft,
1269 Key::MetaRight,
1270 ];
1271 for key in &modifiers {
1272 let event = Event::key_down(*key);
1273 assert!(event.is_keyboard());
1274 }
1275 }
1276
1277 #[test]
1278 fn test_key_punctuation() {
1279 let punctuation = [
1280 Key::Minus,
1281 Key::Equal,
1282 Key::BracketLeft,
1283 Key::BracketRight,
1284 Key::Backslash,
1285 Key::Semicolon,
1286 Key::Quote,
1287 Key::Grave,
1288 Key::Comma,
1289 Key::Period,
1290 Key::Slash,
1291 ];
1292 for key in &punctuation {
1293 let event = Event::key_down(*key);
1294 assert!(event.is_keyboard());
1295 }
1296 }
1297
1298 #[test]
1299 fn test_key_debug() {
1300 assert_eq!(format!("{:?}", Key::Enter), "Enter");
1301 assert_eq!(format!("{:?}", Key::F1), "F1");
1302 }
1303
1304 #[test]
1305 fn test_touch_id_hash() {
1306 use std::collections::HashSet;
1307 let mut set = HashSet::new();
1308 set.insert(TouchId::new(1));
1309 set.insert(TouchId::new(2));
1310 set.insert(TouchId::new(1)); assert_eq!(set.len(), 2);
1312 }
1313
1314 #[test]
1315 fn test_pointer_id_hash() {
1316 use std::collections::HashSet;
1317 let mut set = HashSet::new();
1318 set.insert(PointerId::new(1));
1319 set.insert(PointerId::new(2));
1320 set.insert(PointerId::new(1)); assert_eq!(set.len(), 2);
1322 }
1323
1324 #[test]
1325 fn test_pointer_type_hash() {
1326 use std::collections::HashSet;
1327 let mut set = HashSet::new();
1328 set.insert(PointerType::Mouse);
1329 set.insert(PointerType::Touch);
1330 set.insert(PointerType::Pen);
1331 set.insert(PointerType::Mouse); assert_eq!(set.len(), 3);
1333 }
1334
1335 #[test]
1336 fn test_gesture_state_hash() {
1337 use std::collections::HashSet;
1338 let mut set = HashSet::new();
1339 set.insert(GestureState::Started);
1340 set.insert(GestureState::Changed);
1341 set.insert(GestureState::Ended);
1342 set.insert(GestureState::Cancelled);
1343 assert_eq!(set.len(), 4);
1344 }
1345
1346 #[test]
1347 fn test_event_debug() {
1348 let event = Event::FocusIn;
1349 let debug = format!("{event:?}");
1350 assert!(debug.contains("FocusIn"));
1351 }
1352
1353 #[test]
1354 fn test_event_clone() {
1355 let event = Event::MouseMove {
1356 position: Point::new(100.0, 200.0),
1357 };
1358 let cloned = event.clone();
1359 assert_eq!(event, cloned);
1360 }
1361
1362 #[test]
1363 fn test_text_input_event() {
1364 let event = Event::TextInput {
1365 text: "Hello, 世界!".to_string(),
1366 };
1367 assert!(event.is_keyboard());
1368 assert!(!event.is_mouse());
1369 assert!(event.position().is_none());
1370 }
1371
1372 #[test]
1373 fn test_scroll_event_deltas() {
1374 let event = Event::Scroll {
1375 delta_x: -10.5,
1376 delta_y: 20.3,
1377 };
1378 assert!(!event.is_mouse());
1379 assert!(!event.is_touch());
1380 assert!(!event.is_pointer());
1381 }
1382
1383 #[test]
1384 fn test_resize_event() {
1385 let event = Event::Resize {
1386 width: 1920.0,
1387 height: 1080.0,
1388 };
1389 assert!(!event.is_mouse());
1390 assert!(event.position().is_none());
1391 }
1392
1393 #[test]
1394 fn test_gesture_pan_no_position() {
1395 let event = Event::GesturePan {
1396 delta: Point::new(50.0, 30.0),
1397 velocity: Point::new(200.0, 150.0),
1398 state: GestureState::Changed,
1399 };
1400 assert!(event.is_gesture());
1401 assert!(event.position().is_none());
1403 }
1404
1405 #[test]
1406 fn test_all_event_serialization() {
1407 let events = vec![
1408 Event::MouseMove {
1409 position: Point::new(1.0, 2.0),
1410 },
1411 Event::MouseDown {
1412 position: Point::new(1.0, 2.0),
1413 button: MouseButton::Left,
1414 },
1415 Event::MouseUp {
1416 position: Point::new(1.0, 2.0),
1417 button: MouseButton::Right,
1418 },
1419 Event::Scroll {
1420 delta_x: 1.0,
1421 delta_y: -1.0,
1422 },
1423 Event::key_down(Key::A),
1424 Event::key_up(Key::B),
1425 Event::TextInput {
1426 text: "test".to_string(),
1427 },
1428 Event::FocusIn,
1429 Event::FocusOut,
1430 Event::MouseEnter,
1431 Event::MouseLeave,
1432 Event::Resize {
1433 width: 800.0,
1434 height: 600.0,
1435 },
1436 ];
1437
1438 for event in events {
1439 let json = serde_json::to_string(&event).unwrap();
1440 let deserialized: Event = serde_json::from_str(&json).unwrap();
1441 assert_eq!(event, deserialized);
1442 }
1443 }
1444
1445 #[test]
1446 fn test_touch_events_serialization() {
1447 let events = vec![
1448 Event::TouchStart {
1449 id: TouchId(1),
1450 position: Point::new(10.0, 20.0),
1451 pressure: 0.5,
1452 },
1453 Event::TouchMove {
1454 id: TouchId(1),
1455 position: Point::new(15.0, 25.0),
1456 pressure: 0.6,
1457 },
1458 Event::TouchEnd {
1459 id: TouchId(1),
1460 position: Point::new(20.0, 30.0),
1461 },
1462 Event::TouchCancel { id: TouchId(1) },
1463 ];
1464
1465 for event in events {
1466 let json = serde_json::to_string(&event).unwrap();
1467 let deserialized: Event = serde_json::from_str(&json).unwrap();
1468 assert_eq!(event, deserialized);
1469 }
1470 }
1471
1472 #[test]
1473 fn test_gesture_events_serialization() {
1474 let events = vec![
1475 Event::GesturePinch {
1476 scale: 1.5,
1477 center: Point::new(100.0, 100.0),
1478 state: GestureState::Started,
1479 },
1480 Event::GestureRotate {
1481 angle: 0.5,
1482 center: Point::new(100.0, 100.0),
1483 state: GestureState::Changed,
1484 },
1485 Event::GesturePan {
1486 delta: Point::new(10.0, 5.0),
1487 velocity: Point::new(50.0, 25.0),
1488 state: GestureState::Ended,
1489 },
1490 Event::GestureLongPress {
1491 position: Point::new(50.0, 50.0),
1492 },
1493 Event::GestureTap {
1494 position: Point::new(50.0, 50.0),
1495 count: 2,
1496 },
1497 ];
1498
1499 for event in events {
1500 let json = serde_json::to_string(&event).unwrap();
1501 let deserialized: Event = serde_json::from_str(&json).unwrap();
1502 assert_eq!(event, deserialized);
1503 }
1504 }
1505
1506 #[test]
1507 fn test_pointer_events_serialization() {
1508 let events = vec![
1509 Event::PointerDown {
1510 pointer_id: PointerId(1),
1511 pointer_type: PointerType::Mouse,
1512 position: Point::new(10.0, 20.0),
1513 pressure: 0.5,
1514 is_primary: true,
1515 button: Some(MouseButton::Left),
1516 },
1517 Event::PointerMove {
1518 pointer_id: PointerId(1),
1519 pointer_type: PointerType::Touch,
1520 position: Point::new(15.0, 25.0),
1521 pressure: 0.6,
1522 is_primary: true,
1523 },
1524 Event::PointerUp {
1525 pointer_id: PointerId(1),
1526 pointer_type: PointerType::Pen,
1527 position: Point::new(20.0, 30.0),
1528 is_primary: false,
1529 button: None,
1530 },
1531 Event::PointerCancel {
1532 pointer_id: PointerId(1),
1533 },
1534 Event::PointerEnter {
1535 pointer_id: PointerId(2),
1536 pointer_type: PointerType::Mouse,
1537 },
1538 Event::PointerLeave {
1539 pointer_id: PointerId(2),
1540 pointer_type: PointerType::Touch,
1541 },
1542 ];
1543
1544 for event in events {
1545 let json = serde_json::to_string(&event).unwrap();
1546 let deserialized: Event = serde_json::from_str(&json).unwrap();
1547 assert_eq!(event, deserialized);
1548 }
1549 }
1550
1551 #[test]
1552 fn test_key_hash() {
1553 use std::collections::HashSet;
1554 let mut set = HashSet::new();
1555 set.insert(Key::A);
1556 set.insert(Key::B);
1557 set.insert(Key::A); assert_eq!(set.len(), 2);
1559 }
1560
1561 #[test]
1562 fn test_mouse_button_hash() {
1563 use std::collections::HashSet;
1564 let mut set = HashSet::new();
1565 set.insert(MouseButton::Left);
1566 set.insert(MouseButton::Right);
1567 set.insert(MouseButton::Left); assert_eq!(set.len(), 2);
1569 }
1570}