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 all 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
9 changes: 4 additions & 5 deletions core/src/mouse/event.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::Point;

use super::Button;

/// A mouse event.
Expand All @@ -16,11 +18,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.
Expand Down
8 changes: 7 additions & 1 deletion native/src/event.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
//! Handle events of a user interface.
use crate::{keyboard, mouse, window};
use crate::keyboard;
use crate::mouse;
use crate::touch;
use crate::window;

/// A user interface event.
///
Expand All @@ -17,6 +20,9 @@ pub enum Event {

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

/// A touch event
Touch(touch::Event),
}

/// The status of an [`Event`] after being processed.
Expand Down
1 change: 1 addition & 0 deletions native/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ pub mod overlay;
pub mod program;
pub mod renderer;
pub mod subscription;
pub mod touch;
pub mod widget;
pub mod window;

Expand Down
23 changes: 23 additions & 0 deletions native/src/touch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//! Build touch events.
use crate::Point;

/// A touch interaction.
#[derive(Debug, Clone, Copy, PartialEq)]
#[allow(missing_docs)]
pub enum Event {
/// A touch interaction was started.
FingerPressed { id: Finger, position: Point },

/// An on-going touch interaction was moved.
FingerMoved { id: Finger, position: Point },

/// A touch interaction was ended.
FingerLifted { id: Finger, position: Point },

/// A touch interaction was canceled.
FingerLost { id: Finger, position: Point },
}

/// A unique identifier representing a finger on a touch interaction.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Finger(pub u64);
10 changes: 8 additions & 2 deletions native/src/widget/button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use crate::event::{self, Event};
use crate::layout;
use crate::mouse;
use crate::touch;
use crate::{
Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Widget,
};
Expand Down Expand Up @@ -164,7 +165,8 @@ where
_clipboard: Option<&dyn Clipboard>,
) -> event::Status {
match event {
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => {
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
| Event::Touch(touch::Event::FingerPressed { .. }) => {
if self.on_press.is_some() {
let bounds = layout.bounds();

Expand All @@ -175,7 +177,8 @@ where
}
}
}
Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) => {
Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left))
| Event::Touch(touch::Event::FingerLifted { .. }) => {
if let Some(on_press) = self.on_press.clone() {
let bounds = layout.bounds();

Expand All @@ -190,6 +193,9 @@ where
}
}
}
Event::Touch(touch::Event::FingerLost { .. }) => {
self.state.is_pressed = false;
}
_ => {}
}

