diff options
Diffstat (limited to 'widget/src/mouse_area.rs')
-rw-r--r-- | widget/src/mouse_area.rs | 52 |
1 files 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<Message>, on_release: Option<Message>, + on_double_click: Option<Message>, on_right_press: Option<Message>, on_right_release: Option<Message>, on_middle_press: Option<Message>, @@ -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<Point>, + previous_click: Option<mouse::Click>, } 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<Message: Clone, Theme, Renderer>( 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; } } |