Skip to main content

geng_utils/
key.rs

1use geng::{
2    prelude::{Deserialize, Serialize},
3    Window,
4};
5
6/// A convenience type that combines [Key](geng::Key) and [MouseButton](geng::MouseButton).
7/// Can often be used for specifying controls where only press/release plays a role.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
9pub enum EventKey {
10    Key(geng::Key),
11    Mouse(geng::MouseButton),
12}
13
14impl From<&EventKey> for EventKey {
15    fn from(value: &EventKey) -> Self {
16        *value
17    }
18}
19
20impl From<geng::Key> for EventKey {
21    fn from(value: geng::Key) -> Self {
22        Self::Key(value)
23    }
24}
25
26impl From<&geng::Key> for EventKey {
27    fn from(value: &geng::Key) -> Self {
28        Self::Key(*value)
29    }
30}
31
32impl From<geng::MouseButton> for EventKey {
33    fn from(value: geng::MouseButton) -> Self {
34        Self::Mouse(value)
35    }
36}
37
38impl From<&geng::MouseButton> for EventKey {
39    fn from(value: &geng::MouseButton) -> Self {
40        Self::Mouse(*value)
41    }
42}
43
44impl EventKey {
45    /// Check whether the key is pressed.
46    pub fn is_pressed(self, window: &geng::Window) -> bool {
47        match self {
48            Self::Key(key) => window.is_key_pressed(key),
49            Self::Mouse(button) => window.is_button_pressed(button),
50        }
51    }
52
53    /// Check whether the event corresponds to the press of the key.
54    pub fn is_event_press(self, event: &geng::Event) -> bool {
55        match (&self, event) {
56            (Self::Key(self_key), geng::Event::KeyPress { key }) => self_key == key,
57            (Self::Mouse(self_button), geng::Event::MousePress { button, .. }) => {
58                self_button == button
59            }
60            _ => false,
61        }
62    }
63
64    /// Check whether the event corresponds to the release of the key.
65    pub fn is_event_release(self, event: &geng::Event) -> bool {
66        match (&self, event) {
67            (Self::Key(self_key), geng::Event::KeyRelease { key }) => self_key == key,
68            (Self::Mouse(self_button), geng::Event::MouseRelease { button, .. }) => {
69                self_button == button
70            }
71            _ => false,
72        }
73    }
74}
75
76/// Check whether at least one of the keys is pressed.
77pub fn is_key_pressed(
78    window: &Window,
79    keys: impl IntoIterator<Item = impl Into<EventKey>>,
80) -> bool {
81    keys.into_iter()
82        .any(|key| Into::<EventKey>::into(key).is_pressed(window))
83}
84
85/// Check whether the event corresponds to the press of at least one of the keys.
86pub fn is_event_press(
87    event: &geng::Event,
88    keys: impl IntoIterator<Item = impl Into<EventKey>>,
89) -> bool {
90    keys.into_iter()
91        .any(|key| Into::<EventKey>::into(key).is_event_press(event))
92}
93
94/// Check whether the event corresponds to the release of at least one of the keys.
95pub fn is_event_release(
96    event: &geng::Event,
97    keys: impl IntoIterator<Item = impl Into<EventKey>>,
98) -> bool {
99    keys.into_iter()
100        .any(|key| Into::<EventKey>::into(key).is_event_release(event))
101}