Expand Down
4 changes: 3 additions & 1 deletion native/src/widget/checkbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::layout;
use crate::mouse;
use crate::row;
use crate::text;
use crate::touch;
use crate::{
Align, Clipboard, Element, Hasher, HorizontalAlignment, Layout, Length,
Point, Rectangle, Row, Text, VerticalAlignment, Widget,
Expand Down Expand Up @@ -154,7 +155,8 @@ where
_clipboard: Option<&dyn Clipboard>,
) -> event::Status {
match event {
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => {
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
| Event::Touch(touch::Event::FingerPressed { .. }) => {
let mouse_over = layout.bounds().contains(cursor_position);

if mouse_over {
Expand Down
4 changes: 3 additions & 1 deletion native/src/widget/radio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::layout;
use crate::mouse;
use crate::row;
use crate::text;
use crate::touch;
use crate::{
Align, Clipboard, Element, Hasher, HorizontalAlignment, Layout, Length,
Point, Rectangle, Row, Text, VerticalAlignment, Widget,
Expand Down Expand Up @@ -160,7 +161,8 @@ where
_clipboard: Option<&dyn Clipboard>,
) -> event::Status {
match event {
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => {
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
| Event::Touch(touch::Event::FingerPressed { .. }) => {
if layout.bounds().contains(cursor_position) {
messages.push(self.on_click.clone());

Expand Down
48 changes: 45 additions & 3 deletions native/src/widget/scrollable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::event::{self, Event};
use crate::layout;
use crate::mouse;
use crate::overlay;
use crate::touch;
use crate::{
Align, Clipboard, Column, Element, Hasher, Layout, Length, Point,
Rectangle, Size, Vector, Widget,
Expand Down Expand Up @@ -229,6 +230,37 @@ where

return event::Status::Captured;
}
Event::Touch(event) => {
match event {
touch::Event::FingerPressed { .. } => {
self.state.scroll_box_touched_at =
Some(cursor_position);
}
touch::Event::FingerMoved { .. } => {
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::Event::FingerLifted { .. }
| touch::Event::FingerLost { .. } => {
self.state.scroll_box_touched_at = None;
}
}

return event::Status::Captured;
}
_ => {}
}
}
Expand All @@ -237,12 +269,15 @@ where
match event {
Event::Mouse(mouse::Event::ButtonReleased(
mouse::Button::Left,
)) => {
))
| Event::Touch(touch::Event::FingerLifted { .. })
| Event::Touch(touch::Event::FingerLost { .. }) => {
self.state.scroller_grabbed_at = None;

return event::Status::Captured;
}
Event::Mouse(mouse::Event::CursorMoved { .. }) => {
Event::Mouse(mouse::Event::CursorMoved { .. })
| Event::Touch(touch::Event::FingerMoved { .. }) => {
if let (Some(scrollbar), Some(scroller_grabbed_at)) =
(scrollbar, self.state.scroller_grabbed_at)
{
Expand All @@ -264,7 +299,8 @@ where
match event {
Event::Mouse(mouse::Event::ButtonPressed(
mouse::Button::Left,
)) => {
))
| Event::Touch(touch::Event::FingerPressed { .. }) => {
if let Some(scrollbar) = scrollbar {
if let Some(scroller_grabbed_at) =
scrollbar.grab_scroller(cursor_position)
Expand Down Expand Up @@ -385,6 +421,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 @@ -439,6 +476,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
46 changes: 24 additions & 22 deletions native/src/widget/slider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use crate::event::{self, Event};
use crate::layout;
use crate::mouse;
use crate::touch;
use crate::{
Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Size, Widget,
};
Expand Down Expand Up @@ -207,34 +208,35 @@ where
};

match event {
Event::Mouse(mouse_event) => match mouse_event {
mouse::Event::ButtonPressed(mouse::Button::Left) => {
if layout.bounds().contains(cursor_position) {
change();
self.state.is_dragging = true;
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
| Event::Touch(touch::Event::FingerPressed { .. }) => {
if layout.bounds().contains(cursor_position) {
change();
self.state.is_dragging = true;

return event::Status::Captured;
}
return event::Status::Captured;
}
mouse::Event::ButtonReleased(mouse::Button::Left) => {
if self.state.is_dragging {
if let Some(on_release) = self.on_release.clone() {
messages.push(on_release);
}
self.state.is_dragging = false;

return event::Status::Captured;
}
Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left))
| Event::Touch(touch::Event::FingerLifted { .. })
| Event::Touch(touch::Event::FingerLost { .. }) => {
if self.state.is_dragging {
if let Some(on_release) = self.on_release.clone() {
messages.push(on_release);
}
self.state.is_dragging = false;

return event::Status::Captured;
}
mouse::Event::CursorMoved { .. } => {
if self.state.is_dragging {
change();
}
Event::Mouse(mouse::Event::CursorMoved { .. })
| Event::Touch(touch::Event::FingerMoved { .. }) => {
if self.state.is_dragging {
change();

return event::Status::Captured;
}
return event::Status::Captured;
}
_ => {}
},
}
_ => {}
}

Expand Down
13 changes: 9 additions & 4 deletions native/src/widget/text_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::keyboard;
use crate::layout;
use crate::mouse::{self, click};
use crate::text;
use crate::touch;
use crate::{
Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Size, Widget,
};
Expand Down Expand Up @@ -247,7 +248,8 @@ where
clipboard: Option<&dyn Clipboard>,
) -> event::Status {
match event {
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => {
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
| Event::Touch(touch::Event::FingerPressed { .. }) => {
let is_clicked = layout.bounds().contains(cursor_position);

self.state.is_focused = is_clicked;
Expand Down Expand Up @@ -318,13 +320,16 @@ where
return event::Status::Captured;
}
}
Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) => {
Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left))
| Event::Touch(touch::Event::FingerLifted { .. })
| Event::Touch(touch::Event::FingerLost { .. }) => {
self.state.is_dragging = false;
}
Event::Mouse(mouse::Event::CursorMoved { x, .. }) => {
Event::Mouse(mouse::Event::CursorMoved { position })
| Event::Touch(touch::Event::FingerMoved { position, .. }) => {
if self.state.is_dragging {
let text_layout = layout.children().next().unwrap();
let target = x - text_layout.bounds().x;
let target = position.x - text_layout.bounds().x;

if target > 0.0 {
let value = if self.is_secure {
Expand Down
7 changes: 5 additions & 2 deletions winit/src/application/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::conversion;
use crate::{Application, Color, Debug, Mode, Point, Size, Viewport};

use std::marker::PhantomData;
use winit::event::WindowEvent;
use winit::event::{Touch, WindowEvent};
use winit::window::Window;

/// The state of a windowed [`Application`].
Expand Down Expand Up @@ -128,7 +128,10 @@ impl<A: Application> State<A> {

self.viewport_version = self.viewport_version.wrapping_add(1);
}
WindowEvent::CursorMoved { position, .. } => {
WindowEvent::CursorMoved { position, .. }
| WindowEvent::Touch(Touch {
location: position, ..
}) => {
self.cursor_position = *position;
}
WindowEvent::CursorLeft { .. } => {
Expand Down
Loading