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}