diff --git a/native/src/widget/button.rs b/native/src/widget/button.rs index c469a0e5..8939e3c5 100644 --- a/native/src/widget/button.rs +++ b/native/src/widget/button.rs @@ -6,10 +6,12 @@ use crate::layout; use crate::mouse; use crate::overlay; use crate::touch; +use crate::touch::Finger; use crate::{ Clipboard, Element, Hasher, Layout, Length, Padding, Point, Rectangle, Widget, }; +use std::collections::HashSet; use std::hash::Hash; /// A generic widget that produces a message when pressed. @@ -63,6 +65,7 @@ pub struct Button<'a, Message, Renderer: self::Renderer> { min_height: u32, padding: Padding, style: Renderer::Style, + fingers_mid_press: HashSet, } impl<'a, Message, Renderer> Button<'a, Message, Renderer> @@ -86,6 +89,8 @@ where min_height: 0, padding: Renderer::DEFAULT_PADDING, style: Renderer::Style::default(), + + fingers_mid_press: HashSet::with_capacity(2), } } @@ -204,8 +209,7 @@ where } match event { - Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) - | Event::Touch(touch::Event::FingerPressed { .. }) => { + Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => { if self.on_press.is_some() { let bounds = layout.bounds(); @@ -216,8 +220,7 @@ where } } } - Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) - | Event::Touch(touch::Event::FingerLifted { .. }) => { + Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) => { if let Some(on_press) = self.on_press.clone() { let bounds = layout.bounds(); @@ -232,8 +235,38 @@ where } } } - Event::Touch(touch::Event::FingerLost { .. }) => { - self.state.is_pressed = false; + Event::Touch(x) => { + match x { + touch::Event::FingerPressed { id, position } => { + if layout.bounds().contains(position) { + let _ = self.fingers_mid_press.insert(id); + + return event::Status::Captured; + } + } + touch::Event::FingerMoved { id, position } => { + if !layout.bounds().contains(position) { + let _ = self.fingers_mid_press.remove(&id); + + return event::Status::Captured; + } + } + touch::Event::FingerLifted { id, position } => { + if self.fingers_mid_press.remove(&id) + && layout.bounds().contains(position) + { + // this should be treated as a click + if let Some(on_press) = self.on_press.clone() { + messages.push(on_press); + } + + return event::Status::Captured; + } + } + touch::Event::FingerLost { id, .. } => { + let _ = self.fingers_mid_press.remove(&id); + } + } } _ => {} } diff --git a/native/src/widget/toggler.rs b/native/src/widget/toggler.rs index 022a2ca6..17405219 100644 --- a/native/src/widget/toggler.rs +++ b/native/src/widget/toggler.rs @@ -181,8 +181,6 @@ where } } Event::Touch(x) => { - eprintln!("{:?}", x); - match x { touch::Event::FingerPressed { id, position } => { if layout.bounds().contains(position) {