1use crate::{Button, Event, Input};
2
3#[derive(Copy, Clone, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
5pub enum ButtonState {
6 Press,
8 Release,
10}
11
12#[derive(Copy, Clone, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
14pub struct ButtonArgs {
15 pub state: ButtonState,
17 pub button: Button,
19 pub scancode: Option<i32>,
29}
30
31pub trait ButtonEvent: Sized {
33 fn from_button_args(args: ButtonArgs, old_event: &Self) -> Option<Self>;
37 fn button<U, F>(&self, f: F) -> Option<U>
39 where
40 F: FnMut(ButtonArgs) -> U;
41 fn button_args(&self) -> Option<ButtonArgs> {
43 self.button(|args| args)
44 }
45}
46
47impl ButtonEvent for Event {
48 fn from_button_args(args: ButtonArgs, old_event: &Self) -> Option<Self> {
49 let timestamp = if let Event::Input(_, x) = old_event {
50 *x
51 } else {
52 None
53 };
54 Some(Event::Input(Input::Button(args), timestamp))
55 }
56 fn button<U, F>(&self, mut f: F) -> Option<U>
57 where
58 F: FnMut(ButtonArgs) -> U,
59 {
60 match *self {
61 Event::Input(Input::Button(args), _) => Some(f(args)),
62 _ => None,
63 }
64 }
65}
66
67pub trait PressEvent: Sized {
69 fn from_button(button: Button, old_event: &Self) -> Option<Self>;
74 fn press<U, F>(&self, f: F) -> Option<U>
76 where
77 F: FnMut(Button) -> U;
78 fn press_args(&self) -> Option<Button> {
80 self.press(|button| button)
81 }
82}
83
84impl<T> PressEvent for T
85where
86 T: ButtonEvent,
87{
88 fn from_button(button: Button, old_event: &Self) -> Option<Self> {
89 if let Some(mut args) = old_event.button_args() {
90 args.state = ButtonState::Press;
91 args.button = button;
92 ButtonEvent::from_button_args(args, old_event)
93 } else {
94 ButtonEvent::from_button_args(
95 ButtonArgs {
96 state: ButtonState::Press,
97 button,
98 scancode: None,
99 },
100 old_event,
101 )
102 }
103 }
104
105 fn press<U, F>(&self, mut f: F) -> Option<U>
106 where
107 F: FnMut(Button) -> U,
108 {
109 if let Some(ButtonArgs {
110 state: ButtonState::Press,
111 button,
112 ..
113 }) = self.button_args()
114 {
115 Some(f(button))
116 } else {
117 None
118 }
119 }
120}
121
122pub trait ReleaseEvent: Sized {
124 fn from_button(button: Button, old_event: &Self) -> Option<Self>;
129 fn release<U, F>(&self, f: F) -> Option<U>
131 where
132 F: FnMut(Button) -> U;
133 fn release_args(&self) -> Option<Button> {
135 self.release(|button| button)
136 }
137}
138
139impl<T> ReleaseEvent for T
140where
141 T: ButtonEvent,
142{
143 fn from_button(button: Button, old_event: &Self) -> Option<Self> {
144 if let Some(mut args) = old_event.button_args() {
145 args.state = ButtonState::Release;
146 args.button = button;
147 ButtonEvent::from_button_args(args, old_event)
148 } else {
149 ButtonEvent::from_button_args(
150 ButtonArgs {
151 state: ButtonState::Release,
152 button,
153 scancode: None,
154 },
155 old_event,
156 )
157 }
158 }
159
160 fn release<U, F>(&self, mut f: F) -> Option<U>
161 where
162 F: FnMut(Button) -> U,
163 {
164 if let Some(ButtonArgs {
165 state: ButtonState::Release,
166 button,
167 ..
168 }) = self.button_args()
169 {
170 Some(f(button))
171 } else {
172 None
173 }
174 }
175}
176
177#[cfg(test)]
178mod tests {
179 use super::*;
180
181 #[test]
182 fn test_input_press() {
183 use super::super::{Button, Key};
184
185 let e: Event = ButtonArgs {
186 state: ButtonState::Press,
187 button: Key::S.into(),
188 scancode: None,
189 }
190 .into();
191 let button = Button::Keyboard(Key::A);
192 let x: Option<Event> = PressEvent::from_button(button, &e);
193 let y: Option<Event> = x
194 .clone()
195 .unwrap()
196 .press(|button| PressEvent::from_button(button, x.as_ref().unwrap()))
197 .unwrap();
198 assert_eq!(x, y);
199 }
200
201 #[test]
202 fn test_input_release() {
203 use super::super::{Button, Key};
204
205 let e: Event = ButtonArgs {
206 state: ButtonState::Release,
207 button: Key::S.into(),
208 scancode: None,
209 }
210 .into();
211 let button = Button::Keyboard(Key::A);
212 let x: Option<Event> = ReleaseEvent::from_button(button, &e);
213 let y: Option<Event> = x
214 .clone()
215 .unwrap()
216 .release(|button| ReleaseEvent::from_button(button, x.as_ref().unwrap()))
217 .unwrap();
218 assert_eq!(x, y);
219 }
220}