1use super::input_element::routed_event_accessor;
5use super::{
6 ContextRequestedEventArgs, HoldingRoutedEventArgs, HoldingState, InputElement, PinchEndedEventArgs,
7 PinchEventArgs, PointerDeltaEventArgs, PullGestureEndedEventArgs, PullGestureEventArgs,
8 ScrollGestureEndedEventArgs, ScrollGestureEventArgs, ScrollGestureInertiaStartingEventArgs,
9 SwipeGestureEndedEventArgs, SwipeGestureEventArgs, TappedEventArgs,
10};
11use crate::interactivity::{
12 Interactive, RoutedEvent, RoutedEventArgs, RoutedEventHandlerToken, RoutingStrategies,
13};
14use crate::{ferro_property, ferro_routed_event, AttachedProperty, FerroProperty, StyledElement};
15
16crate::ferro_properties! { impl InputElement, fn register_gesture_properties {
17 ferro_property!(
18 pub fn is_holding_enabled_property() -> AttachedProperty<bool> {
20 FerroProperty::register_attached::<InputElement, StyledElement, _>("IsHoldingEnabled", true)
21 }
22 );
23
24 ferro_property!(
25 pub fn is_hold_with_mouse_enabled_property() -> AttachedProperty<bool> {
27 FerroProperty::register_attached::<InputElement, StyledElement, _>("IsHoldWithMouseEnabled", false)
28 }
29 );
30} }
31
32impl InputElement {
33 ferro_routed_event!(
34 pub fn pinch_event() -> RoutedEvent<PinchEventArgs> {
36 RoutedEvent::register::<InputElement, _>("Pinch", RoutingStrategies::BUBBLE)
37 }
38 );
39
40 ferro_routed_event!(
41 pub fn pinch_ended_event() -> RoutedEvent<PinchEndedEventArgs> {
43 RoutedEvent::register::<InputElement, _>("PinchEnded", RoutingStrategies::BUBBLE)
44 }
45 );
46
47 ferro_routed_event!(
48 pub fn pull_gesture_event() -> RoutedEvent<PullGestureEventArgs> {
50 RoutedEvent::register::<InputElement, _>("PullGesture", RoutingStrategies::BUBBLE)
51 }
52 );
53
54 ferro_routed_event!(
55 pub fn pull_gesture_ended_event() -> RoutedEvent<PullGestureEndedEventArgs> {
57 RoutedEvent::register::<InputElement, _>("PullGestureEnded", RoutingStrategies::BUBBLE)
58 }
59 );
60
61 ferro_routed_event!(
62 pub fn swipe_gesture_event() -> RoutedEvent<SwipeGestureEventArgs> {
64 RoutedEvent::register::<InputElement, _>("SwipeGesture", RoutingStrategies::BUBBLE)
65 }
66 );
67
68 ferro_routed_event!(
69 pub fn swipe_gesture_ended_event() -> RoutedEvent<SwipeGestureEndedEventArgs> {
71 RoutedEvent::register::<InputElement, _>("SwipeGestureEnded", RoutingStrategies::BUBBLE)
72 }
73 );
74
75 ferro_routed_event!(
76 pub fn scroll_gesture_event() -> RoutedEvent<ScrollGestureEventArgs> {
78 RoutedEvent::register::<InputElement, _>("ScrollGesture", RoutingStrategies::BUBBLE)
79 }
80 );
81
82 ferro_routed_event!(
83 pub fn scroll_gesture_inertia_starting_event() -> RoutedEvent<ScrollGestureInertiaStartingEventArgs> {
85 RoutedEvent::register::<InputElement, _>("ScrollGestureInertiaStarting", RoutingStrategies::BUBBLE)
86 }
87 );
88
89 ferro_routed_event!(
90 pub fn scroll_gesture_ended_event() -> RoutedEvent<ScrollGestureEndedEventArgs> {
92 RoutedEvent::register::<InputElement, _>("ScrollGestureEnded", RoutingStrategies::BUBBLE)
93 }
94 );
95
96 ferro_routed_event!(
97 pub fn pointer_touch_pad_gesture_magnify_event() -> RoutedEvent<PointerDeltaEventArgs> {
99 RoutedEvent::register::<InputElement, _>("PointerTouchPadGestureMagnify", RoutingStrategies::BUBBLE)
100 }
101 );
102
103 ferro_routed_event!(
104 pub fn pointer_touch_pad_gesture_rotate_event() -> RoutedEvent<PointerDeltaEventArgs> {
106 RoutedEvent::register::<InputElement, _>("PointerTouchPadGestureRotate", RoutingStrategies::BUBBLE)
107 }
108 );
109
110 ferro_routed_event!(
111 pub fn pointer_touch_pad_gesture_swipe_event() -> RoutedEvent<PointerDeltaEventArgs> {
113 RoutedEvent::register::<InputElement, _>("PointerTouchPadGestureSwipe", RoutingStrategies::BUBBLE)
114 }
115 );
116
117 ferro_routed_event!(
118 pub fn tapped_event() -> RoutedEvent<TappedEventArgs> {
120 RoutedEvent::register::<InputElement, _>("Tapped", RoutingStrategies::BUBBLE)
121 }
122 );
123
124 ferro_routed_event!(
125 pub fn right_tapped_event() -> RoutedEvent<TappedEventArgs> {
127 RoutedEvent::register::<InputElement, _>("RightTapped", RoutingStrategies::BUBBLE)
128 }
129 );
130
131 ferro_routed_event!(
132 pub fn holding_event() -> RoutedEvent<HoldingRoutedEventArgs> {
134 RoutedEvent::register::<InputElement, _>("Holding", RoutingStrategies::BUBBLE)
135 }
136 );
137
138 ferro_routed_event!(
139 pub fn double_tapped_event() -> RoutedEvent<TappedEventArgs> {
141 RoutedEvent::register::<InputElement, _>("DoubleTapped", RoutingStrategies::BUBBLE)
142 }
143 );
144
145 pub(super) fn register_gesture_events() {
147 Self::pinch_event();
148 Self::pinch_ended_event();
149 Self::pull_gesture_event();
150 Self::pull_gesture_ended_event();
151 Self::swipe_gesture_event();
152 Self::swipe_gesture_ended_event();
153 Self::scroll_gesture_event();
154 Self::scroll_gesture_inertia_starting_event();
155 Self::scroll_gesture_ended_event();
156 Self::pointer_touch_pad_gesture_magnify_event();
157 Self::pointer_touch_pad_gesture_rotate_event();
158 Self::pointer_touch_pad_gesture_swipe_event();
159 }
160
161 pub fn get_is_holding_enabled(element: &StyledElement) -> bool {
163 element.get_value(Self::is_holding_enabled_property())
164 }
165
166 pub fn set_is_holding_enabled(element: &StyledElement, value: bool) {
168 element.set_value(Self::is_holding_enabled_property(), value)
169 }
170
171 pub fn get_is_hold_with_mouse_enabled(element: &StyledElement) -> bool {
174 element.get_value(Self::is_hold_with_mouse_enabled_property())
175 }
176
177 pub fn set_is_hold_with_mouse_enabled(element: &StyledElement, value: bool) {
180 element.set_value(Self::is_hold_with_mouse_enabled_property(), value)
181 }
182
183 routed_event_accessor!(
184 pinch, pinch_event, PinchEventArgs
186 );
187
188 routed_event_accessor!(
189 pinch_ended, pinch_ended_event, PinchEndedEventArgs
192 );
193
194 routed_event_accessor!(
195 pull_gesture, pull_gesture_event, PullGestureEventArgs
197 );
198
199 routed_event_accessor!(
200 pull_gesture_ended, pull_gesture_ended_event, PullGestureEndedEventArgs
202 );
203
204 routed_event_accessor!(
205 scroll_gesture, scroll_gesture_event, ScrollGestureEventArgs
208 );
209
210 routed_event_accessor!(
211 scroll_gesture_inertia_starting, scroll_gesture_inertia_starting_event, ScrollGestureInertiaStartingEventArgs
214 );
215
216 routed_event_accessor!(
217 scroll_gesture_ended, scroll_gesture_ended_event, ScrollGestureEndedEventArgs
219 );
220
221 routed_event_accessor!(
222 pointer_touch_pad_gesture_magnify, pointer_touch_pad_gesture_magnify_event, PointerDeltaEventArgs
225 );
226
227 routed_event_accessor!(
228 pointer_touch_pad_gesture_rotate, pointer_touch_pad_gesture_rotate_event, PointerDeltaEventArgs
231 );
232
233 routed_event_accessor!(
234 swipe_gesture, swipe_gesture_event, SwipeGestureEventArgs
237 );
238
239 routed_event_accessor!(
240 swipe_gesture_ended, swipe_gesture_ended_event, SwipeGestureEndedEventArgs
242 );
243
244 routed_event_accessor!(
245 pointer_touch_pad_gesture_swipe, pointer_touch_pad_gesture_swipe_event, PointerDeltaEventArgs
248 );
249
250 routed_event_accessor!(
251 tapped, tapped_event, TappedEventArgs
254 );
255
256 routed_event_accessor!(
257 right_tapped, right_tapped_event, TappedEventArgs
260 );
261
262 routed_event_accessor!(
263 holding, holding_event, HoldingRoutedEventArgs
267 );
268
269 routed_event_accessor!(
270 double_tapped, double_tapped_event, TappedEventArgs
273 );
274
275 pub(super) fn on_preview_holding(sender: &Interactive, e: &HoldingRoutedEventArgs) {
276 let Some(input_element) = sender.downcast_ref::<InputElement>() else { return };
277
278 input_element.raise_event(e);
279
280 if !e.handled() && e.holding_state() == HoldingState::Started {
281 let context_event = ContextRequestedEventArgs::from_holding(e);
282 input_element.raise_event(&context_event);
283 e.set_handled(context_event.handled());
284
285 if context_event.handled() {
286 input_element.is_context_menu_on_holding.set(true);
287 }
288 } else if e.holding_state() == HoldingState::Canceled && input_element.is_context_menu_on_holding.get() {
289 let args = RoutedEventArgs::with_event_and_source(
290 InputElement::context_canceled_event(),
291 input_element.to_ref(),
292 );
293 input_element.raise_event(&args);
294 input_element.is_context_menu_on_holding.set(false);
295 } else if e.holding_state() == HoldingState::Completed {
296 input_element.is_context_menu_on_holding.set(false);
297 }
298 }
299}