Skip to main content

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