diff options
Diffstat (limited to '')
| -rw-r--r-- | native/src/event.rs | 8 | ||||
| -rw-r--r-- | native/src/lib.rs | 1 | ||||
| -rw-r--r-- | native/src/touch.rs | 35 | ||||
| -rw-r--r-- | native/src/widget/button.rs | 19 | ||||
| -rw-r--r-- | native/src/widget/checkbox.rs | 7 | ||||
| -rw-r--r-- | native/src/widget/radio.rs | 7 | ||||
| -rw-r--r-- | native/src/widget/scrollable.rs | 49 | ||||
| -rw-r--r-- | native/src/widget/slider.rs | 58 | ||||
| -rw-r--r-- | native/src/widget/text_input.rs | 11 | 
9 files changed, 160 insertions, 35 deletions
| diff --git a/native/src/event.rs b/native/src/event.rs index 0e86171e..f3c260c0 100644 --- a/native/src/event.rs +++ b/native/src/event.rs @@ -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.  /// @@ -17,6 +20,9 @@ pub enum Event {      /// A window event      Window(window::Event), + +    /// A touch event +    Touch(touch::Touch),  }  /// The status of an [`Event`] after being processed. diff --git a/native/src/lib.rs b/native/src/lib.rs index f9a99c48..0890785b 100644 --- a/native/src/lib.rs +++ b/native/src/lib.rs @@ -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; diff --git a/native/src/touch.rs b/native/src/touch.rs new file mode 100644 index 00000000..88bd83bb --- /dev/null +++ b/native/src/touch.rs @@ -0,0 +1,35 @@ +//! 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, +} diff --git a/native/src/widget/button.rs b/native/src/widget/button.rs index dca20e13..7d5eb30c 100644 --- a/native/src/widget/button.rs +++ b/native/src/widget/button.rs @@ -4,6 +4,7 @@  use crate::event::{self, Event};  use crate::layout;  use crate::mouse; +use crate::touch::{self, Touch};  use crate::{      Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Widget,  }; @@ -164,7 +165,11 @@ 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 { +                phase: touch::Phase::Started, +                .. +            }) => {                  if self.on_press.is_some() {                      let bounds = layout.bounds(); @@ -175,7 +180,11 @@ where                      }                  }              } -            Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) => { +            Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) +            | Event::Touch(Touch { +                phase: touch::Phase::Ended, +                .. +            }) => {                  if let Some(on_press) = self.on_press.clone() {                      let bounds = layout.bounds(); @@ -190,6 +199,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 81420458..92175b25 100644 --- a/native/src/widget/checkbox.rs +++ b/native/src/widget/checkbox.rs @@ -6,6 +6,7 @@ use crate::layout;  use crate::mouse;  use crate::row;  use crate::text; +use crate::touch::{self, Touch};  use crate::{      Align, Clipboard, Element, Hasher, HorizontalAlignment, Layout, Length,      Point, Rectangle, Row, Text, VerticalAlignment, Widget, @@ -154,7 +155,11 @@ 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 { +                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 4935569f..3a1dd386 100644 --- a/native/src/widget/radio.rs +++ b/native/src/widget/radio.rs @@ -4,6 +4,7 @@ use crate::layout;  use crate::mouse;  use crate::row;  use crate::text; +use crate::touch::{self, Touch};  use crate::{      Align, Clipboard, Element, Hasher, HorizontalAlignment, Layout, Length,      Point, Rectangle, Row, Text, VerticalAlignment, Widget, @@ -160,7 +161,11 @@ 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 { +                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 e23ab06a..8c321ee5 100644 --- a/native/src/widget/scrollable.rs +++ b/native/src/widget/scrollable.rs @@ -4,6 +4,7 @@ use crate::event::{self, Event};  use crate::layout;  use crate::mouse;  use crate::overlay; +use crate::touch::{self, Touch};  use crate::{      Align, Clipboard, Column, Element, Hasher, Layout, Length, Point,      Rectangle, Size, Vector, Widget, @@ -229,6 +230,26 @@ 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); +                            self.state.scroll_box_touched_at = +                                Some(cursor_position); +                        } +                    } +                    touch::Phase::Ended | touch::Phase::Canceled => { +                        self.state.scroll_box_touched_at = None; +                    } +                },                  _ => {}              }          } @@ -237,12 +258,24 @@ where              match event {                  Event::Mouse(mouse::Event::ButtonReleased(                      mouse::Button::Left, -                )) => { +                )) +                | Event::Touch(Touch { +                    phase: touch::Phase::Ended, +                    .. +                }) +                | Event::Touch(Touch { +                    phase: touch::Phase::Canceled, +                    .. +                }) => {                      self.state.scroller_grabbed_at = None;                      return event::Status::Captured;                  } -                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)                      { @@ -264,7 +297,11 @@ where              match event {                  Event::Mouse(mouse::Event::ButtonPressed(                      mouse::Button::Left, -                )) => { +                )) +                | Event::Touch(Touch { +                    phase: touch::Phase::Started, +                    .. +                }) => {                      if let Some(scrollbar) = scrollbar {                          if let Some(scroller_grabbed_at) =                              scrollbar.grab_scroller(cursor_position) @@ -385,6 +422,7 @@ where  #[derive(Debug, Clone, Copy, Default)]  pub struct State {      scroller_grabbed_at: Option<f32>, +    scroll_box_touched_at: Option<Point>,      offset: f32,  } @@ -439,6 +477,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 ff39b816..755e6b2b 100644 --- a/native/src/widget/slider.rs +++ b/native/src/widget/slider.rs @@ -4,6 +4,7 @@  use crate::event::{self, Event};  use crate::layout;  use crate::mouse; +use crate::touch::{self, Touch};  use crate::{      Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Size, Widget,  }; @@ -207,34 +208,43 @@ 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; - -                        return event::Status::Captured; -                    } +            Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) +            | Event::Touch(Touch { +                phase: touch::Phase::Started, +                .. +            }) => { +                if layout.bounds().contains(cursor_position) { +                    change(); +                    self.state.is_dragging = true; + +                    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 { +                phase: touch::Phase::Ended, +                .. +            }) => { +                if self.state.is_dragging { +                    if let Some(on_release) = self.on_release.clone() { +                        messages.push(on_release);                      } -                } -                mouse::Event::CursorMoved { .. } => { -                    if self.state.is_dragging { -                        change(); +                    self.state.is_dragging = false; -                        return event::Status::Captured; -                    } +                    return event::Status::Captured; +                } +            } +            Event::Mouse(mouse::Event::CursorMoved { .. }) +            | Event::Touch(Touch { +                phase: touch::Phase::Moved, +                .. +            }) => { +                if self.state.is_dragging { +                    change(); + +                    return event::Status::Captured;                  } -                _ => {} -            }, +            }              _ => {}          } diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs index 3e637e97..ca71c20c 100644 --- a/native/src/widget/text_input.rs +++ b/native/src/widget/text_input.rs @@ -16,6 +16,7 @@ use crate::keyboard;  use crate::layout;  use crate::mouse::{self, click};  use crate::text; +use crate::touch::{self, Touch};  use crate::{      Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Size, Widget,  }; @@ -247,7 +248,11 @@ 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 { +                phase: touch::Phase::Started, +                .. +            }) => {                  let is_clicked = layout.bounds().contains(cursor_position);                  self.state.is_focused = is_clicked; @@ -321,10 +326,10 @@ where              Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) => {                  self.state.is_dragging = false;              } -            Event::Mouse(mouse::Event::CursorMoved { x, .. }) => { +            Event::Mouse(mouse::Event::CursorMoved { 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 { | 
