gtk4/
custom_filter.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, CustomFilter};
8
9impl CustomFilter {
10    /// Creates a new filter using the given function to filter items.
11    ///
12    /// If @match_func is `NULL`, the filter matches all items.
13    ///
14    /// If the filter func changes its filtering behavior,
15    /// [`FilterExt::changed()`][crate::prelude::FilterExt::changed()] needs to be called.
16    /// ## `match_func`
17    /// function to filter items
18    ///
19    /// # Returns
20    ///
21    /// a new [`CustomFilter`][crate::CustomFilter]
22    #[doc(alias = "gtk_custom_filter_new")]
23    pub fn new<F>(filter_func: F) -> Self
24    where
25        F: Fn(&glib::Object) -> bool + 'static,
26    {
27        assert_initialized_main_thread!();
28        unsafe {
29            from_glib_full(ffi::gtk_custom_filter_new(
30                Some(trampoline::<F>),
31                Box::into_raw(Box::new(filter_func)) as *mut _,
32                Some(destroy_closure::<F>),
33            ))
34        }
35    }
36
37    /// Sets the function used for filtering items.
38    ///
39    /// If @match_func is `NULL`, the filter matches all items.
40    ///
41    /// If the filter func changes its filtering behavior,
42    /// [`FilterExt::changed()`][crate::prelude::FilterExt::changed()] needs to be called.
43    ///
44    /// If a previous function was set, its @user_destroy
45    /// will be called.
46    /// ## `match_func`
47    /// function to filter items
48    #[doc(alias = "gtk_custom_filter_set_filter_func")]
49    pub fn set_filter_func<F>(&self, filter_func: F)
50    where
51        F: Fn(&glib::Object) -> bool + 'static,
52    {
53        unsafe {
54            ffi::gtk_custom_filter_set_filter_func(
55                self.to_glib_none().0,
56                Some(trampoline::<F>),
57                Box::into_raw(Box::new(filter_func)) as *mut _,
58                Some(destroy_closure::<F>),
59            )
60        }
61    }
62
63    #[doc(alias = "gtk_custom_filter_set_filter_func")]
64    #[doc(alias = "set_filter_func")]
65    pub fn unset_filter_func(&self) {
66        unsafe {
67            ffi::gtk_custom_filter_set_filter_func(
68                self.to_glib_none().0,
69                None,
70                ptr::null_mut(),
71                None,
72            )
73        }
74    }
75}
76
77impl Default for CustomFilter {
78    fn default() -> Self {
79        assert_initialized_main_thread!();
80        unsafe { from_glib_full(ffi::gtk_custom_filter_new(None, ptr::null_mut(), None)) }
81    }
82}
83
84unsafe extern "C" fn destroy_closure<F: Fn(&glib::Object) -> bool + 'static>(
85    ptr: glib::ffi::gpointer,
86) {
87    let _ = Box::<F>::from_raw(ptr as *mut _);
88}
89
90unsafe extern "C" fn trampoline<F: Fn(&glib::Object) -> bool + 'static>(
91    item: *mut glib::gobject_ffi::GObject,
92    f: glib::ffi::gpointer,
93) -> glib::ffi::gboolean {
94    let f: &F = &*(f as *const F);
95    f(&from_glib_borrow(item)).into_glib()
96}