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    /// The [`Drop`][crate::Drop] object 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 [`EventType::DragEnter`][crate::EventType::DragEnter], [`EventType::DragLeave`][crate::EventType::DragLeave],
18    /// [`EventType::DragMotion`][crate::EventType::DragMotion] and [`EventType::DropStart`][crate::EventType::DropStart]. 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 0 if the drop failed
83    #[doc(alias = "gdk_drop_finish")]
84    pub fn finish(&self, action: DragAction) {
85        unsafe {
86            ffi::gdk_drop_finish(self.to_glib_none().0, action.into_glib());
87        }
88    }
89
90    /// Returns the possible actions for this [`Drop`][crate::Drop].
91    ///
92    /// If this value contains multiple actions - i.e.
93    /// [`DragAction::is_unique()`][crate::DragAction::is_unique()] returns [`false`] for the result -
94    /// [`finish()`][Self::finish()] must choose the action to use when
95    /// accepting the drop. This will only happen if you passed
96    /// [`DragAction::ASK`][crate::DragAction::ASK] as one of the possible actions in
97    /// [`status()`][Self::status()]. [`DragAction::ASK`][crate::DragAction::ASK] itself will not
98    /// be included in the actions returned by this function.
99    ///
100    /// This value may change over the lifetime of the [`Drop`][crate::Drop]
101    /// both as a response to source side actions as well as to calls to
102    /// [`status()`][Self::status()] or [`finish()`][Self::finish()]. The source
103    /// side will not change this value anymore once a drop has started.
104    ///
105    /// # Returns
106    ///
107    /// The possible `GdkDragActions`
108    #[doc(alias = "gdk_drop_get_actions")]
109    #[doc(alias = "get_actions")]
110    pub fn actions(&self) -> DragAction {
111        unsafe { from_glib(ffi::gdk_drop_get_actions(self.to_glib_none().0)) }
112    }
113
114    /// Returns the [`Device`][crate::Device] performing the drop.
115    ///
116    /// # Returns
117    ///
118    /// The [`Device`][crate::Device] performing the drop.
119    #[doc(alias = "gdk_drop_get_device")]
120    #[doc(alias = "get_device")]
121    pub fn device(&self) -> Device {
122        unsafe { from_glib_none(ffi::gdk_drop_get_device(self.to_glib_none().0)) }
123    }
124
125    /// Gets the [`Display`][crate::Display] that @self was created for.
126    ///
127    /// # Returns
128    ///
129    /// a [`Display`][crate::Display]
130    #[doc(alias = "gdk_drop_get_display")]
131    #[doc(alias = "get_display")]
132    pub fn display(&self) -> Display {
133        unsafe { from_glib_none(ffi::gdk_drop_get_display(self.to_glib_none().0)) }
134    }
135
136    /// If this is an in-app drag-and-drop operation, returns the [`Drag`][crate::Drag]
137    /// that corresponds to this drop.
138    ///
139    /// If it is not, [`None`] is returned.
140    ///
141    /// # Returns
142    ///
143    /// the corresponding [`Drag`][crate::Drag]
144    #[doc(alias = "gdk_drop_get_drag")]
145    #[doc(alias = "get_drag")]
146    pub fn drag(&self) -> Option<Drag> {
147        unsafe { from_glib_none(ffi::gdk_drop_get_drag(self.to_glib_none().0)) }
148    }
149
150    /// Returns the [`ContentFormats`][crate::ContentFormats] that the drop offers the data
151    /// to be read in.
152    ///
153    /// # Returns
154    ///
155    /// The possible [`ContentFormats`][crate::ContentFormats]
156    #[doc(alias = "gdk_drop_get_formats")]
157    #[doc(alias = "get_formats")]
158    pub fn formats(&self) -> ContentFormats {
159        unsafe { from_glib_none(ffi::gdk_drop_get_formats(self.to_glib_none().0)) }
160    }
161
162    /// Returns the [`Surface`][crate::Surface] performing the drop.
163    ///
164    /// # Returns
165    ///
166    /// The [`Surface`][crate::Surface] performing the drop.
167    #[doc(alias = "gdk_drop_get_surface")]
168    #[doc(alias = "get_surface")]
169    pub fn surface(&self) -> Surface {
170        unsafe { from_glib_none(ffi::gdk_drop_get_surface(self.to_glib_none().0)) }
171    }
172
173    /// Asynchronously request the drag operation's contents converted
174    /// to the given @type_.
175    ///
176    /// For local drag-and-drop operations that are available in the given
177    /// `GType`, the value will be copied directly. Otherwise, GDK will
178    /// try to use [`content_deserialize_async()`][crate::content_deserialize_async()] to convert the data.
179    /// ## `type_`
180    /// a `GType` to read
181    /// ## `io_priority`
182    /// the I/O priority of the request.
183    /// ## `cancellable`
184    /// optional `GCancellable` object, [`None`] to ignore.
185    /// ## `callback`
186    /// callback to call when the request is satisfied
187    #[doc(alias = "gdk_drop_read_value_async")]
188    pub fn read_value_async<P: FnOnce(Result<glib::Value, glib::Error>) + 'static>(
189        &self,
190        type_: glib::types::Type,
191        io_priority: glib::Priority,
192        cancellable: Option<&impl IsA<gio::Cancellable>>,
193        callback: P,
194    ) {
195        let main_context = glib::MainContext::ref_thread_default();
196        let is_main_context_owner = main_context.is_owner();
197        let has_acquired_main_context = (!is_main_context_owner)
198            .then(|| main_context.acquire().ok())
199            .flatten();
200        assert!(
201            is_main_context_owner || has_acquired_main_context.is_some(),
202            "Async operations only allowed if the thread is owning the MainContext"
203        );
204
205        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
206            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
207        unsafe extern "C" fn read_value_async_trampoline<
208            P: FnOnce(Result<glib::Value, glib::Error>) + 'static,
209        >(
210            _source_object: *mut glib::gobject_ffi::GObject,
211            res: *mut gio::ffi::GAsyncResult,
212            user_data: glib::ffi::gpointer,
213        ) {
214            let mut error = std::ptr::null_mut();
215            let ret = ffi::gdk_drop_read_value_finish(_source_object as *mut _, res, &mut error);
216            let result = if error.is_null() {
217                Ok(from_glib_none(ret))
218            } else {
219                Err(from_glib_full(error))
220            };
221            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
222                Box_::from_raw(user_data as *mut _);
223            let callback: P = callback.into_inner();
224            callback(result);
225        }
226        let callback = read_value_async_trampoline::<P>;
227        unsafe {
228            ffi::gdk_drop_read_value_async(
229                self.to_glib_none().0,
230                type_.into_glib(),
231                io_priority.into_glib(),
232                cancellable.map(|p| p.as_ref()).to_glib_none().0,
233                Some(callback),
234                Box_::into_raw(user_data) as *mut _,
235            );
236        }
237    }
238
239    pub fn read_value_future(
240        &self,
241        type_: glib::types::Type,
242        io_priority: glib::Priority,
243    ) -> Pin<Box_<dyn std::future::Future<Output = Result<glib::Value, glib::Error>> + 'static>>
244    {
245        Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
246            obj.read_value_async(type_, io_priority, Some(cancellable), move |res| {
247                send.resolve(res);
248            });
249        }))
250    }
251
252    /// Selects all actions that are potentially supported by the destination.
253    ///
254    /// When calling this function, do not restrict the passed in actions to
255    /// the ones provided by [`actions()`][Self::actions()]. Those actions may
256    /// change in the future, even depending on the actions you provide here.
257    ///
258    /// The @preferred action is a hint to the drag-and-drop mechanism about which
259    /// action to use when multiple actions are possible.
260    ///
261    /// This function should be called by drag destinations in response to
262    /// [`EventType::DragEnter`][crate::EventType::DragEnter] or [`EventType::DragMotion`][crate::EventType::DragMotion] events. If the destination does
263    /// not yet know the exact actions it supports, it should set any possible
264    /// actions first and then later call this function again.
265    /// ## `actions`
266    /// Supported actions of the destination, or 0 to indicate
267    ///    that a drop will not be accepted
268    /// ## `preferred`
269    /// A unique action that's a member of @actions indicating the
270    ///    preferred action
271    #[doc(alias = "gdk_drop_status")]
272    pub fn status(&self, actions: DragAction, preferred: DragAction) {
273        unsafe {
274            ffi::gdk_drop_status(
275                self.to_glib_none().0,
276                actions.into_glib(),
277                preferred.into_glib(),
278            );
279        }
280    }
281
282    #[doc(alias = "display")]
283    pub fn connect_display_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
284        unsafe extern "C" fn notify_display_trampoline<F: Fn(&Drop) + 'static>(
285            this: *mut ffi::GdkDrop,
286            _param_spec: glib::ffi::gpointer,
287            f: glib::ffi::gpointer,
288        ) {
289            let f: &F = &*(f as *const F);
290            f(&from_glib_borrow(this))
291        }
292        unsafe {
293            let f: Box_<F> = Box_::new(f);
294            connect_raw(
295                self.as_ptr() as *mut _,
296                b"notify::display\0".as_ptr() as *const _,
297                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
298                    notify_display_trampoline::<F> as *const (),
299                )),
300                Box_::into_raw(f),
301            )
302        }
303    }
304}