gtk4/
custom_sorter.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::ptr;
4
5use glib::translate::*;
6
7use crate::{ffi, CustomSorter, Ordering};
8
9impl CustomSorter {
10    /// Creates a new [`Sorter`][crate::Sorter] that works by calling
11    /// @sort_func to compare items.
12    ///
13    /// If @sort_func is [`None`], all items are considered equal.
14    /// ## `sort_func`
15    /// the `GCompareDataFunc` to use for sorting
16    ///
17    /// # Returns
18    ///
19    /// a new [`CustomSorter`][crate::CustomSorter]
20    #[doc(alias = "gtk_custom_sorter_new")]
21    pub fn new<F>(sort_func: F) -> Self
22    where
23        F: Fn(&glib::Object, &glib::Object) -> Ordering + 'static,
24    {
25        assert_initialized_main_thread!();
26        unsafe {
27            from_glib_full(ffi::gtk_custom_sorter_new(
28                Some(trampoline::<F>),
29                Box::into_raw(Box::new(sort_func)) as *mut _,
30                Some(destroy_closure::<F>),
31            ))
32        }
33    }
34
35    /// Sets (or unsets) the function used for sorting items.
36    ///
37    /// If @sort_func is [`None`], all items are considered equal.
38    ///
39    /// If the sort func changes its sorting behavior,
40    /// gtk_sorter_changed() needs to be called.
41    ///
42    /// If a previous function was set, its @user_destroy will be
43    /// called now.
44    /// ## `sort_func`
45    /// function to sort items
46    #[doc(alias = "gtk_custom_sorter_set_sort_func")]
47    pub fn set_sort_func<F>(&self, sort_func: F)
48    where
49        F: Fn(&glib::Object, &glib::Object) -> Ordering + 'static,
50    {
51        unsafe {
52            ffi::gtk_custom_sorter_set_sort_func(
53                self.to_glib_none().0,
54                Some(trampoline::<F>),
55                Box::into_raw(Box::new(sort_func)) as *mut _,
56                Some(destroy_closure::<F>),
57            )
58        }
59    }
60
61    #[doc(alias = "gtk_custom_sorter_set_sort_func")]
62    #[doc(alias = "set_sort_func")]
63    pub fn unset_sort_func(&self) {
64        unsafe {
65            ffi::gtk_custom_sorter_set_sort_func(self.to_glib_none().0, None, ptr::null_mut(), None)
66        }
67    }
68}
69
70impl Default for CustomSorter {
71    fn default() -> Self {
72        assert_initialized_main_thread!();
73        unsafe { from_glib_full(ffi::gtk_custom_sorter_new(None, ptr::null_mut(), None)) }
74    }
75}
76
77unsafe extern "C" fn destroy_closure<F: Fn(&glib::Object, &glib::Object) -> Ordering + 'static>(
78    ptr: glib::ffi::gpointer,
79) {
80    let _ = Box::<F>::from_raw(ptr as *mut _);
81}
82
83unsafe extern "C" fn trampoline<F: Fn(&glib::Object, &glib::Object) -> Ordering + 'static>(
84    a: glib::ffi::gconstpointer,
85    b: glib::ffi::gconstpointer,
86    f: glib::ffi::gpointer,
87) -> i32 {
88    let f: &F = &*(f as *const F);
89    f(
90        &from_glib_borrow(a as *mut glib::gobject_ffi::GObject),
91        &from_glib_borrow(b as *mut glib::gobject_ffi::GObject),
92    )
93    .into_glib()
94}