Skip to main content

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::{ContentFormats, Device, Display, Drag, DragAction, Surface, ffi};
6use glib::{
7    prelude::*,
8    signal::{SignalHandlerId, connect_raw},
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            unsafe {
216                let mut error = std::ptr::null_mut();
217                let ret =
218                    ffi::gdk_drop_read_value_finish(_source_object as *mut _, res, &mut error);
219                let result = if error.is_null() {
220                    Ok(from_glib_none(ret))
221                } else {
222                    Err(from_glib_full(error))
223                };
224                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
225                    Box_::from_raw(user_data as *mut _);
226                let callback: P = callback.into_inner();
227                callback(result);
228            }
229        }
230        let callback = read_value_async_trampoline::<P>;
231        unsafe {
232            ffi::gdk_drop_read_value_async(
233                self.to_glib_none().0,
234                type_.into_glib(),
235                io_priority.into_glib(),
236                cancellable.map(|p| p.as_ref()).to_glib_none().0,
237                Some(callback),
238                Box_::into_raw(user_data) as *mut _,
239            );
240        }
241    }
242
243    pub fn read_value_future(
244        &self,
245        type_: glib::types::Type,
246        io_priority: glib::Priority,
247    ) -> Pin<Box_<dyn std::future::Future<Output = Result<glib::Value, glib::Error>> + 'static>>
248    {
249        Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
250            obj.read_value_async(type_, io_priority, Some(cancellable), move |res| {
251                send.resolve(res);
252            });
253        }))
254    }
255
256    /// Selects all actions that are potentially supported by the destination.
257    ///
258    /// When calling this function, do not restrict the passed in actions to
259    /// the ones provided by [`actions()`][Self::actions()]. Those actions may
260    /// change in the future, even depending on the actions you provide here.
261    ///
262    /// The @preferred action is a hint to the drag-and-drop mechanism about which
263    /// action to use when multiple actions are possible.
264    ///
265    /// This function should be called by drag destinations in response to
266    /// `GDK_DRAG_ENTER` or `GDK_DRAG_MOTION` events. If the destination does
267    /// not yet know the exact actions it supports, it should set any possible
268    /// actions first and then later call this function again.
269    /// ## `actions`
270    /// Supported actions of the destination, or `GDK_ACTION_NONE` to
271    ///    indicate that a drop will not be accepted
272    /// ## `preferred`
273    /// A unique action that's a member of @actions indicating the
274    ///    preferred action
275    #[doc(alias = "gdk_drop_status")]
276    pub fn status(&self, actions: DragAction, preferred: DragAction) {
277        unsafe {
278            ffi::gdk_drop_status(
279                self.to_glib_none().0,
280                actions.into_glib(),
281                preferred.into_glib(),
282            );
283        }
284    }
285
286    #[doc(alias = "display")]
287    pub fn connect_display_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
288        unsafe extern "C" fn notify_display_trampoline<F: Fn(&Drop) + 'static>(
289            this: *mut ffi::GdkDrop,
290            _param_spec: glib::ffi::gpointer,
291            f: glib::ffi::gpointer,
292        ) {
293            unsafe {
294                let f: &F = &*(f as *const F);
295                f(&from_glib_borrow(this))
296            }
297        }
298        unsafe {
299            let f: Box_<F> = Box_::new(f);
300            connect_raw(
301                self.as_ptr() as *mut _,
302                c"notify::display".as_ptr(),
303                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
304                    notify_display_trampoline::<F> as *const (),
305                )),
306                Box_::into_raw(f),
307            )
308        }
309    }
310}