1 #![crate_name = "input"]
2 #![deny(missing_docs)]
3 #![deny(missing_copy_implementations)]
4 
5 //! A flexible structure for user interactions
6 //! to be used in window frameworks and widgets libraries.
7 
8 #[macro_use]
9 extern crate bitflags;
10 #[macro_use]
11 extern crate serde_derive;
12 extern crate serde;
13 extern crate viewport;
14 
15 use std::fmt;
16 use std::any::Any;
17 use std::sync::Arc;
18 use std::path::PathBuf;
19 use std::cmp::Ordering;
20 
21 pub use mouse::MouseButton;
22 pub use keyboard::Key;
23 pub use controller::{ControllerAxisArgs, ControllerButton, ControllerHat};
24 
25 pub mod controller;
26 pub mod keyboard;
27 pub mod mouse;
28 
29 pub use after_render::{AfterRenderArgs, AfterRenderEvent};
30 pub use close::{CloseArgs, CloseEvent};
31 pub use controller::ControllerAxisEvent;
32 pub use cursor::CursorEvent;
33 pub use focus::FocusEvent;
34 pub use generic_event::GenericEvent;
35 pub use idle::{IdleArgs, IdleEvent};
36 pub use mouse::{MouseCursorEvent, MouseRelativeEvent, MouseScrollEvent};
37 pub use button::{ButtonState, ButtonArgs, ButtonEvent, PressEvent, ReleaseEvent};
38 pub use resize::{ResizeArgs, ResizeEvent};
39 pub use render::{RenderArgs, RenderEvent};
40 pub use text::TextEvent;
41 pub use touch::{Touch, TouchArgs, TouchEvent};
42 pub use update::{UpdateArgs, UpdateEvent};
43 
44 use event_id::EventId;
45 
46 pub mod event_id;
47 pub mod generic_event;
48 
49 mod after_render;
50 mod button;
51 mod close;
52 mod cursor;
53 mod focus;
54 mod idle;
55 mod render;
56 mod resize;
57 mod text;
58 mod touch;
59 mod update;
60 
61 /// The type of time stamp.
62 ///
63 /// Measured in milliseconds since initialization of window.
64 pub type TimeStamp = u32;
65 
66 /// Models different kinds of buttons.
67 #[derive(Copy, Clone, Deserialize, Serialize, PartialEq, PartialOrd, Ord, Eq, Hash, Debug)]
68 pub enum Button {
69     /// A keyboard button.
70     Keyboard(Key),
71     /// A mouse button.
72     Mouse(MouseButton),
73     /// A controller button.
74     Controller(ControllerButton),
75     /// A controller hat (d-Pad)
76     Hat(ControllerHat),
77 }
78 
79 /// Models different kinds of motion.
80 #[derive(Copy, Clone, Deserialize, Serialize, PartialEq, PartialOrd, Debug)]
81 pub enum Motion {
82     /// Position in window coordinates.
83     MouseCursor([f64; 2]),
84     /// Position in relative coordinates.
85     MouseRelative([f64; 2]),
86     /// Position in scroll ticks.
87     MouseScroll([f64; 2]),
88     /// Controller axis move event.
89     ControllerAxis(ControllerAxisArgs),
90     /// Touch event.
91     Touch(TouchArgs),
92 }
93 
94 /// Stores controller hat state.
95 #[derive(Copy, Clone, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
96 pub enum HatState {
97     /// Centered (no direction).
98     Centered,
99     /// Up direction.
100     Up,
101     /// Right direction.
102     Right,
103     /// Down direction.
104     Down,
105     /// Left direction.
106     Left,
107     /// Right-up direction.
108     RightUp,
109     /// Right-down direction.
110     RightDown,
111     /// Left-up direction.
112     LeftUp,
113     /// Left-down direction.
114     LeftDown,
115 }
116 
117 /// Models dragging and dropping files.
118 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, Hash)]
119 pub enum FileDrag {
120     /// A file is being hovered over the window.
121     Hover(PathBuf),
122     /// A file has been dropped into the window.
123     Drop(PathBuf),
124     /// A file was hovered, but has exited the window.
125     Cancel,
126 }
127 
128 /// Models input events.
129 #[derive(Clone, Debug, PartialEq, PartialOrd, Deserialize, Serialize)]
130 pub enum Input {
131     /// Changed button state.
132     Button(ButtonArgs),
133     /// Moved mouse cursor.
134     Move(Motion),
135     /// Text (usually from keyboard).
136     Text(String),
137     /// Window got resized.
138     Resize(ResizeArgs),
139     /// Window gained or lost focus.
140     Focus(bool),
141     /// Window gained or lost cursor.
142     Cursor(bool),
143     /// A file is being dragged or dropped over the window.
144     FileDrag(FileDrag),
145     /// Window closed.
146     Close(CloseArgs),
147 }
148 
149 /// Models loop events.
150 #[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Deserialize, Serialize)]
151 pub enum Loop {
152     /// Render graphics.
153     Render(RenderArgs),
154     /// After rendering and swapping buffers.
155     AfterRender(AfterRenderArgs),
156     /// Update the state of the application.
157     Update(UpdateArgs),
158     /// Do background tasks that can be done incrementally.
159     Idle(IdleArgs),
160 }
161 
162 /// Models all events.
163 #[derive(Clone)]
164 pub enum Event {
165     /// Input events.
166     ///
167     /// Time stamp is ignored when comparing input events for equality and order.
168     Input(Input, Option<TimeStamp>),
169     /// Events that commonly used by event loops.
170     Loop(Loop),
171     /// Custom event.
172     ///
173     /// When comparing two custom events for equality,
174     /// they always return `false`.
175     ///
176     /// When comparing partial order of two custom events,
177     /// the event ids are checked and if they are equal it returns `None`.
178     ///
179     /// Time stamp is ignored both when comparing custom events for equality and order.
180     Custom(EventId, Arc<Any + Send + Sync>, Option<TimeStamp>),
181 }
182 
183 impl fmt::Debug for Event {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result184     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
185         match *self {
186             Event::Input(ref input, _) => write!(f, "{:?}", input),
187             Event::Loop(ref l) => write!(f, "{:?}", l),
188             Event::Custom(ref id, _, _) => write!(f, "Custom({:?}, _)", id),
189         }
190     }
191 }
192 
193 impl PartialEq for Event {
eq(&self, other: &Event) -> bool194     fn eq(&self, other: &Event) -> bool {
195         use Event::*;
196 
197         match (self, other) {
198             (&Input(ref a, _), &Input(ref b, _)) => a == b,
199             (&Loop(ref a), &Loop(ref b)) => a == b,
200             (_, _) => false,
201         }
202     }
203 }
204 
205 impl PartialOrd for Event {
partial_cmp(&self, other: &Event) -> Option<Ordering>206     fn partial_cmp(&self, other: &Event) -> Option<Ordering> {
207         use Event::*;
208 
209         match (self, other) {
210             (&Input(ref a, _), &Input(ref b, _)) => a.partial_cmp(b),
211             (&Loop(ref a), &Loop(ref b)) => a.partial_cmp(b),
212             (&Custom(ref a_id, _, _), &Custom(ref b_id, _, _)) => {
213                 let res = a_id.partial_cmp(b_id);
214                 if res == Some(Ordering::Equal) {None}
215                 else {res}
216             }
217             (&Input(_, _), _) => Some(Ordering::Less),
218             (_, &Input(_, _)) => Some(Ordering::Greater),
219             (&Loop(_), &Custom(_, _, _)) => Some(Ordering::Less),
220             (&Custom(_, _, _), &Loop(_)) => Some(Ordering::Greater),
221         }
222     }
223 }
224 
225 impl From<Key> for Button {
from(key: Key) -> Self226     fn from(key: Key) -> Self {
227         Button::Keyboard(key)
228     }
229 }
230 
231 impl From<MouseButton> for Button {
from(btn: MouseButton) -> Self232     fn from(btn: MouseButton) -> Self {
233         Button::Mouse(btn)
234     }
235 }
236 
237 impl From<ControllerButton> for Button {
from(btn: ControllerButton) -> Self238     fn from(btn: ControllerButton) -> Self {
239         Button::Controller(btn)
240     }
241 }
242 
243 impl From<ButtonArgs> for Input {
from(args: ButtonArgs) -> Self244     fn from(args: ButtonArgs) -> Self {
245         Input::Button(args)
246     }
247 }
248 
249 impl From<ControllerAxisArgs> for Motion {
from(args: ControllerAxisArgs) -> Self250     fn from(args: ControllerAxisArgs) -> Self {
251         Motion::ControllerAxis(args)
252     }
253 }
254 
255 impl From<ControllerAxisArgs> for Input {
from(args: ControllerAxisArgs) -> Self256     fn from(args: ControllerAxisArgs) -> Self {
257         Input::Move(Motion::ControllerAxis(args))
258     }
259 }
260 
261 impl From<TouchArgs> for Motion {
from(args: TouchArgs) -> Self262     fn from(args: TouchArgs) -> Self {
263         Motion::Touch(args)
264     }
265 }
266 
267 impl From<TouchArgs> for Input {
from(args: TouchArgs) -> Self268     fn from(args: TouchArgs) -> Self {
269         Input::Move(Motion::Touch(args))
270     }
271 }
272 
273 impl From<Motion> for Input {
from(motion: Motion) -> Self274     fn from(motion: Motion) -> Self {
275         Input::Move(motion)
276     }
277 }
278 
279 impl From<RenderArgs> for Loop {
from(args: RenderArgs) -> Self280     fn from(args: RenderArgs) -> Self {
281         Loop::Render(args)
282     }
283 }
284 
285 impl From<RenderArgs> for Event {
from(args: RenderArgs) -> Self286     fn from(args: RenderArgs) -> Self {
287         Event::Loop(Loop::Render(args))
288     }
289 }
290 
291 impl From<AfterRenderArgs> for Loop {
from(args: AfterRenderArgs) -> Self292     fn from(args: AfterRenderArgs) -> Self {
293         Loop::AfterRender(args)
294     }
295 }
296 
297 impl From<AfterRenderArgs> for Event {
from(args: AfterRenderArgs) -> Self298     fn from(args: AfterRenderArgs) -> Self {
299         Event::Loop(Loop::AfterRender(args))
300     }
301 }
302 
303 impl From<UpdateArgs> for Loop {
from(args: UpdateArgs) -> Self304     fn from(args: UpdateArgs) -> Self {
305         Loop::Update(args)
306     }
307 }
308 
309 impl From<UpdateArgs> for Event {
from(args: UpdateArgs) -> Self310     fn from(args: UpdateArgs) -> Self {
311         Event::Loop(Loop::Update(args))
312     }
313 }
314 
315 impl From<IdleArgs> for Loop {
from(args: IdleArgs) -> Self316     fn from(args: IdleArgs) -> Self {
317         Loop::Idle(args)
318     }
319 }
320 
321 impl From<IdleArgs> for Event {
from(args: IdleArgs) -> Self322     fn from(args: IdleArgs) -> Self {
323         Event::Loop(Loop::Idle(args))
324     }
325 }
326 
327 impl From<CloseArgs> for Input {
from(args: CloseArgs) -> Self328     fn from(args: CloseArgs) -> Self {
329         Input::Close(args)
330     }
331 }
332 
333 impl<T> From<T> for Event
334     where Input: From<T>
335 {
from(args: T) -> Self336     fn from(args: T) -> Self {
337         Event::Input(args.into(), None)
338     }
339 }
340 
341 impl<T> From<(T, Option<TimeStamp>)> for Event
342     where Input: From<T>
343 {
from(args: (T, Option<TimeStamp>)) -> Self344     fn from(args: (T, Option<TimeStamp>)) -> Self {
345         Event::Input(args.0.into(), args.1)
346     }
347 }
348 
349 impl From<Loop> for Event {
from(l: Loop) -> Self350     fn from(l: Loop) -> Self {
351         Event::Loop(l)
352     }
353 }
354 
355 impl Into<Option<Input>> for Event {
into(self) -> Option<Input>356     fn into(self) -> Option<Input> {
357         if let Event::Input(input, _) = self {
358             Some(input)
359         } else {
360             None
361         }
362     }
363 }
364 
365 impl Into<Option<Loop>> for Event {
into(self) -> Option<Loop>366     fn into(self) -> Option<Loop> {
367         if let Event::Loop(l) = self {
368             Some(l)
369         } else {
370             None
371         }
372     }
373 }
374 
375 #[cfg(test)]
376 mod tests {
377     use super::*;
378 
379     #[test]
test_input_sync_send()380     fn test_input_sync_send() {
381         fn chk<T: Sync + Send>() {}
382 
383         chk::<Input>();
384         chk::<Loop>();
385         chk::<Event>();
386     }
387 }
388