Skip to main content

gtk/subclass/
tree_drag_dest.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use glib::translate::*;
4
5use crate::{SelectionData, TreeDragDest, TreePath, ffi, prelude::*, subclass::prelude::*};
6
7pub trait TreeDragDestImpl: ObjectImpl + ObjectSubclass<Type: IsA<TreeDragDest>> {
8    fn drag_data_received(&self, dest: &TreePath, selection_data: &SelectionData) -> bool;
9
10    fn row_drop_possible(&self, dest: &TreePath, selection_data: &SelectionData) -> bool {
11        self.parent_row_drop_possible(dest, selection_data)
12    }
13}
14
15pub trait TreeDragDestImplExt: TreeDragDestImpl {
16    fn parent_drag_data_received(&self, dest: &TreePath, selection_data: &SelectionData) -> bool {
17        unsafe {
18            let type_data = Self::type_data();
19            let parent_iface = type_data.as_ref().parent_interface::<TreeDragDest>()
20                as *const ffi::GtkTreeDragDestIface;
21
22            let func = (*parent_iface)
23                .drag_data_received
24                .expect("no parent \"drag_data_received\" implementation");
25
26            from_glib(func(
27                self.obj()
28                    .unsafe_cast_ref::<TreeDragDest>()
29                    .to_glib_none()
30                    .0,
31                mut_override(dest.to_glib_none().0),
32                selection_data.to_glib_none().0,
33            ))
34        }
35    }
36
37    fn parent_row_drop_possible(&self, dest: &TreePath, selection_data: &SelectionData) -> bool {
38        unsafe {
39            let type_data = Self::type_data();
40            let parent_iface = type_data.as_ref().parent_interface::<TreeDragDest>()
41                as *const ffi::GtkTreeDragDestIface;
42
43            if let Some(func) = (*parent_iface).row_drop_possible {
44                from_glib(func(
45                    self.obj()
46                        .unsafe_cast_ref::<TreeDragDest>()
47                        .to_glib_none()
48                        .0,
49                    mut_override(dest.to_glib_none().0),
50                    selection_data.to_glib_none().0,
51                ))
52            } else {
53                // same answer gtk_tree_drag_dest_row_drop_possible() gives for a NULL vfunc
54                false
55            }
56        }
57    }
58}
59
60impl<T: TreeDragDestImpl> TreeDragDestImplExt for T {}
61
62unsafe impl<T: TreeDragDestImpl> IsImplementable<T> for TreeDragDest {
63    fn interface_init(iface: &mut glib::Interface<Self>) {
64        let iface = iface.as_mut();
65
66        if !crate::rt::is_initialized() {
67            panic!("GTK has to be initialized first");
68        }
69
70        iface.drag_data_received = Some(tree_drag_dest_drag_data_received::<T>);
71        iface.row_drop_possible = Some(tree_drag_dest_row_drop_possible::<T>);
72    }
73}
74
75unsafe extern "C" fn tree_drag_dest_drag_data_received<T: TreeDragDestImpl>(
76    tree_drag_dest: *mut ffi::GtkTreeDragDest,
77    destptr: *mut ffi::GtkTreePath,
78    selectiondataptr: *mut ffi::GtkSelectionData,
79) -> glib::ffi::gboolean {
80    unsafe {
81        let instance = &*(tree_drag_dest as *mut T::Instance);
82        let imp = instance.imp();
83
84        let dest: Borrowed<TreePath> = from_glib_borrow(destptr);
85        let selection_data: Borrowed<SelectionData> = from_glib_borrow(selectiondataptr);
86
87        imp.drag_data_received(&dest, &selection_data).into_glib()
88    }
89}
90
91unsafe extern "C" fn tree_drag_dest_row_drop_possible<T: TreeDragDestImpl>(
92    tree_drag_dest: *mut ffi::GtkTreeDragDest,
93    destptr: *mut ffi::GtkTreePath,
94    selectiondataptr: *mut ffi::GtkSelectionData,
95) -> glib::ffi::gboolean {
96    unsafe {
97        let instance = &*(tree_drag_dest as *mut T::Instance);
98        let imp = instance.imp();
99        let dest: Borrowed<TreePath> = from_glib_borrow(destptr);
100        let selection_data: Borrowed<SelectionData> = from_glib_borrow(selectiondataptr);
101
102        imp.row_drop_possible(&dest, &selection_data).into_glib()
103    }
104}