Skip to content

Commit c262e72

Browse files
committed
Merge pull request #698 from mitchmindtree/events_tweaks
Tweaks to events API following #684
2 parents 412cac6 + 7fe93fc commit c262e72

7 files changed

Lines changed: 68 additions & 46 deletions

File tree

src/events/global_input.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ pub struct GlobalInput {
2525
/// of the window.
2626
pub type GlobalInputEventIterator<'a> = ::std::slice::Iter<'a, UiEvent>;
2727

28-
impl <'a> InputProvider<'a, GlobalInputEventIterator<'a>> for GlobalInput {
29-
fn all_events(&'a self) -> GlobalInputEventIterator {
28+
impl<'a> InputProvider<'a> for GlobalInput {
29+
type Events = GlobalInputEventIterator<'a>;
30+
31+
fn all_events(&'a self) -> Self::Events {
3032
self.events.iter()
3133
}
3234

src/events/input_provider.rs

Lines changed: 51 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,20 @@ use input::{Input, Button};
55
use input::keyboard::Key;
66
use input::mouse::MouseButton;
77
use position::Point;
8+
use std::marker::PhantomData;
89

910

1011
/// Trait for something that provides events to be consumed by a widget.
12+
///
1113
/// Provides a bunch of convenience methods for filtering out specific types of events.
12-
pub trait InputProvider<'a, T: Iterator<Item=&'a UiEvent>> {
14+
pub trait InputProvider<'a> {
15+
/// An iterator yielding references to the `InputProvider`'s `UiEvent`s.
16+
type Events: Iterator<Item=&'a UiEvent>;
17+
1318
/// This is the only method that needs to be implemented.
1419
/// Just provided a reference to a `Vec<UiEvent>` that contains
1520
/// all the events for this update cycle.
16-
fn all_events(&'a self) -> T;
21+
fn all_events(&'a self) -> Self::Events;
1722

1823
/// Returns the current input state. The returned state is assumed to be up to
1924
/// date with all of the events so far.
@@ -27,54 +32,43 @@ pub trait InputProvider<'a, T: Iterator<Item=&'a UiEvent>> {
2732
// Methods that just check the stream of events //
2833
//////////////////////////////////////////////////
2934

30-
/// Returns a `String` containing _all_ the text that was entered since
31-
/// the last update cycle.
32-
fn text_just_entered(&'a self) -> Option<String> {
33-
let all_text: String = self.all_events().filter_map(|evt| {
34-
match *evt {
35-
UiEvent::Raw(Input::Text(ref text)) => Some(text),
36-
_ => None
37-
}
38-
}).fold(String::new(), |acc, item| {
39-
acc + item
40-
});
41-
42-
if all_text.is_empty() {
43-
None
44-
} else {
45-
Some(all_text)
35+
/// Returns a reference to each slice of `Text` that was entered since the last update.
36+
fn text_just_entered(&'a self) -> TextJustEntered<'a, Self::Events> {
37+
TextJustEntered {
38+
events: self.all_events(),
39+
lifetime: PhantomData,
4640
}
4741
}
4842

4943
/// Returns all of the `Key`s that were released since the last update.
50-
fn keys_just_released(&'a self) -> KeysJustReleased<'a, T> {
44+
fn keys_just_released(&'a self) -> KeysJustReleased<'a, Self::Events> {
5145
KeysJustReleased{
5246
event_iter: self.all_events(),
53-
lifetime: ::std::marker::PhantomData
47+
lifetime: PhantomData
5448
}
5549
}
5650

5751
/// Returns all of the keyboard `Key`s that were pressed since the last update.
58-
fn keys_just_pressed(&'a self) -> KeysJustPressed<'a, T> {
52+
fn keys_just_pressed(&'a self) -> KeysJustPressed<'a, Self::Events> {
5953
KeysJustPressed {
6054
event_iter: self.all_events(),
61-
lifetime: ::std::marker::PhantomData
55+
lifetime: PhantomData
6256
}
6357
}
6458

6559
/// Returns all of the `MouseButton`s that were pressed since the last update.
66-
fn mouse_buttons_just_pressed(&'a self) -> MouseButtonsJustPressed<'a, T> {
60+
fn mouse_buttons_just_pressed(&'a self) -> MouseButtonsJustPressed<'a, Self::Events> {
6761
MouseButtonsJustPressed {
6862
event_iter: self.all_events(),
69-
lifetime: ::std::marker::PhantomData
63+
lifetime: PhantomData
7064
}
7165
}
7266

7367
/// Returns all of the `MouseButton`s that were released since the last update.
74-
fn mouse_buttons_just_released(&'a self) -> MouseButtonsJustReleased<'a, T> {
68+
fn mouse_buttons_just_released(&'a self) -> MouseButtonsJustReleased<'a, Self::Events> {
7569
MouseButtonsJustReleased {
7670
event_iter: self.all_events(),
77-
lifetime: ::std::marker::PhantomData
71+
lifetime: PhantomData
7872
}
7973
}
8074

@@ -173,11 +167,34 @@ pub trait InputProvider<'a, T: Iterator<Item=&'a UiEvent>> {
173167

174168
}
175169

170+
/// An iterator yielding the `&str` of each `Text` event's `String` that was just entered.
171+
#[derive(Clone, Debug)]
172+
pub struct TextJustEntered<'a, I>
173+
where I: Iterator<Item=&'a UiEvent>,
174+
{
175+
events: I,
176+
lifetime: PhantomData<&'a ()>,
177+
}
178+
179+
impl<'a, I> Iterator for TextJustEntered<'a, I>
180+
where I: Iterator<Item=&'a UiEvent>,
181+
{
182+
type Item=&'a str;
183+
fn next(&mut self) -> Option<Self::Item> {
184+
while let Some(event) = self.events.next() {
185+
if let UiEvent::Raw(Input::Text(ref text)) = *event {
186+
return Some(text);
187+
}
188+
}
189+
None
190+
}
191+
}
192+
176193
/// An Iterator over `input::keyboard::Key`s that were just released.
177-
#[derive(Debug)]
194+
#[derive(Clone, Debug)]
178195
pub struct KeysJustReleased<'a, T: Iterator<Item=&'a UiEvent> + Sized> {
179196
event_iter: T,
180-
lifetime: ::std::marker::PhantomData<&'a ()>
197+
lifetime: PhantomData<&'a ()>
181198
}
182199

183200
impl<'a, T> Iterator for KeysJustReleased<'a, T> where T: Iterator<Item=&'a UiEvent> + Sized {
@@ -194,10 +211,10 @@ impl<'a, T> Iterator for KeysJustReleased<'a, T> where T: Iterator<Item=&'a UiEv
194211
}
195212

196213
/// An Iterator over `input::keyboard::Key`s that were just pressed.
197-
#[derive(Debug)]
214+
#[derive(Clone, Debug)]
198215
pub struct KeysJustPressed<'a, T: Iterator<Item=&'a UiEvent> + Sized> {
199216
event_iter: T,
200-
lifetime: ::std::marker::PhantomData<&'a ()>
217+
lifetime: PhantomData<&'a ()>
201218
}
202219

203220
impl<'a, T> Iterator for KeysJustPressed<'a, T> where T: Iterator<Item=&'a UiEvent> + Sized {
@@ -214,10 +231,10 @@ impl<'a, T> Iterator for KeysJustPressed<'a, T> where T: Iterator<Item=&'a UiEve
214231
}
215232

216233
/// An Iterator over `input::mouse::MouseButton`s that were just pressed.
217-
#[derive(Debug)]
234+
#[derive(Clone, Debug)]
218235
pub struct MouseButtonsJustPressed<'a, T: Iterator<Item=&'a UiEvent> + Sized> {
219236
event_iter: T,
220-
lifetime: ::std::marker::PhantomData<&'a ()>
237+
lifetime: PhantomData<&'a ()>
221238
}
222239

223240
impl<'a, T> Iterator for MouseButtonsJustPressed<'a, T> where T: Iterator<Item=&'a UiEvent> + Sized {
@@ -234,10 +251,10 @@ impl<'a, T> Iterator for MouseButtonsJustPressed<'a, T> where T: Iterator<Item=&
234251
}
235252

236253
/// An Iterator over `input::mouse::MouseButton`s that were just released.
237-
#[derive(Debug)]
254+
#[derive(Clone, Debug)]
238255
pub struct MouseButtonsJustReleased<'a, T: Iterator<Item=&'a UiEvent> + Sized> {
239256
event_iter: T,
240-
lifetime: ::std::marker::PhantomData<&'a ()>
257+
lifetime: PhantomData<&'a ()>
241258
}
242259

243260
impl<'a, T> Iterator for MouseButtonsJustReleased<'a, T> where T: Iterator<Item=&'a UiEvent> + Sized {

src/events/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! This module contains all the logic for handling input events and providing them to widgets.
22
//! All user input is provided to the `Ui` in the form of `input::Input` events, which are continuously
3-
//! polled from the backend window implementation. These raw input events tent to be fairly low level.
3+
//! polled from the backend window implementation. These raw input events tend to be fairly low level.
44
//! The `Ui` passes each of these events off to it's `GlobalInput`, which keeps track of the state of
55
//! affairs for the entire `Ui`. `GlobalInput` will also aggregate the low level events into higher
66
//! level ones. For instance, two events indicating that a mouse button was pressed then released

src/events/widget_input.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,13 @@ impl<'a> Iterator for WidgetInputEventIterator<'a> {
8787
}
8888
})
8989
}
90-
9190
}
9291

9392

94-
impl<'a> InputProvider<'a, WidgetInputEventIterator<'a>> for WidgetInput<'a> {
93+
impl<'a> InputProvider<'a> for WidgetInput<'a> {
94+
type Events = WidgetInputEventIterator<'a>;
9595

96-
fn all_events(&'a self) -> WidgetInputEventIterator<'a> {
96+
fn all_events(&'a self) -> Self::Events {
9797
WidgetInputEventIterator{
9898
global_event_iter: self.global_input.all_events(),
9999
current_state: self.global_input.start_state.relative_to(self.widget_area.xy()),

src/tests/global_input.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ fn entered_text_should_be_aggregated_from_multiple_events() {
109109
input.push_event(UiEvent::Raw(Input::Text("is a".to_string())));
110110
input.push_event(UiEvent::Raw(Input::Text("wesome".to_string())));
111111

112-
let actual_text = input.text_just_entered().expect("expected to get a String, got None");
112+
let actual_text: String = input.text_just_entered().collect();
113113
assert_eq!("Phil is awesome".to_string(), actual_text);
114114
}
115115

src/tests/input_provider.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,10 @@ impl ProviderImpl {
185185
pub type TestInputEventIterator<'a> = ::std::slice::Iter<'a, UiEvent>;
186186

187187

188-
impl<'a> InputProvider<'a, TestInputEventIterator<'a>> for ProviderImpl {
189-
fn all_events(&'a self) -> TestInputEventIterator<'a> {
188+
impl<'a> InputProvider<'a> for ProviderImpl {
189+
type Events = TestInputEventIterator<'a>;
190+
191+
fn all_events(&'a self) -> Self::Events {
190192
self.events.iter()
191193
}
192194

src/tests/widget_input.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,13 +156,14 @@ fn widget_input_should_only_provide_keyboard_input_to_widget_that_has_focus() {
156156
global_input.push_event(UiEvent::Raw(Input::Text("some text".to_string())));
157157

158158
let widget_4_input = WidgetInput::for_widget(widget_4, some_rect, &global_input);
159-
let widget_4_text = widget_4_input.text_just_entered();
160-
assert_eq!(Some("some text".to_string()), widget_4_text);
159+
let widget_4_text: String = widget_4_input.text_just_entered().collect();
160+
assert_eq!("some text".to_string(), widget_4_text);
161161

162162
let another_widget_input = WidgetInput::for_widget(Index::Public(Id(7)),
163163
some_rect,
164164
&global_input);
165-
assert!(another_widget_input.text_just_entered().is_none());
165+
let another_widget_text: String = another_widget_input.text_just_entered().collect();
166+
assert_eq!("".to_string(), another_widget_text);
166167
}
167168

168169
#[test]

0 commit comments

Comments
 (0)