1 // Take a look at the license at the top of the repository in the LICENSE file.
2 
3 use crate::ListStore;
4 use glib::translate::*;
5 use glib::{IsA, Object};
6 use std::cmp::Ordering;
7 
8 pub trait ListStoreExtManual {
9     #[doc(alias = "g_list_store_insert_sorted")]
insert_sorted<P: IsA<glib::Object>, F: FnMut(&Object, &Object) -> Ordering>( &self, item: &P, compare_func: F, ) -> u3210     fn insert_sorted<P: IsA<glib::Object>, F: FnMut(&Object, &Object) -> Ordering>(
11         &self,
12         item: &P,
13         compare_func: F,
14     ) -> u32;
15 
16     #[doc(alias = "g_list_store_sort")]
sort<F: FnMut(&Object, &Object) -> Ordering>(&self, compare_func: F)17     fn sort<F: FnMut(&Object, &Object) -> Ordering>(&self, compare_func: F);
18 }
19 
20 impl<O: IsA<ListStore>> ListStoreExtManual for O {
insert_sorted<P: IsA<glib::Object>, F: FnMut(&Object, &Object) -> Ordering>( &self, item: &P, compare_func: F, ) -> u3221     fn insert_sorted<P: IsA<glib::Object>, F: FnMut(&Object, &Object) -> Ordering>(
22         &self,
23         item: &P,
24         compare_func: F,
25     ) -> u32 {
26         unsafe {
27             let mut func = compare_func;
28             let func_obj: &mut (dyn FnMut(&Object, &Object) -> Ordering) = &mut func;
29             let func_ptr = &func_obj as *const &mut (dyn FnMut(&Object, &Object) -> Ordering)
30                 as glib::ffi::gpointer;
31 
32             ffi::g_list_store_insert_sorted(
33                 self.as_ref().to_glib_none().0,
34                 item.as_ref().to_glib_none().0,
35                 Some(compare_func_trampoline),
36                 func_ptr,
37             )
38         }
39     }
40 
sort<F: FnMut(&Object, &Object) -> Ordering>(&self, compare_func: F)41     fn sort<F: FnMut(&Object, &Object) -> Ordering>(&self, compare_func: F) {
42         unsafe {
43             let mut func = compare_func;
44             let func_obj: &mut (dyn FnMut(&Object, &Object) -> Ordering) = &mut func;
45             let func_ptr = &func_obj as *const &mut (dyn FnMut(&Object, &Object) -> Ordering)
46                 as glib::ffi::gpointer;
47 
48             ffi::g_list_store_sort(
49                 self.as_ref().to_glib_none().0,
50                 Some(compare_func_trampoline),
51                 func_ptr,
52             )
53         }
54     }
55 }
56 
compare_func_trampoline( a: glib::ffi::gconstpointer, b: glib::ffi::gconstpointer, func: glib::ffi::gpointer, ) -> i3257 unsafe extern "C" fn compare_func_trampoline(
58     a: glib::ffi::gconstpointer,
59     b: glib::ffi::gconstpointer,
60     func: glib::ffi::gpointer,
61 ) -> i32 {
62     let func = func as *mut &mut (dyn FnMut(&Object, &Object) -> Ordering);
63 
64     let a = from_glib_borrow(a as *mut glib::gobject_ffi::GObject);
65     let b = from_glib_borrow(b as *mut glib::gobject_ffi::GObject);
66 
67     match (*func)(&a, &b) {
68         Ordering::Less => -1,
69         Ordering::Equal => 0,
70         Ordering::Greater => 1,
71     }
72 }
73