1#![crate_name = "input"]
2#![deny(
3 rust_2018_compatibility,
4 rust_2018_idioms,
5 future_incompatible,
6 nonstandard_style,
7 unused,
8 clippy::all,
9 clippy::doc_markdown,
10 missing_docs,
11 missing_copy_implementations,
12 missing_debug_implementations
13)]
14
15#[macro_use]
19extern crate bitflags;
20#[macro_use]
21extern crate serde_derive;
22
23use std::{any::Any, cmp::Ordering, fmt, path::PathBuf, sync::Arc};
24
25pub use controller::{ControllerAxisArgs, ControllerButton, ControllerHat};
26pub use keyboard::Key;
27pub use mouse::MouseButton;
28
29pub mod controller;
30pub mod keyboard;
31pub mod mouse;
32
33pub use after_render::{AfterRenderArgs, AfterRenderEvent};
34pub use button::{ButtonArgs, ButtonEvent, ButtonState, PressEvent, ReleaseEvent};
35pub use close::{CloseArgs, CloseEvent};
36pub use controller::ControllerAxisEvent;
37pub use cursor::CursorEvent;
38use event_id::EventId;
39pub use focus::FocusEvent;
40pub use generic_event::GenericEvent;
41pub use idle::{IdleArgs, IdleEvent};
42pub use mouse::{MouseCursorEvent, MouseRelativeEvent, MouseScrollEvent};
43pub use render::{RenderArgs, RenderEvent};
44pub use resize::{ResizeArgs, ResizeEvent};
45pub use text::TextEvent;
46pub use touch::{Touch, TouchArgs, TouchEvent};
47pub use update::{UpdateArgs, UpdateEvent};
48
49pub mod event_id;
50pub mod generic_event;
51
52mod after_render;
53mod button;
54mod close;
55mod cursor;
56mod focus;
57mod idle;
58mod render;
59mod resize;
60mod text;
61mod touch;
62mod update;
63
64pub type TimeStamp = u32;
68
69#[derive(Copy, Clone, Deserialize, Serialize, PartialEq, PartialOrd, Ord, Eq, Hash, Debug)]
71pub enum Button {
72 Keyboard(Key),
74 Mouse(MouseButton),
76 Controller(ControllerButton),
78 Hat(ControllerHat),
80}
81
82#[derive(Copy, Clone, Deserialize, Serialize, PartialEq, PartialOrd, Debug)]
84pub enum Motion {
85 MouseCursor([f64; 2]),
87 MouseRelative([f64; 2]),
89 MouseScroll([f64; 2]),
91 ControllerAxis(ControllerAxisArgs),
93 Touch(TouchArgs),
95}
96
97#[derive(Copy, Clone, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
99pub enum HatState {
100 Centered,
102 Up,
104 Right,
106 Down,
108 Left,
110 RightUp,
112 RightDown,
114 LeftUp,
116 LeftDown,
118}
119
120#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, Hash)]
122pub enum FileDrag {
123 Hover(PathBuf),
125 Drop(PathBuf),
127 Cancel,
129}
130
131#[derive(Clone, Debug, PartialEq, PartialOrd, Deserialize, Serialize)]
133pub enum Input {
134 Button(ButtonArgs),
136 Move(Motion),
138 Text(String),
140 Resize(ResizeArgs),
142 Focus(bool),
144 Cursor(bool),
146 FileDrag(FileDrag),
148 Close(CloseArgs),
150}
151
152#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Deserialize, Serialize)]
154pub enum Loop {
155 Render(RenderArgs),
157 AfterRender(AfterRenderArgs),
159 Update(UpdateArgs),
161 Idle(IdleArgs),
163}
164
165#[derive(Clone)]
167pub enum Event {
168 Input(Input, Option<TimeStamp>),
172 Loop(Loop),
174 Custom(EventId, Arc<dyn Any + Send + Sync>, Option<TimeStamp>),
184}
185
186impl fmt::Debug for Event {
187 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
188 match *self {
189 Event::Input(ref input, _) => write!(f, "{:?}", input),
190 Event::Loop(ref l) => write!(f, "{:?}", l),
191 Event::Custom(ref id, _, _) => write!(f, "Custom({:?}, _)", id),
192 }
193 }
194}
195
196impl PartialEq for Event {
197 fn eq(&self, other: &Event) -> bool {
198 use Event::*;
199
200 match (self, other) {
201 (&Input(ref a, _), &Input(ref b, _)) => a == b,
202 (&Loop(ref a), &Loop(ref b)) => a == b,
203 (_, _) => false,
204 }
205 }
206}
207
208impl PartialOrd for Event {
209 fn partial_cmp(&self, other: &Event) -> Option<Ordering> {
210 use Event::*;
211
212 match (self, other) {
213 (&Input(ref a, _), &Input(ref b, _)) => a.partial_cmp(b),
214 (&Loop(ref a), &Loop(ref b)) => a.partial_cmp(b),
215 (&Custom(ref a_id, _, _), &Custom(ref b_id, _, _)) => {
216 let res = a_id.partial_cmp(b_id);
217 if res == Some(Ordering::Equal) {
218 None
219 } else {
220 res
221 }
222 }
223 (&Input(_, _), _) => Some(Ordering::Less),
224 (_, &Input(_, _)) => Some(Ordering::Greater),
225 (&Loop(_), &Custom(_, _, _)) => Some(Ordering::Less),
226 (&Custom(_, _, _), &Loop(_)) => Some(Ordering::Greater),
227 }
228 }
229}
230
231impl From<Key> for Button {
232 fn from(key: Key) -> Self {
233 Button::Keyboard(key)
234 }
235}
236
237impl From<MouseButton> for Button {
238 fn from(btn: MouseButton) -> Self {
239 Button::Mouse(btn)
240 }
241}
242
243impl From<ControllerButton> for Button {
244 fn from(btn: ControllerButton) -> Self {
245 Button::Controller(btn)
246 }
247}
248
249impl From<ButtonArgs> for Input {
250 fn from(args: ButtonArgs) -> Self {
251 Input::Button(args)
252 }
253}
254
255impl From<ControllerAxisArgs> for Motion {
256 fn from(args: ControllerAxisArgs) -> Self {
257 Motion::ControllerAxis(args)
258 }
259}
260
261impl From<ControllerAxisArgs> for Input {
262 fn from(args: ControllerAxisArgs) -> Self {
263 Input::Move(Motion::ControllerAxis(args))
264 }
265}
266
267impl From<TouchArgs> for Motion {
268 fn from(args: TouchArgs) -> Self {
269 Motion::Touch(args)
270 }
271}
272
273impl From<TouchArgs> for Input {
274 fn from(args: TouchArgs) -> Self {
275 Input::Move(Motion::Touch(args))
276 }
277}
278
279impl From<Motion> for Input {
280 fn from(motion: Motion) -> Self {
281 Input::Move(motion)
282 }
283}
284
285impl From<RenderArgs> for Loop {
286 fn from(args: RenderArgs) -> Self {
287 Loop::Render(args)
288 }
289}
290
291impl From<RenderArgs> for Event {
292 fn from(args: RenderArgs) -> Self {
293 Event::Loop(Loop::Render(args))
294 }
295}
296
297impl From<AfterRenderArgs> for Loop {
298 fn from(args: AfterRenderArgs) -> Self {
299 Loop::AfterRender(args)
300 }
301}
302
303impl From<AfterRenderArgs> for Event {
304 fn from(args: AfterRenderArgs) -> Self {
305 Event::Loop(Loop::AfterRender(args))
306 }
307}
308
309impl From<UpdateArgs> for Loop {
310 fn from(args: UpdateArgs) -> Self {
311 Loop::Update(args)
312 }
313}
314
315impl From<UpdateArgs> for Event {
316 fn from(args: UpdateArgs) -> Self {
317 Event::Loop(Loop::Update(args))
318 }
319}
320
321impl From<IdleArgs> for Loop {
322 fn from(args: IdleArgs) -> Self {
323 Loop::Idle(args)
324 }
325}
326
327impl From<IdleArgs> for Event {
328 fn from(args: IdleArgs) -> Self {
329 Event::Loop(Loop::Idle(args))
330 }
331}
332
333impl From<CloseArgs> for Input {
334 fn from(args: CloseArgs) -> Self {
335 Input::Close(args)
336 }
337}
338
339impl<T> From<T> for Event
340where
341 Input: From<T>,
342{
343 fn from(args: T) -> Self {
344 Event::Input(args.into(), None)
345 }
346}
347
348impl<T> From<(T, Option<TimeStamp>)> for Event
349where
350 Input: From<T>,
351{
352 fn from(args: (T, Option<TimeStamp>)) -> Self {
353 Event::Input(args.0.into(), args.1)
354 }
355}
356
357impl From<Loop> for Event {
358 fn from(l: Loop) -> Self {
359 Event::Loop(l)
360 }
361}
362
363impl From<Event> for Option<Input> {
364 fn from(event: Event) -> Option<Input> {
365 if let Event::Input(input, _) = event {
366 Some(input)
367 } else {
368 None
369 }
370 }
371}
372
373impl From<Event> for Option<Loop> {
374 fn from(event: Event) -> Option<Loop> {
375 if let Event::Loop(l) = event {
376 Some(l)
377 } else {
378 None
379 }
380 }
381}
382
383#[cfg(test)]
384mod tests {
385 use super::*;
386
387 #[test]
388 fn test_input_sync_send() {
389 fn chk<T: Sync + Send>() {}
390
391 chk::<Input>();
392 chk::<Loop>();
393 chk::<Event>();
394 }
395}