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