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