Skip to main content

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 {}