gtk4/auto/
drag_source.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::{ffi, EventController, Gesture, GestureSingle, PropagationLimit, PropagationPhase};
6use glib::{
7    object::ObjectType as _,
8    prelude::*,
9    signal::{connect_raw, SignalHandlerId},
10    translate::*,
11};
12use std::boxed::Box as Box_;
13
14glib::wrapper! {
15    /// [`DragSource`][crate::DragSource] is an event controller to initiate Drag-And-Drop operations.
16    ///
17    /// [`DragSource`][crate::DragSource] can be set up with the necessary
18    /// ingredients for a DND operation ahead of time. This includes
19    /// the source for the data that is being transferred, in the form
20    /// of a [`gdk::ContentProvider`][crate::gdk::ContentProvider], the desired action, and the icon to
21    /// use during the drag operation. After setting it up, the drag
22    /// source must be added to a widget as an event controller, using
23    /// [`WidgetExt::add_controller()`][crate::prelude::WidgetExt::add_controller()].
24    ///
25    /// **⚠️ The following code is in c ⚠️**
26    ///
27    /// ```c
28    /// static void
29    /// my_widget_init (MyWidget *self)
30    /// {
31    ///   GtkDragSource *drag_source = gtk_drag_source_new ();
32    ///
33    ///   g_signal_connect (drag_source, "prepare", G_CALLBACK (on_drag_prepare), self);
34    ///   g_signal_connect (drag_source, "drag-begin", G_CALLBACK (on_drag_begin), self);
35    ///
36    ///   gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (drag_source));
37    /// }
38    /// ```
39    ///
40    /// Setting up the content provider and icon ahead of time only makes
41    /// sense when the data does not change. More commonly, you will want
42    /// to set them up just in time. To do so, [`DragSource`][crate::DragSource] has
43    /// [`prepare`][struct@crate::DragSource#prepare] and [`drag-begin`][struct@crate::DragSource#drag-begin]
44    /// signals.
45    ///
46    /// The ::prepare signal is emitted before a drag is started, and
47    /// can be used to set the content provider and actions that the
48    /// drag should be started with.
49    ///
50    /// **⚠️ The following code is in c ⚠️**
51    ///
52    /// ```c
53    /// static GdkContentProvider *
54    /// on_drag_prepare (GtkDragSource *source,
55    ///                  double         x,
56    ///                  double         y,
57    ///                  MyWidget      *self)
58    /// {
59    ///   // This widget supports two types of content: GFile objects
60    ///   // and GdkPixbuf objects; GTK will handle the serialization
61    ///   // of these types automatically
62    ///   GFile *file = my_widget_get_file (self);
63    ///   GdkPixbuf *pixbuf = my_widget_get_pixbuf (self);
64    ///
65    ///   return gdk_content_provider_new_union ((GdkContentProvider *[2]) {
66    ///       gdk_content_provider_new_typed (G_TYPE_FILE, file),
67    ///       gdk_content_provider_new_typed (GDK_TYPE_PIXBUF, pixbuf),
68    ///     }, 2);
69    /// }
70    /// ```
71    ///
72    /// The ::drag-begin signal is emitted after the [`gdk::Drag`][crate::gdk::Drag] object has
73    /// been created, and can be used to set up the drag icon.
74    ///
75    /// **⚠️ The following code is in c ⚠️**
76    ///
77    /// ```c
78    /// static void
79    /// on_drag_begin (GtkDragSource *source,
80    ///                GdkDrag       *drag,
81    ///                MyWidget      *self)
82    /// {
83    ///   // Set the widget as the drag icon
84    ///   GdkPaintable *paintable = gtk_widget_paintable_new (GTK_WIDGET (self));
85    ///   gtk_drag_source_set_icon (source, paintable, 0, 0);
86    ///   g_object_unref (paintable);
87    /// }
88    /// ```
89    ///
90    /// During the DND operation, [`DragSource`][crate::DragSource] emits signals that
91    /// can be used to obtain updates about the status of the operation,
92    /// but it is not normally necessary to connect to any signals,
93    /// except for one case: when the supported actions include
94    /// [`gdk::DragAction::MOVE`][crate::gdk::DragAction::MOVE], you need to listen for the
95    /// [`drag-end`][struct@crate::DragSource#drag-end] signal and delete the
96    /// data after it has been transferred.
97    ///
98    /// ## Properties
99    ///
100    ///
101    /// #### `actions`
102    ///  The actions that are supported by drag operations from the source.
103    ///
104    /// Note that you must handle the [`drag-end`][struct@crate::DragSource#drag-end] signal
105    /// if the actions include [`gdk::DragAction::MOVE`][crate::gdk::DragAction::MOVE].
106    ///
107    /// Readable | Writeable
108    ///
109    ///
110    /// #### `content`
111    ///  The data that is offered by drag operations from this source.
112    ///
113    /// Readable | Writeable
114    /// <details><summary><h4>GestureSingle</h4></summary>
115    ///
116    ///
117    /// #### `button`
118    ///  Mouse button number to listen to, or 0 to listen for any button.
119    ///
120    /// Readable | Writeable
121    ///
122    ///
123    /// #### `exclusive`
124    ///  Whether the gesture is exclusive.
125    ///
126    /// Exclusive gestures only listen to pointer and pointer emulated events.
127    ///
128    /// Readable | Writeable
129    ///
130    ///
131    /// #### `touch-only`
132    ///  Whether the gesture handles only touch events.
133    ///
134    /// Readable | Writeable
135    /// </details>
136    /// <details><summary><h4>Gesture</h4></summary>
137    ///
138    ///
139    /// #### `n-points`
140    ///  The number of touch points that trigger
141    /// recognition on this gesture.
142    ///
143    /// Readable | Writeable | Construct Only
144    /// </details>
145    /// <details><summary><h4>EventController</h4></summary>
146    ///
147    ///
148    /// #### `name`
149    ///  The name for this controller, typically used for debugging purposes.
150    ///
151    /// Readable | Writeable
152    ///
153    ///
154    /// #### `propagation-limit`
155    ///  The limit for which events this controller will handle.
156    ///
157    /// Readable | Writeable
158    ///
159    ///
160    /// #### `propagation-phase`
161    ///  The propagation phase at which this controller will handle events.
162    ///
163    /// Readable | Writeable
164    ///
165    ///
166    /// #### `widget`
167    ///  The widget receiving the `GdkEvents` that the controller will handle.
168    ///
169    /// Readable
170    /// </details>
171    ///
172    /// ## Signals
173    ///
174    ///
175    /// #### `drag-begin`
176    ///  Emitted on the drag source when a drag is started.
177    ///
178    /// It can be used to e.g. set a custom drag icon with
179    /// [`DragSource::set_icon()`][crate::DragSource::set_icon()].
180    ///
181    ///
182    ///
183    ///
184    /// #### `drag-cancel`
185    ///  Emitted on the drag source when a drag has failed.
186    ///
187    /// The signal handler may handle a failed drag operation based on
188    /// the type of error. It should return [`true`] if the failure has been handled
189    /// and the default "drag operation failed" animation should not be shown.
190    ///
191    ///
192    ///
193    ///
194    /// #### `drag-end`
195    ///  Emitted on the drag source when a drag is finished.
196    ///
197    /// A typical reason to connect to this signal is to undo
198    /// things done in [`prepare`][struct@crate::DragSource#prepare] or
199    /// [`drag-begin`][struct@crate::DragSource#drag-begin] handlers.
200    ///
201    ///
202    ///
203    ///
204    /// #### `prepare`
205    ///  Emitted when a drag is about to be initiated.
206    ///
207    /// It returns the [`gdk::ContentProvider`][crate::gdk::ContentProvider] to use for the drag that is about
208    /// to start. The default handler for this signal returns the value of
209    /// the [`content`][struct@crate::DragSource#content] property, so if you set up that
210    /// property ahead of time, you don't need to connect to this signal.
211    ///
212    ///
213    /// <details><summary><h4>Gesture</h4></summary>
214    ///
215    ///
216    /// #### `begin`
217    ///  Emitted when the gesture is recognized.
218    ///
219    /// This means the number of touch sequences matches
220    /// [`n-points`][struct@crate::Gesture#n-points].
221    ///
222    /// Note: These conditions may also happen when an extra touch
223    /// (eg. a third touch on a 2-touches gesture) is lifted, in that
224    /// situation @sequence won't pertain to the current set of active
225    /// touches, so don't rely on this being true.
226    ///
227    ///
228    ///
229    ///
230    /// #### `cancel`
231    ///  Emitted whenever a sequence is cancelled.
232    ///
233    /// This usually happens on active touches when
234    /// [`EventControllerExt::reset()`][crate::prelude::EventControllerExt::reset()] is called on @gesture
235    /// (manually, due to grabs...), or the individual @sequence
236    /// was claimed by parent widgets' controllers (see
237    /// [`GestureExt::set_sequence_state()`][crate::prelude::GestureExt::set_sequence_state()]).
238    ///
239    /// @gesture must forget everything about @sequence as in
240    /// response to this signal.
241    ///
242    ///
243    ///
244    ///
245    /// #### `end`
246    ///  Emitted when @gesture either stopped recognizing the event
247    /// sequences as something to be handled, or the number of touch
248    /// sequences became higher or lower than [`n-points`][struct@crate::Gesture#n-points].
249    ///
250    /// Note: @sequence might not pertain to the group of sequences that
251    /// were previously triggering recognition on @gesture (ie. a just
252    /// pressed touch sequence that exceeds [`n-points`][struct@crate::Gesture#n-points]).
253    /// This situation may be detected by checking through
254    /// [`GestureExt::handles_sequence()`][crate::prelude::GestureExt::handles_sequence()].
255    ///
256    ///
257    ///
258    ///
259    /// #### `sequence-state-changed`
260    ///  Emitted whenever a sequence state changes.
261    ///
262    /// See [`GestureExt::set_sequence_state()`][crate::prelude::GestureExt::set_sequence_state()] to know
263    /// more about the expectable sequence lifetimes.
264    ///
265    ///
266    ///
267    ///
268    /// #### `update`
269    ///  Emitted whenever an event is handled while the gesture is recognized.
270    ///
271    /// @sequence is guaranteed to pertain to the set of active touches.
272    ///
273    ///
274    /// </details>
275    ///
276    /// # Implements
277    ///
278    /// [`GestureSingleExt`][trait@crate::prelude::GestureSingleExt], [`GestureExt`][trait@crate::prelude::GestureExt], [`EventControllerExt`][trait@crate::prelude::EventControllerExt], [`trait@glib::ObjectExt`]
279    #[doc(alias = "GtkDragSource")]
280    pub struct DragSource(Object<ffi::GtkDragSource, ffi::GtkDragSourceClass>) @extends GestureSingle, Gesture, EventController;
281
282    match fn {
283        type_ => || ffi::gtk_drag_source_get_type(),
284    }
285}
286
287impl DragSource {
288    /// Creates a new [`DragSource`][crate::DragSource] object.
289    ///
290    /// # Returns
291    ///
292    /// the new [`DragSource`][crate::DragSource]
293    #[doc(alias = "gtk_drag_source_new")]
294    pub fn new() -> DragSource {
295        assert_initialized_main_thread!();
296        unsafe { from_glib_full(ffi::gtk_drag_source_new()) }
297    }
298
299    // rustdoc-stripper-ignore-next
300    /// Creates a new builder-pattern struct instance to construct [`DragSource`] objects.
301    ///
302    /// This method returns an instance of [`DragSourceBuilder`](crate::builders::DragSourceBuilder) which can be used to create [`DragSource`] objects.
303    pub fn builder() -> DragSourceBuilder {
304        DragSourceBuilder::new()
305    }
306
307    /// Cancels a currently ongoing drag operation.
308    #[doc(alias = "gtk_drag_source_drag_cancel")]
309    pub fn drag_cancel(&self) {
310        unsafe {
311            ffi::gtk_drag_source_drag_cancel(self.to_glib_none().0);
312        }
313    }
314
315    /// Gets the actions that are currently set on the [`DragSource`][crate::DragSource].
316    ///
317    /// # Returns
318    ///
319    /// the actions set on @self
320    #[doc(alias = "gtk_drag_source_get_actions")]
321    #[doc(alias = "get_actions")]
322    pub fn actions(&self) -> gdk::DragAction {
323        unsafe { from_glib(ffi::gtk_drag_source_get_actions(self.to_glib_none().0)) }
324    }
325
326    /// Gets the current content provider of a [`DragSource`][crate::DragSource].
327    ///
328    /// # Returns
329    ///
330    /// the [`gdk::ContentProvider`][crate::gdk::ContentProvider] of @self
331    #[doc(alias = "gtk_drag_source_get_content")]
332    #[doc(alias = "get_content")]
333    pub fn content(&self) -> Option<gdk::ContentProvider> {
334        unsafe { from_glib_none(ffi::gtk_drag_source_get_content(self.to_glib_none().0)) }
335    }
336
337    /// Returns the underlying [`gdk::Drag`][crate::gdk::Drag] object for an ongoing drag.
338    ///
339    /// # Returns
340    ///
341    /// the [`gdk::Drag`][crate::gdk::Drag] of the current
342    ///   drag operation
343    #[doc(alias = "gtk_drag_source_get_drag")]
344    #[doc(alias = "get_drag")]
345    pub fn drag(&self) -> Option<gdk::Drag> {
346        unsafe { from_glib_none(ffi::gtk_drag_source_get_drag(self.to_glib_none().0)) }
347    }
348
349    /// Sets the actions on the [`DragSource`][crate::DragSource].
350    ///
351    /// During a DND operation, the actions are offered to potential
352    /// drop targets. If @actions include [`gdk::DragAction::MOVE`][crate::gdk::DragAction::MOVE], you need
353    /// to listen to the [`drag-end`][struct@crate::DragSource#drag-end] signal and
354    /// handle @delete_data being [`true`].
355    ///
356    /// This function can be called before a drag is started,
357    /// or in a handler for the [`prepare`][struct@crate::DragSource#prepare] signal.
358    /// ## `actions`
359    /// the actions to offer
360    #[doc(alias = "gtk_drag_source_set_actions")]
361    #[doc(alias = "actions")]
362    pub fn set_actions(&self, actions: gdk::DragAction) {
363        unsafe {
364            ffi::gtk_drag_source_set_actions(self.to_glib_none().0, actions.into_glib());
365        }
366    }
367
368    /// Sets a content provider on a [`DragSource`][crate::DragSource].
369    ///
370    /// When the data is requested in the cause of a DND operation,
371    /// it will be obtained from the content provider.
372    ///
373    /// This function can be called before a drag is started,
374    /// or in a handler for the [`prepare`][struct@crate::DragSource#prepare] signal.
375    ///
376    /// You may consider setting the content provider back to
377    /// [`None`] in a [`drag-end`][struct@crate::DragSource#drag-end] signal handler.
378    /// ## `content`
379    /// a [`gdk::ContentProvider`][crate::gdk::ContentProvider]
380    #[doc(alias = "gtk_drag_source_set_content")]
381    #[doc(alias = "content")]
382    pub fn set_content(&self, content: Option<&impl IsA<gdk::ContentProvider>>) {
383        unsafe {
384            ffi::gtk_drag_source_set_content(
385                self.to_glib_none().0,
386                content.map(|p| p.as_ref()).to_glib_none().0,
387            );
388        }
389    }
390
391    /// Sets a paintable to use as icon during DND operations.
392    ///
393    /// The hotspot coordinates determine the point on the icon
394    /// that gets aligned with the hotspot of the cursor.
395    ///
396    /// If @paintable is [`None`], a default icon is used.
397    ///
398    /// This function can be called before a drag is started, or in
399    /// a [`prepare`][struct@crate::DragSource#prepare] or
400    /// [`drag-begin`][struct@crate::DragSource#drag-begin] signal handler.
401    /// ## `paintable`
402    /// the [`gdk::Paintable`][crate::gdk::Paintable] to use as icon
403    /// ## `hot_x`
404    /// the hotspot X coordinate on the icon
405    /// ## `hot_y`
406    /// the hotspot Y coordinate on the icon
407    #[doc(alias = "gtk_drag_source_set_icon")]
408    pub fn set_icon(&self, paintable: Option<&impl IsA<gdk::Paintable>>, hot_x: i32, hot_y: i32) {
409        unsafe {
410            ffi::gtk_drag_source_set_icon(
411                self.to_glib_none().0,
412                paintable.map(|p| p.as_ref()).to_glib_none().0,
413                hot_x,
414                hot_y,
415            );
416        }
417    }
418
419    /// Emitted on the drag source when a drag is started.
420    ///
421    /// It can be used to e.g. set a custom drag icon with
422    /// [`set_icon()`][Self::set_icon()].
423    /// ## `drag`
424    /// the [`gdk::Drag`][crate::gdk::Drag] object
425    #[doc(alias = "drag-begin")]
426    pub fn connect_drag_begin<F: Fn(&Self, &gdk::Drag) + 'static>(&self, f: F) -> SignalHandlerId {
427        unsafe extern "C" fn drag_begin_trampoline<F: Fn(&DragSource, &gdk::Drag) + 'static>(
428            this: *mut ffi::GtkDragSource,
429            drag: *mut gdk::ffi::GdkDrag,
430            f: glib::ffi::gpointer,
431        ) {
432            let f: &F = &*(f as *const F);
433            f(&from_glib_borrow(this), &from_glib_borrow(drag))
434        }
435        unsafe {
436            let f: Box_<F> = Box_::new(f);
437            connect_raw(
438                self.as_ptr() as *mut _,
439                b"drag-begin\0".as_ptr() as *const _,
440                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
441                    drag_begin_trampoline::<F> as *const (),
442                )),
443                Box_::into_raw(f),
444            )
445        }
446    }
447
448    /// Emitted on the drag source when a drag has failed.
449    ///
450    /// The signal handler may handle a failed drag operation based on
451    /// the type of error. It should return [`true`] if the failure has been handled
452    /// and the default "drag operation failed" animation should not be shown.
453    /// ## `drag`
454    /// the [`gdk::Drag`][crate::gdk::Drag] object
455    /// ## `reason`
456    /// information on why the drag failed
457    ///
458    /// # Returns
459    ///
460    /// [`true`] if the failed drag operation has been already handled
461    #[doc(alias = "drag-cancel")]
462    pub fn connect_drag_cancel<
463        F: Fn(&Self, &gdk::Drag, gdk::DragCancelReason) -> bool + 'static,
464    >(
465        &self,
466        f: F,
467    ) -> SignalHandlerId {
468        unsafe extern "C" fn drag_cancel_trampoline<
469            F: Fn(&DragSource, &gdk::Drag, gdk::DragCancelReason) -> bool + 'static,
470        >(
471            this: *mut ffi::GtkDragSource,
472            drag: *mut gdk::ffi::GdkDrag,
473            reason: gdk::ffi::GdkDragCancelReason,
474            f: glib::ffi::gpointer,
475        ) -> glib::ffi::gboolean {
476            let f: &F = &*(f as *const F);
477            f(
478                &from_glib_borrow(this),
479                &from_glib_borrow(drag),
480                from_glib(reason),
481            )
482            .into_glib()
483        }
484        unsafe {
485            let f: Box_<F> = Box_::new(f);
486            connect_raw(
487                self.as_ptr() as *mut _,
488                b"drag-cancel\0".as_ptr() as *const _,
489                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
490                    drag_cancel_trampoline::<F> as *const (),
491                )),
492                Box_::into_raw(f),
493            )
494        }
495    }
496
497    /// Emitted on the drag source when a drag is finished.
498    ///
499    /// A typical reason to connect to this signal is to undo
500    /// things done in [`prepare`][struct@crate::DragSource#prepare] or
501    /// [`drag-begin`][struct@crate::DragSource#drag-begin] handlers.
502    /// ## `drag`
503    /// the [`gdk::Drag`][crate::gdk::Drag] object
504    /// ## `delete_data`
505    /// [`true`] if the drag was performing [`gdk::DragAction::MOVE`][crate::gdk::DragAction::MOVE],
506    ///    and the data should be deleted
507    #[doc(alias = "drag-end")]
508    pub fn connect_drag_end<F: Fn(&Self, &gdk::Drag, bool) + 'static>(
509        &self,
510        f: F,
511    ) -> SignalHandlerId {
512        unsafe extern "C" fn drag_end_trampoline<F: Fn(&DragSource, &gdk::Drag, bool) + 'static>(
513            this: *mut ffi::GtkDragSource,
514            drag: *mut gdk::ffi::GdkDrag,
515            delete_data: glib::ffi::gboolean,
516            f: glib::ffi::gpointer,
517        ) {
518            let f: &F = &*(f as *const F);
519            f(
520                &from_glib_borrow(this),
521                &from_glib_borrow(drag),
522                from_glib(delete_data),
523            )
524        }
525        unsafe {
526            let f: Box_<F> = Box_::new(f);
527            connect_raw(
528                self.as_ptr() as *mut _,
529                b"drag-end\0".as_ptr() as *const _,
530                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
531                    drag_end_trampoline::<F> as *const (),
532                )),
533                Box_::into_raw(f),
534            )
535        }
536    }
537
538    /// Emitted when a drag is about to be initiated.
539    ///
540    /// It returns the [`gdk::ContentProvider`][crate::gdk::ContentProvider] to use for the drag that is about
541    /// to start. The default handler for this signal returns the value of
542    /// the [`content`][struct@crate::DragSource#content] property, so if you set up that
543    /// property ahead of time, you don't need to connect to this signal.
544    /// ## `x`
545    /// the X coordinate of the drag starting point
546    /// ## `y`
547    /// the Y coordinate of the drag starting point
548    ///
549    /// # Returns
550    ///
551    /// a [`gdk::ContentProvider`][crate::gdk::ContentProvider]
552    #[doc(alias = "prepare")]
553    pub fn connect_prepare<F: Fn(&Self, f64, f64) -> Option<gdk::ContentProvider> + 'static>(
554        &self,
555        f: F,
556    ) -> SignalHandlerId {
557        unsafe extern "C" fn prepare_trampoline<
558            F: Fn(&DragSource, f64, f64) -> Option<gdk::ContentProvider> + 'static,
559        >(
560            this: *mut ffi::GtkDragSource,
561            x: std::ffi::c_double,
562            y: std::ffi::c_double,
563            f: glib::ffi::gpointer,
564        ) -> *mut gdk::ffi::GdkContentProvider {
565            let f: &F = &*(f as *const F);
566            f(&from_glib_borrow(this), x, y).to_glib_full()
567        }
568        unsafe {
569            let f: Box_<F> = Box_::new(f);
570            connect_raw(
571                self.as_ptr() as *mut _,
572                b"prepare\0".as_ptr() as *const _,
573                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
574                    prepare_trampoline::<F> as *const (),
575                )),
576                Box_::into_raw(f),
577            )
578        }
579    }
580
581    #[doc(alias = "actions")]
582    pub fn connect_actions_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
583        unsafe extern "C" fn notify_actions_trampoline<F: Fn(&DragSource) + 'static>(
584            this: *mut ffi::GtkDragSource,
585            _param_spec: glib::ffi::gpointer,
586            f: glib::ffi::gpointer,
587        ) {
588            let f: &F = &*(f as *const F);
589            f(&from_glib_borrow(this))
590        }
591        unsafe {
592            let f: Box_<F> = Box_::new(f);
593            connect_raw(
594                self.as_ptr() as *mut _,
595                b"notify::actions\0".as_ptr() as *const _,
596                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
597                    notify_actions_trampoline::<F> as *const (),
598                )),
599                Box_::into_raw(f),
600            )
601        }
602    }
603
604    #[doc(alias = "content")]
605    pub fn connect_content_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
606        unsafe extern "C" fn notify_content_trampoline<F: Fn(&DragSource) + 'static>(
607            this: *mut ffi::GtkDragSource,
608            _param_spec: glib::ffi::gpointer,
609            f: glib::ffi::gpointer,
610        ) {
611            let f: &F = &*(f as *const F);
612            f(&from_glib_borrow(this))
613        }
614        unsafe {
615            let f: Box_<F> = Box_::new(f);
616            connect_raw(
617                self.as_ptr() as *mut _,
618                b"notify::content\0".as_ptr() as *const _,
619                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
620                    notify_content_trampoline::<F> as *const (),
621                )),
622                Box_::into_raw(f),
623            )
624        }
625    }
626}
627
628impl Default for DragSource {
629    fn default() -> Self {
630        Self::new()
631    }
632}
633
634// rustdoc-stripper-ignore-next
635/// A [builder-pattern] type to construct [`DragSource`] objects.
636///
637/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html
638#[must_use = "The builder must be built to be used"]
639pub struct DragSourceBuilder {
640    builder: glib::object::ObjectBuilder<'static, DragSource>,
641}
642
643impl DragSourceBuilder {
644    fn new() -> Self {
645        Self {
646            builder: glib::object::Object::builder(),
647        }
648    }
649
650    /// The actions that are supported by drag operations from the source.
651    ///
652    /// Note that you must handle the [`drag-end`][struct@crate::DragSource#drag-end] signal
653    /// if the actions include [`gdk::DragAction::MOVE`][crate::gdk::DragAction::MOVE].
654    pub fn actions(self, actions: gdk::DragAction) -> Self {
655        Self {
656            builder: self.builder.property("actions", actions),
657        }
658    }
659
660    /// The data that is offered by drag operations from this source.
661    pub fn content(self, content: &impl IsA<gdk::ContentProvider>) -> Self {
662        Self {
663            builder: self.builder.property("content", content.clone().upcast()),
664        }
665    }
666
667    /// Mouse button number to listen to, or 0 to listen for any button.
668    pub fn button(self, button: u32) -> Self {
669        Self {
670            builder: self.builder.property("button", button),
671        }
672    }
673
674    /// Whether the gesture is exclusive.
675    ///
676    /// Exclusive gestures only listen to pointer and pointer emulated events.
677    pub fn exclusive(self, exclusive: bool) -> Self {
678        Self {
679            builder: self.builder.property("exclusive", exclusive),
680        }
681    }
682
683    /// Whether the gesture handles only touch events.
684    pub fn touch_only(self, touch_only: bool) -> Self {
685        Self {
686            builder: self.builder.property("touch-only", touch_only),
687        }
688    }
689
690    /// The number of touch points that trigger
691    /// recognition on this gesture.
692    pub fn n_points(self, n_points: u32) -> Self {
693        Self {
694            builder: self.builder.property("n-points", n_points),
695        }
696    }
697
698    /// The name for this controller, typically used for debugging purposes.
699    pub fn name(self, name: impl Into<glib::GString>) -> Self {
700        Self {
701            builder: self.builder.property("name", name.into()),
702        }
703    }
704
705    /// The limit for which events this controller will handle.
706    pub fn propagation_limit(self, propagation_limit: PropagationLimit) -> Self {
707        Self {
708            builder: self
709                .builder
710                .property("propagation-limit", propagation_limit),
711        }
712    }
713
714    /// The propagation phase at which this controller will handle events.
715    pub fn propagation_phase(self, propagation_phase: PropagationPhase) -> Self {
716        Self {
717            builder: self
718                .builder
719                .property("propagation-phase", propagation_phase),
720        }
721    }
722
723    // rustdoc-stripper-ignore-next
724    /// Build the [`DragSource`].
725    #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"]
726    pub fn build(self) -> DragSource {
727        assert_initialized_main_thread!();
728        self.builder.build()
729    }
730}