Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Touch support #57

Merged
merged 8 commits into from
Dec 17, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions native/src/event.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{
input::{keyboard, mouse},
input::{keyboard, mouse, Touch},
window,
};

Expand All @@ -9,7 +9,7 @@ use crate::{
/// additional events, feel free to [open an issue] and share your use case!_
///
/// [open an issue]: https://github.com/hecrj/iced/issues
#[derive(PartialEq, Clone, Debug)]
#[derive(Debug, Clone, PartialEq)]
pub enum Event {
/// A keyboard event
Keyboard(keyboard::Event),
Expand All @@ -19,4 +19,7 @@ pub enum Event {

/// A window event
Window(window::Event),

/// A touch event
Touch(Touch),
}
2 changes: 2 additions & 0 deletions native/src/input.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
//! Map your system events into input events that the runtime can understand.
pub mod keyboard;
pub mod mouse;
pub mod touch;

mod button_state;

pub use button_state::ButtonState;
pub use touch::Touch;
9 changes: 3 additions & 6 deletions native/src/input/mouse/event.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::Button;
use crate::input::ButtonState;
use crate::{input::ButtonState, Point};

/// A mouse event.
///
Expand All @@ -17,11 +17,8 @@ pub enum Event {

/// The mouse cursor was moved
CursorMoved {
/// The X coordinate of the mouse position
x: f32,

/// The Y coordinate of the mouse position
y: f32,
/// The new position of the mouse cursor
position: Point,
},

/// A mouse button was pressed or released.
Expand Down
36 changes: 36 additions & 0 deletions native/src/input/touch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//! Build touch events.

use crate::Point;

/// A touch interaction.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Touch {
/// The finger of the touch.
pub finger: Finger,

/// The position of the touch.
pub position: Point,

/// The state of the touch.
pub phase: Phase,
}

/// A unique identifier representing a finger on a touch interaction.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Finger(pub u64);

/// The state of a touch interaction.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Phase {
/// A touch interaction was started.
Started,

/// An on-going touch interaction was moved.
Moved,

/// A touch interaction was ended.
Ended,

/// A touch interaction was canceled.
Canceled,
}
11 changes: 8 additions & 3 deletions native/src/user_interface.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{
input::mouse, layout, Clipboard, Element, Event, Layout, Point, Size,
input::{mouse, Touch},
layout, Clipboard, Element, Event, Layout, Point, Size,
};

use std::hash::Hasher;
Expand Down Expand Up @@ -181,8 +182,12 @@ where
let mut messages = Vec::new();

for event in events {
if let Event::Mouse(mouse::Event::CursorMoved { x, y }) = event {
self.cursor_position = Point::new(x, y);
match event {
Event::Mouse(mouse::Event::CursorMoved { position })
| Event::Touch(Touch { position, .. }) => {
self.cursor_position = position;
}
_ => {}
}

self.root.widget.on_event(
Expand Down
47 changes: 31 additions & 16 deletions native/src/widget/button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//! [`Button`]: struct.Button.html
//! [`State`]: struct.State.html
use crate::{
input::{mouse, ButtonState},
input::{mouse, touch, ButtonState, Touch},
layout, Clipboard, Element, Event, Hasher, Layout, Length, Point,
Rectangle, Widget,
};
Expand Down Expand Up @@ -187,29 +187,44 @@ where
match event {
Event::Mouse(mouse::Event::Input {
button: mouse::Button::Left,
state,
state: ButtonState::Pressed,
})
| Event::Touch(Touch {
phase: touch::Phase::Started,
..
}) => {
if let Some(on_press) = self.on_press.clone() {
if self.on_press.is_some() {
let bounds = layout.bounds();

match state {
ButtonState::Pressed => {
self.state.is_pressed =
bounds.contains(cursor_position);
}
ButtonState::Released => {
let is_clicked = self.state.is_pressed
&& bounds.contains(cursor_position);
self.state.is_pressed = bounds.contains(cursor_position);
}
}
Event::Mouse(mouse::Event::Input {
button: mouse::Button::Left,
state: ButtonState::Released,
})
| Event::Touch(Touch {
phase: touch::Phase::Ended,
..
}) => {
if let Some(on_press) = self.on_press.clone() {
let bounds = layout.bounds();
let is_clicked = self.state.is_pressed
&& bounds.contains(cursor_position);

self.state.is_pressed = false;
self.state.is_pressed = false;

if is_clicked {
messages.push(on_press);
}
}
if is_clicked {
messages.push(on_press);
}
}
}
Event::Touch(Touch {
phase: touch::Phase::Canceled,
..
}) => {
self.state.is_pressed = false;
}
_ => {}
}
}
Expand Down
6 changes: 5 additions & 1 deletion native/src/widget/checkbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use std::hash::Hash;

use crate::{
input::{mouse, ButtonState},
input::{mouse, touch, ButtonState, Touch},
layout, row, text, Align, Clipboard, Element, Event, Font, Hasher,
HorizontalAlignment, Layout, Length, Point, Rectangle, Row, Text,
VerticalAlignment, Widget,
Expand Down Expand Up @@ -155,6 +155,10 @@ where
Event::Mouse(mouse::Event::Input {
button: mouse::Button::Left,
state: ButtonState::Pressed,
})
| Event::Touch(Touch {
phase: touch::Phase::Started,
..
}) => {
let mouse_over = layout.bounds().contains(cursor_position);

Expand Down
6 changes: 5 additions & 1 deletion native/src/widget/radio.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Create choices using radio buttons.
use crate::{
input::{mouse, ButtonState},
input::{mouse, touch, ButtonState, Touch},
layout, row, text, Align, Clipboard, Element, Event, Font, Hasher,
HorizontalAlignment, Layout, Length, Point, Rectangle, Row, Text,
VerticalAlignment, Widget,
Expand Down Expand Up @@ -121,6 +121,10 @@ where
Event::Mouse(mouse::Event::Input {
button: mouse::Button::Left,
state: ButtonState::Pressed,
})
| Event::Touch(Touch {
phase: touch::Phase::Started,
..
}) => {
if layout.bounds().contains(cursor_position) {
messages.push(self.on_click.clone());
Expand Down
46 changes: 44 additions & 2 deletions native/src/widget/scrollable.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Navigate an endless amount of content with a scrollbar.
use crate::{
column,
input::{mouse, ButtonState},
input::{mouse, touch, ButtonState, Touch},
layout, Align, Clipboard, Column, Element, Event, Hasher, Layout, Length,
Point, Rectangle, Size, Widget,
};
Expand Down Expand Up @@ -175,6 +175,26 @@ where
}
}
}
Event::Touch(Touch { phase, .. }) => match phase {
touch::Phase::Started => {
self.state.scroll_box_touched_at =
Some(cursor_position);
}
touch::Phase::Moved => {
if let Some(scroll_box_touched_at) =
self.state.scroll_box_touched_at
{
let delta =
cursor_position.y - scroll_box_touched_at.y;
self.state.scroll(delta, bounds, content_bounds);
self.state.scroll_box_touched_at =
Some(cursor_position);
}
}
touch::Phase::Ended | touch::Phase::Canceled => {
self.state.scroll_box_touched_at = None;
}
},
_ => {}
}
}
Expand All @@ -191,10 +211,22 @@ where
Event::Mouse(mouse::Event::Input {
button: mouse::Button::Left,
state: ButtonState::Released,
})
| Event::Touch(Touch {
phase: touch::Phase::Ended,
..
})
| Event::Touch(Touch {
phase: touch::Phase::Canceled,
..
}) => {
self.state.scroller_grabbed_at = None;
}
Event::Mouse(mouse::Event::CursorMoved { .. }) => {
Event::Mouse(mouse::Event::CursorMoved { .. })
| Event::Touch(Touch {
phase: touch::Phase::Moved,
..
}) => {
if let (Some(scrollbar), Some(scroller_grabbed_at)) =
(scrollbar, self.state.scroller_grabbed_at)
{
Expand All @@ -215,6 +247,10 @@ where
Event::Mouse(mouse::Event::Input {
button: mouse::Button::Left,
state: ButtonState::Pressed,
})
| Event::Touch(Touch {
phase: touch::Phase::Started,
..
}) => {
if let Some(scrollbar) = scrollbar {
if let Some(scroller_grabbed_at) =
Expand Down Expand Up @@ -326,6 +362,7 @@ where
#[derive(Debug, Clone, Copy, Default)]
pub struct State {
scroller_grabbed_at: Option<f32>,
scroll_box_touched_at: Option<Point>,
offset: f32,
}

Expand Down Expand Up @@ -391,6 +428,11 @@ impl State {
pub fn is_scroller_grabbed(&self) -> bool {
self.scroller_grabbed_at.is_some()
}

/// Returns whether the scroll box is currently touched or not.
pub fn is_scroll_box_touched(&self) -> bool {
self.scroll_box_touched_at.is_some()
}
}

/// The scrollbar of a [`Scrollable`].
Expand Down
39 changes: 26 additions & 13 deletions native/src/widget/slider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//! [`Slider`]: struct.Slider.html
//! [`State`]: struct.State.html
use crate::{
input::{mouse, ButtonState},
input::{mouse, touch, ButtonState, Touch},
layout, Clipboard, Element, Event, Hasher, Layout, Length, Point,
Rectangle, Size, Widget,
};
Expand Down Expand Up @@ -166,19 +166,32 @@ where
match event {
Event::Mouse(mouse::Event::Input {
button: mouse::Button::Left,
state,
}) => match state {
ButtonState::Pressed => {
if layout.bounds().contains(cursor_position) {
change();
self.state.is_dragging = true;
}
}
ButtonState::Released => {
self.state.is_dragging = false;
state: ButtonState::Pressed,
})
| Event::Touch(Touch {
phase: touch::Phase::Started,
..
}) => {
if layout.bounds().contains(cursor_position) {
change();
self.state.is_dragging = true;
}
},
Event::Mouse(mouse::Event::CursorMoved { .. }) => {
}
Event::Mouse(mouse::Event::Input {
button: mouse::Button::Left,
state: ButtonState::Released,
})
| Event::Touch(Touch {
phase: touch::Phase::Ended,
..
}) => {
self.state.is_dragging = false;
}
Event::Mouse(mouse::Event::CursorMoved { .. })
| Event::Touch(Touch {
phase: touch::Phase::Moved,
..
}) => {
if self.state.is_dragging {
change();
}
Expand Down
6 changes: 5 additions & 1 deletion native/src/widget/text_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//! [`TextInput`]: struct.TextInput.html
//! [`State`]: struct.State.html
use crate::{
input::{keyboard, mouse, ButtonState},
input::{keyboard, mouse, touch, ButtonState, Touch},
layout, Clipboard, Element, Event, Font, Hasher, Layout, Length, Point,
Rectangle, Size, Widget,
};
Expand Down Expand Up @@ -202,6 +202,10 @@ where
Event::Mouse(mouse::Event::Input {
button: mouse::Button::Left,
state: ButtonState::Pressed,
})
| Event::Touch(Touch {
phase: touch::Phase::Started,
..
}) => {
let is_clicked = layout.bounds().contains(cursor_position);

Expand Down
2 changes: 1 addition & 1 deletion wgpu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ wgpu_glyph = "0.7"
glyph_brush = "0.6"
raw-window-handle = "0.3"
glam = "0.8"
font-kit = "0.4"
font-kit = "0.5"
log = "0.4"
guillotiere = "0.4"

Expand Down
Loading