From e19a07d40049f40f36d879a498fab4ce63778b27 Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Mon, 11 Nov 2019 20:29:58 -0800 Subject: [PATCH 1/7] Added initial touch events to support iOS --- native/src/event.rs | 5 +++- native/src/input.rs | 1 + native/src/input/touch.rs | 39 +++++++++++++++++++++++++++++ native/src/user_interface.rs | 14 ++++++++--- native/src/widget/button.rs | 35 +++++++++++++------------- native/src/widget/checkbox.rs | 5 ++-- native/src/widget/radio.rs | 5 ++-- native/src/widget/scrollable.rs | 44 ++++++++++++++++++++++++++++++--- native/src/widget/slider.rs | 30 ++++++++++++---------- native/src/widget/text_input.rs | 5 ++-- wgpu/Cargo.toml | 2 +- winit/src/application.rs | 1 - winit/src/conversion.rs | 26 ++++++++++++++++++- 13 files changed, 165 insertions(+), 47 deletions(-) create mode 100644 native/src/input/touch.rs 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, + scroll_box_touched_at: Option, 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; - } + state: ButtonState::Pressed, + }) + | Event::Touch(Touch::Started { .. }) => { + if layout.bounds().contains(cursor_position) { + change(); + self.state.is_dragging = true; } - ButtonState::Released => { - self.state.is_dragging = false; - } - }, - 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 { diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 6c75af7b..b03fa43f 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -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.0" log = "0.4" guillotiere = "0.4" diff --git a/winit/src/application.rs b/winit/src/application.rs index 891b8f12..65bffd5b 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -310,7 +310,6 @@ pub trait Application: Sized { physical_size.width, physical_size.height, ); - resized = false; } diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs index b6a0b64b..2fc76c9d 100644 --- a/winit/src/conversion.rs +++ b/winit/src/conversion.rs @@ -5,7 +5,7 @@ use crate::{ input::{ keyboard::{self, KeyCode, ModifiersState}, - mouse, ButtonState, + mouse, touch, ButtonState, }, window, Event, Mode, MouseCursor, }; @@ -84,6 +84,9 @@ pub fn window_event( WindowEvent::HoveredFileCancelled => { Some(Event::Window(window::Event::FilesHoveredLeft)) } + WindowEvent::Touch(touch) => { + Some(Event::Touch(touch_event(touch))) + } _ => None, } } @@ -342,3 +345,24 @@ pub(crate) fn is_private_use_character(c: char) -> bool { _ => false, } } +pub(crate) fn touch_event(touch: winit::event::Touch) -> touch::Touch { + let location = touch.location; + match touch.phase { + winit::event::TouchPhase::Started => touch::Touch::Started { + x: location.x as f32, + y: location.y as f32, + }, + winit::event::TouchPhase::Ended => touch::Touch::Ended { + x: location.x as f32, + y: location.y as f32, + }, + winit::event::TouchPhase::Moved => touch::Touch::Moved { + x: location.x as f32, + y: location.y as f32, + }, + winit::event::TouchPhase::Cancelled => touch::Touch::Cancelled { + x: location.x as f32, + y: location.y as f32, + }, + } +} From d3572e1b819ff4d40de4f39f48eab71b9d0d4d5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 19 Mar 2020 12:17:16 +0100 Subject: [PATCH 2/7] Turn `Touch` into a struct and add finger id --- native/src/event.rs | 6 +-- native/src/input.rs | 1 + native/src/input/mouse/event.rs | 9 ++--- native/src/input/touch.rs | 65 ++++++++++++++++----------------- native/src/user_interface.rs | 11 ++---- native/src/widget/button.rs | 24 +++++++++--- native/src/widget/checkbox.rs | 7 +++- native/src/widget/radio.rs | 7 +++- native/src/widget/scrollable.rs | 56 +++++++++++++++++++--------- native/src/widget/slider.rs | 17 +++++++-- native/src/widget/text_input.rs | 7 +++- wgpu/Cargo.toml | 2 +- winit/src/conversion.rs | 51 ++++++++++++-------------- 13 files changed, 151 insertions(+), 112 deletions(-) diff --git a/native/src/event.rs b/native/src/event.rs index fb5b9977..99a8e880 100644 --- a/native/src/event.rs +++ b/native/src/event.rs @@ -1,5 +1,5 @@ use crate::{ - input::{keyboard, mouse, touch}, + input::{keyboard, mouse, Touch}, window, }; @@ -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), @@ -21,5 +21,5 @@ pub enum Event { Window(window::Event), /// A touch event - Touch(touch::Touch), + Touch(Touch), } diff --git a/native/src/input.rs b/native/src/input.rs index c08beaf9..514a98ea 100644 --- a/native/src/input.rs +++ b/native/src/input.rs @@ -6,3 +6,4 @@ pub mod touch; mod button_state; pub use button_state::ButtonState; +pub use touch::Touch; diff --git a/native/src/input/mouse/event.rs b/native/src/input/mouse/event.rs index aafc4fe3..5068d634 100644 --- a/native/src/input/mouse/event.rs +++ b/native/src/input/mouse/event.rs @@ -1,5 +1,5 @@ use super::Button; -use crate::input::ButtonState; +use crate::{input::ButtonState, Point}; /// A mouse event. /// @@ -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. diff --git a/native/src/input/touch.rs b/native/src/input/touch.rs index 7c4a6210..ea879427 100644 --- a/native/src/input/touch.rs +++ b/native/src/input/touch.rs @@ -1,39 +1,36 @@ //! Build touch events. -/// The touch of a mobile device. + +use crate::Point; + +/// A touch interaction. #[derive(Debug, Clone, Copy, PartialEq)] -pub enum Touch { - /// The touch cursor was started - Started { - /// The X coordinate of the touch position - x: f32, +pub struct Touch { + /// The finger of the touch. + pub finger: Finger, - /// 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 position of the touch. + pub position: Point, - /// 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, - }, + /// 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, } diff --git a/native/src/user_interface.rs b/native/src/user_interface.rs index 751b2652..b71b9003 100644 --- a/native/src/user_interface.rs +++ b/native/src/user_interface.rs @@ -1,5 +1,5 @@ use crate::{ - input::{mouse, touch}, + input::{mouse, Touch}, layout, Clipboard, Element, Event, Layout, Point, Size, }; @@ -183,12 +183,9 @@ where for event in events { 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); + Event::Mouse(mouse::Event::CursorMoved { position }) + | Event::Touch(Touch { position, .. }) => { + self.cursor_position = position; } _ => {} } diff --git a/native/src/widget/button.rs b/native/src/widget/button.rs index 8c397bc1..81dbe7c5 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, touch::Touch, ButtonState}, + input::{mouse, touch, ButtonState, Touch}, layout, Clipboard, Element, Event, Hasher, Layout, Length, Point, Rectangle, Widget, }; @@ -189,16 +189,24 @@ where button: mouse::Button::Left, state: ButtonState::Pressed, }) - | Event::Touch(Touch::Started { .. }) => { - let bounds = layout.bounds(); + | Event::Touch(Touch { + phase: touch::Phase::Started, + .. + }) => { + if self.on_press.is_some() { + let bounds = layout.bounds(); - 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::Ended { .. }) => { + | 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 @@ -211,6 +219,12 @@ where } } } + Event::Touch(Touch { + phase: touch::Phase::Canceled, + .. + }) => { + self.state.is_pressed = false; + } _ => {} } } diff --git a/native/src/widget/checkbox.rs b/native/src/widget/checkbox.rs index 26665d8b..7b2345de 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, touch::Touch, ButtonState}, + input::{mouse, touch, ButtonState, Touch}, layout, row, text, Align, Clipboard, Element, Event, Font, Hasher, HorizontalAlignment, Layout, Length, Point, Rectangle, Row, Text, VerticalAlignment, Widget, @@ -156,7 +156,10 @@ where button: mouse::Button::Left, state: ButtonState::Pressed, }) - | Event::Touch(Touch::Started { .. }) => { + | Event::Touch(Touch { + phase: touch::Phase::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 8a9c02ce..46983db3 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, touch, ButtonState}, + input::{mouse, touch, ButtonState, Touch}, layout, row, text, Align, Clipboard, Element, Event, Font, Hasher, HorizontalAlignment, Layout, Length, Point, Rectangle, Row, Text, VerticalAlignment, Widget, @@ -122,7 +122,10 @@ where button: mouse::Button::Left, state: ButtonState::Pressed, }) - | Event::Touch(touch::Touch::Started { .. }) => { + | Event::Touch(Touch { + phase: touch::Phase::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 2a658bcc..2f5a4820 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, touch, ButtonState}, + input::{mouse, touch, ButtonState, Touch}, layout, Align, Clipboard, Column, Element, Event, Hasher, Layout, Length, Point, Rectangle, Size, Widget, }; @@ -175,22 +175,26 @@ 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); + Event::Touch(Touch { phase, .. }) => match phase { + touch::Phase::Started => { self.state.scroll_box_touched_at = Some(cursor_position); } - } - Event::Touch(touch::Touch::Ended { .. }) => { - self.state.scroll_box_touched_at = None; - } + 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; + } + }, _ => {} } } @@ -208,14 +212,24 @@ where button: mouse::Button::Left, state: ButtonState::Released, }) - | Event::Touch(touch::Touch::Ended { .. }) => { + | Event::Touch(Touch { + phase: touch::Phase::Ended, + .. + }) + | Event::Touch(Touch { + phase: touch::Phase::Canceled, + .. + }) => { self.state.scroller_grabbed_at = None; } Event::Mouse(mouse::Event::Input { button: mouse::Button::Left, state: ButtonState::Pressed, }) - | Event::Touch(touch::Touch::Started { .. }) => { + | Event::Touch(Touch { + phase: touch::Phase::Started, + .. + }) => { self.state.scroll_to( cursor_position.y / (bounds.y + bounds.height), bounds, @@ -223,7 +237,10 @@ where ); } Event::Mouse(mouse::Event::CursorMoved { .. }) - | Event::Touch(touch::Touch::Moved { .. }) => { + | Event::Touch(Touch { + phase: touch::Phase::Moved, + .. + }) => { if let (Some(scrollbar), Some(scroller_grabbed_at)) = (scrollbar, self.state.scroller_grabbed_at) { @@ -245,7 +262,10 @@ where button: mouse::Button::Left, state: ButtonState::Pressed, }) - | Event::Touch(touch::Touch::Started { .. }) => { + | Event::Touch(Touch { + phase: touch::Phase::Started, + .. + }) => { if let Some(scrollbar) = scrollbar { if let Some(scroller_grabbed_at) = scrollbar.grab_scroller(cursor_position) diff --git a/native/src/widget/slider.rs b/native/src/widget/slider.rs index 95f63921..c98cebb6 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, touch::Touch, ButtonState}, + input::{mouse, touch, ButtonState, Touch}, layout, Clipboard, Element, Event, Hasher, Layout, Length, Point, Rectangle, Size, Widget, }; @@ -168,7 +168,10 @@ where button: mouse::Button::Left, state: ButtonState::Pressed, }) - | Event::Touch(Touch::Started { .. }) => { + | Event::Touch(Touch { + phase: touch::Phase::Started, + .. + }) => { if layout.bounds().contains(cursor_position) { change(); self.state.is_dragging = true; @@ -178,11 +181,17 @@ where button: mouse::Button::Left, state: ButtonState::Released, }) - | Event::Touch(Touch::Ended { .. }) => { + | Event::Touch(Touch { + phase: touch::Phase::Ended, + .. + }) => { self.state.is_dragging = false; } Event::Mouse(mouse::Event::CursorMoved { .. }) - | Event::Touch(Touch::Moved { .. }) => { + | Event::Touch(Touch { + phase: touch::Phase::Moved, + .. + }) => { if self.state.is_dragging { change(); } diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs index 9cfc6bf0..c06a8cce 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, touch, ButtonState}, + input::{keyboard, mouse, touch, ButtonState, Touch}, layout, Clipboard, Element, Event, Font, Hasher, Layout, Length, Point, Rectangle, Size, Widget, }; @@ -203,7 +203,10 @@ where button: mouse::Button::Left, state: ButtonState::Pressed, }) - | Event::Touch(touch::Touch::Started { .. }) => { + | Event::Touch(Touch { + phase: touch::Phase::Started, + .. + }) => { let is_clicked = layout.bounds().contains(cursor_position); if is_clicked { diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index b03fa43f..17dfb4a3 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -19,7 +19,7 @@ wgpu_glyph = "0.7" glyph_brush = "0.6" raw-window-handle = "0.3" glam = "0.8" -font-kit = "0.5.0" +font-kit = "0.5" log = "0.4" guillotiere = "0.4" diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs index 2fc76c9d..1d008d05 100644 --- a/winit/src/conversion.rs +++ b/winit/src/conversion.rs @@ -5,9 +5,9 @@ use crate::{ input::{ keyboard::{self, KeyCode, ModifiersState}, - mouse, touch, ButtonState, + mouse, touch, ButtonState, Touch, }, - window, Event, Mode, MouseCursor, + window, Event, Mode, MouseCursor, Point, }; /// Converts a winit window event into an iced event. @@ -31,8 +31,7 @@ pub fn window_event( let position = position.to_logical::(scale_factor); Some(Event::Mouse(mouse::Event::CursorMoved { - x: position.x as f32, - y: position.y as f32, + position: Point::new(position.x as f32, position.y as f32), })) } WindowEvent::MouseInput { button, state, .. } => { @@ -84,9 +83,7 @@ pub fn window_event( WindowEvent::HoveredFileCancelled => { Some(Event::Window(window::Event::FilesHoveredLeft)) } - WindowEvent::Touch(touch) => { - Some(Event::Touch(touch_event(touch))) - } + WindowEvent::Touch(touch) => Some(Event::Touch(touch_event(touch))), _ => None, } } @@ -162,6 +159,25 @@ pub fn modifiers_state( } } +/// Converts a `Touch` from [`winit`] to an [`iced_native`] touch event. +/// +/// [`winit`]: https://github.com/rust-windowing/winit +/// [`iced_native`]: https://github.com/hecrj/iced/tree/master/native +pub fn touch_event(touch: winit::event::Touch) -> Touch { + let phase = match touch.phase { + winit::event::TouchPhase::Started => touch::Phase::Started, + winit::event::TouchPhase::Moved => touch::Phase::Moved, + winit::event::TouchPhase::Ended => touch::Phase::Ended, + winit::event::TouchPhase::Cancelled => touch::Phase::Canceled, + }; + + Touch { + finger: touch::Finger(touch.id), + position: Point::new(touch.location.x as f32, touch.location.y as f32), + phase, + } +} + /// Converts a `VirtualKeyCode` from [`winit`] to an [`iced_native`] key code. /// /// [`winit`]: https://github.com/rust-windowing/winit @@ -345,24 +361,3 @@ pub(crate) fn is_private_use_character(c: char) -> bool { _ => false, } } -pub(crate) fn touch_event(touch: winit::event::Touch) -> touch::Touch { - let location = touch.location; - match touch.phase { - winit::event::TouchPhase::Started => touch::Touch::Started { - x: location.x as f32, - y: location.y as f32, - }, - winit::event::TouchPhase::Ended => touch::Touch::Ended { - x: location.x as f32, - y: location.y as f32, - }, - winit::event::TouchPhase::Moved => touch::Touch::Moved { - x: location.x as f32, - y: location.y as f32, - }, - winit::event::TouchPhase::Cancelled => touch::Touch::Cancelled { - x: location.x as f32, - y: location.y as f32, - }, - } -} From 36bdc0be1a0f959c84c18286b85c1ab51be330e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 19 Mar 2020 12:23:31 +0100 Subject: [PATCH 3/7] Remove redundant `scroll_to` in `Scrollable` --- native/src/widget/scrollable.rs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/native/src/widget/scrollable.rs b/native/src/widget/scrollable.rs index 2f5a4820..eb1722ed 100644 --- a/native/src/widget/scrollable.rs +++ b/native/src/widget/scrollable.rs @@ -222,20 +222,6 @@ where }) => { self.state.scroller_grabbed_at = None; } - Event::Mouse(mouse::Event::Input { - button: mouse::Button::Left, - state: ButtonState::Pressed, - }) - | Event::Touch(Touch { - phase: touch::Phase::Started, - .. - }) => { - self.state.scroll_to( - cursor_position.y / (bounds.y + bounds.height), - bounds, - content_bounds, - ); - } Event::Mouse(mouse::Event::CursorMoved { .. }) | Event::Touch(Touch { phase: touch::Phase::Moved, From 3bdf931925067acbaabf040f6c437a54640ed1a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 15 Dec 2020 06:38:46 +0100 Subject: [PATCH 4/7] Turn `Touch` into a `touch::Event` enum --- native/src/event.rs | 2 +- native/src/touch.rs | 34 ++++++----------- native/src/widget/button.rs | 17 ++------- native/src/widget/checkbox.rs | 7 +--- native/src/widget/radio.rs | 7 +--- native/src/widget/scrollable.rs | 65 ++++++++++++++++----------------- native/src/widget/slider.rs | 18 +++------ native/src/widget/text_input.rs | 7 +--- winit/src/conversion.rs | 50 +++++++++++++++---------- 9 files changed, 89 insertions(+), 118 deletions(-) diff --git a/native/src/event.rs b/native/src/event.rs index f3c260c0..205bb797 100644 --- a/native/src/event.rs +++ b/native/src/event.rs @@ -22,7 +22,7 @@ pub enum Event { Window(window::Event), /// A touch event - Touch(touch::Touch), + Touch(touch::Event), } /// The status of an [`Event`] after being processed. diff --git a/native/src/touch.rs b/native/src/touch.rs index 88bd83bb..18120644 100644 --- a/native/src/touch.rs +++ b/native/src/touch.rs @@ -3,33 +3,21 @@ use crate::Point; /// A touch interaction. #[derive(Debug, Clone, Copy, PartialEq)] -pub struct Touch { - /// The finger of the touch. - pub finger: Finger, +#[allow(missing_docs)] +pub enum Event { + /// A touch interaction was started. + FingerPressed { id: Finger, position: Point }, - /// The position of the touch. - pub position: Point, + /// An on-going touch interaction was moved. + FingerMoved { id: Finger, position: Point }, - /// The state of the touch. - pub phase: Phase, + /// 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); - -/// 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, -} diff --git a/native/src/widget/button.rs b/native/src/widget/button.rs index 7d5eb30c..8e2450de 100644 --- a/native/src/widget/button.rs +++ b/native/src/widget/button.rs @@ -4,7 +4,7 @@ use crate::event::{self, Event}; use crate::layout; use crate::mouse; -use crate::touch::{self, Touch}; +use crate::touch; use crate::{ Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Widget, }; @@ -166,10 +166,7 @@ where ) -> event::Status { match event { Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) - | Event::Touch(Touch { - phase: touch::Phase::Started, - .. - }) => { + | Event::Touch(touch::Event::FingerPressed { .. }) => { if self.on_press.is_some() { let bounds = layout.bounds(); @@ -181,10 +178,7 @@ where } } Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) - | Event::Touch(Touch { - phase: touch::Phase::Ended, - .. - }) => { + | Event::Touch(touch::Event::FingerLifted { .. }) => { if let Some(on_press) = self.on_press.clone() { let bounds = layout.bounds(); @@ -199,10 +193,7 @@ where } } } - Event::Touch(Touch { - phase: touch::Phase::Canceled, - .. - }) => { + Event::Touch(touch::Event::FingerLost { .. }) => { self.state.is_pressed = false; } _ => {} diff --git a/native/src/widget/checkbox.rs b/native/src/widget/checkbox.rs index 92175b25..77a82fad 100644 --- a/native/src/widget/checkbox.rs +++ b/native/src/widget/checkbox.rs @@ -6,7 +6,7 @@ use crate::layout; use crate::mouse; use crate::row; use crate::text; -use crate::touch::{self, Touch}; +use crate::touch; use crate::{ Align, Clipboard, Element, Hasher, HorizontalAlignment, Layout, Length, Point, Rectangle, Row, Text, VerticalAlignment, Widget, @@ -156,10 +156,7 @@ where ) -> event::Status { match event { Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) - | Event::Touch(Touch { - phase: touch::Phase::Started, - .. - }) => { + | Event::Touch(touch::Event::FingerPressed { .. }) => { 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 3a1dd386..69952345 100644 --- a/native/src/widget/radio.rs +++ b/native/src/widget/radio.rs @@ -4,7 +4,7 @@ use crate::layout; use crate::mouse; use crate::row; use crate::text; -use crate::touch::{self, Touch}; +use crate::touch; use crate::{ Align, Clipboard, Element, Hasher, HorizontalAlignment, Layout, Length, Point, Rectangle, Row, Text, VerticalAlignment, Widget, @@ -162,10 +162,7 @@ where ) -> event::Status { match event { Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) - | Event::Touch(Touch { - phase: touch::Phase::Started, - .. - }) => { + | Event::Touch(touch::Event::FingerPressed { .. }) => { 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 8c321ee5..18cdf169 100644 --- a/native/src/widget/scrollable.rs +++ b/native/src/widget/scrollable.rs @@ -4,7 +4,7 @@ use crate::event::{self, Event}; use crate::layout; use crate::mouse; use crate::overlay; -use crate::touch::{self, Touch}; +use crate::touch; use crate::{ Align, Clipboard, Column, Element, Hasher, Layout, Length, Point, Rectangle, Size, Vector, Widget, @@ -230,26 +230,37 @@ where return event::Status::Captured; } - 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); + 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; + } } - touch::Phase::Ended | touch::Phase::Canceled => { - self.state.scroll_box_touched_at = None; - } - }, + + return event::Status::Captured; + } _ => {} } } @@ -259,23 +270,14 @@ where Event::Mouse(mouse::Event::ButtonReleased( mouse::Button::Left, )) - | Event::Touch(Touch { - phase: touch::Phase::Ended, - .. - }) - | Event::Touch(Touch { - phase: touch::Phase::Canceled, - .. - }) => { + | 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::Touch(Touch { - phase: touch::Phase::Moved, - .. - }) => { + | Event::Touch(touch::Event::FingerMoved { .. }) => { if let (Some(scrollbar), Some(scroller_grabbed_at)) = (scrollbar, self.state.scroller_grabbed_at) { @@ -298,10 +300,7 @@ where Event::Mouse(mouse::Event::ButtonPressed( mouse::Button::Left, )) - | Event::Touch(Touch { - phase: touch::Phase::Started, - .. - }) => { + | Event::Touch(touch::Event::FingerPressed { .. }) => { if let Some(scrollbar) = scrollbar { if let Some(scroller_grabbed_at) = scrollbar.grab_scroller(cursor_position) diff --git a/native/src/widget/slider.rs b/native/src/widget/slider.rs index 755e6b2b..010c6e53 100644 --- a/native/src/widget/slider.rs +++ b/native/src/widget/slider.rs @@ -4,7 +4,7 @@ use crate::event::{self, Event}; use crate::layout; use crate::mouse; -use crate::touch::{self, Touch}; +use crate::touch; use crate::{ Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Size, Widget, }; @@ -209,10 +209,7 @@ where match event { Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) - | Event::Touch(Touch { - phase: touch::Phase::Started, - .. - }) => { + | Event::Touch(touch::Event::FingerPressed { .. }) => { if layout.bounds().contains(cursor_position) { change(); self.state.is_dragging = true; @@ -221,10 +218,8 @@ where } } Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) - | Event::Touch(Touch { - phase: touch::Phase::Ended, - .. - }) => { + | 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); @@ -235,10 +230,7 @@ where } } Event::Mouse(mouse::Event::CursorMoved { .. }) - | Event::Touch(Touch { - phase: touch::Phase::Moved, - .. - }) => { + | Event::Touch(touch::Event::FingerMoved { .. }) => { if self.state.is_dragging { change(); diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs index ca71c20c..1e84e22a 100644 --- a/native/src/widget/text_input.rs +++ b/native/src/widget/text_input.rs @@ -16,7 +16,7 @@ use crate::keyboard; use crate::layout; use crate::mouse::{self, click}; use crate::text; -use crate::touch::{self, Touch}; +use crate::touch; use crate::{ Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Size, Widget, }; @@ -249,10 +249,7 @@ where ) -> event::Status { match event { Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) - | Event::Touch(Touch { - phase: touch::Phase::Started, - .. - }) => { + | Event::Touch(touch::Event::FingerPressed { .. }) => { let is_clicked = layout.bounds().contains(cursor_position); self.state.is_focused = is_clicked; diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs index e6fc4b96..7a6ab2de 100644 --- a/winit/src/conversion.rs +++ b/winit/src/conversion.rs @@ -2,12 +2,11 @@ //! //! [`winit`]: https://github.com/rust-windowing/winit //! [`iced_native`]: https://github.com/hecrj/iced/tree/master/native -use crate::{ - keyboard::{self, KeyCode, Modifiers}, - mouse, - touch::{self, Touch}, - window, Event, Mode, Point, -}; +use crate::keyboard; +use crate::mouse; +use crate::touch; +use crate::window; +use crate::{Event, Mode, Point}; /// Converts a winit window event into an iced event. pub fn window_event( @@ -183,8 +182,10 @@ pub fn mouse_button(mouse_button: winit::event::MouseButton) -> mouse::Button { /// /// [`winit`]: https://github.com/rust-windowing/winit /// [`iced_native`]: https://github.com/hecrj/iced/tree/master/native -pub fn modifiers(modifiers: winit::event::ModifiersState) -> Modifiers { - Modifiers { +pub fn modifiers( + modifiers: winit::event::ModifiersState, +) -> keyboard::Modifiers { + keyboard::Modifiers { shift: modifiers.shift(), control: modifiers.ctrl(), alt: modifiers.alt(), @@ -206,18 +207,23 @@ pub fn cursor_position( /// /// [`winit`]: https://github.com/rust-windowing/winit /// [`iced_native`]: https://github.com/hecrj/iced/tree/master/native -pub fn touch_event(touch: winit::event::Touch) -> Touch { - let phase = match touch.phase { - winit::event::TouchPhase::Started => touch::Phase::Started, - winit::event::TouchPhase::Moved => touch::Phase::Moved, - winit::event::TouchPhase::Ended => touch::Phase::Ended, - winit::event::TouchPhase::Cancelled => touch::Phase::Canceled, - }; +pub fn touch_event(touch: winit::event::Touch) -> touch::Event { + let id = touch::Finger(touch.id); + let position = Point::new(touch.location.x as f32, touch.location.y as f32); - Touch { - finger: touch::Finger(touch.id), - position: Point::new(touch.location.x as f32, touch.location.y as f32), - phase, + match touch.phase { + winit::event::TouchPhase::Started => { + touch::Event::FingerPressed { id, position } + } + winit::event::TouchPhase::Moved => { + touch::Event::FingerMoved { id, position } + } + winit::event::TouchPhase::Ended => { + touch::Event::FingerLifted { id, position } + } + winit::event::TouchPhase::Cancelled => { + touch::Event::FingerLost { id, position } + } } } @@ -225,7 +231,11 @@ pub fn touch_event(touch: winit::event::Touch) -> Touch { /// /// [`winit`]: https://github.com/rust-windowing/winit /// [`iced_native`]: https://github.com/hecrj/iced/tree/master/native -pub fn key_code(virtual_keycode: winit::event::VirtualKeyCode) -> KeyCode { +pub fn key_code( + virtual_keycode: winit::event::VirtualKeyCode, +) -> keyboard::KeyCode { + use keyboard::KeyCode; + match virtual_keycode { winit::event::VirtualKeyCode::Key1 => KeyCode::Key1, winit::event::VirtualKeyCode::Key2 => KeyCode::Key2, From 056f7e6951f6e96da82f35626b8920f6853bea43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 15 Dec 2020 06:44:00 +0100 Subject: [PATCH 5/7] Change cursor position on touch event --- winit/src/application/state.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/winit/src/application/state.rs b/winit/src/application/state.rs index 58bc7ed6..46297370 100644 --- a/winit/src/application/state.rs +++ b/winit/src/application/state.rs @@ -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`]. @@ -128,7 +128,10 @@ impl State { 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 { .. } => { From 70164f68a6cfca6f7c86cb5cb46e7b2b1f08cf2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 15 Dec 2020 06:48:12 +0100 Subject: [PATCH 6/7] Fix text selection with touch events in `TextInput` --- native/src/widget/text_input.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs index 1e84e22a..2fd9cec1 100644 --- a/native/src/widget/text_input.rs +++ b/native/src/widget/text_input.rs @@ -320,10 +320,13 @@ 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 { position }) => { + 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 = position.x - text_layout.bounds().x; From 277ae74d6817ee6192b5f7a44de19dcbdf8d58f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 15 Dec 2020 06:58:15 +0100 Subject: [PATCH 7/7] Produce logical coordinates for `touch::Event` --- winit/src/conversion.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs index 7a6ab2de..f073c474 100644 --- a/winit/src/conversion.rs +++ b/winit/src/conversion.rs @@ -118,7 +118,9 @@ pub fn window_event( WindowEvent::HoveredFileCancelled => { Some(Event::Window(window::Event::FilesHoveredLeft)) } - WindowEvent::Touch(touch) => Some(Event::Touch(touch_event(*touch))), + WindowEvent::Touch(touch) => { + Some(Event::Touch(touch_event(*touch, scale_factor))) + } _ => None, } } @@ -207,9 +209,16 @@ pub fn cursor_position( /// /// [`winit`]: https://github.com/rust-windowing/winit /// [`iced_native`]: https://github.com/hecrj/iced/tree/master/native -pub fn touch_event(touch: winit::event::Touch) -> touch::Event { +pub fn touch_event( + touch: winit::event::Touch, + scale_factor: f64, +) -> touch::Event { let id = touch::Finger(touch.id); - let position = Point::new(touch.location.x as f32, touch.location.y as f32); + let position = { + let location = touch.location.to_logical::(scale_factor); + + Point::new(location.x as f32, location.y as f32) + }; match touch.phase { winit::event::TouchPhase::Started => {