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