zng_wgt_input/
mouse.rs

1//! Mouse events, [`on_mouse_move`](fn@on_mouse_move), [`on_mouse_enter`](fn@on_mouse_enter),
2//! [`on_mouse_down`](fn@on_mouse_down) and more.
3//!
4//! There events are low level and directly tied to a mouse device.
5//! Before using them review the [`gesture`](super::gesture) events, in particular the
6//! [`on_click`](fn@super::gesture::on_click) event.
7
8use zng_ext_input::mouse::{
9    CTRL_SCROLL_VAR, MOUSE_CLICK_EVENT, MOUSE_HOVERED_EVENT, MOUSE_INPUT_EVENT, MOUSE_MOVE_EVENT, MOUSE_WHEEL_EVENT, MouseClickArgs,
10    MouseHoverArgs, MouseInputArgs, MouseMoveArgs, MouseWheelArgs,
11};
12use zng_wgt::prelude::*;
13
14event_property! {
15    /// Mouse cursor moved over the widget and cursor capture allows it.
16    #[property(EVENT)]
17    pub fn on_mouse_move<on_pre_mouse_move>(child: impl IntoUiNode, handler: Handler<MouseMoveArgs>) -> UiNode {
18        const PRE: bool;
19        EventNodeBuilder::new(MOUSE_MOVE_EVENT)
20            .filter(|| {
21                let wgt = (WINDOW.id(), WIDGET.id());
22                move |args| args.capture_allows(wgt)
23            })
24            .build::<PRE>(child, handler)
25    }
26
27    /// Mouse button pressed or released while the cursor is over the widget, the widget is enabled and no cursor
28    /// capture blocks it.
29    #[property(EVENT)]
30    pub fn on_mouse_input<on_pre_mouse_input>(child: impl IntoUiNode, handler: Handler<MouseInputArgs>) -> UiNode {
31        const PRE: bool;
32        EventNodeBuilder::new(MOUSE_INPUT_EVENT)
33            .filter(|| {
34                let wgt = (WINDOW.id(), WIDGET.id());
35                move |args| args.target.contains_enabled(wgt.1) && args.capture_allows(wgt)
36            })
37            .build::<PRE>(child, handler)
38    }
39
40    /// Mouse button pressed or release while the cursor is over the widget, the widget is disabled and no cursor
41    /// capture blocks it.
42    #[property(EVENT)]
43    pub fn on_disabled_mouse_input<on_pre_disabled_mouse_input>(child: impl IntoUiNode, handler: Handler<MouseInputArgs>) -> UiNode {
44        const PRE: bool;
45        EventNodeBuilder::new(MOUSE_INPUT_EVENT)
46            .filter(|| {
47                let wgt = (WINDOW.id(), WIDGET.id());
48                move |args| args.target.contains_disabled(wgt.1) && args.capture_allows(wgt)
49            })
50            .build::<PRE>(child, handler)
51    }
52
53    /// Mouse button pressed while the cursor is over the widget, the widget is enabled and cursor capture allows it.
54    #[property(EVENT)]
55    pub fn on_mouse_down<on_pre_mouse_down>(child: impl IntoUiNode, handler: Handler<MouseInputArgs>) -> UiNode {
56        const PRE: bool;
57        EventNodeBuilder::new(MOUSE_INPUT_EVENT)
58            .filter(|| {
59                let wgt = (WINDOW.id(), WIDGET.id());
60                move |args| args.is_mouse_down() && args.target.contains_enabled(wgt.1) && args.capture_allows(wgt)
61            })
62            .build::<PRE>(child, handler)
63    }
64
65    /// Mouse button released while the cursor if over the widget, the widget is enabled and cursor capture allows it.
66    #[property(EVENT)]
67    pub fn on_mouse_up<on_pre_mouse_up>(child: impl IntoUiNode, handler: Handler<MouseInputArgs>) -> UiNode {
68        const PRE: bool;
69        EventNodeBuilder::new(MOUSE_INPUT_EVENT)
70            .filter(|| {
71                let wgt = (WINDOW.id(), WIDGET.id());
72                move |args| args.is_mouse_up() && args.target.contains_enabled(wgt.1) && args.capture_allows(wgt)
73            })
74            .build::<PRE>(child, handler)
75    }
76
77    /// Mouse clicked on the widget with any button and including repeat clicks and it is enabled.
78    #[property(EVENT)]
79    pub fn on_mouse_any_click<on_pre_mouse_any_click>(child: impl IntoUiNode, handler: Handler<MouseClickArgs>) -> UiNode {
80        const PRE: bool;
81        EventNodeBuilder::new(MOUSE_CLICK_EVENT)
82            .filter(|| {
83                let id = WIDGET.id();
84                move |args| args.target.contains_enabled(id)
85            })
86            .build::<PRE>(child, handler)
87    }
88
89    /// Mouse clicked on the disabled widget with any button, including repeat clicks.
90    #[property(EVENT)]
91    pub fn on_disabled_mouse_any_click<on_pre_disabled_mouse_any_click>(
92        child: impl IntoUiNode,
93        handler: Handler<MouseClickArgs>,
94    ) -> UiNode {
95        const PRE: bool;
96        EventNodeBuilder::new(MOUSE_CLICK_EVENT)
97            .filter(|| {
98                let id = WIDGET.id();
99                move |args| args.target.contains_disabled(id)
100            })
101            .build::<PRE>(child, handler)
102    }
103
104    /// Mouse clicked on the widget with any button but excluding repeat clicks and it is enabled.
105    #[property(EVENT)]
106    pub fn on_mouse_any_single_click<on_pre_mouse_any_single_click>(
107        child: impl IntoUiNode,
108        handler: Handler<MouseClickArgs>,
109    ) -> UiNode {
110        const PRE: bool;
111        EventNodeBuilder::new(MOUSE_CLICK_EVENT)
112            .filter(|| {
113                let id = WIDGET.id();
114                move |args| args.is_single() && args.target.contains_enabled(id)
115            })
116            .build::<PRE>(child, handler)
117    }
118
119    /// Mouse double clicked on the widget with any button and it is enabled.
120    #[property(EVENT)]
121    pub fn on_mouse_any_double_click<on_pre_mouse_any_double_click>(
122        child: impl IntoUiNode,
123        handler: Handler<MouseClickArgs>,
124    ) -> UiNode {
125        const PRE: bool;
126        EventNodeBuilder::new(MOUSE_CLICK_EVENT)
127            .filter(|| {
128                let id = WIDGET.id();
129                move |args| args.is_double() && args.target.contains_enabled(id)
130            })
131            .build::<PRE>(child, handler)
132    }
133
134    /// Mouse triple clicked on the widget with any button and it is enabled.
135    #[property(EVENT)]
136    pub fn on_mouse_any_triple_click<on_pre_mouse_any_triple_click>(
137        child: impl IntoUiNode,
138        handler: Handler<MouseClickArgs>,
139    ) -> UiNode {
140        const PRE: bool;
141        EventNodeBuilder::new(MOUSE_CLICK_EVENT)
142            .filter(|| {
143                let id = WIDGET.id();
144                move |args| args.is_triple() && args.target.contains_enabled(id)
145            })
146            .build::<PRE>(child, handler)
147    }
148
149    /// Mouse clicked on the widget with the primary button including repeat clicks and it is enabled.
150    #[property(EVENT)]
151    pub fn on_mouse_click<on_pre_mouse_click>(child: impl IntoUiNode, handler: Handler<MouseClickArgs>) -> UiNode {
152        const PRE: bool;
153        EventNodeBuilder::new(MOUSE_CLICK_EVENT)
154            .filter(|| {
155                let id = WIDGET.id();
156                move |args| args.is_primary() && args.target.contains_enabled(id)
157            })
158            .build::<PRE>(child, handler)
159    }
160
161    /// Mouse clicked on the disabled widget with the primary button, including repeat clicks.
162    #[property(EVENT)]
163    pub fn on_disabled_mouse_click<on_pre_disabled_mouse_click>(child: impl IntoUiNode, handler: Handler<MouseClickArgs>) -> UiNode {
164        const PRE: bool;
165        EventNodeBuilder::new(MOUSE_CLICK_EVENT)
166            .filter(|| {
167                let id = WIDGET.id();
168                move |args| args.is_primary() && args.target.contains_disabled(id)
169            })
170            .build::<PRE>(child, handler)
171    }
172
173    /// Mouse clicked on the widget with the primary button excluding repeat clicks and it is enabled.
174    #[property(EVENT)]
175    pub fn on_mouse_single_click<on_pre_mouse_single_click>(child: impl IntoUiNode, handler: Handler<MouseClickArgs>) -> UiNode {
176        const PRE: bool;
177        EventNodeBuilder::new(MOUSE_CLICK_EVENT)
178            .filter(|| {
179                let id = WIDGET.id();
180                move |args| args.is_primary() && args.is_single() && args.target.contains_enabled(id)
181            })
182            .build::<PRE>(child, handler)
183    }
184
185    /// Mouse double clicked on the widget with the primary button and it is enabled.
186    #[property(EVENT)]
187    pub fn on_mouse_double_click<on_pre_mouse_double_click>(child: impl IntoUiNode, handler: Handler<MouseClickArgs>) -> UiNode {
188        const PRE: bool;
189        EventNodeBuilder::new(MOUSE_CLICK_EVENT)
190            .filter(|| {
191                let id = WIDGET.id();
192                move |args| args.is_primary() && args.is_double() && args.target.contains_enabled(id)
193            })
194            .build::<PRE>(child, handler)
195    }
196
197    /// Mouse triple clicked on the widget with the primary button and it is enabled.
198    #[property(EVENT)]
199    pub fn on_mouse_triple_click<on_pre_mouse_triple_click>(child: impl IntoUiNode, handler: Handler<MouseClickArgs>) -> UiNode {
200        const PRE: bool;
201        EventNodeBuilder::new(MOUSE_CLICK_EVENT)
202            .filter(|| {
203                let id = WIDGET.id();
204                move |args| args.is_primary() && args.is_triple() && args.target.contains_enabled(id)
205            })
206            .build::<PRE>(child, handler)
207    }
208
209    /// Mouse is now over the widget or a descendant widget, the widget is enabled and cursor capture allows it.
210    #[property(EVENT)]
211    pub fn on_mouse_enter<on_pre_mouse_enter>(child: impl IntoUiNode, handler: Handler<MouseHoverArgs>) -> UiNode {
212        const PRE: bool;
213        EventNodeBuilder::new(MOUSE_HOVERED_EVENT)
214            .filter(|| {
215                let wgt = (WINDOW.id(), WIDGET.id());
216                move |args| args.is_mouse_enter_enabled(wgt)
217            })
218            .build::<PRE>(child, handler)
219    }
220
221    /// Mouse is no longer over the widget or any descendant widget, the widget is enabled and cursor capture allows it.
222    #[property(EVENT)]
223    pub fn on_mouse_leave<on_pre_mouse_leave>(child: impl IntoUiNode, handler: Handler<MouseHoverArgs>) -> UiNode {
224        const PRE: bool;
225        EventNodeBuilder::new(MOUSE_HOVERED_EVENT)
226            .filter(|| {
227                let wgt = (WINDOW.id(), WIDGET.id());
228                move |args| args.is_mouse_leave_enabled(wgt)
229            })
230            .build::<PRE>(child, handler)
231    }
232
233    /// Mouse entered or left the widget and descendant widgets area, the widget is enabled and cursor capture allows it.
234    ///
235    /// You can use the [`is_mouse_enter`] and [`is_mouse_leave`] methods to determinate the state change.
236    ///
237    /// [`is_mouse_enter`]: MouseHoverArgs::is_mouse_enter
238    /// [`is_mouse_leave`]: MouseHoverArgs::is_mouse_leave
239    #[property(EVENT)]
240    pub fn on_mouse_hovered<on_pre_mouse_hovered>(child: impl IntoUiNode, handler: Handler<MouseHoverArgs>) -> UiNode {
241        const PRE: bool;
242        EventNodeBuilder::new(MOUSE_HOVERED_EVENT)
243            .filter(|| {
244                let wgt = (WINDOW.id(), WIDGET.id());
245                move |args| args.is_enabled(wgt.1) && args.capture_allows(wgt)
246            })
247            .build::<PRE>(child, handler)
248    }
249
250    /// Mouse entered or left the widget and descendant widgets area, the widget is disabled and cursor capture allows it.
251    #[property(EVENT)]
252    pub fn on_disabled_mouse_hovered<on_pre_disabled_mouse_hovered>(
253        child: impl IntoUiNode,
254        handler: Handler<MouseHoverArgs>,
255    ) -> UiNode {
256        const PRE: bool;
257        EventNodeBuilder::new(MOUSE_HOVERED_EVENT)
258            .filter(|| {
259                let wgt = (WINDOW.id(), WIDGET.id());
260                move |args| args.is_disabled(wgt.1) && args.capture_allows(wgt)
261            })
262            .build::<PRE>(child, handler)
263    }
264
265    /// Mouse wheel scrolled while pointer is hovering widget and it is enabled.
266    #[property(EVENT)]
267    pub fn on_mouse_wheel<on_pre_mouse_wheel>(child: impl IntoUiNode, handler: Handler<MouseWheelArgs>) -> UiNode {
268        const PRE: bool;
269        EventNodeBuilder::new(MOUSE_WHEEL_EVENT)
270            .filter(|| {
271                let id = WIDGET.id();
272                move |args| args.target.contains_enabled(id)
273            })
274            .build::<PRE>(child, handler)
275    }
276
277    /// Mouse wheel scrolled while pointer is hovering widget and it is disabled.
278    #[property(EVENT)]
279    pub fn on_disabled_mouse_wheel<on_pre_disabled_mouse_wheel>(child: impl IntoUiNode, handler: Handler<MouseWheelArgs>) -> UiNode {
280        const PRE: bool;
281        EventNodeBuilder::new(MOUSE_WHEEL_EVENT)
282            .filter(|| {
283                let id = WIDGET.id();
284                move |args| args.target.contains_enabled(id)
285            })
286            .build::<PRE>(child, handler)
287    }
288
289    /// Mouse wheel scrolled while pointer is hovering the widget and the pressed keyboard modifiers allow a scroll operation and
290    /// the widget is enabled.
291    #[property(EVENT)]
292    pub fn on_mouse_scroll<on_pre_mouse_scroll>(child: impl IntoUiNode, handler: Handler<MouseWheelArgs>) -> UiNode {
293        const PRE: bool;
294        EventNodeBuilder::new(MOUSE_WHEEL_EVENT)
295            .filter(|| {
296                let id = WIDGET.id();
297                move |args| args.is_scroll() && args.target.contains_enabled(id)
298            })
299            .build::<PRE>(child, handler)
300    }
301
302    /// Mouse wheel scrolled while pointer is hovering the widget and the pressed keyboard modifiers allow a zoom operation and
303    /// the widget is enabled.
304    #[property(EVENT)]
305    pub fn on_mouse_zoom<on_pre_mouse_zoom>(child: impl IntoUiNode, handler: Handler<MouseWheelArgs>) -> UiNode {
306        const PRE: bool;
307        EventNodeBuilder::new(MOUSE_WHEEL_EVENT)
308            .filter(|| {
309                let id = WIDGET.id();
310                move |args| args.is_zoom() && args.target.contains_enabled(id)
311            })
312            .build::<PRE>(child, handler)
313    }
314}
315
316/// Defines if [`MouseWheelArgs`] gesture [`is_scroll`] when `CTRL` is pressed and [`is_zoom`] when no modifier is pressed.
317///
318/// This property sets the [`CTRL_SCROLL_VAR`].
319///
320/// [`is_scroll`]: MouseWheelArgs::is_scroll
321/// [`is_zoom`]: MouseWheelArgs::is_zoom
322#[property(CONTEXT, default(CTRL_SCROLL_VAR))]
323pub fn ctrl_scroll(child: impl IntoUiNode, ctrl_scroll: impl IntoVar<bool>) -> UiNode {
324    with_context_var(child, CTRL_SCROLL_VAR, ctrl_scroll)
325}