1use glib::translate::*;
7
8use crate::{
9 MovementStep, Scrollable, TreeIter, TreePath, TreeView, TreeViewColumn, ffi, prelude::*,
10 subclass::prelude::*,
11};
12
13#[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
14#[allow(deprecated)]
15pub trait TreeViewImpl: WidgetImpl + ObjectSubclass<Type: IsA<TreeView> + IsA<Scrollable>> {
16 fn columns_changed(&self) {
17 self.parent_columns_changed()
18 }
19
20 fn cursor_changed(&self) {
21 self.parent_cursor_changed()
22 }
23
24 fn expand_collapse_cursor_row(&self, logical: bool, expand: bool, open_all: bool) -> bool {
25 self.parent_expand_collapse_cursor_row(logical, expand, open_all)
26 }
27
28 fn move_cursor(&self, step: MovementStep, count: i32, expand: bool, modify: bool) -> bool {
29 self.parent_move_cursor(step, count, expand, modify)
30 }
31
32 fn row_activated(&self, path: &TreePath, column: &TreeViewColumn) {
42 self.parent_row_activated(path, column)
43 }
44
45 fn row_collapsed(&self, iter: &TreeIter, path: &TreePath) {
46 self.parent_row_collapsed(iter, path)
47 }
48
49 fn row_expanded(&self, iter: &TreeIter, path: &TreePath) {
50 self.parent_row_expanded(iter, path)
51 }
52
53 fn select_all(&self) -> bool {
54 self.parent_select_all()
55 }
56
57 fn select_cursor_parent(&self) -> bool {
58 self.parent_select_cursor_parent()
59 }
60
61 fn select_cursor_row(&self, start_editing: bool) -> bool {
62 self.parent_select_cursor_row(start_editing)
63 }
64
65 fn start_interactive_search(&self) -> bool {
66 self.parent_start_interactive_search()
67 }
68
69 fn test_collapse_row(&self, iter: &TreeIter, path: &TreePath) -> bool {
70 self.parent_test_collapse_row(iter, path)
71 }
72
73 fn test_expand_row(&self, iter: &TreeIter, path: &TreePath) -> bool {
74 self.parent_test_expand_row(iter, path)
75 }
76
77 fn toggle_cursor_row(&self) -> bool {
78 self.parent_toggle_cursor_row()
79 }
80
81 fn unselect_all(&self) -> bool {
82 self.parent_unselect_all()
83 }
84}
85
86#[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
87#[allow(deprecated)]
88pub trait TreeViewImplExt: TreeViewImpl {
89 fn parent_columns_changed(&self) {
90 unsafe {
91 let data = Self::type_data();
92 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTreeViewClass;
93 if let Some(f) = (*parent_class).columns_changed {
95 f(self.obj().unsafe_cast_ref::<TreeView>().to_glib_none().0)
96 }
97 }
98 }
99
100 fn parent_cursor_changed(&self) {
101 unsafe {
102 let data = Self::type_data();
103 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTreeViewClass;
104 if let Some(f) = (*parent_class).cursor_changed {
106 f(self.obj().unsafe_cast_ref::<TreeView>().to_glib_none().0)
107 }
108 }
109 }
110
111 fn parent_expand_collapse_cursor_row(
112 &self,
113 logical: bool,
114 expand: bool,
115 open_all: bool,
116 ) -> bool {
117 unsafe {
118 let data = Self::type_data();
119 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTreeViewClass;
120 if let Some(f) = (*parent_class).expand_collapse_cursor_row {
122 from_glib(f(
123 self.obj().unsafe_cast_ref::<TreeView>().to_glib_none().0,
124 logical.into_glib(),
125 expand.into_glib(),
126 open_all.into_glib(),
127 ))
128 } else {
129 false
130 }
131 }
132 }
133
134 fn parent_move_cursor(
135 &self,
136 step: MovementStep,
137 count: i32,
138 extend: bool,
139 modify: bool,
140 ) -> bool {
141 unsafe {
142 let data = Self::type_data();
143 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTreeViewClass;
144 if let Some(f) = (*parent_class).move_cursor {
146 from_glib(f(
147 self.obj().unsafe_cast_ref::<TreeView>().to_glib_none().0,
148 step.into_glib(),
149 count,
150 extend.into_glib(),
151 modify.into_glib(),
152 ))
153 } else {
154 false
156 }
157 }
158 }
159
160 fn parent_row_activated(&self, path: &TreePath, column: &TreeViewColumn) {
161 unsafe {
162 let data = Self::type_data();
163 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTreeViewClass;
164 if let Some(f) = (*parent_class).row_activated {
166 f(
167 self.obj().unsafe_cast_ref::<TreeView>().to_glib_none().0,
168 path.to_glib_none().0,
169 column.to_glib_none().0,
170 );
171 }
172 }
173 }
174
175 fn parent_row_collapsed(&self, iter: &TreeIter, path: &TreePath) {
176 unsafe {
177 let data = Self::type_data();
178 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTreeViewClass;
179 if let Some(f) = (*parent_class).row_collapsed {
181 f(
182 self.obj().unsafe_cast_ref::<TreeView>().to_glib_none().0,
183 iter.to_glib_none().0 as *mut _,
184 path.to_glib_none().0,
185 )
186 }
187 }
188 }
189
190 fn parent_row_expanded(&self, iter: &TreeIter, path: &TreePath) {
191 unsafe {
192 let data = Self::type_data();
193 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTreeViewClass;
194 if let Some(f) = (*parent_class).row_expanded {
196 f(
197 self.obj().unsafe_cast_ref::<TreeView>().to_glib_none().0,
198 iter.to_glib_none().0 as *mut _,
199 path.to_glib_none().0,
200 )
201 }
202 }
203 }
204
205 fn parent_select_all(&self) -> bool {
206 unsafe {
207 let data = Self::type_data();
208 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTreeViewClass;
209 if let Some(f) = (*parent_class).select_all {
211 from_glib(f(self.obj().unsafe_cast_ref::<TreeView>().to_glib_none().0))
212 } else {
213 false
214 }
215 }
216 }
217
218 fn parent_select_cursor_parent(&self) -> bool {
219 unsafe {
220 let data = Self::type_data();
221 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTreeViewClass;
222 if let Some(f) = (*parent_class).select_cursor_parent {
224 from_glib(f(self.obj().unsafe_cast_ref::<TreeView>().to_glib_none().0))
225 } else {
226 false
227 }
228 }
229 }
230
231 fn parent_select_cursor_row(&self, start_editing: bool) -> bool {
232 unsafe {
233 let data = Self::type_data();
234 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTreeViewClass;
235 if let Some(f) = (*parent_class).select_cursor_row {
237 from_glib(f(
238 self.obj().unsafe_cast_ref::<TreeView>().to_glib_none().0,
239 start_editing.into_glib(),
240 ))
241 } else {
242 false
243 }
244 }
245 }
246
247 fn parent_start_interactive_search(&self) -> bool {
248 unsafe {
249 let data = Self::type_data();
250 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTreeViewClass;
251 if let Some(f) = (*parent_class).start_interactive_search {
253 from_glib(f(self.obj().unsafe_cast_ref::<TreeView>().to_glib_none().0))
254 } else {
255 false
256 }
257 }
258 }
259
260 fn parent_test_collapse_row(&self, iter: &TreeIter, path: &TreePath) -> bool {
261 unsafe {
262 let data = Self::type_data();
263 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTreeViewClass;
264 if let Some(f) = (*parent_class).test_collapse_row {
266 from_glib(f(
267 self.obj().unsafe_cast_ref::<TreeView>().to_glib_none().0,
268 iter.to_glib_none().0 as *mut _,
269 path.to_glib_none().0,
270 ))
271 } else {
272 false
274 }
275 }
276 }
277
278 fn parent_test_expand_row(&self, iter: &TreeIter, path: &TreePath) -> bool {
279 unsafe {
280 let data = Self::type_data();
281 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTreeViewClass;
282 if let Some(f) = (*parent_class).test_expand_row {
284 from_glib(f(
285 self.obj().unsafe_cast_ref::<TreeView>().to_glib_none().0,
286 iter.to_glib_none().0 as *mut _,
287 path.to_glib_none().0,
288 ))
289 } else {
290 false
292 }
293 }
294 }
295
296 fn parent_toggle_cursor_row(&self) -> bool {
297 unsafe {
298 let data = Self::type_data();
299 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTreeViewClass;
300 if let Some(f) = (*parent_class).toggle_cursor_row {
302 from_glib(f(self.obj().unsafe_cast_ref::<TreeView>().to_glib_none().0))
303 } else {
304 false
305 }
306 }
307 }
308
309 fn parent_unselect_all(&self) -> bool {
310 unsafe {
311 let data = Self::type_data();
312 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTreeViewClass;
313 if let Some(f) = (*parent_class).unselect_all {
315 from_glib(f(self.obj().unsafe_cast_ref::<TreeView>().to_glib_none().0))
316 } else {
317 false
318 }
319 }
320 }
321}
322
323impl<T: TreeViewImpl> TreeViewImplExt for T {}
324
325unsafe impl<T: TreeViewImpl> IsSubclassable<T> for TreeView {
326 fn class_init(class: &mut glib::Class<Self>) {
327 Self::parent_class_init::<T>(class);
328
329 let klass = class.as_mut();
330 klass.columns_changed = Some(tree_view_columns_changed::<T>);
331 klass.cursor_changed = Some(tree_view_cursor_changed::<T>);
332 klass.expand_collapse_cursor_row = Some(tree_view_expand_collapse_cursor_row::<T>);
333 klass.move_cursor = Some(tree_view_move_cursor::<T>);
334 klass.row_activated = Some(tree_view_row_activated::<T>);
335 klass.row_collapsed = Some(tree_view_row_collapsed::<T>);
336 klass.row_expanded = Some(tree_view_row_expanded::<T>);
337 klass.select_all = Some(tree_view_select_all::<T>);
338 klass.select_cursor_parent = Some(tree_view_select_cursor_parent::<T>);
339 klass.select_cursor_row = Some(tree_view_select_cursor_row::<T>);
340 klass.start_interactive_search = Some(tree_view_start_interactive_search::<T>);
341 klass.test_collapse_row = Some(tree_view_test_collapse_row::<T>);
342 klass.test_expand_row = Some(tree_view_test_expand_row::<T>);
343 klass.toggle_cursor_row = Some(tree_view_toggle_cursor_row::<T>);
344 klass.unselect_all = Some(tree_view_unselect_all::<T>);
345 }
346}
347
348unsafe extern "C" fn tree_view_columns_changed<T: TreeViewImpl>(ptr: *mut ffi::GtkTreeView) {
349 unsafe {
350 let instance = &*(ptr as *mut T::Instance);
351 let imp = instance.imp();
352
353 imp.columns_changed()
354 }
355}
356
357unsafe extern "C" fn tree_view_cursor_changed<T: TreeViewImpl>(ptr: *mut ffi::GtkTreeView) {
358 unsafe {
359 let instance = &*(ptr as *mut T::Instance);
360 let imp = instance.imp();
361
362 imp.cursor_changed()
363 }
364}
365
366unsafe extern "C" fn tree_view_expand_collapse_cursor_row<T: TreeViewImpl>(
367 ptr: *mut ffi::GtkTreeView,
368 logical: glib::ffi::gboolean,
369 expand: glib::ffi::gboolean,
370 open_all: glib::ffi::gboolean,
371) -> glib::ffi::gboolean {
372 unsafe {
373 let instance = &*(ptr as *mut T::Instance);
374 let imp = instance.imp();
375
376 imp.expand_collapse_cursor_row(from_glib(logical), from_glib(expand), from_glib(open_all))
377 .into_glib()
378 }
379}
380
381unsafe extern "C" fn tree_view_move_cursor<T: TreeViewImpl>(
382 ptr: *mut ffi::GtkTreeView,
383 step: ffi::GtkMovementStep,
384 count: i32,
385 extend: glib::ffi::gboolean,
386 modify: glib::ffi::gboolean,
387) -> glib::ffi::gboolean {
388 unsafe {
389 let instance = &*(ptr as *mut T::Instance);
390 let imp = instance.imp();
391
392 imp.move_cursor(from_glib(step), count, from_glib(extend), from_glib(modify))
393 .into_glib()
394 }
395}
396
397unsafe extern "C" fn tree_view_row_activated<T: TreeViewImpl>(
398 ptr: *mut ffi::GtkTreeView,
399 pathptr: *mut ffi::GtkTreePath,
400 columnptr: *mut ffi::GtkTreeViewColumn,
401) {
402 unsafe {
403 let instance = &*(ptr as *mut T::Instance);
404 let imp = instance.imp();
405 let path: Borrowed<TreePath> = from_glib_borrow(pathptr);
406 let column: Borrowed<TreeViewColumn> = from_glib_borrow(columnptr);
407
408 imp.row_activated(&path, &column)
409 }
410}
411
412unsafe extern "C" fn tree_view_row_collapsed<T: TreeViewImpl>(
413 ptr: *mut ffi::GtkTreeView,
414 iterptr: *mut ffi::GtkTreeIter,
415 pathptr: *mut ffi::GtkTreePath,
416) {
417 unsafe {
418 let instance = &*(ptr as *mut T::Instance);
419 let imp = instance.imp();
420 let path: Borrowed<TreePath> = from_glib_borrow(pathptr);
421 let iter: Borrowed<TreeIter> = from_glib_borrow(iterptr);
422
423 imp.row_collapsed(&iter, &path)
424 }
425}
426
427unsafe extern "C" fn tree_view_row_expanded<T: TreeViewImpl>(
428 ptr: *mut ffi::GtkTreeView,
429 iterptr: *mut ffi::GtkTreeIter,
430 pathptr: *mut ffi::GtkTreePath,
431) {
432 unsafe {
433 let instance = &*(ptr as *mut T::Instance);
434 let imp = instance.imp();
435 let path: Borrowed<TreePath> = from_glib_borrow(pathptr);
436 let iter: Borrowed<TreeIter> = from_glib_borrow(iterptr);
437
438 imp.row_expanded(&iter, &path)
439 }
440}
441
442unsafe extern "C" fn tree_view_select_all<T: TreeViewImpl>(
443 ptr: *mut ffi::GtkTreeView,
444) -> glib::ffi::gboolean {
445 unsafe {
446 let instance = &*(ptr as *mut T::Instance);
447 let imp = instance.imp();
448
449 imp.select_all().into_glib()
450 }
451}
452
453unsafe extern "C" fn tree_view_select_cursor_parent<T: TreeViewImpl>(
454 ptr: *mut ffi::GtkTreeView,
455) -> glib::ffi::gboolean {
456 unsafe {
457 let instance = &*(ptr as *mut T::Instance);
458 let imp = instance.imp();
459
460 imp.select_cursor_parent().into_glib()
461 }
462}
463
464unsafe extern "C" fn tree_view_select_cursor_row<T: TreeViewImpl>(
465 ptr: *mut ffi::GtkTreeView,
466 start_editing: glib::ffi::gboolean,
467) -> glib::ffi::gboolean {
468 unsafe {
469 let instance = &*(ptr as *mut T::Instance);
470 let imp = instance.imp();
471
472 imp.select_cursor_row(from_glib(start_editing)).into_glib()
473 }
474}
475
476unsafe extern "C" fn tree_view_start_interactive_search<T: TreeViewImpl>(
477 ptr: *mut ffi::GtkTreeView,
478) -> glib::ffi::gboolean {
479 unsafe {
480 let instance = &*(ptr as *mut T::Instance);
481 let imp = instance.imp();
482
483 imp.start_interactive_search().into_glib()
484 }
485}
486
487unsafe extern "C" fn tree_view_test_collapse_row<T: TreeViewImpl>(
488 ptr: *mut ffi::GtkTreeView,
489 iterptr: *mut ffi::GtkTreeIter,
490 pathptr: *mut ffi::GtkTreePath,
491) -> glib::ffi::gboolean {
492 unsafe {
493 let instance = &*(ptr as *mut T::Instance);
494 let imp = instance.imp();
495 let path: Borrowed<TreePath> = from_glib_borrow(pathptr);
496 let iter: Borrowed<TreeIter> = from_glib_borrow(iterptr);
497
498 imp.test_collapse_row(&iter, &path).into_glib()
499 }
500}
501
502unsafe extern "C" fn tree_view_test_expand_row<T: TreeViewImpl>(
503 ptr: *mut ffi::GtkTreeView,
504 iterptr: *mut ffi::GtkTreeIter,
505 pathptr: *mut ffi::GtkTreePath,
506) -> glib::ffi::gboolean {
507 unsafe {
508 let instance = &*(ptr as *mut T::Instance);
509 let imp = instance.imp();
510 let path: Borrowed<TreePath> = from_glib_borrow(pathptr);
511 let iter: Borrowed<TreeIter> = from_glib_borrow(iterptr);
512
513 imp.test_expand_row(&iter, &path).into_glib()
514 }
515}
516
517unsafe extern "C" fn tree_view_toggle_cursor_row<T: TreeViewImpl>(
518 ptr: *mut ffi::GtkTreeView,
519) -> glib::ffi::gboolean {
520 unsafe {
521 let instance = &*(ptr as *mut T::Instance);
522 let imp = instance.imp();
523
524 imp.toggle_cursor_row().into_glib()
525 }
526}
527
528unsafe extern "C" fn tree_view_unselect_all<T: TreeViewImpl>(
529 ptr: *mut ffi::GtkTreeView,
530) -> glib::ffi::gboolean {
531 unsafe {
532 let instance = &*(ptr as *mut T::Instance);
533 let imp = instance.imp();
534
535 imp.unselect_all().into_glib()
536 }
537}