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