1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//! Flutter counterpart: `services/mouse_tracking.dart`.
use std::fmt;
use inset_gestures::{PointerEnterEventListener, PointerExitEventListener};
use crate::mouse_cursor::{MouseCursor, MouseCursorRef};
/// The annotation object used to annotate regions that are interested in mouse
/// movements.
///
/// To use an annotation, return this object as a `HitTestTarget` in a hit test.
/// Typically this is done using a `RenderMouseRegion`.
///
/// The `MouseTracker` uses this class as a label to filter the hit test results.
/// Only hit test targets that have this annotation as their target will receive
/// mouse events.
///
/// Dart's constructor takes named optional arguments; write
/// `MouseTrackerAnnotation { on_enter: Some(..), ..Default::default() }`.
pub struct MouseTrackerAnnotation {
/// Triggered when a mouse pointer, with or without buttons pressed, has
/// entered the region and `valid_for_mouse_tracker` is true.
///
/// This callback is triggered when the pointer has started to be contained by
/// the region, either due to a pointer event, or due to the movement or
/// disappearance of the region. This method is always matched by a later
/// `on_exit`.
pub on_enter: Option<PointerEnterEventListener>,
/// Triggered when a mouse pointer, with or without buttons pressed, has
/// exited the region and `valid_for_mouse_tracker` is true.
///
/// This callback is triggered when the pointer has stopped being contained
/// by the region, either due to a pointer event, or due to the movement or
/// disappearance of the region. This method always matches an earlier
/// `on_enter`.
pub on_exit: Option<PointerExitEventListener>,
/// The mouse cursor for mouse pointers that are hovering over the region.
///
/// When a mouse enters the region, its cursor will be changed to the `cursor`.
/// When the mouse leaves the region, the cursor will be set by the region
/// found at the new location.
///
/// Defaults to `MouseCursor.defer`, deferring the choice of cursor to the next
/// region behind it in hit-test order.
pub cursor: MouseCursorRef,
/// Whether this is included when a `MouseTracker` collects the list of
/// annotations.
///
/// If [`valid_for_mouse_tracker`](Self::valid_for_mouse_tracker) is false, this
/// object is excluded from the current annotation list even if it's included
/// in the hit test, affecting mouse-related behavior such as enter events,
/// exit events, and mouse cursors. The [`valid_for_mouse_tracker`] does not
/// affect hit testing.
///
/// Defaults to true.
///
/// [`valid_for_mouse_tracker`]: Self::valid_for_mouse_tracker
pub valid_for_mouse_tracker: bool,
}
impl Default for MouseTrackerAnnotation {
fn default() -> MouseTrackerAnnotation {
MouseTrackerAnnotation {
on_enter: None,
on_exit: None,
cursor: <dyn MouseCursor>::defer(),
valid_for_mouse_tracker: true,
}
}
}
impl fmt::Debug for MouseTrackerAnnotation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut callbacks = Vec::new();
if self.on_enter.is_some() {
callbacks.push("enter");
}
if self.on_exit.is_some() {
callbacks.push("exit");
}
f.debug_struct("MouseTrackerAnnotation")
.field("callbacks", &callbacks)
.field("cursor", &self.cursor.debug_description())
.field("valid_for_mouse_tracker", &self.valid_for_mouse_tracker)
.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_defers_the_cursor_and_is_valid() {
let annotation = MouseTrackerAnnotation::default();
assert!(annotation.on_enter.is_none());
assert!(annotation.on_exit.is_none());
assert!(*annotation.cursor == *<dyn MouseCursor>::defer());
assert!(annotation.valid_for_mouse_tracker);
}
}