gdk4/auto/
drop.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, ContentFormats, Device, Display, Drag, DragAction, Surface};
6use glib::{
7    prelude::*,
8    signal::{connect_raw, SignalHandlerId},
9    translate::*,
10};
11use std::{boxed::Box as Box_, pin::Pin};
12
13glib::wrapper! {
14    /// Represents the target of an ongoing DND operation.
15    ///
16    /// Possible drop sites get informed about the status of the ongoing drag
17    /// operation with events of type `GDK_DRAG_ENTER`, `GDK_DRAG_LEAVE`,
18    /// `GDK_DRAG_MOTION` and `GDK_DROP_START`. The [`Drop`][crate::Drop] object can be obtained
19    /// from these [`Event`][crate::Event] types using [`DNDEvent::drop()`][crate::DNDEvent::drop()].
20    ///
21    /// The actual data transfer is initiated from the target side via an async
22    /// read, using one of the [`Drop`][crate::Drop] methods for this purpose:
23    /// [`read_async()`][Self::read_async()] or [`read_value_async()`][Self::read_value_async()].
24    ///
25    /// GTK provides a higher level abstraction based on top of these functions,
26    /// and so they are not normally needed in GTK applications. See the
27    /// "Drag and Drop" section of the GTK documentation for more information.
28    ///
29    /// This is an Abstract Base Class, you cannot instantiate it.
30    ///
31    /// ## Properties
32    ///
33    ///
34    /// #### `actions`
35    ///  The possible actions for this drop
36    ///
37    /// Readable | Writeable | Construct Only
38    ///
39    ///
40    /// #### `device`
41    ///  The [`Device`][crate::Device] performing the drop
42    ///
43    /// Readable | Writeable | Construct Only
44    ///
45    ///
46    /// #### `display`
47    ///  The [`Display`][crate::Display] that the drop belongs to.
48    ///
49    /// Readable
50    ///
51    ///
52    /// #### `drag`
53    ///  The [`Drag`][crate::Drag] that initiated this drop
54    ///
55    /// Readable | Writeable | Construct Only
56    ///
57    ///
58    /// #### `formats`
59    ///  The possible formats that the drop can provide its data in.
60    ///
61    /// Readable | Writeable | Construct Only
62    ///
63    ///
64    /// #### `surface`
65    ///  The [`Surface`][crate::Surface] the drop happens on
66    ///
67    /// Readable | Writeable | Construct Only
68    #[doc(alias = "GdkDrop")]
69    pub struct Drop(Object<ffi::GdkDrop>);
70
71    match fn {
72        type_ => || ffi::gdk_drop_get_type(),
73    }
74}
75
76impl Drop {
77    /// Ends the drag operation after a drop.
78    ///
79    /// The @action must be a single action selected from the actions
80    /// available via [`actions()`][Self::actions()].
81    /// ## `action`
82    /// the action performed by the destination or `GDK_ACTION_NONE` if the
83    ///   drop failed
84    #[doc(alias = "gdk_drop_finish")]
85    pub fn finish(&self, action: DragAction) {
86        unsafe {
87            ffi::gdk_drop_finish(self.to_glib_none().0, action.into_glib());
88        }
89    }
90
91    /// Returns the possible actions for this [`Drop`][crate::Drop].
92    ///
93    /// If this value contains multiple actions - i.e.
94    /// [`DragAction::is_unique()`][crate::DragAction::is_unique()] returns false for the result -
95    /// [`finish()`][Self::finish()] must choose the action to use when
96    /// accepting the drop. This will only happen if you passed
97    /// `GDK_ACTION_ASK` as one of the possible actions in
98    /// [`status()`][Self::status()]. `GDK_ACTION_ASK` itself will not
99    /// be included in the actions returned by this function.
100    ///
101    /// This value may change over the lifetime of the [`Drop`][crate::Drop]
102    /// both as a response to source side actions as well as to calls to
103    /// [`status()`][Self::status()] or [`finish()`][Self::finish()]. The source
104    /// side will not change this value anymore once a drop has started.
105    ///
106    /// # Returns
107    ///
108    /// The possible `GdkDragActions`
109    #[doc(alias = "gdk_drop_get_actions")]
110    #[doc(alias = "get_actions")]
111    pub fn actions(&self) -> DragAction {
112        unsafe { from_glib(ffi::gdk_drop_get_actions(self.to_glib_none().0)) }
113    }
114
115    /// Returns the [`Device`][crate::Device] performing the drop.
116    ///
117    /// # Returns
118    ///
119    /// The [`Device`][crate::Device] performing the drop.
120    #[doc(alias = "gdk_drop_get_device")]
121    #[doc(alias = "get_device")]
122    pub fn device(&self) -> Device {
123        unsafe { from_glib_none(ffi::gdk_drop_get_device(self.to_glib_none().0)) }
124    }
125
126    /// Gets the [`Display`][crate::Display] that @self was created for.
127    ///
128    /// # Returns
129    ///
130    /// a [`Display`][crate::Display]
131    #[doc(alias = "gdk_drop_get_display")]
132    #[doc(alias = "get_display")]
133    pub fn display(&self) -> Display {
134        unsafe { from_glib_none(ffi::gdk_drop_get_display(self.to_glib_none().0)) }
135    }
136
137    /// If this is an in-app drag-and-drop operation, returns the [`Drag`][crate::Drag]
138    /// that corresponds to this drop.
139    ///
140    /// If it is not, `NULL` is returned.
141    ///
142    /// # Returns
143    ///
144    /// the corresponding [`Drag`][crate::Drag]
145    #[doc(alias = "gdk_drop_get_drag")]
146    #[doc(alias = "get_drag")]
147    pub fn drag(&self) -> Option<Drag> {
148        unsafe { from_glib_none(ffi::gdk_drop_get_drag(self.to_glib_none().0)) }
149    }
150
151    /// Returns the [`ContentFormats`][crate::ContentFormats] that the drop offers the data
152    /// to be read in.
153    ///
154    /// # Returns
155    ///
156    /// The possible [`ContentFormats`][crate::ContentFormats]
157    #[doc(alias = "gdk_drop_get_formats")]
158    #[doc(alias = "get_formats")]
159    pub fn formats(&self) -> ContentFormats {
160        unsafe { from_glib_none(ffi::gdk_drop_get_formats(self.to_glib_none().0)) }
161    }
162
163    /// Returns the [`Surface`][crate::Surface] performing the drop.
164    ///
165    /// # Returns
166    ///
167    /// The [`Surface`][crate::Surface] performing the drop.
168    #[doc(alias = "gdk_drop_get_surface")]
169    #[doc(alias = "get_surface")]
170    pub fn surface(&self) -> Surface {
171        unsafe { from_glib_none(ffi::gdk_drop_get_surface(self.to_glib_none().0)) }
172    }
173
174    /// Asynchronously request the drag operation's contents converted
175    /// to the given @type_.
176    ///
177    /// For local drag-and-drop operations that are available in the given
178    /// `GType`, the value will be copied directly. Otherwise, GDK will
179    /// try to use [`content_deserialize_async()`][crate::content_deserialize_async()] to convert the data.
180    /// ## `type_`
181    /// a `GType` to read
182    /// ## `io_priority`
183    /// the I/O priority of the request.
184    /// ## `cancellable`
185    /// optional `GCancellable` object, [`None`] to ignore.
186    /// ## `callback`
187    /// callback to call when the request is satisfied
188    #[doc(alias = "gdk_drop_read_value_async")]
189    pub fn read_value_async<P: FnOnce(Result<glib::Value, glib::Error>) + 'static>(
190        &self,
191        type_: glib::types::Type,
192        io_priority: glib::Priority,
193        cancellable: Option<&impl IsA<gio::Cancellable>>,
194        callback: P,
195    ) {
196        let main_context = glib::MainContext::ref_thread_default();
197        let is_main_context_owner = main_context.is_owner();
198        let has_acquired_main_context = (!is_main_context_owner)
199            .then(|| main_context.acquire().ok())
200            .flatten();
201        assert!(
202            is_main_context_owner || has_acquired_main_context.is_some(),
203            "Async operations only allowed if the thread is owning the MainContext"
204        );
205
206        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
207            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
208        unsafe extern "C" fn read_value_async_trampoline<
209            P: FnOnce(Result<glib::Value, glib::Error>) + 'static,
210        >(
211            _source_object: *mut glib::gobject_ffi::GObject,
212            res: *mut gio::ffi::GAsyncResult,
213            user_data: glib::ffi::gpointer,
214        ) {
215            let mut error = std::ptr::null_mut();
216            let ret = ffi::gdk_drop_read_value_finish(_source_object as *mut _, res, &mut error);
217            let result = if error.is_null() {
218                Ok(from_glib_none(ret))
219            } else {
220                Err(from_glib_full(error))
221            };
222            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
223                Box_::from_raw(user_data as *mut _);
224            let callback: P = callback.into_inner();
225            callback(result);
226        }
227        let callback = read_value_async_trampoline::<P>;
228        unsafe {
229            ffi::gdk_drop_read_value_async(
230                self.to_glib_none().0,
231                type_.into_glib(),
232                io_priority.into_glib(),
233                cancellable.map(|p| p.as_ref()).to_glib_none().0,
234                Some(callback),
235                Box_::into_raw(user_data) as *mut _,
236            );
237        }
238    }
239
240    pub fn read_value_future(
241        &self,
242        type_: glib::types::Type,
243        io_priority: glib::Priority,
244    ) -> Pin<Box_<dyn std::future::Future<Output = Result<glib::Value, glib::Error>> + 'static>>
245    {
246        Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
247            obj.read_value_async(type_, io_priority, Some(cancellable), move |res| {
248                send.resolve(res);
249            });
250        }))
251    }
252
253    /// Selects all actions that are potentially supported by the destination.
254    ///
255    /// When calling this function, do not restrict the passed in actions to
256    /// the ones provided by [`actions()`][Self::actions()]. Those actions may
257    /// change in the future, even depending on the actions you provide here.
258    ///
259    /// The @preferred action is a hint to the drag-and-drop mechanism about which
260    /// action to use when multiple actions are possible.
261    ///
262    /// This function should be called by drag destinations in response to
263    /// `GDK_DRAG_ENTER` or `GDK_DRAG_MOTION` events. If the destination does
264    /// not yet know the exact actions it supports, it should set any possible
265    /// actions first and then later call this function again.
266    /// ## `actions`
267    /// Supported actions of the destination, or `GDK_ACTION_NONE` to
268    ///    indicate that a drop will not be accepted
269    /// ## `preferred`
270    /// A unique action that's a member of @actions indicating the
271    ///    preferred action
272    #[doc(alias = "gdk_drop_status")]
273    pub fn status(&self, actions: DragAction, preferred: DragAction) {
274        unsafe {
275            ffi::gdk_drop_status(
276                self.to_glib_none().0,
277                actions.into_glib(),
278                preferred.into_glib(),
279            );
280        }
281    }
282
283    #[doc(alias = "display")]
284    pub fn connect_display_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
285        unsafe extern "C" fn notify_display_trampoline<F: Fn(&Drop) + 'static>(
286            this: *mut ffi::GdkDrop,
287            _param_spec: glib::ffi::gpointer,
288            f: glib::ffi::gpointer,
289        ) {
290            let f: &F = &*(f as *const F);
291            f(&from_glib_borrow(this))
292        }
293        unsafe {
294            let f: Box_<F> = Box_::new(f);
295            connect_raw(
296                self.as_ptr() as *mut _,
297                c"notify::display".as_ptr() as *const _,
298                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
299                    notify_display_trampoline::<F> as *const (),
300                )),
301                Box_::into_raw(f),
302            )
303        }
304    }
305}