conrod_core/event.rs
1//! Contains all types used to describe the input events that `Widget`s may handle.
2//!
3//! The two primary types of this module are:
4//!
5//! - `Input`: conrod's input type passed by the user to `Ui::handle_event` in order to drive the
6//! `Ui`.
7//! - `Event`: enumerates all possible events interpreted by conrod that may be propagated to
8//! widgets.
9//!
10//! The Event System
11//! ----------------
12//!
13//! Conrod's event system looks like this:
14//!
15//! *Input -> Ui -> Event -> Widget*
16//!
17//! The **Ui** receives **Input**s such as `Press` and `Release` via the `Ui::handle_event` method.
18//! It interprets these **Input**s to create higher-level **Event**s such as `DoubleClick`,
19//! `WidgetCapturesKeyboard`, etc. These **Event**s are stored and then fed to each **Widget** when
20//! `Ui::set_widgets` is called. At the end of `Ui::set_widgets` the stored **Event**s are flushed
21//! ready for the next incoming **Input**s.
22//!
23//! Conrod uses the `pistoncore-input` crate's `Input` type. There are a few reasons for this:
24//!
25//! 1. This `Input` type already provides a number of useful variants of events that we wish to
26//! provide and handle within conrod, and we do not yet see any great need to re-write it and
27//! duplicate code.
28//! 2. The `Input` type is already compatible with all `pistoncore-window` backends including
29//! `glfw_window`, `sdl2_window` and `glutin_window`. That said, co-ordinates and scroll
30//! directions may need to be translated to conrod's orientation.
31//! 3. The `pistoncore-input` crate also provides a `GenericEvent` trait which allows us to easily
32//! provide a blanket implementation of `ToRawEvent` for all event types that already implement
33//! this trait.
34//!
35//! Because we use the `pistoncore-input` `Event` type, we also re-export its associated data
36//! types (`Button`, `ControllerAxisArgs`, `Key`, etc).
37
38use input;
39use position::{Dimensions, Point};
40use utils::vec2_sub;
41use widget;
42
43/// The event type that is used by conrod to track inputs from the world. Events yielded by polling
44/// window backends should be converted to this type. This can be thought of as the event type
45/// which is supplied by the window backend to drive the state of the `Ui` forward.
46///
47/// This type is solely used within the `Ui::handle_event` method. The `Input` events are
48/// interpreted to create higher level `Event`s (such as DoubleClick, WidgetCapturesKeyboard, etc)
49/// which are stored for later processing by `Widget`s, which will occur during the call to
50/// `Ui::set_widgets`.
51///
52/// **Note:** `Input` events that contain co-ordinates must be oriented with (0, 0) at the middle
53/// of the window with the *y* axis pointing upwards (Cartesian co-ordinates). All co-ordinates and
54/// dimensions must be given as `Scalar` (DPI agnostic) values. Many windows provide coordinates
55/// with the origin in the top left with *y* pointing down, so you might need to translate these
56/// co-ordinates when converting to this event. Also be sure to invert the *y* axis of MouseScroll
57/// events.
58#[derive(Clone, Debug, PartialEq)]
59pub enum Input {
60 /// A button on some input device was pressed.
61 Press(input::Button),
62 /// A button on some input device was released.
63 Release(input::Button),
64 /// The window was received to the given dimensions.
65 Resize(f64, f64),
66 /// Some motion input was received (e.g. moving mouse or joystick axis).
67 Motion(input::Motion),
68 /// Input from a touch surface/screen.
69 Touch(input::Touch),
70 /// Text input was received, usually via the keyboard.
71 Text(String),
72 /// The window was focused or lost focus.
73 Focus(bool),
74 /// The backed requested to redraw.
75 Redraw,
76}
77
78/// Enum containing all the events that the `Ui` may provide.
79#[derive(Clone, PartialEq, Debug)]
80pub enum Event {
81 /// Represents a raw `input::Input` event.
82 Raw(Input),
83 /// Events that have been interpreted from `backend::RawEvent`s by the `Ui`.
84 ///
85 /// Most events usually
86 Ui(Ui),
87}
88
89/// Represents all events interpreted by the `Ui`.
90#[derive(Clone, PartialEq, Debug)]
91pub enum Ui {
92 /// Entered text, along with the widget that was capturing the keyboard at the time.
93 Text(Option<widget::Id>, Text),
94 /// Some button was pressed, along with the widget that was capturing the device whose button
95 /// was pressed.
96 Press(Option<widget::Id>, Press),
97 /// Some button was released, along with the widget that was capturing the device whose button
98 /// was released.
99 Release(Option<widget::Id>, Release),
100 /// Represents all forms of motion input, alongside with the widget that was capturing the
101 /// mouse at the time.
102 Motion(Option<widget::Id>, Motion),
103 /// Interaction with a touch screen/surface.
104 Touch(Option<widget::Id>, input::Touch),
105 /// The window's dimensions were resized.
106 WindowResized(Dimensions),
107 /// Represents a pointing device being pressed and subsequently released while over the same
108 /// location.
109 Click(Option<widget::Id>, Click),
110 /// Two `Click` events with the same `button` and `xy` occurring within a duration that is less
111 /// that the `theme.double_click_threshold`.
112 DoubleClick(Option<widget::Id>, DoubleClick),
113 /// A user tapped a touch screen/surface.
114 Tap(Option<widget::Id>, Tap),
115 /// Represents a pointing device button being pressed and a subsequent movement of the mouse.
116 Drag(Option<widget::Id>, Drag),
117 /// A generic scroll event.
118 ///
119 /// `Scroll` does not necessarily have to get created by a mouse wheel, it could be generated
120 /// from a keypress, or as a response to handling some other event.
121 ///
122 /// Received `Scroll` events are first applied to all scrollable widgets under the mouse from
123 /// top to bottom. The remainder will then be applied to either 1. whatever widget captures the
124 /// device from which the scroll was emitted or 2. whatever widget was specified.
125 Scroll(Option<widget::Id>, Scroll),
126 /// Indicates that the given widget has captured the given user input source.
127 WidgetCapturesInputSource(widget::Id, input::Source),
128 /// Indicates that the given widget has released the given user input source.
129 WidgetUncapturesInputSource(widget::Id, input::Source),
130}
131
132/// Events that apply to a specific widget.
133///
134/// Rather than delivering entire `event::Event`s to the widget (with a lot of redundant
135/// information), this `event::Widget` is used as a refined, widget-specific event.
136///
137/// All `Widget` event co-ordinates will be relative to the centre of the `Widget` to which they
138/// are delivered.
139#[derive(Clone, PartialEq, Debug)]
140pub enum Widget {
141 /// Entered text.
142 Text(Text),
143 /// Represents all forms of motion input.
144 Motion(Motion),
145 /// Interaction with a touch screen.
146 Touch(input::Touch),
147 /// Some button was pressed.
148 Press(Press),
149 /// Some button was released.
150 Release(Release),
151 /// Represents a pointing device being pressed and subsequently released while over the same
152 /// location.
153 Click(Click),
154 /// Two `Click` events with the same `button` and `xy` occurring within a duration that is less
155 /// that the `theme.double_click_threshold`.
156 DoubleClick(DoubleClick),
157 /// A user tapped the widget on a touch screen/surface.
158 Tap(Tap),
159 /// Represents a pointing device button being pressed and a subsequent movement of the mouse.
160 Drag(Drag),
161 /// Represents the amount of scroll that has been applied to this widget.
162 Scroll(Scroll),
163 /// The window's dimensions were resized.
164 WindowResized(Dimensions),
165 /// The widget has captured the given input source.
166 CapturesInputSource(input::Source),
167 /// The widget has released the input source from capturing.
168 UncapturesInputSource(input::Source),
169}
170
171/// Contains all relevant information for a Text event.
172#[derive(Clone, PartialEq, Debug)]
173pub struct Text {
174 /// All text that was entered as a part of the event.
175 pub string: String,
176 /// The modifier keys that were down at the time.
177 pub modifiers: input::keyboard::ModifierKey,
178}
179
180/// Contains all relevant information for a Motion event.
181#[derive(Copy, Clone, PartialEq, Debug)]
182pub struct Motion {
183 /// The type of `Motion` that occurred.
184 pub motion: input::Motion,
185 /// The modifier keys that were down at the time.
186 pub modifiers: input::keyboard::ModifierKey,
187}
188
189/// The different kinds of `Button`s that may be `Press`ed or `Release`d.
190#[derive(Copy, Clone, PartialEq, Debug)]
191pub enum Button {
192 /// A keyboard button.
193 Keyboard(input::Key),
194 /// A mouse button along with the location at which it was `Press`ed/`Release`d.
195 Mouse(input::MouseButton, Point),
196 /// A controller button.
197 Controller(input::ControllerButton),
198}
199
200/// Contains all relevant information for a Press event.
201#[derive(Copy, Clone, PartialEq, Debug)]
202pub struct Press {
203 /// The `Button` that was pressed.
204 pub button: Button,
205 /// The modifier keys that were down at the time.
206 pub modifiers: input::keyboard::ModifierKey,
207}
208
209/// Contains all relevant information for the event where a mouse button was pressed.
210#[derive(Copy, Clone, PartialEq, Debug)]
211pub struct MousePress {
212 /// The mouse button that was pressed.
213 pub button: input::MouseButton,
214 /// The location at which the mouse was pressed.
215 pub xy: Point,
216 /// The modifier keys that were down at the time.
217 pub modifiers: input::keyboard::ModifierKey,
218}
219
220/// Contains all relevant information for the event where a keyboard button was pressed.
221#[derive(Copy, Clone, PartialEq, Debug)]
222pub struct KeyPress {
223 /// The key that was pressed.
224 pub key: input::Key,
225 /// The modifier keys that were down at the time.
226 pub modifiers: input::keyboard::ModifierKey,
227}
228
229/// Contains all relevant information for a Release event.
230#[derive(Copy, Clone, PartialEq, Debug)]
231pub struct Release {
232 /// The `Button` that was released.
233 pub button: Button,
234 /// The modifier keys that were down at the time.
235 pub modifiers: input::keyboard::ModifierKey,
236}
237
238/// Contains all relevant information for the event where a mouse button was released.
239#[derive(Copy, Clone, PartialEq, Debug)]
240pub struct MouseRelease {
241 /// The mouse button that was released.
242 pub button: input::MouseButton,
243 /// The location at which the mouse was released.
244 pub xy: Point,
245 /// The modifier keys that were down at the time.
246 pub modifiers: input::keyboard::ModifierKey,
247}
248
249/// Contains all relevant information for the event where a keyboard button was release.
250#[derive(Copy, Clone, PartialEq, Debug)]
251pub struct KeyRelease {
252 /// The key that was release.
253 pub key: input::Key,
254 /// The modifier keys that were down at the time.
255 pub modifiers: input::keyboard::ModifierKey,
256}
257
258/// Contains all the relevant information for a mouse drag.
259#[derive(Copy, Clone, PartialEq, Debug)]
260pub struct Drag {
261 /// Which mouse button was being held during the drag
262 pub button: input::MouseButton,
263 /// The point from which the current series of drag events began.
264 ///
265 /// This will be the position of the pointing device whenever the dragging press began.
266 pub origin: Point,
267 /// The point from which this drag event began.
268 pub from: Point,
269 /// The point at which this drag event ended.
270 pub to: Point,
271 /// The magnitude of the vector between `from` and `to`.
272 pub delta_xy: Point,
273 /// The magnitude of the vector between `origin` and `to`.
274 pub total_delta_xy: Point,
275 /// Which modifier keys are being held during the mouse drag.
276 pub modifiers: input::keyboard::ModifierKey,
277}
278
279/// Contains all the relevant information for a mouse click.
280#[derive(Copy, Clone, PartialEq, Debug)]
281pub struct Click {
282 /// Which mouse button was clicked
283 pub button: input::MouseButton,
284 /// The position at which the mouse was released.
285 pub xy: Point,
286 /// Which modifier keys, if any, that were being held down when the user clicked
287 pub modifiers: input::keyboard::ModifierKey,
288}
289
290/// Contains all the relevant information for a double click.
291///
292/// When handling this event, be sure to check that you are handling the intended `button` too.
293#[derive(Copy, Clone, PartialEq, Debug)]
294pub struct DoubleClick {
295 /// Which mouse button was clicked
296 pub button: input::MouseButton,
297 /// The position at which the mouse was released.
298 pub xy: Point,
299 /// Which modifier keys, if any, that were being held down when the user clicked
300 pub modifiers: input::keyboard::ModifierKey,
301}
302
303/// All relevant information for a touch-screen tap event.
304#[derive(Copy, Clone, PartialEq, Debug)]
305pub struct Tap {
306 /// The unique identifier of the source of the touch.
307 pub id: input::touch::Id,
308 /// The position at which the finger left the screen.
309 pub xy: Point,
310}
311
312/// Holds all the relevant information about a scroll event
313#[derive(Copy, Clone, PartialEq, Debug)]
314pub struct Scroll {
315 /// The amount of scroll along the x axis.
316 pub x: f64,
317 /// The amount of scroll along the y axis.
318 pub y: f64,
319 /// Which modifier keys, if any, that were being held down while the scroll occured
320 pub modifiers: input::keyboard::ModifierKey,
321}
322
323impl Motion {
324 /// Returns a copy of the `Motion` relative to the given `xy`
325 pub fn relative_to(&self, xy: Point) -> Motion {
326 let motion = match self.motion {
327 input::Motion::MouseCursor { x, y } => input::Motion::MouseCursor {
328 x: x - xy[0],
329 y: y - xy[1],
330 },
331 motion => motion,
332 };
333 Motion {
334 motion: motion,
335 ..*self
336 }
337 }
338}
339
340impl Button {
341 /// Returns a copy of the Button relative to the given `xy`
342 pub fn relative_to(&self, xy: Point) -> Button {
343 match *self {
344 Button::Mouse(m_button, self_xy) => Button::Mouse(m_button, vec2_sub(self_xy, xy)),
345 button => button,
346 }
347 }
348}
349
350impl Press {
351 /// Returns a copy of the Press relative to the given `xy`
352 pub fn relative_to(&self, xy: Point) -> Press {
353 Press {
354 button: self.button.relative_to(xy),
355 ..*self
356 }
357 }
358
359 /// If the `Press` event represents the pressing of a mouse button, return `Some`.
360 pub fn mouse(self) -> Option<MousePress> {
361 match self.button {
362 Button::Mouse(button, xy) => Some(MousePress {
363 button: button,
364 xy: xy,
365 modifiers: self.modifiers,
366 }),
367 _ => None,
368 }
369 }
370
371 /// If the `Press` event represents the pressing of keyboard button, return `Some`.
372 pub fn key(self) -> Option<KeyPress> {
373 match self.button {
374 Button::Keyboard(key) => Some(KeyPress {
375 key: key,
376 modifiers: self.modifiers,
377 }),
378 _ => None,
379 }
380 }
381}
382
383impl Release {
384 /// Returns a copy of the Release relative to the given `xy`
385 pub fn relative_to(&self, xy: Point) -> Release {
386 Release {
387 button: self.button.relative_to(xy),
388 ..*self
389 }
390 }
391
392 /// If the `Release` event represents the releasing of a mouse button, return `Some`.
393 pub fn mouse(self) -> Option<MouseRelease> {
394 match self.button {
395 Button::Mouse(button, xy) => Some(MouseRelease {
396 button: button,
397 xy: xy,
398 modifiers: self.modifiers,
399 }),
400 _ => None,
401 }
402 }
403
404 /// If the `Release` event represents the release of keyboard button, return `Some`.
405 pub fn key(self) -> Option<KeyRelease> {
406 match self.button {
407 Button::Keyboard(key) => Some(KeyRelease {
408 key: key,
409 modifiers: self.modifiers,
410 }),
411 _ => None,
412 }
413 }
414}
415
416impl Tap {
417 /// Returns a copy of the `Tap` relative to the given `xy`
418 pub fn relative_to(&self, xy: Point) -> Self {
419 Tap {
420 xy: vec2_sub(self.xy, xy),
421 ..*self
422 }
423 }
424}
425
426impl Click {
427 /// Returns a copy of the Click relative to the given `xy`
428 pub fn relative_to(&self, xy: Point) -> Click {
429 Click {
430 xy: vec2_sub(self.xy, xy),
431 ..*self
432 }
433 }
434}
435
436impl DoubleClick {
437 /// Returns a copy of the DoubleClick relative to the given `xy`
438 pub fn relative_to(&self, xy: Point) -> DoubleClick {
439 DoubleClick {
440 xy: vec2_sub(self.xy, xy),
441 ..*self
442 }
443 }
444}
445
446impl Drag {
447 /// Returns a copy of the Drag relative to the given `xy`
448 pub fn relative_to(&self, xy: Point) -> Drag {
449 Drag {
450 origin: vec2_sub(self.origin, xy),
451 from: vec2_sub(self.from, xy),
452 to: vec2_sub(self.to, xy),
453 ..*self
454 }
455 }
456}
457
458impl From<input::Motion> for Input {
459 fn from(motion: input::Motion) -> Self {
460 Input::Motion(motion)
461 }
462}
463
464impl From<input::Touch> for Input {
465 fn from(touch: input::Touch) -> Self {
466 Input::Touch(touch)
467 }
468}
469
470impl From<Ui> for Event {
471 fn from(ui: Ui) -> Self {
472 Event::Ui(ui)
473 }
474}
475
476impl From<Input> for Event {
477 fn from(input: Input) -> Self {
478 Event::Raw(input)
479 }
480}
481
482impl From<Text> for Widget {
483 fn from(text: Text) -> Self {
484 Widget::Text(text)
485 }
486}
487
488impl From<Motion> for Widget {
489 fn from(motion: Motion) -> Self {
490 Widget::Motion(motion)
491 }
492}
493
494impl From<input::Touch> for Widget {
495 fn from(touch: input::Touch) -> Self {
496 Widget::Touch(touch)
497 }
498}
499
500impl From<Press> for Widget {
501 fn from(press: Press) -> Self {
502 Widget::Press(press)
503 }
504}
505
506impl From<Release> for Widget {
507 fn from(release: Release) -> Self {
508 Widget::Release(release)
509 }
510}
511
512impl From<Click> for Widget {
513 fn from(click: Click) -> Self {
514 Widget::Click(click)
515 }
516}
517
518impl From<DoubleClick> for Widget {
519 fn from(double_click: DoubleClick) -> Self {
520 Widget::DoubleClick(double_click)
521 }
522}
523
524impl From<Tap> for Widget {
525 fn from(tap: Tap) -> Self {
526 Widget::Tap(tap)
527 }
528}
529
530impl From<Scroll> for Widget {
531 fn from(scroll: Scroll) -> Self {
532 Widget::Scroll(scroll)
533 }
534}
535
536impl From<Drag> for Widget {
537 fn from(drag: Drag) -> Self {
538 Widget::Drag(drag)
539 }
540}