Skip to content

Commit eb0bbfb

Browse files
committed
Added initial touch events to support iOS
1 parent 9da6ce4 commit eb0bbfb

14 files changed

Lines changed: 169 additions & 47 deletions

File tree

native/src/event.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{
2-
input::{keyboard, mouse},
2+
input::{keyboard, mouse, touch},
33
window,
44
};
55

@@ -19,4 +19,7 @@ pub enum Event {
1919

2020
/// A window event
2121
Window(window::Event),
22+
23+
/// A touch event
24+
Touch(touch::Touch),
2225
}

native/src/input.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Map your system events into input events that the runtime can understand.
22
pub mod keyboard;
33
pub mod mouse;
4+
pub mod touch;
45

56
mod button_state;
67

native/src/input/touch.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//! Build touch events.
2+
/// The touch of a mobile device.
3+
#[derive(Debug, Clone, Copy, PartialEq)]
4+
pub enum Touch {
5+
/// The touch cursor was started
6+
Started {
7+
/// The X coordinate of the touch position
8+
x: f32,
9+
10+
/// The Y coordinate of the touch position
11+
y: f32,
12+
},
13+
/// The touch cursor was ended
14+
Ended {
15+
/// The X coordinate of the touch position
16+
x: f32,
17+
18+
/// The Y coordinate of the touch position
19+
y: f32,
20+
},
21+
22+
/// The touch was moved.
23+
Moved {
24+
/// The X coordinate of the touch position
25+
x: f32,
26+
27+
/// The Y coordinate of the touch position
28+
y: f32,
29+
},
30+
31+
/// Some canceled button.
32+
Cancelled {
33+
/// The X coordinate of the touch position
34+
x: f32,
35+
36+
/// The Y coordinate of the touch position
37+
y: f32,
38+
},
39+
}

native/src/user_interface.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::{
2-
input::mouse, layout, Clipboard, Element, Event, Layout, Point, Size,
2+
input::{mouse, touch},
3+
layout, Clipboard, Element, Event, Layout, Point, Size,
34
};
45

56
use std::hash::Hasher;
@@ -181,8 +182,15 @@ where
181182
let mut messages = Vec::new();
182183

