gtk4/subclass/
tree_drag_source.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3// rustdoc-stripper-ignore-next
4//! Traits intended for implementing the [`TreeDragSource`] interface.
5
6use glib::translate::*;
7
8use crate::{ffi, prelude::*, subclass::prelude::*, TreeDragSource, TreePath};
9
10#[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
11#[allow(deprecated)]
12pub trait TreeDragSourceImpl: ObjectImpl + ObjectSubclass<Type: IsA<TreeDragSource>> {
13    fn row_draggable(&self, path: &TreePath) -> bool {
14        self.parent_row_draggable(path)
15    }
16    fn drag_data_get(&self, path: &TreePath) -> gdk::ContentProvider;
17    fn drag_data_delete(&self, path: &TreePath) -> bool;
18}
19
20#[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
21#[allow(deprecated)]
22pub trait TreeDragSourceImplExt: TreeDragSourceImpl {
23    // Returns true if the row can be dragged
24    fn parent_row_draggable(&self, path: &TreePath) -> bool {
25        unsafe {
26            let type_data = Self::type_data();
27            let parent_iface = type_data.as_ref().parent_interface::<TreeDragSource>()
28                as *const ffi::GtkTreeDragSourceIface;
29
30            if let Some(func) = (*parent_iface).row_draggable {
31                from_glib(func(
32                    self.obj()
33                        .unsafe_cast_ref::<TreeDragSource>()
34                        .to_glib_none()
35                        .0,
36                    mut_override(path.to_glib_none().0),
37                ))
38            } else {
39                // Assume the row is draggable by default
40                true
41            }
42        }
43    }
44
45    fn parent_drag_data_get(&self, path: &TreePath) -> gdk::ContentProvider {
46        unsafe {
47            let type_data = Self::type_data();
48            let parent_iface = type_data.as_ref().parent_interface::<TreeDragSource>()
49                as *const ffi::GtkTreeDragSourceIface;
50
51            let func = (*parent_iface)
52                .drag_data_get
53                .expect("no parent \"drag_data_get\" implementation");
54
55            from_glib_full(func(
56                self.obj()
57                    .unsafe_cast_ref::<TreeDragSource>()
58                    .to_glib_none()
59                    .0,
60                mut_override(path.to_glib_none().0),
61            ))
62        }
63    }
64
65    // True if the row was successfully deleted
66    fn parent_drag_data_delete(&self, path: &TreePath) -> bool {
67        unsafe {
68            let type_data = Self::type_data();
69            let parent_iface = type_data.as_ref().parent_interface::<TreeDragSource>()
70                as *const ffi::GtkTreeDragSourceIface;
71
72            let func = (*parent_iface)
73                .drag_data_delete
74                .expect("no parent \"drag_data_delete\" implementation");
75
76            from_glib(func(
77                self.obj()
78                    .unsafe_cast_ref::<TreeDragSource>()
79                    .to_glib_none()
80                    .0,
81                mut_override(path.to_glib_none().0),
82            ))
83        }
84    }
85}
86
87impl<T: TreeDragSourceImpl> TreeDragSourceImplExt for T {}
88
89unsafe impl<T: TreeDragSourceImpl> IsImplementable<T> for TreeDragSource {
90    fn interface_init(iface: &mut glib::Interface<Self>) {
91        let iface = iface.as_mut();
92
93        assert_initialized_main_thread!();
94
95        iface.row_draggable = Some(tree_drag_source_row_draggable::<T>);
96        iface.drag_data_get = Some(tree_drag_source_drag_data_get::<T>);
97        iface.drag_data_delete = Some(tree_drag_source_drag_data_delete::<T>);
98    }
99}
100
101unsafe extern "C" fn tree_drag_source_row_draggable<T: TreeDragSourceImpl>(
102    tree_drag_source: *mut ffi::GtkTreeDragSource,
103    pathptr: *mut ffi::GtkTreePath,
104) -> glib::ffi::gboolean {
105    let instance = &*(tree_drag_source as *mut T::Instance);
106    let imp = instance.imp();
107
108    let path: Borrowed<TreePath> = from_glib_borrow(pathptr);
109
110    imp.row_draggable(&path).into_glib()
111}
112
113unsafe extern "C" fn tree_drag_source_drag_data_get<T: TreeDragSourceImpl>(
114    tree_drag_source: *mut ffi::GtkTreeDragSource,
115    pathptr: *mut ffi::GtkTreePath,
116) -> *mut gdk::ffi::GdkContentProvider {
117    let instance = &*(tree_drag_source as *mut T::Instance);
118    let imp = instance.imp();
119    let path: Borrowed<TreePath> = from_glib_borrow(pathptr);
120
121    imp.drag_data_get(&path).into_glib_ptr()
122}
123
124unsafe extern "C" fn tree_drag_source_drag_data_delete<T: TreeDragSourceImpl>(
125    tree_drag_source: *mut ffi::GtkTreeDragSource,
126    pathptr: *mut ffi::GtkTreePath,
127) -> glib::ffi::gboolean {
128    let instance = &*(tree_drag_source as *mut T::Instance);
129    let imp = instance.imp();
130    let path: Borrowed<TreePath> = from_glib_borrow(pathptr);
131    imp.drag_data_delete(&path).into_glib()
132}