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}