conrod_core/input/
widget.rs

1//! Contains all the logic for filtering input events and making them relative to widgets.
2//!
3//! The core of this module is the `Widget::for_widget` method, which creates an
4//! `InputProvider` that provides input events for a specific widget.
5
6use event;
7use input;
8use utils;
9use widget;
10use {Point, Rect};
11
12/// Provides only events and input state that are relevant to a specific widget.
13///
14/// This type can be produced by calling the `UiCell::input` method with the target widget's
15/// `widget::Id`. This is particularly useful
16///
17/// Unlike `input::Global`, `input::Widget` methods are tailored to the widget for which they are
18/// produced.
19#[derive(Clone)]
20pub struct Widget<'a> {
21    global: &'a input::Global,
22    rect: Rect,
23    idx: widget::Id,
24}
25
26/// A view of the `input::state::Mouse` that is specific to a single widget.
27#[derive(Copy, Clone, Debug)]
28pub struct Mouse<'a> {
29    rect: Rect,
30    mouse_abs_xy: Point,
31    /// The state of each `MouseButton`.
32    pub buttons: &'a input::state::mouse::ButtonMap,
33}
34
35/// An iterator yielding all events that are relevant to a specific widget.
36///
37/// All events provided by this Iterator will be filtered in accordance with input capturing. For
38/// example: If the widget does not capture the mouse, it *will not* receive any mouse-related
39/// events. If the widget captures the keyboard it *will* receive all keyboard events.
40///
41/// All mouse events will have their coordinates relative to the middle of the widget's `Rect`.
42#[derive(Clone)]
43pub struct Events<'a> {
44    ui_events: input::global::UiEvents<'a>,
45    capturing_keyboard: Option<widget::Id>,
46    capturing_mouse: Option<widget::Id>,
47    rect: Rect,
48    idx: widget::Id,
49}
50
51/// An `Iterator` yielding all button presses occuring within the given sequence of
52/// `widget::Event`s.
53#[derive(Clone)]
54pub struct Presses<'a> {
55    events: Events<'a>,
56}
57
58/// An `Iterator` yielding all mouse button presses occuring within the given sequence of `Presses`.
59#[derive(Clone)]
60pub struct MousePresses<'a> {
61    presses: Presses<'a>,
62}
63
64/// An `Iterator` yielding all mouse button presses occuring within the given sequence of
65/// `Presses` for some specific mouse button.
66#[derive(Clone)]
67pub struct MouseButtonPresses<'a> {
68    mouse_presses: MousePresses<'a>,
69    button: input::MouseButton,
70}
71
72/// An `Iterator` yielding all keyboard button presses occuring within the given sequence of
73/// `Presses`.
74#[derive(Clone)]
75pub struct KeyPresses<'a> {
76    presses: Presses<'a>,
77}
78
79/// An `Iterator` yielding all button releases occuring within the given sequence of
80/// `widget::Event`s.
81#[derive(Clone)]
82pub struct Releases<'a> {
83    events: Events<'a>,
84}
85
86/// An `Iterator` yielding all mouse button releases occuring within the given sequence of
87/// `Releases` for some specific mouse button.
88#[derive(Clone)]
89pub struct MouseButtonReleases<'a> {
90    mouse_releases: MouseReleases<'a>,
91    button: input::MouseButton,
92}
93
94/// An `Iterator` yielding all mouse button releases occuring within the given sequence of
95/// `Releases`.
96#[derive(Clone)]
97pub struct MouseReleases<'a> {
98    releases: Releases<'a>,
99}
100
101/// An `Iterator` yielding all keyboard button releases occuring within the given sequence of
102/// `Releases`.
103#[derive(Clone)]
104pub struct KeyReleases<'a> {
105    releases: Releases<'a>,
106}
107
108/// An `Iterator` yielding all mouse clicks occuring within the given sequence of `widget::Event`s.
109#[derive(Clone)]
110pub struct Clicks<'a> {
111    events: Events<'a>,
112}
113
114/// An `Iterator` yielding all mouse `button` clicks occuring within the given sequence of
115/// `widget::Click`s.
116#[derive(Clone)]
117pub struct ButtonClicks<'a> {
118    clicks: Clicks<'a>,
119    button: input::MouseButton,
120}
121
122/// An `Iterator` yielding all touch screen taps occuring within the given sequence of
123/// `widget::Event`s.
124#[derive(Clone)]
125pub struct Taps<'a> {
126    events: Events<'a>,
127}
128
129/// An iterator that yields all `event::Drag` events yielded by the `Events` iterator.
130///
131/// Only events that occurred while the widget was capturing the device that did the dragging will
132/// be yielded.
133#[derive(Clone)]
134pub struct Drags<'a> {
135    events: Events<'a>,
136}
137
138/// An `Iterator` yielding all mouse `button` drags occuring within the given sequence of
139/// `widget::Drag`s.
140#[derive(Clone)]
141pub struct ButtonDrags<'a> {
142    drags: Drags<'a>,
143    button: input::MouseButton,
144}
145
146/// An iterator that yields all `Input::Text` events yielded by the `Events` iterator.
147///
148/// Only events that occurred while the widget was capturing the keyboard will be yielded.
149#[derive(Clone)]
150pub struct Texts<'a> {
151    events: Events<'a>,
152}
153
154/// An iterator that yields all `Scroll` events yielded by the given `Events` iterator.
155#[derive(Clone)]
156pub struct Scrolls<'a> {
157    events: Events<'a>,
158}
159
160impl<'a> Widget<'a> {
161    /// Returns a `Widget` with events specifically for the given widget.
162    ///
163    /// Filters out only the events that directly pertain to the widget.
164    ///
165    /// All events will also be made relative to the widget's own (0, 0) origin.
166    pub fn for_widget(idx: widget::Id, rect: Rect, global: &'a input::Global) -> Self {
167        Widget {
168            global: global,
169            rect: rect,
170            idx: idx,
171        }
172    }
173
174    /// If the widget is currently capturing the mouse, this returns the state of the mouse.
175    ///
176    /// Returns `None` if the widget is not capturing the mouse.
177    pub fn mouse(&self) -> Option<Mouse<'a>> {
178        if self.global.current.widget_capturing_mouse == Some(self.idx) {
179            let mouse = Mouse {
180                buttons: &self.global.current.mouse.buttons,
181                mouse_abs_xy: self.global.current.mouse.xy,
182                rect: self.rect,
183            };
184            return Some(mouse);
185        }
186        None
187    }
188
189    /// Produces an iterator yielding all events that are relevant to a specific widget.
190    ///
191    /// All events provided by this Iterator will be filtered in accordance with input capturing. For
192    /// example: If the widget does not capture the mouse, it *will not* receive any mouse-related
193    /// events. If the widget captures the keyboard it *will* receive all keyboard events.
194    ///
195    /// All mouse events will have their coordinates relative to the middle of the widget's `Rect`.
196    pub fn events(&self) -> Events<'a> {
197        Events {
198            ui_events: self.global.events().ui(),
199            capturing_keyboard: self.global.start.widget_capturing_keyboard,
200            capturing_mouse: self.global.start.widget_capturing_mouse,
201            rect: self.rect,
202            idx: self.idx,
203        }
204    }
205
206    /// Filters all events yielded by `Self::events` other than `event::Press`es.
207    pub fn presses(&self) -> Presses<'a> {
208        Presses {
209            events: self.events(),
210        }
211    }
212
213    /// Filters all events yielded by `Self::events` other than `event::Release`es.
214    pub fn releases(&self) -> Releases<'a> {
215        Releases {
216            events: self.events(),
217        }
218    }
219
220    /// Filters all events yielded by `Self::events` for all `event::Click`s.
221    ///
222    /// A _click_ is determined to have occured if a pointing device button was both pressed and
223    /// released over the widget.
224    pub fn clicks(&self) -> Clicks<'a> {
225        Clicks {
226            events: self.events(),
227        }
228    }
229
230    /// Filters all events yielded by `Self::events` for all `event::Tap`s.
231    ///
232    /// A _tap_ is determined to have occured if a touch interaction both started and ended over
233    /// the widget.
234    pub fn taps(&self) -> Taps<'a> {
235        Taps {
236            events: self.events(),
237        }
238    }
239
240    /// Produces an iterator that yields all `event::Drag` events yielded by the `Events` iterator.
241    ///
242    /// Only events that occurred while the widget was capturing the device that did the dragging
243    /// will be yielded.
244    pub fn drags(&self) -> Drags<'a> {
245        Drags {
246            events: self.events(),
247        }
248    }
249
250    /// Produces an iterator that yields all `Input::Text` events that have occurred as `&str`s
251    /// since the last time `Ui::set_widgets` was called.
252    ///
253    /// Only events that occurred while the widget was capturing the keyboard will be yielded.
254    pub fn texts(&self) -> Texts<'a> {
255        Texts {
256            events: self.events(),
257        }
258    }
259
260    /// Produce an iterator that yields only the `Scroll` events yielded by the `Events` iterator.
261    pub fn scrolls(&self) -> Scrolls<'a> {
262        Scrolls {
263            events: self.events(),
264        }
265    }
266}
267
268impl<'a> Mouse<'a> {
269    /// The absolute position of the mouse within the window.
270    pub fn abs_xy(&self) -> Point {
271        self.mouse_abs_xy
272    }
273
274    /// The position of the mouse relative to the middle of the widget's `Rect`.
275    pub fn rel_xy(&self) -> Point {
276        utils::vec2_sub(self.mouse_abs_xy, self.rect.xy())
277    }
278
279    /// Is the mouse currently over the widget.
280    pub fn is_over(&self) -> bool {
281        self.rect.is_over(self.mouse_abs_xy)
282    }
283}
284
285impl<'a> Presses<'a> {
286    /// Produces an `Iterator` that yields only the press events that correspond with mouse buttons.
287    pub fn mouse(self) -> MousePresses<'a> {
288        MousePresses { presses: self }
289    }
290
291    /// Produces an `Iterator` that yields only the press events that correspond with keyboard
292    /// buttons.
293    pub fn key(self) -> KeyPresses<'a> {
294        KeyPresses { presses: self }
295    }
296}
297
298impl<'a> MousePresses<'a> {
299    /// Produces an `Iterator` that yields only events associated with the given mouse button.
300    pub fn button(self, button: input::MouseButton) -> MouseButtonPresses<'a> {
301        MouseButtonPresses {
302            mouse_presses: self,
303            button: button,
304        }
305    }
306
307    /// Produces an `Iterator` that yields only the left mouse button press events.
308    pub fn left(self) -> MouseButtonPresses<'a> {
309        self.button(input::MouseButton::Left)
310    }
311
312    /// Produces an `Iterator` that yields only the middle mouse button press events.
313    pub fn middle(self) -> MouseButtonPresses<'a> {
314        self.button(input::MouseButton::Middle)
315    }
316
317    /// Produces an `Iterator` that yields only the right mouse button press events.
318    pub fn right(self) -> MouseButtonPresses<'a> {
319        self.button(input::MouseButton::Right)
320    }
321}
322
323impl<'a> Releases<'a> {
324    /// Produces an `Iterator` that yields only the release events that correspond with mouse
325    /// buttons.
326    pub fn mouse(self) -> MouseReleases<'a> {
327        MouseReleases { releases: self }
328    }
329
330    /// Produces an `Iterator` that yields only the release events that correspond with keyboard
331    /// buttons.
332    pub fn key(self) -> KeyReleases<'a> {
333        KeyReleases { releases: self }
334    }
335}
336
337impl<'a> MouseReleases<'a> {
338    /// Produces an `Iterator` that yields only events associated with the given mouse button.
339    pub fn button(self, button: input::MouseButton) -> MouseButtonReleases<'a> {
340        MouseButtonReleases {
341            mouse_releases: self,
342            button: button,
343        }
344    }
345
346    /// Produces an `Iterator` that yields only the left mouse button release events.
347    pub fn left(self) -> MouseButtonReleases<'a> {
348        self.button(input::MouseButton::Left)
349    }
350
351    /// Produces an `Iterator` that yields only the middle mouse button release events.
352    pub fn middle(self) -> MouseButtonReleases<'a> {
353        self.button(input::MouseButton::Middle)
354    }
355
356    /// Produces an `Iterator` that yields only the right mouse button release events.
357    pub fn right(self) -> MouseButtonReleases<'a> {
358        self.button(input::MouseButton::Right)
359    }
360}
361
362impl<'a> Clicks<'a> {
363    /// Yield only the `Click`s that occurred from the given button.
364    pub fn button(self, button: input::MouseButton) -> ButtonClicks<'a> {
365        ButtonClicks {
366            clicks: self,
367            button: button,
368        }
369    }
370
371    /// Yield only left mouse button `Click`s.
372    pub fn left(self) -> ButtonClicks<'a> {
373        self.button(input::MouseButton::Left)
374    }
375
376    /// Yields only middle mouse button `Click`s.
377    pub fn middle(self) -> ButtonClicks<'a> {
378        self.button(input::MouseButton::Middle)
379    }
380
381    /// Yield only right mouse button `Click`s.
382    pub fn right(self) -> ButtonClicks<'a> {
383        self.button(input::MouseButton::Right)
384    }
385}
386
387impl<'a> Drags<'a> {
388    /// Yield only the `Drag`s that occurred from the given button.
389    pub fn button(self, button: input::MouseButton) -> ButtonDrags<'a> {
390        ButtonDrags {
391            drags: self,
392            button: button,
393        }
394    }
395
396    /// Yield only left mouse button `Drag`s.
397    pub fn left(self) -> ButtonDrags<'a> {
398        self.button(input::MouseButton::Left)
399    }
400
401    /// Yields only middle mouse button `Drag`s.
402    pub fn middle(self) -> ButtonDrags<'a> {
403        self.button(input::MouseButton::Middle)
404    }
405
406    /// Yield only right mouse button `Drag`s.
407    pub fn right(self) -> ButtonDrags<'a> {
408        self.button(input::MouseButton::Right)
409    }
410}
411
412impl<'a> Iterator for Events<'a> {
413    type Item = event::Widget;
414
415    fn next(&mut self) -> Option<event::Widget> {
416        // Loop through all events in the `ui_events` until we find one associated with our widget
417        // that we can return.
418        while let Some(ui_event) = self.ui_events.next() {
419            match *ui_event {
420                // Input source capturing.
421                event::Ui::WidgetCapturesInputSource(idx, source) => {
422                    self.capturing_mouse = Some(idx);
423                    if idx == self.idx {
424                        return Some(event::Widget::CapturesInputSource(source));
425                    }
426                }
427                event::Ui::WidgetUncapturesInputSource(idx, source) => {
428                    if Some(idx) == self.capturing_mouse {
429                        self.capturing_mouse = None;
430                    }
431                    if idx == self.idx {
432                        return Some(event::Widget::UncapturesInputSource(source));
433                    }
434                }
435
436                event::Ui::WindowResized(dim) => return Some(event::Widget::WindowResized(dim)),
437
438                event::Ui::Text(idx, ref text) if idx == Some(self.idx) => {
439                    return Some(text.clone().into())
440                }
441
442                event::Ui::Motion(idx, ref motion) if idx == Some(self.idx) => {
443                    return Some(motion.clone().into())
444                }
445
446                event::Ui::Touch(idx, ref touch) if idx == Some(self.idx) => {
447                    return Some(touch.clone().relative_to(self.rect.xy()).into())
448                }
449
450                event::Ui::Press(idx, ref press) if idx == Some(self.idx) => {
451                    return Some(press.clone().relative_to(self.rect.xy()).into())
452                }
453
454                event::Ui::Release(idx, ref release) if idx == Some(self.idx) => {
455                    return Some(release.clone().relative_to(self.rect.xy()).into())
456                }
457
458                event::Ui::Click(idx, ref click) if idx == Some(self.idx) => {
459                    return Some(click.clone().relative_to(self.rect.xy()).into())
460                }
461
462                event::Ui::DoubleClick(idx, ref double_click) if idx == Some(self.idx) => {
463                    return Some(double_click.clone().relative_to(self.rect.xy()).into())
464                }
465
466                event::Ui::Tap(idx, ref tap) if idx == Some(self.idx) => {
467                    return Some(tap.clone().relative_to(self.rect.xy()).into())
468                }
469
470                event::Ui::Drag(idx, ref drag) if idx == Some(self.idx) => {
471                    return Some(drag.clone().relative_to(self.rect.xy()).into())
472                }
473
474                event::Ui::Scroll(idx, ref scroll) if idx == Some(self.idx) => {
475                    return Some(scroll.clone().into())
476                }
477
478                _ => (),
479            }
480        }
481
482        None
483    }
484}
485
486impl<'a> Iterator for Presses<'a> {
487    type Item = event::Press;
488    fn next(&mut self) -> Option<Self::Item> {
489        while let Some(event) = self.events.next() {
490            if let event::Widget::Press(press) = event {
491                return Some(press);
492            }
493        }
494        None
495    }
496}
497
498impl<'a> Iterator for MousePresses<'a> {
499    type Item = event::MousePress;
500    fn next(&mut self) -> Option<Self::Item> {
501        while let Some(press) = self.presses.next() {
502            if let Some(mouse_press) = press.mouse() {
503                return Some(mouse_press);
504            }
505        }
506        None
507    }
508}
509
510impl<'a> Iterator for MouseButtonPresses<'a> {
511    type Item = (Point, input::keyboard::ModifierKey);
512    fn next(&mut self) -> Option<Self::Item> {
513        while let Some(mouse_press) = self.mouse_presses.next() {
514            if self.button == mouse_press.button {
515                return Some((mouse_press.xy, mouse_press.modifiers));
516            }
517        }
518        None
519    }
520}
521
522impl<'a> Iterator for KeyPresses<'a> {
523    type Item = event::KeyPress;
524    fn next(&mut self) -> Option<Self::Item> {
525        while let Some(press) = self.presses.next() {
526            if let Some(key_press) = press.key() {
527                return Some(key_press);
528            }
529        }
530        None
531    }
532}
533
534impl<'a> Iterator for Releases<'a> {
535    type Item = event::Release;
536    fn next(&mut self) -> Option<Self::Item> {
537        while let Some(event) = self.events.next() {
538            if let event::Widget::Release(release) = event {
539                return Some(release);
540            }
541        }
542        None
543    }
544}
545
546impl<'a> Iterator for MouseReleases<'a> {
547    type Item = event::MouseRelease;
548    fn next(&mut self) -> Option<Self::Item> {
549        while let Some(release) = self.releases.next() {
550            if let Some(mouse_release) = release.mouse() {
551                return Some(mouse_release);
552            }
553        }
554        None
555    }
556}
557
558impl<'a> Iterator for MouseButtonReleases<'a> {
559    type Item = (Point, input::keyboard::ModifierKey);
560    fn next(&mut self) -> Option<Self::Item> {
561        while let Some(mouse_release) = self.mouse_releases.next() {
562            if self.button == mouse_release.button {
563                return Some((mouse_release.xy, mouse_release.modifiers));
564            }
565        }
566        None
567    }
568}
569
570impl<'a> Iterator for KeyReleases<'a> {
571    type Item = event::KeyRelease;
572    fn next(&mut self) -> Option<Self::Item> {
573        while let Some(release) = self.releases.next() {
574            if let Some(key_release) = release.key() {
575                return Some(key_release);
576            }
577        }
578        None
579    }
580}
581
582impl<'a> Iterator for Clicks<'a> {
583    type Item = event::Click;
584    fn next(&mut self) -> Option<Self::Item> {
585        while let Some(event) = self.events.next() {
586            if let event::Widget::Click(click) = event {
587                return Some(click);
588            }
589        }
590        None
591    }
592}
593
594impl<'a> Iterator for ButtonClicks<'a> {
595    type Item = event::Click;
596    fn next(&mut self) -> Option<Self::Item> {
597        while let Some(click) = self.clicks.next() {
598            if self.button == click.button {
599                return Some(click);
600            }
601        }
602        None
603    }
604}
605
606impl<'a> Iterator for Taps<'a> {
607    type Item = event::Tap;
608    fn next(&mut self) -> Option<Self::Item> {
609        while let Some(event) = self.events.next() {
610            if let event::Widget::Tap(tap) = event {
611                return Some(tap);
612            }
613        }
614        None
615    }
616}
617
618impl<'a> Iterator for Drags<'a> {
619    type Item = event::Drag;
620    fn next(&mut self) -> Option<Self::Item> {
621        while let Some(event) = self.events.next() {
622            if let event::Widget::Drag(drag) = event {
623                return Some(drag);
624            }
625        }
626        None
627    }
628}
629
630impl<'a> Iterator for ButtonDrags<'a> {
631    type Item = event::Drag;
632    fn next(&mut self) -> Option<Self::Item> {
633        while let Some(drag) = self.drags.next() {
634            if self.button == drag.button {
635                return Some(drag);
636            }
637        }
638        None
639    }
640}
641
642impl<'a> Iterator for Texts<'a> {
643    type Item = event::Text;
644    fn next(&mut self) -> Option<Self::Item> {
645        while let Some(event) = self.events.next() {
646            if let event::Widget::Text(text) = event {
647                return Some(text);
648            }
649        }
650        None
651    }
652}
653
654impl<'a> Iterator for Scrolls<'a> {
655    type Item = event::Scroll;
656    fn next(&mut self) -> Option<Self::Item> {
657        while let Some(event) = self.events.next() {
658            if let event::Widget::Scroll(scroll) = event {
659                return Some(scroll);
660            }
661        }
662        None
663    }
664}