diff options
author | 2019-11-11 20:29:58 -0800 | |
---|---|---|
committer | 2020-03-18 11:26:53 -0700 | |
commit | e19a07d40049f40f36d879a498fab4ce63778b27 (patch) | |
tree | 6ecdcb5345f6c00c2b53ee4d93afd8585c1dda2e /native/src | |
parent | 9da6ce474c2cd178ca5365d46760ba0882ce7121 (diff) | |
download | iced-e19a07d40049f40f36d879a498fab4ce63778b27.tar.gz iced-e19a07d40049f40f36d879a498fab4ce63778b27.tar.bz2 iced-e19a07d40049f40f36d879a498fab4ce63778b27.zip |
Added initial touch events to support iOS
Diffstat (limited to 'native/src')
-rw-r--r-- | native/src/event.rs | 5 | ||||
-rw-r--r-- | native/src/input.rs | 1 | ||||
-rw-r--r-- | native/src/input/touch.rs | 39 | ||||
-rw-r--r-- | native/src/user_interface.rs | 14 | ||||
-rw-r--r-- | native/src/widget/button.rs | 35 | ||||
-rw-r--r-- | native/src/widget/checkbox.rs | 5 | ||||
-rw-r--r-- | native/src/widget/radio.rs | 5 | ||||
-rw-r--r-- | native/src/widget/scrollable.rs | 44 | ||||
-rw-r--r-- | native/src/widget/slider.rs | 30 | ||||
-rw-r--r-- | native/src/widget/text_input.rs | 5 |
10 files changed, 139 insertions, 44 deletions
diff --git a/native/src/event.rs b/native/src/event.rs index b2550ead..fb5b9977 100644 --- a/native/src/event.rs +++ b/native/src/event.rs @@ -1,5 +1,5 @@ use crate::{ - input::{keyboard, mouse}, + input::{keyboard, mouse, touch}, window, }; @@ -19,4 +19,7 @@ pub enum Event { /// A window event Window(window::Event), + + /// A touch event + Touch(touch::Touch), } diff --git a/native/src/input.rs b/native/src/input.rs index 097fa730..c08beaf9 100644 --- a/native/src/input.rs +++ b/native/src/input.rs @@ -1,6 +1,7 @@ //! Map your system events into input events that the runtime can understand. pub mod keyboard; pub mod mouse; +pub mod touch; mod button_state; diff --git a/native/src/input/touch.rs b/native/src/input/touch.rs new file mode 100644 index 00000000..7c4a6210 --- /dev/null +++ b/native/src/input/touch.rs @@ -0,0 +1,39 @@ +//! Build touch events. +/// The touch of a mobile device. +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum Touch { + /// The touch cursor was started + Started { + /// The X coordinate of the touch position + x: f32, + + /// The Y coordinate of the touch position + y: f32, + }, + /// The touch cursor was ended + Ended { + /// The X coordinate of the touch position + x: f32, + + /// The Y coordinate of the touch position + y: f32, + }, + + /// The touch was moved. + Moved { + /// The X coordinate of the touch position + x: f32, + + /// The Y coordinate of the touch position + y: f32, + }, + + /// Some canceled button. + Cancelled { + /// The X coordinate of the touch position + x: f32, + + /// The Y coordinate of the touch position + y: f32, + }, +} diff --git a/native/src/user_interface.rs b/native/src/user_interface.rs index 08914bed..751b2652 100644 --- a/native/src/user_interface.rs +++ b/native/src/user_interface.rs @@ -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; @@ -181,8 +182,15 @@ 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 { x, y }) + | Event::Touch(touch::Touch::Started { x, y }) + | Event::Touch(touch::Touch::Ended { x, y }) + | Event::Touch(touch::Touch::Moved { x, y }) + | Event::Touch(touch::Touch::Cancelled { x, y }) => { + self.cursor_position = Point::new(x, y); + } + _ => {} } self.root.widget.on_event( diff --git a/native/src/widget/button.rs b/native/src/widget/button.rs index f1d46936..8c397bc1 100644 --- a/native/src/widget/button.rs +++ b/native/src/widget/button.rs @@ -5,7 +5,7 @@ //! [`Button`]: struct.Button.html //! [`State`]: struct.State.html use crate::{ - input::{mouse, ButtonState}, + input::{mouse, touch::Touch, ButtonState}, layout, Clipboard, Element, Event, Hasher, Layout, Length, Point, Rectangle, Widget, }; @@ -187,26 +187,27 @@ where match event { Event::Mouse(mouse::Event::Input { button: mouse::Button::Left, - state, - }) => { + state: ButtonState::Pressed, + }) + | Event::Touch(Touch::Started { .. }) => { + let bounds = layout.bounds(); + + self.state.is_pressed = bounds.contains(cursor_position); + } + Event::Mouse(mouse::Event::Input { + button: mouse::Button::Left, + state: ButtonState::Released, + }) + | Event::Touch(Touch::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); - 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 = false; + self.state.is_pressed = false; - if is_clicked { - messages.push(on_press); - } - } + if is_clicked { + messages.push(on_press); } } } diff --git a/native/src/widget/checkbox.rs b/native/src/widget/checkbox.rs index b36d10a4..26665d8b 100644 --- a/native/src/widget/checkbox.rs +++ b/native/src/widget/checkbox.rs @@ -2,7 +2,7 @@ use std::hash::Hash; use crate::{ - input::{mouse, ButtonState}, + input::{mouse, touch::Touch, ButtonState}, layout, row, text, Align, Clipboard, Element, Event, Font, Hasher, HorizontalAlignment, Layout, Length, Point, Rectangle, Row, Text, VerticalAlignment, Widget, @@ -155,7 +155,8 @@ where Event::Mouse(mouse::Event::Input { button: mouse::Button::Left, state: ButtonState::Pressed, - }) => { + }) + | Event::Touch(Touch::Started { .. }) => { let mouse_over = layout.bounds().contains(cursor_position); if mouse_over { diff --git a/native/src/widget/radio.rs b/native/src/widget/radio.rs index cdc4862c..8a9c02ce 100644 --- a/native/src/widget/radio.rs +++ b/native/src/widget/radio.rs @@ -1,6 +1,6 @@ //! Create choices using radio buttons. use crate::{ - input::{mouse, ButtonState}, + input::{mouse, touch, ButtonState}, layout, row, text, Align, Clipboard, Element, Event, Font, Hasher, HorizontalAlignment, Layout, Length, Point, Rectangle, Row, Text, VerticalAlignment, Widget, @@ -121,7 +121,8 @@ where Event::Mouse(mouse::Event::Input { button: mouse::Button::Left, state: ButtonState::Pressed, - }) => { + }) + | Event::Touch(touch::Touch::Started { .. }) => { if layout.bounds().contains(cursor_position) { messages.push(self.on_click.clone()); } diff --git a/native/src/widget/scrollable.rs b/native/src/widget/scrollable.rs index ec9746d4..2a658bcc 100644 --- a/native/src/widget/scrollable.rs +++ b/native/src/widget/scrollable.rs @@ -1,7 +1,7 @@ //! Navigate an endless amount of content with a scrollbar. use crate::{ column, - input::{mouse, ButtonState}, + input::{mouse, touch, ButtonState}, layout, Align, Clipboard, Column, Element, Event, Hasher, Layout, Length, Point, Rectangle, Size, Widget, }; @@ -175,6 +175,22 @@ where } } } + Event::Touch(touch::Touch::Started { .. }) => { + self.state.scroll_box_touched_at = Some(cursor_position); + } + Event::Touch(touch::Touch::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); + } + } + Event::Touch(touch::Touch::Ended { .. }) => { + self.state.scroll_box_touched_at = None; + } _ => {} } } @@ -191,10 +207,23 @@ where Event::Mouse(mouse::Event::Input { button: mouse::Button::Left, state: ButtonState::Released, - }) => { + }) + | Event::Touch(touch::Touch::Ended { .. }) => { self.state.scroller_grabbed_at = None; } - Event::Mouse(mouse::Event::CursorMoved { .. }) => { + Event::Mouse(mouse::Event::Input { + button: mouse::Button::Left, + state: ButtonState::Pressed, + }) + | Event::Touch(touch::Touch::Started { .. }) => { + self.state.scroll_to( + cursor_position.y / (bounds.y + bounds.height), + bounds, + content_bounds, + ); + } + Event::Mouse(mouse::Event::CursorMoved { .. }) + | Event::Touch(touch::Touch::Moved { .. }) => { if let (Some(scrollbar), Some(scroller_grabbed_at)) = (scrollbar, self.state.scroller_grabbed_at) { @@ -215,7 +244,8 @@ where Event::Mouse(mouse::Event::Input { button: mouse::Button::Left, state: ButtonState::Pressed, - }) => { + }) + | Event::Touch(touch::Touch::Started { .. }) => { if let Some(scrollbar) = scrollbar { if let Some(scroller_grabbed_at) = scrollbar.grab_scroller(cursor_position) @@ -326,6 +356,7 @@ where #[derive(Debug, Clone, Copy, Default)] pub struct State { scroller_grabbed_at: Option<f32>, + scroll_box_touched_at: Option<Point>, offset: f32, } @@ -391,6 +422,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`]. diff --git a/native/src/widget/slider.rs b/native/src/widget/slider.rs index 008203fe..95f63921 100644 --- a/native/src/widget/slider.rs +++ b/native/src/widget/slider.rs @@ -5,7 +5,7 @@ //! [`Slider`]: struct.Slider.html //! [`State`]: struct.State.html use crate::{ - input::{mouse, ButtonState}, + input::{mouse, touch::Touch, ButtonState}, layout, Clipboard, Element, Event, Hasher, Layout, Length, Point, Rectangle, Size, Widget, }; @@ -166,19 +166,23 @@ 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::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::Ended { .. }) => { + self.state.is_dragging = false; + } + Event::Mouse(mouse::Event::CursorMoved { .. }) + | Event::Touch(Touch::Moved { .. }) => { if self.state.is_dragging { change(); } diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs index c068b895..9cfc6bf0 100644 --- a/native/src/widget/text_input.rs +++ b/native/src/widget/text_input.rs @@ -5,7 +5,7 @@ //! [`TextInput`]: struct.TextInput.html //! [`State`]: struct.State.html use crate::{ - input::{keyboard, mouse, ButtonState}, + input::{keyboard, mouse, touch, ButtonState}, layout, Clipboard, Element, Event, Font, Hasher, Layout, Length, Point, Rectangle, Size, Widget, }; @@ -202,7 +202,8 @@ where Event::Mouse(mouse::Event::Input { button: mouse::Button::Left, state: ButtonState::Pressed, - }) => { + }) + | Event::Touch(touch::Touch::Started { .. }) => { let is_clicked = layout.bounds().contains(cursor_position); if is_clicked { |