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::{ffi, EventController, EventSequenceState};
7use glib::{
8    object::ObjectType as _,
9    prelude::*,
10    signal::{connect_raw, SignalHandlerId},
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 | Writeable | 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 | Writeable
123    ///
124    ///
125    /// #### `propagation-limit`
126    ///  The limit for which events this controller will handle.
127    ///
128    /// Readable | Writeable
129    ///
130    ///
131    /// #### `propagation-phase`
132    ///  The propagation phase at which this controller will handle events.
133    ///
134    /// Readable | Writeable
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`]
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 {
254                Some(rect)
255            } else {
256                None
257            }
258        }
259    }
260
261    /// If there are touch sequences being currently handled by @self,
262    /// returns [`true`] and fills in @x and @y with the center of the bounding
263    /// box containing all active touches.
264    ///
265    /// Otherwise, [`false`] will be returned.
266    ///
267    /// # Returns
268    ///
269    /// [`false`] if no active touches are present, [`true`] otherwise
270    ///
271    /// ## `x`
272    /// X coordinate for the bounding box center
273    ///
274    /// ## `y`
275    /// Y coordinate for the bounding box center
276    #[doc(alias = "gtk_gesture_get_bounding_box_center")]
277    #[doc(alias = "get_bounding_box_center")]
278    fn bounding_box_center(&self) -> Option<(f64, f64)> {
279        unsafe {
280            let mut x = std::mem::MaybeUninit::uninit();
281            let mut y = std::mem::MaybeUninit::uninit();
282            let ret = from_glib(ffi::gtk_gesture_get_bounding_box_center(
283                self.as_ref().to_glib_none().0,
284                x.as_mut_ptr(),
285                y.as_mut_ptr(),
286            ));
287            if ret {
288                Some((x.assume_init(), y.assume_init()))
289            } else {
290                None
291            }
292        }
293    }
294
295    /// Returns the logical [`gdk::Device`][crate::gdk::Device] that is currently operating
296    /// on @self.
297    ///
298    /// This returns [`None`] if the gesture is not being interacted.
299    ///
300    /// # Returns
301    ///
302    /// a [`gdk::Device`][crate::gdk::Device]
303    #[doc(alias = "gtk_gesture_get_device")]
304    #[doc(alias = "get_device")]
305    fn device(&self) -> Option<gdk::Device> {
306        unsafe { from_glib_none(ffi::gtk_gesture_get_device(self.as_ref().to_glib_none().0)) }
307    }
308
309    /// Returns all gestures in the group of @self
310    ///
311    /// # Returns
312    ///
313    /// The list
314    ///   of [`Gesture`][crate::Gesture]s, free with g_list_free()
315    #[doc(alias = "gtk_gesture_get_group")]
316    #[doc(alias = "get_group")]
317    fn group(&self) -> Vec<Gesture> {
318        unsafe {
319            FromGlibPtrContainer::from_glib_container(ffi::gtk_gesture_get_group(
320                self.as_ref().to_glib_none().0,
321            ))
322        }
323    }
324
325    /// Returns the last event that was processed for @sequence.
326    ///
327    /// Note that the returned pointer is only valid as long as the
328    /// @sequence is still interpreted by the @self. If in doubt,
329    /// you should make a copy of the event.
330    /// ## `sequence`
331    /// a [`gdk::EventSequence`][crate::gdk::EventSequence]
332    ///
333    /// # Returns
334    ///
335    /// The last event from @sequence
336    #[doc(alias = "gtk_gesture_get_last_event")]
337    #[doc(alias = "get_last_event")]
338    fn last_event(&self, sequence: Option<&gdk::EventSequence>) -> Option<gdk::Event> {
339        unsafe {
340            from_glib_none(ffi::gtk_gesture_get_last_event(
341                self.as_ref().to_glib_none().0,
342                mut_override(sequence.to_glib_none().0),
343            ))
344        }
345    }
346
347    /// Returns the [`gdk::EventSequence`][crate::gdk::EventSequence] that was last updated on @self.
348    ///
349    /// # Returns
350    ///
351    /// The last updated sequence
352    #[doc(alias = "gtk_gesture_get_last_updated_sequence")]
353    #[doc(alias = "get_last_updated_sequence")]
354    fn last_updated_sequence(&self) -> Option<gdk::EventSequence> {
355        unsafe {
356            from_glib_none(ffi::gtk_gesture_get_last_updated_sequence(
357                self.as_ref().to_glib_none().0,
358            ))
359        }
360    }
361
362    /// If @sequence is currently being interpreted by @self,
363    /// returns [`true`] and fills in @x and @y with the last coordinates
364    /// stored for that event sequence.
365    ///
366    /// The coordinates are always relative to the widget allocation.
367    /// ## `sequence`
368    /// a [`gdk::EventSequence`][crate::gdk::EventSequence], or [`None`] for pointer events
369    ///
370    /// # Returns
371    ///
372    /// [`true`] if @sequence is currently interpreted
373    ///
374    /// ## `x`
375    /// return location for X axis of the sequence coordinates
376    ///
377    /// ## `y`
378    /// return location for Y axis of the sequence coordinates
379    #[doc(alias = "gtk_gesture_get_point")]
380    #[doc(alias = "get_point")]
381    fn point(&self, sequence: Option<&gdk::EventSequence>) -> Option<(f64, f64)> {
382        unsafe {
383            let mut x = std::mem::MaybeUninit::uninit();
384            let mut y = std::mem::MaybeUninit::uninit();
385            let ret = from_glib(ffi::gtk_gesture_get_point(
386                self.as_ref().to_glib_none().0,
387                mut_override(sequence.to_glib_none().0),
388                x.as_mut_ptr(),
389                y.as_mut_ptr(),
390            ));
391            if ret {
392                Some((x.assume_init(), y.assume_init()))
393            } else {
394                None
395            }
396        }
397    }
398
399    /// Returns the @sequence state, as seen by @self.
400    /// ## `sequence`
401    /// a [`gdk::EventSequence`][crate::gdk::EventSequence]
402    ///
403    /// # Returns
404    ///
405    /// The sequence state in @self
406    #[doc(alias = "gtk_gesture_get_sequence_state")]
407    #[doc(alias = "get_sequence_state")]
408    fn sequence_state(&self, sequence: &gdk::EventSequence) -> EventSequenceState {
409        unsafe {
410            from_glib(ffi::gtk_gesture_get_sequence_state(
411                self.as_ref().to_glib_none().0,
412                mut_override(sequence.to_glib_none().0),
413            ))
414        }
415    }
416
417    /// Returns the list of `GdkEventSequences` currently being interpreted
418    /// by @self.
419    ///
420    /// # Returns
421    ///
422    /// A list
423    ///   of [`gdk::EventSequence`][crate::gdk::EventSequence], the list elements are owned by GTK and must
424    ///   not be freed or modified, the list itself must be deleted
425    ///   through g_list_free()
426    #[doc(alias = "gtk_gesture_get_sequences")]
427    #[doc(alias = "get_sequences")]
428    fn sequences(&self) -> Vec<gdk::EventSequence> {
429        unsafe {
430            FromGlibPtrContainer::from_glib_container(ffi::gtk_gesture_get_sequences(
431                self.as_ref().to_glib_none().0,
432            ))
433        }
434    }
435
436    /// Adds @gesture to the same group than @self.
437    ///
438    /// Gestures are by default isolated in their own groups.
439    ///
440    /// Both gestures must have been added to the same widget before
441    /// they can be grouped.
442    ///
443    /// When gestures are grouped, the state of `GdkEventSequences`
444    /// is kept in sync for all of those, so calling
445    /// [`set_sequence_state()`][Self::set_sequence_state()], on one will transfer
446    /// the same value to the others.
447    ///
448    /// Groups also perform an "implicit grabbing" of sequences, if a
449    /// [`gdk::EventSequence`][crate::gdk::EventSequence] state is set to [`EventSequenceState::Claimed`][crate::EventSequenceState::Claimed]
450    /// on one group, every other gesture group attached to the same
451    /// [`Widget`][crate::Widget] will switch the state for that sequence to
452    /// [`EventSequenceState::Denied`][crate::EventSequenceState::Denied].
453    /// ## `gesture`
454    /// a [`Gesture`][crate::Gesture]
455    #[doc(alias = "gtk_gesture_group")]
456    #[doc(alias = "group")]
457    fn group_with(&self, gesture: &impl IsA<Gesture>) {
458        unsafe {
459            ffi::gtk_gesture_group(
460                self.as_ref().to_glib_none().0,
461                gesture.as_ref().to_glib_none().0,
462            );
463        }
464    }
465
466    /// Returns [`true`] if @self is currently handling events
467    /// corresponding to @sequence.
468    /// ## `sequence`
469    /// a [`gdk::EventSequence`][crate::gdk::EventSequence]
470    ///
471    /// # Returns
472    ///
473    /// [`true`] if @self is handling @sequence, [`false`] otherwise
474    #[doc(alias = "gtk_gesture_handles_sequence")]
475    fn handles_sequence(&self, sequence: Option<&gdk::EventSequence>) -> bool {
476        unsafe {
477            from_glib(ffi::gtk_gesture_handles_sequence(
478                self.as_ref().to_glib_none().0,
479                mut_override(sequence.to_glib_none().0),
480            ))
481        }
482    }
483
484    /// Returns [`true`] if the gesture is currently active.
485    ///
486    /// A gesture is active while there are touch sequences
487    /// interacting with it.
488    ///
489    /// # Returns
490    ///
491    /// [`true`] if gesture is active
492    #[doc(alias = "gtk_gesture_is_active")]
493    fn is_active(&self) -> bool {
494        unsafe { from_glib(ffi::gtk_gesture_is_active(self.as_ref().to_glib_none().0)) }
495    }
496
497    /// Returns [`true`] if both gestures pertain to the same group.
498    /// ## `other`
499    /// another [`Gesture`][crate::Gesture]
500    ///
501    /// # Returns
502    ///
503    /// whether the gestures are grouped
504    #[doc(alias = "gtk_gesture_is_grouped_with")]
505    fn is_grouped_with(&self, other: &impl IsA<Gesture>) -> bool {
506        unsafe {
507            from_glib(ffi::gtk_gesture_is_grouped_with(
508                self.as_ref().to_glib_none().0,
509                other.as_ref().to_glib_none().0,
510            ))
511        }
512    }
513
514    /// Returns [`true`] if the gesture is currently recognized.
515    ///
516    /// A gesture is recognized if there are as many interacting
517    /// touch sequences as required by @self.
518    ///
519    /// # Returns
520    ///
521    /// [`true`] if gesture is recognized
522    #[doc(alias = "gtk_gesture_is_recognized")]
523    fn is_recognized(&self) -> bool {
524        unsafe {
525            from_glib(ffi::gtk_gesture_is_recognized(
526                self.as_ref().to_glib_none().0,
527            ))
528        }
529    }
530
531    /// Sets the state of @sequence in @self.
532    ///
533    /// Sequences start in state [`EventSequenceState::None`][crate::EventSequenceState::None], and whenever
534    /// they change state, they can never go back to that state. Likewise,
535    /// sequences in state [`EventSequenceState::Denied`][crate::EventSequenceState::Denied] cannot turn back to
536    /// a not denied state. With these rules, the lifetime of an event
537    /// sequence is constrained to the next four:
538    ///
539    /// * None
540    /// * None → Denied
541    /// * None → Claimed
542    /// * None → Claimed → Denied
543    ///
544    /// Note: Due to event handling ordering, it may be unsafe to set the
545    /// state on another gesture within a [`begin`][struct@crate::Gesture#begin] signal
546    /// handler, as the callback might be executed before the other gesture
547    /// knows about the sequence. A safe way to perform this could be:
548    ///
549    /// **⚠️ The following code is in c ⚠️**
550    ///
551    /// ```c
552    /// static void
553    /// first_gesture_begin_cb (GtkGesture       *first_gesture,
554    ///                         GdkEventSequence *sequence,
555    ///                         gpointer          user_data)
556    /// {
557    ///   gtk_gesture_set_sequence_state (first_gesture, sequence, GTK_EVENT_SEQUENCE_CLAIMED);
558    ///   gtk_gesture_set_sequence_state (second_gesture, sequence, GTK_EVENT_SEQUENCE_DENIED);
559    /// }
560    ///
561    /// static void
562    /// second_gesture_begin_cb (GtkGesture       *second_gesture,
563    ///                          GdkEventSequence *sequence,
564    ///                          gpointer          user_data)
565    /// {
566    ///   if (gtk_gesture_get_sequence_state (first_gesture, sequence) == GTK_EVENT_SEQUENCE_CLAIMED)
567    ///     gtk_gesture_set_sequence_state (second_gesture, sequence, GTK_EVENT_SEQUENCE_DENIED);
568    /// }
569    /// ```
570    ///
571    /// If both gestures are in the same group, just set the state on
572    /// the gesture emitting the event, the sequence will be already
573    /// be initialized to the group's global state when the second
574    /// gesture processes the event.
575    ///
576    /// # Deprecated since 4.10
577    ///
578    /// Use [`set_state()`][Self::set_state()]
579    /// ## `sequence`
580    /// a [`gdk::EventSequence`][crate::gdk::EventSequence]
581    /// ## `state`
582    /// the sequence state
583    ///
584    /// # Returns
585    ///
586    /// [`true`] if @sequence is handled by @self,
587    ///   and the state is changed successfully
588    #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
589    #[allow(deprecated)]
590    #[doc(alias = "gtk_gesture_set_sequence_state")]
591    fn set_sequence_state(&self, sequence: &gdk::EventSequence, state: EventSequenceState) -> bool {
592        unsafe {
593            from_glib(ffi::gtk_gesture_set_sequence_state(
594                self.as_ref().to_glib_none().0,
595                mut_override(sequence.to_glib_none().0),
596                state.into_glib(),
597            ))
598        }
599    }
600
601    /// Sets the state of all sequences that @self is currently
602    /// interacting with.
603    ///
604    /// Sequences start in state [`EventSequenceState::None`][crate::EventSequenceState::None], and whenever
605    /// they change state, they can never go back to that state. Likewise,
606    /// sequences in state [`EventSequenceState::Denied`][crate::EventSequenceState::Denied] cannot turn back to
607    /// a not denied state. With these rules, the lifetime of an event
608    /// sequence is constrained to the next four:
609    ///
610    /// * None
611    /// * None → Denied
612    /// * None → Claimed
613    /// * None → Claimed → Denied
614    ///
615    /// Note: Due to event handling ordering, it may be unsafe to set the
616    /// state on another gesture within a [`begin`][struct@crate::Gesture#begin] signal
617    /// handler, as the callback might be executed before the other gesture
618    /// knows about the sequence. A safe way to perform this could be:
619    ///
620    /// **⚠️ The following code is in c ⚠️**
621    ///
622    /// ```c
623    /// static void
624    /// first_gesture_begin_cb (GtkGesture       *first_gesture,
625    ///                         GdkEventSequence *sequence,
626    ///                         gpointer          user_data)
627    /// {
628    ///   gtk_gesture_set_state (first_gesture, GTK_EVENT_SEQUENCE_CLAIMED);
629    ///   gtk_gesture_set_state (second_gesture, GTK_EVENT_SEQUENCE_DENIED);
630    /// }
631    ///
632    /// static void
633    /// second_gesture_begin_cb (GtkGesture       *second_gesture,
634    ///                          GdkEventSequence *sequence,
635    ///                          gpointer          user_data)
636    /// {
637    ///   if (gtk_gesture_get_sequence_state (first_gesture, sequence) == GTK_EVENT_SEQUENCE_CLAIMED)
638    ///     gtk_gesture_set_state (second_gesture, GTK_EVENT_SEQUENCE_DENIED);
639    /// }
640    /// ```
641    ///
642    /// If both gestures are in the same group, just set the state on
643    /// the gesture emitting the event, the sequence will be already
644    /// be initialized to the group's global state when the second
645    /// gesture processes the event.
646    /// ## `state`
647    /// the sequence state
648    ///
649    /// # Returns
650    ///
651    /// [`true`] if the state of at least one sequence
652    ///   was changed successfully
653    #[doc(alias = "gtk_gesture_set_state")]
654    fn set_state(&self, state: EventSequenceState) -> bool {
655        unsafe {
656            from_glib(ffi::gtk_gesture_set_state(
657                self.as_ref().to_glib_none().0,
658                state.into_glib(),
659            ))
660        }
661    }
662
663    /// Separates @self into an isolated group.
664    #[doc(alias = "gtk_gesture_ungroup")]
665    fn ungroup(&self) {
666        unsafe {
667            ffi::gtk_gesture_ungroup(self.as_ref().to_glib_none().0);
668        }
669    }
670
671    /// The number of touch points that trigger
672    /// recognition on this gesture.
673    #[doc(alias = "n-points")]
674    fn n_points(&self) -> u32 {
675        ObjectExt::property(self.as_ref(), "n-points")
676    }
677
678    /// Emitted when the gesture is recognized.
679    ///
680    /// This means the number of touch sequences matches
681    /// [`n-points`][struct@crate::Gesture#n-points].
682    ///
683    /// Note: These conditions may also happen when an extra touch
684    /// (eg. a third touch on a 2-touches gesture) is lifted, in that
685    /// situation @sequence won't pertain to the current set of active
686    /// touches, so don't rely on this being true.
687    /// ## `sequence`
688    /// the [`gdk::EventSequence`][crate::gdk::EventSequence] that made the gesture
689    ///   to be recognized
690    #[doc(alias = "begin")]
691    fn connect_begin<F: Fn(&Self, Option<&gdk::EventSequence>) + 'static>(
692        &self,
693        f: F,
694    ) -> SignalHandlerId {
695        unsafe extern "C" fn begin_trampoline<
696            P: IsA<Gesture>,
697            F: Fn(&P, Option<&gdk::EventSequence>) + 'static,
698        >(
699            this: *mut ffi::GtkGesture,
700            sequence: *mut gdk::ffi::GdkEventSequence,
701            f: glib::ffi::gpointer,
702        ) {
703            let f: &F = &*(f as *const F);
704            f(
705                Gesture::from_glib_borrow(this).unsafe_cast_ref(),
706                Option::<gdk::EventSequence>::from_glib_borrow(sequence)
707                    .as_ref()
708                    .as_ref(),
709            )
710        }
711        unsafe {
712            let f: Box_<F> = Box_::new(f);
713            connect_raw(
714                self.as_ptr() as *mut _,
715                c"begin".as_ptr() as *const _,
716                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
717                    begin_trampoline::<Self, F> as *const (),
718                )),
719                Box_::into_raw(f),
720            )
721        }
722    }
723
724    /// Emitted whenever a sequence is cancelled.
725    ///
726    /// This usually happens on active touches when
727    /// [`EventControllerExt::reset()`][crate::prelude::EventControllerExt::reset()] is called on @gesture
728    /// (manually, due to grabs...), or the individual @sequence
729    /// was claimed by parent widgets' controllers (see
730    /// [`set_sequence_state()`][Self::set_sequence_state()]).
731    ///
732    /// @gesture must forget everything about @sequence as in
733    /// response to this signal.
734    /// ## `sequence`
735    /// the [`gdk::EventSequence`][crate::gdk::EventSequence] that was cancelled
736    #[doc(alias = "cancel")]
737    fn connect_cancel<F: Fn(&Self, Option<&gdk::EventSequence>) + 'static>(
738        &self,
739        f: F,
740    ) -> SignalHandlerId {
741        unsafe extern "C" fn cancel_trampoline<
742            P: IsA<Gesture>,
743            F: Fn(&P, Option<&gdk::EventSequence>) + 'static,
744        >(
745            this: *mut ffi::GtkGesture,
746            sequence: *mut gdk::ffi::GdkEventSequence,
747            f: glib::ffi::gpointer,
748        ) {
749            let f: &F = &*(f as *const F);
750            f(
751                Gesture::from_glib_borrow(this).unsafe_cast_ref(),
752                Option::<gdk::EventSequence>::from_glib_borrow(sequence)
753                    .as_ref()
754                    .as_ref(),
755            )
756        }
757        unsafe {
758            let f: Box_<F> = Box_::new(f);
759            connect_raw(
760                self.as_ptr() as *mut _,
761                c"cancel".as_ptr() as *const _,
762                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
763                    cancel_trampoline::<Self, F> as *const (),
764                )),
765                Box_::into_raw(f),
766            )
767        }
768    }
769
770    /// Emitted when @gesture either stopped recognizing the event
771    /// sequences as something to be handled, or the number of touch
772    /// sequences became higher or lower than [`n-points`][struct@crate::Gesture#n-points].
773    ///
774    /// Note: @sequence might not pertain to the group of sequences that
775    /// were previously triggering recognition on @gesture (ie. a just
776    /// pressed touch sequence that exceeds [`n-points`][struct@crate::Gesture#n-points]).
777    /// This situation may be detected by checking through
778    /// [`handles_sequence()`][Self::handles_sequence()].
779    /// ## `sequence`
780    /// the [`gdk::EventSequence`][crate::gdk::EventSequence] that made gesture
781    ///   recognition to finish
782    #[doc(alias = "end")]
783    fn connect_end<F: Fn(&Self, Option<&gdk::EventSequence>) + 'static>(
784        &self,
785        f: F,
786    ) -> SignalHandlerId {
787        unsafe extern "C" fn end_trampoline<
788            P: IsA<Gesture>,
789            F: Fn(&P, Option<&gdk::EventSequence>) + 'static,
790        >(
791            this: *mut ffi::GtkGesture,
792            sequence: *mut gdk::ffi::GdkEventSequence,
793            f: glib::ffi::gpointer,
794        ) {
795            let f: &F = &*(f as *const F);
796            f(
797                Gesture::from_glib_borrow(this).unsafe_cast_ref(),
798                Option::<gdk::EventSequence>::from_glib_borrow(sequence)
799                    .as_ref()
800                    .as_ref(),
801            )
802        }
803        unsafe {
804            let f: Box_<F> = Box_::new(f);
805            connect_raw(
806                self.as_ptr() as *mut _,
807                c"end".as_ptr() as *const _,
808                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
809                    end_trampoline::<Self, F> as *const (),
810                )),
811                Box_::into_raw(f),
812            )
813        }
814    }
815
816    /// Emitted whenever a sequence state changes.
817    ///
818    /// See [`set_sequence_state()`][Self::set_sequence_state()] to know
819    /// more about the expectable sequence lifetimes.
820    /// ## `sequence`
821    /// the [`gdk::EventSequence`][crate::gdk::EventSequence] that was cancelled
822    /// ## `state`
823    /// the new sequence state
824    #[doc(alias = "sequence-state-changed")]
825    fn connect_sequence_state_changed<
826        F: Fn(&Self, Option<&gdk::EventSequence>, EventSequenceState) + 'static,
827    >(
828        &self,
829        f: F,
830    ) -> SignalHandlerId {
831        unsafe extern "C" fn sequence_state_changed_trampoline<
832            P: IsA<Gesture>,
833            F: Fn(&P, Option<&gdk::EventSequence>, EventSequenceState) + 'static,
834        >(
835            this: *mut ffi::GtkGesture,
836            sequence: *mut gdk::ffi::GdkEventSequence,
837            state: ffi::GtkEventSequenceState,
838            f: glib::ffi::gpointer,
839        ) {
840            let f: &F = &*(f as *const F);
841            f(
842                Gesture::from_glib_borrow(this).unsafe_cast_ref(),
843                Option::<gdk::EventSequence>::from_glib_borrow(sequence)
844                    .as_ref()
845                    .as_ref(),
846                from_glib(state),
847            )
848        }
849        unsafe {
850            let f: Box_<F> = Box_::new(f);
851            connect_raw(
852                self.as_ptr() as *mut _,
853                c"sequence-state-changed".as_ptr() as *const _,
854                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
855                    sequence_state_changed_trampoline::<Self, F> as *const (),
856                )),
857                Box_::into_raw(f),
858            )
859        }
860    }
861
862    /// Emitted whenever an event is handled while the gesture is recognized.
863    ///
864    /// @sequence is guaranteed to pertain to the set of active touches.
865    /// ## `sequence`
866    /// the [`gdk::EventSequence`][crate::gdk::EventSequence] that was updated
867    #[doc(alias = "update")]
868    fn connect_update<F: Fn(&Self, Option<&gdk::EventSequence>) + 'static>(
869        &self,
870        f: F,
871    ) -> SignalHandlerId {
872        unsafe extern "C" fn update_trampoline<
873            P: IsA<Gesture>,
874            F: Fn(&P, Option<&gdk::EventSequence>) + 'static,
875        >(
876            this: *mut ffi::GtkGesture,
877            sequence: *mut gdk::ffi::GdkEventSequence,
878            f: glib::ffi::gpointer,
879        ) {
880            let f: &F = &*(f as *const F);
881            f(
882                Gesture::from_glib_borrow(this).unsafe_cast_ref(),
883                Option::<gdk::EventSequence>::from_glib_borrow(sequence)
884                    .as_ref()
885                    .as_ref(),
886            )
887        }
888        unsafe {
889            let f: Box_<F> = Box_::new(f);
890            connect_raw(
891                self.as_ptr() as *mut _,
892                c"update".as_ptr() as *const _,
893                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
894                    update_trampoline::<Self, F> as *const (),
895                )),
896                Box_::into_raw(f),
897            )
898        }
899    }
900}
901
902impl<O: IsA<Gesture>> GestureExt for O {}