[go: up one dir, main page]

gtk4/
drop_target.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::{boxed::Box as Box_, mem::transmute};
4
5use glib::{
6    signal::{connect_raw, SignalHandlerId},
7    translate::*,
8    value::FromValue,
9    Slice, Type,
10};
11
12use crate::{ffi, prelude::*, DropTarget};
13
14impl DropTarget {
15    #[doc(alias = "gtk_drop_target_set_gtypes")]
16    pub fn set_types(&self, types: &[Type]) {
17        let types: Vec<glib::ffi::GType> = types.iter().map(|t| t.into_glib()).collect();
18        unsafe {
19            ffi::gtk_drop_target_set_gtypes(
20                self.to_glib_none().0,
21                mut_override(types.as_ptr()),
22                types.len(),
23            )
24        }
25    }
26
27    #[doc(alias = "gtk_drop_target_get_value")]
28    #[doc(alias = "get_value")]
29    // rustdoc-stripper-ignore-next
30    /// Similar to [`Self::value`] but panics if the value is of a different
31    /// type.
32    pub fn value_as<V: for<'b> FromValue<'b> + 'static>(&self) -> Option<V> {
33        self.value().map(|v| {
34            v.get_owned::<V>()
35                .expect("Failed to get value as this type")
36        })
37    }
38
39    #[doc(alias = "gtk_drop_target_get_gtypes")]
40    #[doc(alias = "get_gtypes")]
41    pub fn types(&self) -> Slice<Type> {
42        unsafe {
43            let mut n_types = std::mem::MaybeUninit::uninit();
44            let types =
45                ffi::gtk_drop_target_get_gtypes(self.to_glib_none().0, n_types.as_mut_ptr());
46
47            Slice::from_glib_none_num(types, n_types.assume_init() as _)
48        }
49    }
50
51    // Returns true if the drop was accepted
52    pub fn connect_drop<F: Fn(&DropTarget, &glib::Value, f64, f64) -> bool + 'static>(
53        &self,
54        f: F,
55    ) -> SignalHandlerId {
56        unsafe extern "C" fn drop_trampoline<
57            F: Fn(&DropTarget, &glib::Value, f64, f64) -> bool + 'static,
58        >(
59            this: *mut ffi::GtkDropTarget,
60            value: *mut glib::gobject_ffi::GValue,
61            x: libc::c_double,
62            y: libc::c_double,
63            f: glib::ffi::gpointer,
64        ) -> glib::ffi::gboolean {
65            let f: &F = &*(f as *const F);
66            f(
67                &from_glib_borrow(this),
68                &*(value as *const glib::Value),
69                x,
70                y,
71            )
72            .into_glib()
73        }
74        unsafe {
75            let f: Box_<F> = Box_::new(f);
76            connect_raw(
77                self.as_ptr() as *mut _,
78                c"drop".as_ptr() as *const _,
79                Some(transmute::<*const (), unsafe extern "C" fn()>(
80                    drop_trampoline::<F> as *const (),
81                )),
82                Box_::into_raw(f),
83            )
84        }
85    }
86}