Add support for double click event to MouseArea (#2602)
* feat(widget/mouse_area): add double_click event * Run `cargo fmt` --------- Co-authored-by: Héctor Ramón Jiménez <hector@hecrj.dev>
This commit is contained in:
parent
3c68b64cbf
commit
75548373a7
1 changed files with 49 additions and 5 deletions
|
|
@ -22,6 +22,7 @@ pub struct MouseArea<
|
||||||
content: Element<'a, Message, Theme, Renderer>,
|
content: Element<'a, Message, Theme, Renderer>,
|
||||||
on_press: Option<Message>,
|
on_press: Option<Message>,
|
||||||
on_release: Option<Message>,
|
on_release: Option<Message>,
|
||||||
|
on_double_click: Option<Message>,
|
||||||
on_right_press: Option<Message>,
|
on_right_press: Option<Message>,
|
||||||
on_right_release: Option<Message>,
|
on_right_release: Option<Message>,
|
||||||
on_middle_press: Option<Message>,
|
on_middle_press: Option<Message>,
|
||||||
|
|
@ -48,6 +49,22 @@ impl<'a, Message, Theme, Renderer> MouseArea<'a, Message, Theme, Renderer> {
|
||||||
self
|
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.
|
/// The message to emit on a right button press.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn on_right_press(mut self, message: Message) -> Self {
|
pub fn on_right_press(mut self, message: Message) -> Self {
|
||||||
|
|
@ -121,6 +138,7 @@ struct State {
|
||||||
is_hovered: bool,
|
is_hovered: bool,
|
||||||
bounds: Rectangle,
|
bounds: Rectangle,
|
||||||
cursor_position: Option<Point>,
|
cursor_position: Option<Point>,
|
||||||
|
previous_click: Option<mouse::Click>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Message, Theme, Renderer> MouseArea<'a, Message, Theme, Renderer> {
|
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(),
|
content: content.into(),
|
||||||
on_press: None,
|
on_press: None,
|
||||||
on_release: None,
|
on_release: None,
|
||||||
|
on_double_click: None,
|
||||||
on_right_press: None,
|
on_right_press: None,
|
||||||
on_right_release: None,
|
on_right_release: None,
|
||||||
on_middle_press: None,
|
on_middle_press: None,
|
||||||
|
|
@ -347,12 +366,37 @@ fn update<Message: Clone, Theme, Renderer>(
|
||||||
return event::Status::Ignored;
|
return event::Status::Ignored;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(message) = widget.on_press.as_ref() {
|
if let Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
|
||||||
if let Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
|
| Event::Touch(touch::Event::FingerPressed { .. }) = event
|
||||||
| Event::Touch(touch::Event::FingerPressed { .. }) = event
|
{
|
||||||
{
|
let mut captured = false;
|
||||||
shell.publish(message.clone());
|
|
||||||
|
|
||||||
|
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;
|
return event::Status::Captured;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue