Skip to content

Commit 8ea85f3

Browse files
committed
Use Fn instead of FnMut in MouseArea
... and simplify event logic a bit.
1 parent bd13c58 commit 8ea85f3

1 file changed

Lines changed: 31 additions & 39 deletions

File tree

widget/src/mouse_area.rs

Lines changed: 31 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub struct MouseArea<
2929
on_middle_press: Option<Message>,
3030
on_middle_release: Option<Message>,
3131
on_mouse_enter: Option<Message>,
32-
on_mouse_move: Option<Box<dyn FnMut(Point) -> Message>>,
32+
on_mouse_move: Option<Box<dyn Fn(Point) -> Message>>,
3333
on_mouse_exit: Option<Message>,
3434
}
3535

@@ -87,7 +87,7 @@ impl<'a, Message, Theme, Renderer> MouseArea<'a, Message, Theme, Renderer> {
8787
#[must_use]
8888
pub fn on_mouse_move<F>(mut self, build_message: F) -> Self
8989
where
90-
F: FnMut(Point) -> Message + 'static,
90+
F: Fn(Point) -> Message + 'static,
9191
{
9292
self.on_mouse_move = Some(Box::new(build_message));
9393
self
@@ -104,7 +104,7 @@ impl<'a, Message, Theme, Renderer> MouseArea<'a, Message, Theme, Renderer> {
104104
/// Local state of the [`MouseArea`].
105105
#[derive(Default)]
106106
struct State {
107-
mouse_in_area: bool,
107+
is_hovered: bool,
108108
}
109109

110110
impl<'a, Message, Theme, Renderer> MouseArea<'a, Message, Theme, Renderer> {
@@ -203,7 +203,7 @@ where
203203
return event::Status::Captured;
204204
}
205205

206-
update(self, tree, &event, layout, cursor, shell)
206+
update(self, tree, event, layout, cursor, shell)
207207
}
208208

209209
fn mouse_interaction(
@@ -279,16 +279,39 @@ where
279279
fn update<Message: Clone, Theme, Renderer>(
280280
widget: &mut MouseArea<'_, Message, Theme, Renderer>,
281281
tree: &mut Tree,
282-
event: &Event,
282+
event: Event,
283283
layout: Layout<'_>,
284284
cursor: mouse::Cursor,
285285
shell: &mut Shell<'_, Message>,
286286
) -> event::Status {
287-
if let Event::Mouse(mouse::Event::CursorMoved { position })
288-
| Event::Touch(touch::Event::FingerMoved { id: _, position }) = event
287+
if let Event::Mouse(mouse::Event::CursorMoved { .. })
288+
| Event::Touch(touch::Event::FingerMoved { .. }) = event
289289
{
290290
let state: &mut State = tree.state.downcast_mut();
291-
handle_mouse_move(widget, state, shell, *position, layout.bounds());
291+
292+
let was_hovered = state.is_hovered;
293+
state.is_hovered = cursor.is_over(layout.bounds());
294+
295+
match (
296+
widget.on_mouse_enter.as_ref(),
297+
widget.on_mouse_move.as_ref(),
298+
widget.on_mouse_exit.as_ref(),
299+
) {
300+
(Some(on_mouse_enter), _, _)
301+
if state.is_hovered && !was_hovered =>
302+
{
303+
shell.publish(on_mouse_enter.clone());
304+
}
305+
(_, Some(on_mouse_move), _) if state.is_hovered => {
306+
if let Some(position) = cursor.position_in(layout.bounds()) {
307+
shell.publish(on_mouse_move(position));
308+
}
309+
}
310+
(_, _, Some(on_mouse_exit)) if !state.is_hovered && was_hovered => {
311+
shell.publish(on_mouse_exit.clone());
312+
}
313+
_ => {}
314+
}
292315
}
293316

294317
if !cursor.is_over(layout.bounds()) {
@@ -360,34 +383,3 @@ fn update<Message: Clone, Theme, Renderer>(
360383

361384
event::Status::Ignored
362385
}
363-
364-
fn handle_mouse_move<Message: Clone, Theme, Renderer>(
365-
widget: &mut MouseArea<'_, Message, Theme, Renderer>,
366-
state: &mut State,
367-
shell: &mut Shell<'_, Message>,
368-
position: Point,
369-
area_bounds: Rectangle,
370-
) {
371-
let mouse_in_area = area_bounds.contains(position);
372-
373-
match (
374-
widget.on_mouse_enter.as_mut(),
375-
widget.on_mouse_move.as_mut(),
376-
widget.on_mouse_exit.as_mut(),
377-
) {
378-
(Some(enter_msg), _, _) if mouse_in_area && !state.mouse_in_area => {
379-
shell.publish(enter_msg.clone());
380-
}
381-
(_, Some(build_move_msg), _)
382-
if mouse_in_area && state.mouse_in_area =>
383-
{
384-
shell.publish(build_move_msg(position));
385-
}
386-
(_, _, Some(exit_msg)) if !mouse_in_area && state.mouse_in_area => {
387-
shell.publish(exit_msg.clone());
388-
}
389-
_ => {}
390-
}
391-
392-
state.mouse_in_area = mouse_in_area;
393-
}

0 commit comments

Comments
 (0)