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}