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}