gtk4/auto/gesture.rs
1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4#![allow(deprecated)]
5
6use crate::{EventController, EventSequenceState, ffi};
7use glib::{
8 object::ObjectType as _,
9 prelude::*,
10 signal::{SignalHandlerId, connect_raw},
11 translate::*,
12};
13use std::boxed::Box as Box_;
14
15glib::wrapper! {
16 /// The base class for gesture recognition.
17 ///
18 /// Although [`Gesture`][crate::Gesture] is quite generalized to serve as a base for
19 /// multi-touch gestures, it is suitable to implement single-touch and
20 /// pointer-based gestures (using the special [`None`] [`gdk::EventSequence`][crate::gdk::EventSequence]
21 /// value for these).
22 ///
23 /// The number of touches that a [`Gesture`][crate::Gesture] need to be recognized is
24 /// controlled by the [`n-points`][struct@crate::Gesture#n-points] property, if a
25 /// gesture is keeping track of less or more than that number of sequences,
26 /// it won't check whether the gesture is recognized.
27 ///
28 /// As soon as the gesture has the expected number of touches, it will check
29 /// regularly if it is recognized, the criteria to consider a gesture as
30 /// "recognized" is left to [`Gesture`][crate::Gesture] subclasses.
31 ///
32 /// A recognized gesture will then emit the following signals:
33 ///
34 /// - [`begin`][struct@crate::Gesture#begin] when the gesture is recognized.
35 /// - [`update`][struct@crate::Gesture#update], whenever an input event is processed.
36 /// - [`end`][struct@crate::Gesture#end] when the gesture is no longer recognized.
37 ///
38 /// ## Event propagation
39 ///
40 /// In order to receive events, a gesture needs to set a propagation phase
41 /// through [`EventControllerExt::set_propagation_phase()`][crate::prelude::EventControllerExt::set_propagation_phase()].
42 ///
43 /// In the capture phase, events are propagated from the toplevel down
44 /// to the target widget, and gestures that are attached to containers
45 /// above the widget get a chance to interact with the event before it
46 /// reaches the target.
47 ///
48 /// In the bubble phase, events are propagated up from the target widget
49 /// to the toplevel, and gestures that are attached to containers above
50 /// the widget get a chance to interact with events that have not been
51 /// handled yet.
52 ///
53 /// ## States of a sequence
54 ///
55 /// Whenever input interaction happens, a single event may trigger a cascade
56 /// of [`Gesture`][crate::Gesture]s, both across the parents of the widget receiving the
57 /// event and in parallel within an individual widget. It is a responsibility
58 /// of the widgets using those gestures to set the state of touch sequences
59 /// accordingly in order to enable cooperation of gestures around the
60 /// [`gdk::EventSequence`][crate::gdk::EventSequence]s triggering those.
61 ///
62 /// Within a widget, gestures can be grouped through [`GestureExt::group_with()`][crate::prelude::GestureExt::group_with()].
63 /// Grouped gestures synchronize the state of sequences, so calling
64 /// [`GestureExt::set_state()`][crate::prelude::GestureExt::set_state()] on one will effectively propagate
65 /// the state throughout the group.
66 ///
67 /// By default, all sequences start out in the [`EventSequenceState::None`][crate::EventSequenceState::None] state,
68 /// sequences in this state trigger the gesture event handler, but event
69 /// propagation will continue unstopped by gestures.
70 ///
71 /// If a sequence enters into the [`EventSequenceState::Denied`][crate::EventSequenceState::Denied] state, the gesture
72 /// group will effectively ignore the sequence, letting events go unstopped
73 /// through the gesture, but the "slot" will still remain occupied while
74 /// the touch is active.
75 ///
76 /// If a sequence enters in the [`EventSequenceState::Claimed`][crate::EventSequenceState::Claimed] state, the gesture
77 /// group will grab all interaction on the sequence, by:
78 ///
79 /// - Setting the same sequence to [`EventSequenceState::Denied`][crate::EventSequenceState::Denied] on every other
80 /// gesture group within the widget, and every gesture on parent widgets
81 /// in the propagation chain.
82 /// - Emitting [`cancel`][struct@crate::Gesture#cancel] on every gesture in widgets
83 /// underneath in the propagation chain.
84 /// - Stopping event propagation after the gesture group handles the event.
85 ///
86 /// Note: if a sequence is set early to [`EventSequenceState::Claimed`][crate::EventSequenceState::Claimed] on
87 /// `GDK_TOUCH_BEGIN`/`GDK_BUTTON_PRESS` (so those events are captured before
88 /// reaching the event widget, this implies [`PropagationPhase::Capture`][crate::PropagationPhase::Capture]), one similar
89 /// event will be emulated if the sequence changes to [`EventSequenceState::Denied`][crate::EventSequenceState::Denied].
90 /// This way event coherence is preserved before event propagation is unstopped
91 /// again.
92 ///
93 /// Sequence states can't be changed freely.
94 /// See [`GestureExt::set_state()`][crate::prelude::GestureExt::set_state()] to know about the possible
95 /// lifetimes of a [`gdk::EventSequence`][crate::gdk::EventSequence].
96 ///
97 /// ## Touchpad gestures
98 ///
99 /// On the platforms that support it, [`Gesture`][crate::Gesture] will handle transparently
100 /// touchpad gesture events. The only precautions users of [`Gesture`][crate::Gesture] should
101 /// do to enable this support are:
102 ///
103 /// - If the gesture has [`PropagationPhase::None`][crate::PropagationPhase::None], ensuring events of type
104 /// `GDK_TOUCHPAD_SWIPE` and `GDK_TOUCHPAD_PINCH` are handled by the [`Gesture`][crate::Gesture]
105 ///
106 /// This is an Abstract Base Class, you cannot instantiate it.
107 ///
108 /// ## Properties
109 ///
110 ///
111 /// #### `n-points`
112 /// The number of touch points that trigger
113 /// recognition on this gesture.
114 ///
115 /// Readable | Writable | Construct Only
116 /// <details><summary><h4>EventController</h4></summary>
117 ///
118 ///
119 /// #### `name`
120 /// The name for this controller, typically used for debugging purposes.
121 ///
122 /// Readable | Writable
123 ///
124 ///
125 /// #### `propagation-limit`
126 /// The limit for which events this controller will handle.
127 ///
128 /// Readable | Writable
129 ///
130 ///
131 /// #### `propagation-phase`
132 /// The propagation phase at which this controller will handle events.
133 ///
134 /// Readable | Writable
135 ///
136 ///
137 /// #### `widget`
138 /// The widget receiving the `GdkEvents` that the controller will handle.
139 ///
140 /// Readable
141 /// </details>
142 ///
143 /// ## Signals
144 ///
145 ///
146 /// #### `begin`
147 /// Emitted when the gesture is recognized.
148 ///
149 /// This means the number of touch sequences matches
150 /// [`n-points`][struct@crate::Gesture#n-points].
151 ///
152 /// Note: These conditions may also happen when an extra touch
153 /// (eg. a third touch on a 2-touches gesture) is lifted, in that
154 /// situation @sequence won't pertain to the current set of active
155 /// touches, so don't rely on this being true.
156 ///
157 ///
158 ///
159 ///
160 /// #### `cancel`
161 /// Emitted whenever a sequence is cancelled.
162 ///
163 /// This usually happens on active touches when
164 /// [`EventControllerExt::reset()`][crate::prelude::EventControllerExt::reset()] is called on @gesture
165 /// (manually, due to grabs...), or the individual @sequence
166 /// was claimed by parent widgets' controllers (see
167 /// [`GestureExt::set_sequence_state()`][crate::prelude::GestureExt::set_sequence_state()]).
168 ///
169 /// @gesture must forget everything about @sequence as in
170 /// response to this signal.
171 ///
172 ///
173 ///
174 ///
175 /// #### `end`
176 /// Emitted when @gesture either stopped recognizing the event
177 /// sequences as something to be handled, or the number of touch
178 /// sequences became higher or lower than [`n-points`][struct@crate::Gesture#n-points].
179 ///
180 /// Note: @sequence might not pertain to the group of sequences that
181 /// were previously triggering recognition on @gesture (ie. a just
182 /// pressed touch sequence that exceeds [`n-points`][struct@crate::Gesture#n-points]).
183 /// This situation may be detected by checking through
184 /// [`GestureExt::handles_sequence()`][crate::prelude::GestureExt::handles_sequence()].
185 ///
186 ///
187 ///
188 ///
189 /// #### `sequence-state-changed`
190 /// Emitted whenever a sequence state changes.
191 ///
192 /// See [`GestureExt::set_sequence_state()`][crate::prelude::GestureExt::set_sequence_state()] to know
193 /// more about the expectable sequence lifetimes.
194 ///
195 ///
196 ///
197 ///
198 /// #### `update`
199 /// Emitted whenever an event is handled while the gesture is recognized.
200 ///
201 /// @sequence is guaranteed to pertain to the set of active touches.
202 ///
203 ///
204 ///
205 /// # Implements
206 ///
207 /// [`GestureExt`][trait@crate::prelude::GestureExt], [`EventControllerExt`][trait@crate::prelude::EventControllerExt], [`trait@glib::ObjectExt`], [`EventControllerExtManual`][trait@crate::prelude::EventControllerExtManual]
208 #[doc(alias = "GtkGesture")]
209 pub struct Gesture(Object<ffi::GtkGesture, ffi::GtkGestureClass>) @extends EventController;
210
211 match fn {
212 type_ => || ffi::gtk_gesture_get_type(),
213 }
214}
215
216impl Gesture {
217 pub const NONE: Option<&'static Gesture> = None;
218}
219
220/// Trait containing all [`struct@Gesture`] methods.
221///
222/// # Implementors
223///
224/// [`GestureRotate`][struct@crate::GestureRotate], [`GestureSingle`][struct@crate::GestureSingle], [`GestureZoom`][struct@crate::GestureZoom], [`Gesture`][struct@crate::Gesture]
225pub trait GestureExt: IsA<Gesture> + 'static {
226 /// If there are touch sequences being currently handled by @self,
227 /// returns [`true`] and fills in @rect with the bounding box containing
228 /// all active touches.
229 ///
230 /// Otherwise, [`false`] will be returned.
231 ///
232 /// Note: This function will yield unexpected results on touchpad
233 /// gestures. Since there is no correlation between physical and
234 /// pixel distances, these will look as if constrained in an
235 /// infinitely small area, @rect width and height will thus be 0
236 /// regardless of the number of touchpoints.
237 ///
238 /// # Returns
239 ///
240 /// [`true`] if there are active touches, [`false`] otherwise
241 ///
242 /// ## `rect`
243 /// bounding box containing all active touches.
244 #[doc(alias = "gtk_gesture_get_bounding_box")]
245 #[doc(alias = "get_bounding_box")]
246 fn bounding_box(&self) -> Option<gdk::Rectangle> {
247 unsafe {
248 let mut rect = gdk::Rectangle::uninitialized();
249 let ret = from_glib(ffi::gtk_gesture_get_bounding_box(
250 self.as_ref().to_glib_none().0,
251 rect.to_glib_none_mut().0,
252 ));
253 if ret { Some(rect) } else { None }
254 }
255 }
256
257 /// If there are touch sequences being currently handled by @self,
258 /// returns [`true`] and fills in @x and @y with the center of the bounding
259 /// box containing all active touches.
260 ///
261 /// Otherwise, [`false`] will be returned.
262 ///
263 /// # Returns
264 ///
265 /// [`false`] if no active touches are present, [`true`] otherwise
266 ///
267 /// ## `x`
268 /// X coordinate for the bounding box center
269 ///
270 /// ## `y`
271 /// Y coordinate for the bounding box center
272 #[doc(alias = "gtk_gesture_get_bounding_box_center")]
273 #[doc(alias = "get_bounding_box_center")]
274 fn bounding_box_center(&self) -> Option<(f64, f64)> {
275 unsafe {
276 let mut x = std::mem::MaybeUninit::uninit();
277 let mut y = std::mem::MaybeUninit::uninit();
278 let ret = from_glib(ffi::gtk_gesture_get_bounding_box_center(
279 self.as_ref().to_glib_none().0,
280 x.as_mut_ptr(),
281 y.as_mut_ptr(),
282 ));
283 if ret {
284 Some((x.assume_init(), y.assume_init()))
285 } else {
286 None
287 }
288 }
289 }
290
291 /// Returns the logical [`gdk::Device`][crate::gdk::Device] that is currently operating
292 /// on @self.
293 ///
294 /// This returns [`None`] if the gesture is not being interacted.
295 ///
296 /// # Returns
297 ///
298 /// a [`gdk::Device`][crate::gdk::Device]
299 #[doc(alias = "gtk_gesture_get_device")]
300 #[doc(alias = "get_device")]
301 fn device(&self) -> Option<gdk::Device> {
302 unsafe { from_glib_none(ffi::gtk_gesture_get_device(self.as_ref().to_glib_none().0)) }
303 }
304
305 /// Returns all gestures in the group of @self
306 ///
307 /// # Returns
308 ///
309 /// The list
310 /// of [`Gesture`][crate::Gesture]s, free with g_list_free()
311 #[doc(alias = "gtk_gesture_get_group")]
312 #[doc(alias = "get_group")]
313 fn group(&self) -> Vec<Gesture> {
314 unsafe {
315 FromGlibPtrContainer::from_glib_container(ffi::gtk_gesture_get_group(
316 self.as_ref().to_glib_none().0,
317 ))
318 }
319 }
320
321 /// Returns the last event that was processed for @sequence.
322 ///
323 /// Note that the returned pointer is only valid as long as the
324 /// @sequence is still interpreted by the @self. If in doubt,
325 /// you should make a copy of the event.
326 /// ## `sequence`
327 /// a [`gdk::EventSequence`][crate::gdk::EventSequence]
328 ///
329 /// # Returns
330 ///
331 /// The last event from @sequence
332 #[doc(alias = "gtk_gesture_get_last_event")]
333 #[doc(alias = "get_last_event")]
334 fn last_event(&self, sequence: Option<&gdk::EventSequence>) -> Option<gdk::Event> {
335 unsafe {
336 from_glib_none(ffi::gtk_gesture_get_last_event(
337 self.as_ref().to_glib_none().0,
338 mut_override(sequence.to_glib_none().0),
339 ))
340 }
341 }
342
343 /// Returns the [`gdk::EventSequence`][crate::gdk::EventSequence] that was last updated on @self.
344 ///
345 /// # Returns
346 ///
347 /// The last updated sequence
348 #[doc(alias = "gtk_gesture_get_last_updated_sequence")]
349 #[doc(alias = "get_last_updated_sequence")]
350 fn last_updated_sequence(&self) -> Option<gdk::EventSequence> {
351 unsafe {
352 from_glib_none(ffi::gtk_gesture_get_last_updated_sequence(
353 self.as_ref().to_glib_none().0,
354 ))
355 }
356 }
357
358 /// If @sequence is currently being interpreted by @self,
359 /// returns [`true`] and fills in @x and @y with the last coordinates
360 /// stored for that event sequence.
361 ///
362 /// The coordinates are always relative to the widget allocation.
363 /// ## `sequence`
364 /// a [`gdk::EventSequence`][crate::gdk::EventSequence], or [`None`] for pointer events
365 ///
366 /// # Returns
367 ///
368 /// [`true`] if @sequence is currently interpreted
369 ///
370 /// ## `x`
371 /// return location for X axis of the sequence coordinates
372 ///
373 /// ## `y`
374 /// return location for Y axis of the sequence coordinates
375 #[doc(alias = "gtk_gesture_get_point")]
376 #[doc(alias = "get_point")]
377 fn point(&self, sequence: Option<&gdk::EventSequence>) -> Option<(f64, f64)> {
378 unsafe {
379 let mut x = std::mem::MaybeUninit::uninit();
380 let mut y = std::mem::MaybeUninit::uninit();
381 let ret = from_glib(ffi::gtk_gesture_get_point(
382 self.as_ref().to_glib_none().0,
383 mut_override(sequence.to_glib_none().0),
384 x.as_mut_ptr(),
385 y.as_mut_ptr(),
386 ));
387 if ret {
388 Some((x.assume_init(), y.assume_init()))
389 } else {
390 None
391 }
392 }
393 }
394
395 /// Returns the @sequence state, as seen by @self.
396 /// ## `sequence`
397 /// a [`gdk::EventSequence`][crate::gdk::EventSequence]
398 ///
399 /// # Returns
400 ///
401 /// The sequence state in @self
402 #[doc(alias = "gtk_gesture_get_sequence_state")]
403 #[doc(alias = "get_sequence_state")]
404 fn sequence_state(&self, sequence: &gdk::EventSequence) -> EventSequenceState {
405 unsafe {
406 from_glib(ffi::gtk_gesture_get_sequence_state(
407 self.as_ref().to_glib_none().0,
408 mut_override(sequence.to_glib_none().0),
409 ))
410 }
411 }
412
413 /// Returns the list of `GdkEventSequences` currently being interpreted
414 /// by @self.
415 ///
416 /// # Returns
417 ///
418 /// A list
419 /// of [`gdk::EventSequence`][crate::gdk::EventSequence], the list elements are owned by GTK and must
420 /// not be freed or modified, the list itself must be deleted
421 /// through g_list_free()
422 #[doc(alias = "gtk_gesture_get_sequences")]
423 #[doc(alias = "get_sequences")]
424 fn sequences(&self) -> Vec<gdk::EventSequence> {
425 unsafe {
426 FromGlibPtrContainer::from_glib_container(ffi::gtk_gesture_get_sequences(
427 self.as_ref().to_glib_none().0,
428 ))
429 }
430 }
431
432 /// Adds @gesture to the same group than @self.
433 ///
434 /// Gestures are by default isolated in their own groups.
435 ///
436 /// Both gestures must have been added to the same widget before
437 /// they can be grouped.
438 ///
439 /// When gestures are grouped, the state of `GdkEventSequences`
440 /// is kept in sync for all of those, so calling
441 /// [`set_sequence_state()`][Self::set_sequence_state()], on one will transfer
442 /// the same value to the others.
443 ///
444 /// Groups also perform an "implicit grabbing" of sequences, if a
445 /// [`gdk::EventSequence`][crate::gdk::EventSequence] state is set to [`EventSequenceState::Claimed`][crate::EventSequenceState::Claimed]
446 /// on one group, every other gesture group attached to the same
447 /// [`Widget`][crate::Widget] will switch the state for that sequence to
448 /// [`EventSequenceState::Denied`][crate::EventSequenceState::Denied].
449 /// ## `gesture`
450 /// a [`Gesture`][crate::Gesture]
451 #[doc(alias = "gtk_gesture_group")]
452 #[doc(alias = "group")]
453 fn group_with(&self, gesture: &impl IsA<Gesture>) {
454 unsafe {
455 ffi::gtk_gesture_group(
456 self.as_ref().to_glib_none().0,
457 gesture.as_ref().to_glib_none().0,
458 );
459 }
460 }
461
462 /// Returns [`true`] if @self is currently handling events
463 /// corresponding to @sequence.
464 /// ## `sequence`
465 /// a [`gdk::EventSequence`][crate::gdk::EventSequence]
466 ///
467 /// # Returns
468 ///
469 /// [`true`] if @self is handling @sequence, [`false`] otherwise
470 #[doc(alias = "gtk_gesture_handles_sequence")]
471 fn handles_sequence(&self, sequence: Option<&gdk::EventSequence>) -> bool {
472 unsafe {
473 from_glib(ffi::gtk_gesture_handles_sequence(
474 self.as_ref().to_glib_none().0,
475 mut_override(sequence.to_glib_none().0),
476 ))
477 }
478 }
479
480 /// Returns [`true`] if the gesture is currently active.
481 ///
482 /// A gesture is active while there are touch sequences
483 /// interacting with it.
484 ///
485 /// # Returns
486 ///
487 /// [`true`] if gesture is active
488 #[doc(alias = "gtk_gesture_is_active")]
489 fn is_active(&self) -> bool {
490 unsafe { from_glib(ffi::gtk_gesture_is_active(self.as_ref().to_glib_none().0)) }
491 }
492
493 /// Returns [`true`] if both gestures pertain to the same group.
494 /// ## `other`
495 /// another [`Gesture`][crate::Gesture]
496 ///
497 /// # Returns
498 ///
499 /// whether the gestures are grouped
500 #[doc(alias = "gtk_gesture_is_grouped_with")]
501 fn is_grouped_with(&self, other: &impl IsA<Gesture>) -> bool {
502 unsafe {
503 from_glib(ffi::gtk_gesture_is_grouped_with(
504 self.as_ref().to_glib_none().0,
505 other.as_ref().to_glib_none().0,
506 ))
507 }
508 }
509
510 /// Returns [`true`] if the gesture is currently recognized.
511 ///
512 /// A gesture is recognized if there are as many interacting
513 /// touch sequences as required by @self.
514 ///
515 /// # Returns
516 ///
517 /// [`true`] if gesture is recognized
518 #[doc(alias = "gtk_gesture_is_recognized")]
519 fn is_recognized(&self) -> bool {
520 unsafe {
521 from_glib(ffi::gtk_gesture_is_recognized(
522 self.as_ref().to_glib_none().0,
523 ))
524 }
525 }
526
527 /// Denied
528 ///
529 /// Note: Due to event handling ordering, it may be unsafe to set the
530 /// state on another gesture within a [`begin`][struct@crate::Gesture#begin] signal
531 /// handler, as the callback might be executed before the other gesture
532 /// knows about the sequence. A safe way to perform this could be:
533 ///
534 /// **⚠️ The following code is in c ⚠️**
535 ///
536 /// ```c
537 /// static void
538 /// first_gesture_begin_cb (GtkGesture *first_gesture,
539 /// GdkEventSequence *sequence,
540 /// gpointer user_data)
541 /// {
542 /// gtk_gesture_set_sequence_state (first_gesture, sequence, GTK_EVENT_SEQUENCE_CLAIMED);
543 /// gtk_gesture_set_sequence_state (second_gesture, sequence, GTK_EVENT_SEQUENCE_DENIED);
544 /// }
545 ///
546 /// static void
547 /// second_gesture_begin_cb (GtkGesture *second_gesture,
548 /// GdkEventSequence *sequence,
549 /// gpointer user_data)
550 /// {
551 /// if (gtk_gesture_get_sequence_state (first_gesture, sequence) == GTK_EVENT_SEQUENCE_CLAIMED)
552 /// gtk_gesture_set_sequence_state (second_gesture, sequence, GTK_EVENT_SEQUENCE_DENIED);
553 /// }
554 /// ```
555 ///
556 /// If both gestures are in the same group, just set the state on
557 /// the gesture emitting the event, the sequence will be already
558 /// be initialized to the group's global state when the second
559 /// gesture processes the event.
560 ///
561 /// # Deprecated since 4.10
562 ///
563 /// Use [`set_state()`][Self::set_state()]
564 /// ## `sequence`
565 /// a [`gdk::EventSequence`][crate::gdk::EventSequence]
566 /// ## `state`
567 /// the sequence state
568 ///
569 /// # Returns
570 ///
571 /// [`true`] if @sequence is handled by @self,
572 /// and the state is changed successfully
573 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
574 #[allow(deprecated)]
575 #[doc(alias = "gtk_gesture_set_sequence_state")]
576 fn set_sequence_state(&self, sequence: &gdk::EventSequence, state: EventSequenceState) -> bool {
577 unsafe {
578 from_glib(ffi::gtk_gesture_set_sequence_state(
579 self.as_ref().to_glib_none().0,
580 mut_override(sequence.to_glib_none().0),
581 state.into_glib(),
582 ))
583 }
584 }
585
586 /// Denied
587 ///
588 /// Note: Due to event handling ordering, it may be unsafe to set the
589 /// state on another gesture within a [`begin`][struct@crate::Gesture#begin] signal
590 /// handler, as the callback might be executed before the other gesture
591 /// knows about the sequence. A safe way to perform this could be:
592 ///
593 /// **⚠️ The following code is in c ⚠️**
594 ///
595 /// ```c
596 /// static void
597 /// first_gesture_begin_cb (GtkGesture *first_gesture,
598 /// GdkEventSequence *sequence,
599 /// gpointer user_data)
600 /// {
601 /// gtk_gesture_set_state (first_gesture, GTK_EVENT_SEQUENCE_CLAIMED);
602 /// gtk_gesture_set_state (second_gesture, GTK_EVENT_SEQUENCE_DENIED);
603 /// }
604 ///
605 /// static void
606 /// second_gesture_begin_cb (GtkGesture *second_gesture,
607 /// GdkEventSequence *sequence,
608 /// gpointer user_data)
609 /// {
610 /// if (gtk_gesture_get_sequence_state (first_gesture, sequence) == GTK_EVENT_SEQUENCE_CLAIMED)
611 /// gtk_gesture_set_state (second_gesture, GTK_EVENT_SEQUENCE_DENIED);
612 /// }
613 /// ```
614 ///
615 /// If both gestures are in the same group, just set the state on
616 /// the gesture emitting the event, the sequence will be already
617 /// be initialized to the group's global state when the second
618 /// gesture processes the event.
619 /// ## `state`
620 /// the sequence state
621 ///
622 /// # Returns
623 ///
624 /// [`true`] if the state of at least one sequence
625 /// was changed successfully
626 #[doc(alias = "gtk_gesture_set_state")]
627 fn set_state(&self, state: EventSequenceState) -> bool {
628 unsafe {
629 from_glib(ffi::gtk_gesture_set_state(
630 self.as_ref().to_glib_none().0,
631 state.into_glib(),
632 ))
633 }
634 }
635
636 /// Separates @self into an isolated group.
637 #[doc(alias = "gtk_gesture_ungroup")]
638 fn ungroup(&self) {
639 unsafe {
640 ffi::gtk_gesture_ungroup(self.as_ref().to_glib_none().0);
641 }
642 }
643
644 /// The number of touch points that trigger
645 /// recognition on this gesture.
646 #[doc(alias = "n-points")]
647 fn n_points(&self) -> u32 {
648 ObjectExt::property(self.as_ref(), "n-points")
649 }
650
651 /// Emitted when the gesture is recognized.
652 ///
653 /// This means the number of touch sequences matches
654 /// [`n-points`][struct@crate::Gesture#n-points].
655 ///
656 /// Note: These conditions may also happen when an extra touch
657 /// (eg. a third touch on a 2-touches gesture) is lifted, in that
658 /// situation @sequence won't pertain to the current set of active
659 /// touches, so don't rely on this being true.
660 /// ## `sequence`
661 /// the [`gdk::EventSequence`][crate::gdk::EventSequence] that made the gesture
662 /// to be recognized
663 #[doc(alias = "begin")]
664 fn connect_begin<F: Fn(&Self, Option<&gdk::EventSequence>) + 'static>(
665 &self,
666 f: F,
667 ) -> SignalHandlerId {
668 unsafe extern "C" fn begin_trampoline<
669 P: IsA<Gesture>,
670 F: Fn(&P, Option<&gdk::EventSequence>) + 'static,
671 >(
672 this: *mut ffi::GtkGesture,
673 sequence: *mut gdk::ffi::GdkEventSequence,
674 f: glib::ffi::gpointer,
675 ) {
676 unsafe {
677 let f: &F = &*(f as *const F);
678 f(
679 Gesture::from_glib_borrow(this).unsafe_cast_ref(),
680 Option::<gdk::EventSequence>::from_glib_borrow(sequence)
681 .as_ref()
682 .as_ref(),
683 )
684 }
685 }
686 unsafe {
687 let f: Box_<F> = Box_::new(f);
688 connect_raw(
689 self.as_ptr() as *mut _,
690 c"begin".as_ptr(),
691 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
692 begin_trampoline::<Self, F> as *const (),
693 )),
694 Box_::into_raw(f),
695 )
696 }
697 }
698
699 /// Emitted whenever a sequence is cancelled.
700 ///
701 /// This usually happens on active touches when
702 /// [`EventControllerExt::reset()`][crate::prelude::EventControllerExt::reset()] is called on @gesture
703 /// (manually, due to grabs...), or the individual @sequence
704 /// was claimed by parent widgets' controllers (see
705 /// [`set_sequence_state()`][Self::set_sequence_state()]).
706 ///
707 /// @gesture must forget everything about @sequence as in
708 /// response to this signal.
709 /// ## `sequence`
710 /// the [`gdk::EventSequence`][crate::gdk::EventSequence] that was cancelled
711 #[doc(alias = "cancel")]
712 fn connect_cancel<F: Fn(&Self, Option<&gdk::EventSequence>) + 'static>(
713 &self,
714 f: F,
715 ) -> SignalHandlerId {
716 unsafe extern "C" fn cancel_trampoline<
717 P: IsA<Gesture>,
718 F: Fn(&P, Option<&gdk::EventSequence>) + 'static,
719 >(
720 this: *mut ffi::GtkGesture,
721 sequence: *mut gdk::ffi::GdkEventSequence,
722 f: glib::ffi::gpointer,
723 ) {
724 unsafe {
725 let f: &F = &*(f as *const F);
726 f(
727 Gesture::from_glib_borrow(this).unsafe_cast_ref(),
728 Option::<gdk::EventSequence>::from_glib_borrow(sequence)
729 .as_ref()
730 .as_ref(),
731 )
732 }
733 }
734 unsafe {
735 let f: Box_<F> = Box_::new(f);
736 connect_raw(
737 self.as_ptr() as *mut _,
738 c"cancel".as_ptr(),
739 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
740 cancel_trampoline::<Self, F> as *const (),
741 )),
742 Box_::into_raw(f),
743 )
744 }
745 }
746
747 /// Emitted when @gesture either stopped recognizing the event
748 /// sequences as something to be handled, or the number of touch
749 /// sequences became higher or lower than [`n-points`][struct@crate::Gesture#n-points].
750 ///
751 /// Note: @sequence might not pertain to the group of sequences that
752 /// were previously triggering recognition on @gesture (ie. a just
753 /// pressed touch sequence that exceeds [`n-points`][struct@crate::Gesture#n-points]).
754 /// This situation may be detected by checking through
755 /// [`handles_sequence()`][Self::handles_sequence()].
756 /// ## `sequence`
757 /// the [`gdk::EventSequence`][crate::gdk::EventSequence] that made gesture
758 /// recognition to finish
759 #[doc(alias = "end")]
760 fn connect_end<F: Fn(&Self, Option<&gdk::EventSequence>) + 'static>(
761 &self,
762 f: F,
763 ) -> SignalHandlerId {
764 unsafe extern "C" fn end_trampoline<
765 P: IsA<Gesture>,
766 F: Fn(&P, Option<&gdk::EventSequence>) + 'static,
767 >(
768 this: *mut ffi::GtkGesture,
769 sequence: *mut gdk::ffi::GdkEventSequence,
770 f: glib::ffi::gpointer,
771 ) {
772 unsafe {
773 let f: &F = &*(f as *const F);
774 f(
775 Gesture::from_glib_borrow(this).unsafe_cast_ref(),
776 Option::<gdk::EventSequence>::from_glib_borrow(sequence)
777 .as_ref()
778 .as_ref(),
779 )
780 }
781 }
782 unsafe {
783 let f: Box_<F> = Box_::new(f);
784 connect_raw(
785 self.as_ptr() as *mut _,
786 c"end".as_ptr(),
787 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
788 end_trampoline::<Self, F> as *const (),
789 )),
790 Box_::into_raw(f),
791 )
792 }
793 }
794
795 /// Emitted whenever a sequence state changes.
796 ///
797 /// See [`set_sequence_state()`][Self::set_sequence_state()] to know
798 /// more about the expectable sequence lifetimes.
799 /// ## `sequence`
800 /// the [`gdk::EventSequence`][crate::gdk::EventSequence] that was cancelled
801 /// ## `state`
802 /// the new sequence state
803 #[doc(alias = "sequence-state-changed")]
804 fn connect_sequence_state_changed<
805 F: Fn(&Self, Option<&gdk::EventSequence>, EventSequenceState) + 'static,
806 >(
807 &self,
808 f: F,
809 ) -> SignalHandlerId {
810 unsafe extern "C" fn sequence_state_changed_trampoline<
811 P: IsA<Gesture>,
812 F: Fn(&P, Option<&gdk::EventSequence>, EventSequenceState) + 'static,
813 >(
814 this: *mut ffi::GtkGesture,
815 sequence: *mut gdk::ffi::GdkEventSequence,
816 state: ffi::GtkEventSequenceState,
817 f: glib::ffi::gpointer,
818 ) {
819 unsafe {
820 let f: &F = &*(f as *const F);
821 f(
822 Gesture::from_glib_borrow(this).unsafe_cast_ref(),
823 Option::<gdk::EventSequence>::from_glib_borrow(sequence)
824 .as_ref()
825 .as_ref(),
826 from_glib(state),
827 )
828 }
829 }
830 unsafe {
831 let f: Box_<F> = Box_::new(f);
832 connect_raw(
833 self.as_ptr() as *mut _,
834 c"sequence-state-changed".as_ptr(),
835 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
836 sequence_state_changed_trampoline::<Self, F> as *const (),
837 )),
838 Box_::into_raw(f),
839 )
840 }
841 }
842
843 /// Emitted whenever an event is handled while the gesture is recognized.
844 ///
845 /// @sequence is guaranteed to pertain to the set of active touches.
846 /// ## `sequence`
847 /// the [`gdk::EventSequence`][crate::gdk::EventSequence] that was updated
848 #[doc(alias = "update")]
849 fn connect_update<F: Fn(&Self, Option<&gdk::EventSequence>) + 'static>(
850 &self,
851 f: F,
852 ) -> SignalHandlerId {
853 unsafe extern "C" fn update_trampoline<
854 P: IsA<Gesture>,
855 F: Fn(&P, Option<&gdk::EventSequence>) + 'static,
856 >(
857 this: *mut ffi::GtkGesture,
858 sequence: *mut gdk::ffi::GdkEventSequence,
859 f: glib::ffi::gpointer,
860 ) {
861 unsafe {
862 let f: &F = &*(f as *const F);
863 f(
864 Gesture::from_glib_borrow(this).unsafe_cast_ref(),
865 Option::<gdk::EventSequence>::from_glib_borrow(sequence)
866 .as_ref()
867 .as_ref(),
868 )
869 }
870 }
871 unsafe {
872 let f: Box_<F> = Box_::new(f);
873 connect_raw(
874 self.as_ptr() as *mut _,
875 c"update".as_ptr(),
876 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
877 update_trampoline::<Self, F> as *const (),
878 )),
879 Box_::into_raw(f),
880 )
881 }
882 }
883}
884
885impl<O: IsA<Gesture>> GestureExt for O {}