183184
for event in events {
184-
if let Event::Mouse(mouse::Event::CursorMoved { x, y }) = event {
185-
self.cursor_position = Point::new(x, y);
185+
match event {
186+
Event::Mouse(mouse::Event::CursorMoved { x, y })
187+
| Event::Touch(touch::Touch::Started { x, y })
188+
| Event::Touch(touch::Touch::Ended { x, y })
189+
| Event::Touch(touch::Touch::Moved { x, y })
190+
| Event::Touch(touch::Touch::Cancelled { x, y }) => {
191+
self.cursor_position = Point::new(x, y);
192+
}
193+
_ => {}
186194
}
187195

188196
self.root.widget.on_event(

native/src/widget/button.rs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
//! [`Button`]: struct.Button.html
66
//! [`State`]: struct.State.html
77
use crate::{
8-
input::{mouse, ButtonState},
8+
input::{mouse, touch::Touch, ButtonState},
99
layout, Clipboard, Element, Event, Hasher, Layout, Length, Point,
1010
Rectangle, Widget,
1111
};
@@ -187,26 +187,27 @@ where
187187
match event {
188188
Event::Mouse(mouse::Event::Input {
189189
button: mouse::Button::Left,
190-
state,
191-
}) => {
190+
state: ButtonState::Pressed,
191+
})
192+
| Event::Touch(Touch::Started { .. }) => {
193+
let bounds = layout.bounds();
194+
195+
self.state.is_pressed = bounds.contains(cursor_position);
196+
}
197+
Event::Mouse(mouse::Event::Input {
198+
button: mouse::Button::Left,
199+
state: ButtonState::Released,
200+
})
201+
| Event::Touch(Touch::Ended { .. }) => {
192202
if let Some(on_press) = self.on_press.clone() {
193203
let bounds = layout.bounds();
204+
let is_clicked = self.state.is_pressed
205+
&& bounds.contains(cursor_position);
194206

195-
match state {
196-
ButtonState::Pressed => {
197-
self.state.is_pressed =
198-
bounds.contains(cursor_position);
199-
}
200-
ButtonState::Released => {
201-
let is_clicked = self.state.is_pressed
202-
&& bounds.contains(cursor_position);
203-
204-
self.state.is_pressed = false;
207+
self.state.is_pressed = false;
205208

206-
if is_clicked {
207-
messages.push(on_press);
208-
}
209-
}
209+
if is_clicked {
210+
messages.push(on_press);
210211
}
211212
}
212213
}

native/src/widget/checkbox.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
use std::hash::Hash;
33

44
use crate::{
5-
input::{mouse, ButtonState},
5+
input::{mouse, touch::Touch, ButtonState},
66
layout, row, text, Align, Clipboard, Element, Event, Font, Hasher,
77
HorizontalAlignment, Layout, Length, Point, Rectangle, Row, Text,
88
VerticalAlignment, Widget,
@@ -155,7 +155,8 @@ where
155155
Event::Mouse(mouse::Event::Input {
156156
button: mouse::Button::Left,
157157
state: ButtonState::Pressed,
158-
}) => {
158+
})
159+
| Event::Touch(Touch::Started { .. }) => {
159160
let mouse_over = layout.bounds().contains(cursor_position);
160161

161162
if mouse_over {

native/src/widget/radio.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Create choices using radio buttons.
22
use crate::{
3-
input::{mouse, ButtonState},
3+
input::{mouse, touch, ButtonState},
44
layout, row, text, Align, Clipboard, Element, Event, Font, Hasher,
55
HorizontalAlignment, Layout, Length, Point, Rectangle, Row, Text,
66
VerticalAlignment, Widget,
@@ -121,7 +121,8 @@ where
121121
Event::Mouse(mouse::Event::Input {
122122
button: mouse::Button::Left,
123123
state: ButtonState::Pressed,
124-
}) => {
124+
})
125+
| Event::Touch(touch::Touch::Started { .. }) => {
125126
if layout.bounds().contains(cursor_position) {
126127
messages.push(self.on_click.clone());
127128
}

native/src/widget/scrollable.rs

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Navigate an endless amount of content with a scrollbar.
22
use crate::{
33
column,
4-
input::{mouse, ButtonState},
4+
input::{mouse, touch, ButtonState},
55
layout, Align, Clipboard, Column, Element, Event, Hasher, Layout, Length,
66
Point, Rectangle, Size, Widget,
77
};
@@ -175,6 +175,22 @@ where
175175
}
176176
}
177177
}
178+
Event::Touch(touch::Touch::Started { .. }) => {
179+
self.state.scroll_box_touched_at = Some(cursor_position);
180+
}
181+
Event::Touch(touch::Touch::Moved { .. }) => {
182+
if let Some(scroll_box_touched_at) =
183+
self.state.scroll_box_touched_at
184+
{
185+
let delta = cursor_position.y - scroll_box_touched_at.y;
186+
self.state.scroll(delta, bounds, content_bounds);
187+
self.state.scroll_box_touched_at =
188+
Some(cursor_position);
189+
}
190+
}
191+
Event::Touch(touch::Touch::Ended { .. }) => {
192+
self.state.scroll_box_touched_at = None;
193+
}
178194
_ => {}
179195
}
180196
}
@@ -191,10 +207,23 @@ where
191207
Event::Mouse(mouse::Event::Input {
192208
button: mouse::Button::Left,
193209
state: ButtonState::Released,
194-
}) => {
210+
})
211+
| Event::Touch(touch::Touch::Ended { .. }) => {
195212
self.state.scroller_grabbed_at = None;
196213
}
197-
Event::Mouse(mouse::Event::CursorMoved { .. }) => {
214+
Event::Mouse(mouse::Event::Input {
215+
button: mouse::Button::Left,
216+
state: ButtonState::Pressed,
217+
})
218+
| Event::Touch(touch::Touch::Started { .. }) => {
219+
self.state.scroll_to(
220+
cursor_position.y / (bounds.y + bounds.height),
221+
bounds,
222+
content_bounds,
223+
);
224+
}
225+
Event::Mouse(mouse::Event::CursorMoved { .. })
226+
| Event::Touch(touch::Touch::Moved { .. }) => {
198227
if let (Some(scrollbar), Some(scroller_grabbed_at)) =
199228
(scrollbar, self.state.scroller_grabbed_at)
200229
{
@@ -215,7 +244,8 @@ where
215244
Event::Mouse(mouse::Event::Input {
216245
button: mouse::Button::Left,
217246
state: ButtonState::Pressed,
218-
}) => {
247+
})
248+
| Event::Touch(touch::Touch::Started { .. }) => {
219249
if let Some(scrollbar) = scrollbar {
220250
if let Some(scroller_grabbed_at) =
221251
scrollbar.grab_scroller(cursor_position)
@@ -326,6 +356,7 @@ where
326356
#[derive(Debug, Clone, Copy, Default)]
327357
pub struct State {
328358
scroller_grabbed_at: Option<f32>,
359+
scroll_box_touched_at: Option<Point>,
329360
offset: f32,
330361
}
331362

@@ -391,6 +422,11 @@ impl State {
391422
pub fn is_scroller_grabbed(&self) -> bool {
392423
self.scroller_grabbed_at.is_some()
393424
}
425+
426+
/// Returns whether the scroll box is currently touched or not.
427+
pub fn is_scroll_box_touched(&self) -> bool {
428+
self.scroll_box_touched_at.is_some()
429+
}
394430
}
395431

396432
/// The scrollbar of a [`Scrollable`].

native/src/widget/slider.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
//! [`Slider`]: struct.Slider.html
66
//! [`State`]: struct.State.html
77
use crate::{
8-
input::{mouse, ButtonState},
8+
input::{mouse, touch::Touch, ButtonState},
99
layout, Clipboard, Element, Event, Hasher, Layout, Length, Point,
1010
Rectangle, Size, Widget,
1111
};
@@ -166,19 +166,23 @@ where
166166
match event {
167167
Event::Mouse(mouse::Event::Input {
168168
button: mouse::Button::Left,
169-
state,
170-
}) => match state {
171-
ButtonState::Pressed => {
172-
if layout.bounds().contains(cursor_position) {
173-
change();
174-
self.state.is_dragging = true;
175-
}
176-
}
177-
ButtonState::Released => {
178-
self.state.is_dragging = false;
169+
state: ButtonState::Pressed,
170+
})
171+
| Event::Touch(Touch::Started { .. }) => {
172+
if layout.bounds().contains(cursor_position) {
173+
change();
174+
self.state.is_dragging = true;
179175
}
180-
},
181-
Event::Mouse(mouse::Event::CursorMoved { .. }) => {
176+
}
177+
Event::Mouse(mouse::Event::Input {
178+
button: mouse::Button::Left,
179+
state: ButtonState::Released,
180+
})
181+
| Event::Touch(Touch::Ended { .. }) => {
182+
self.state.is_dragging = false;
183+
}
184+
Event::Mouse(mouse::Event::CursorMoved { .. })
185+
| Event::Touch(Touch::Moved { .. }) => {
182186
if self.state.is_dragging {
183187
change();
184188
}

native/src/widget/text_input.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
//! [`TextInput`]: struct.TextInput.html
66
//! [`State`]: struct.State.html
77
use crate::{
8-
input::{keyboard, mouse, ButtonState},
8+
input::{keyboard, mouse, touch, ButtonState},
99
layout, Clipboard, Element, Event, Font, Hasher, Layout, Length, Point,
1010
Rectangle, Size, Widget,
1111
};
@@ -202,7 +202,8 @@ where
202202
Event::Mouse(mouse::Event::Input {
203203
button: mouse::Button::Left,
204204
state: ButtonState::Pressed,
205-
}) => {
205+
})
206+
| Event::Touch(touch::Touch::Started { .. }) => {
206207
let is_clicked = layout.bounds().contains(cursor_position);
207208

208209
if is_clicked {

0 commit comments

Comments
 (0)