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