gtk/subclass/
tree_drag_source.rs1use glib::translate::*;
4
5use crate::{SelectionData, TreeDragSource, TreePath, ffi, prelude::*, subclass::prelude::*};
6
7pub trait TreeDragSourceImpl: ObjectImpl + ObjectSubclass<Type: IsA<TreeDragSource>> {
8 fn row_draggable(&self, path: &TreePath) -> bool {
9 self.parent_row_draggable(path)
10 }
11
12 fn drag_data_get(&self, path: &TreePath, selection_data: &SelectionData) -> bool;
13
14 fn drag_data_delete(&self, path: &TreePath) -> bool;
15}
16
17pub trait TreeDragSourceImplExt: TreeDragSourceImpl {
18 fn parent_row_draggable(&self, path: &TreePath) -> bool {
20 unsafe {
21 let type_data = Self::type_data();
22 let parent_iface = type_data.as_ref().parent_interface::<TreeDragSource>()
23 as *const ffi::GtkTreeDragSourceIface;
24
25 if let Some(func) = (*parent_iface).row_draggable {
26 from_glib(func(
27 self.obj()
28 .unsafe_cast_ref::<TreeDragSource>()
29 .to_glib_none()
30 .0,
31 mut_override(path.to_glib_none().0),
32 ))
33 } else {
34 true
36 }
37 }
38 }
39
40 fn parent_drag_data_get(&self, path: &TreePath, selection_data: &SelectionData) -> bool {
41 unsafe {
42 let type_data = Self::type_data();
43 let parent_iface = type_data.as_ref().parent_interface::<TreeDragSource>()
44 as *const ffi::GtkTreeDragSourceIface;
45
46 let func = (*parent_iface)
47 .drag_data_get
48 .expect("no parent \"drag_data_get\" implementation");
49
50 from_glib(func(
51 self.obj()
52 .unsafe_cast_ref::<TreeDragSource>()
53 .to_glib_none()
54 .0,
55 mut_override(path.to_glib_none().0),
56 selection_data.to_glib_none().0,
57 ))
58 }
59 }
60
61 fn parent_drag_data_delete(&self, path: &TreePath) -> bool {
63 unsafe {
64 let type_data = Self::type_data();
65 let parent_iface = type_data.as_ref().parent_interface::<TreeDragSource>()
66 as *const ffi::GtkTreeDragSourceIface;
67
68 let func = (*parent_iface)
69 .drag_data_delete
70 .expect("no parent \"drag_data_delete\" implementation");
71
72 from_glib(func(
73 self.obj()
74 .unsafe_cast_ref::<TreeDragSource>()
75 .to_glib_none()
76 .0,
77 mut_override(path.to_glib_none().0),
78 ))
79 }
80 }
81}
82
83impl<T: TreeDragSourceImpl> TreeDragSourceImplExt for T {}
84
85unsafe impl<T: TreeDragSourceImpl> IsImplementable<T> for TreeDragSource {
86 fn interface_init(iface: &mut glib::Interface<Self>) {
87 let iface = iface.as_mut();
88
89 if !crate::rt::is_initialized() {
90 panic!("GTK has to be initialized first");
91 }
92
93 iface.row_draggable = Some(tree_drag_source_row_draggable::<T>);
94 iface.drag_data_get = Some(tree_drag_source_drag_data_get::<T>);
95 iface.drag_data_delete = Some(tree_drag_source_drag_data_delete::<T>);
96 }
97}
98
99unsafe extern "C" fn tree_drag_source_row_draggable<T: TreeDragSourceImpl>(
100 tree_drag_source: *mut ffi::GtkTreeDragSource,
101 pathptr: *mut ffi::GtkTreePath,
102) -> glib::ffi::gboolean {
103 unsafe {
104 let instance = &*(tree_drag_source as *mut T::Instance);
105 let imp = instance.imp();
106
107 let path: Borrowed<TreePath> = from_glib_borrow(pathptr);
108
109 imp.row_draggable(&path).into_glib()
110 }
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 selectiondataptr: *mut ffi::GtkSelectionData,
117) -> glib::ffi::gboolean {
118 unsafe {
119 let instance = &*(tree_drag_source as *mut T::Instance);
120 let imp = instance.imp();
121 let path: Borrowed<TreePath> = from_glib_borrow(pathptr);
122 let selection_data: Borrowed<SelectionData> = from_glib_borrow(selectiondataptr);
123
124 imp.drag_data_get(&path, &selection_data).into_glib()
125 }
126}
127
128unsafe extern "C" fn tree_drag_source_drag_data_delete<T: TreeDragSourceImpl>(
129 tree_drag_source: *mut ffi::GtkTreeDragSource,
130 pathptr: *mut ffi::GtkTreePath,
131) -> glib::ffi::gboolean {
132 unsafe {
133 let instance = &*(tree_drag_source as *mut T::Instance);
134 let imp = instance.imp();
135 let path: Borrowed<TreePath> = from_glib_borrow(pathptr);
136 imp.drag_data_delete(&path).into_glib()
137 }
138}