From 75548373a761d66df364494267c89697dda91fbe Mon Sep 17 00:00:00 2001 From: 7sDream Date: Wed, 25 Sep 2024 05:05:17 +0800 Subject: Add support for double click event to MouseArea (#2602) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(widget/mouse_area): add double_click event * Run `cargo fmt` --------- Co-authored-by: Héctor Ramón Jiménez --- widget/src/mouse_area.rs | 52 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/widget/src/mouse_area.rs b/widget/src/mouse_area.rs index 7330874a..c5a37ae3 100644 --- a/widget/src/mouse_area.rs +++ b/widget/src/mouse_area.rs @@ -22,6 +22,7 @@ pub struct MouseArea< content: Element<'a, Message, Theme, Renderer>, on_press: Option, on_release: Option, + on_double_click: Option, on_right_press: Option, on_right_release: Option, on_middle_press: Option, @@ -48,6 +49,22 @@ impl<'a, Message, Theme, Renderer> MouseArea<'a, Message, Theme, Renderer> { self } + /// The message to emit on a double click. + /// + /// If you use this with [`on_press`]/[`on_release`], those + /// event will be emit as normal. + /// + /// The events stream will be: on_press -> on_release -> on_press + /// -> on_double_click -> on_release -> on_press ... + /// + /// [`on_press`]: Self::on_press + /// [`on_release`]: Self::on_release + #[must_use] + pub fn on_double_click(mut self, message: Message) -> Self { + self.on_double_click = Some(message); + self + } + /// The message to emit on a right button press. #[must_use] pub fn on_right_press(mut self, message: Message) -> Self { @@ -121,6 +138,7 @@ struct State { is_hovered: bool, bounds: Rectangle, cursor_position: Option, + previous_click: Option, } impl<'a, Message, Theme, Renderer> MouseArea<'a, Message, Theme, Renderer> { @@ -132,6 +150,7 @@ impl<'a, Message, Theme, Renderer> MouseArea<'a, Message, Theme, Renderer> { content: content.into(), on_press: None, on_release: None, + on_double_click: None, on_right_press: None, on_right_release: None, on_middle_press: None, @@ -347,12 +366,37 @@ fn update( return event::Status::Ignored; } - if let Some(message) = widget.on_press.as_ref() { - if let Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) - | Event::Touch(touch::Event::FingerPressed { .. }) = event - { + if let Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) + | Event::Touch(touch::Event::FingerPressed { .. }) = event + { + let mut captured = false; + + if let Some(message) = widget.on_press.as_ref() { + captured = true; shell.publish(message.clone()); + } + + if let Some(position) = cursor_position { + if let Some(message) = widget.on_double_click.as_ref() { + let new_click = mouse::Click::new( + position, + mouse::Button::Left, + state.previous_click, + ); + + if matches!(new_click.kind(), mouse::click::Kind::Double) { + shell.publish(message.clone()); + } + + state.previous_click = Some(new_click); + + // Even if this is not a double click, but the press is nevertheless + // processed by us and should not be popup to parent widgets. + captured = true; + } + } + if captured { return event::Status::Captured; } } -- cgit