Skip to main content

gtk/
menu.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use crate::Widget;
4use crate::{Menu, ffi};
5use glib::object::Cast;
6use glib::object::IsA;
7use glib::translate::*;
8use libc::c_int;
9use std::boxed::Box as Box_;
10use std::ptr;
11
12pub trait GtkMenuExtManual: IsA<Menu> + 'static {
13    #[doc(alias = "gtk_menu_popup")]
14    fn popup<
15        T: IsA<Widget>,
16        U: IsA<Widget>,
17        F: FnOnce(&Self, &mut i32, &mut i32) -> bool + 'static,
18    >(
19        &self,
20        parent_menu_shell: Option<&T>,
21        parent_menu_item: Option<&U>,
22        f: F,
23        button: u32,
24        activate_time: u32,
25    ) {
26        unsafe extern "C" fn position_callback<
27            T,
28            F: FnOnce(&T, &mut i32, &mut i32) -> bool + 'static,
29        >(
30            this: *mut ffi::GtkMenu,
31            x: *mut c_int,
32            y: *mut c_int,
33            push_in: *mut glib::ffi::gboolean,
34            f: glib::ffi::gpointer,
35        ) where
36            T: IsA<Menu>,
37        {
38            unsafe {
39                let mut f: Box<Option<F>> = Box::from_raw(f as *mut _);
40                let f = f.take().expect("No callback");
41                *push_in = f(
42                    &Menu::from_glib_none(this).unsafe_cast(),
43                    x.as_mut().unwrap(),
44                    y.as_mut().unwrap(),
45                )
46                .into_glib();
47            }
48        }
49        unsafe {
50            let f: Box_<Option<F>> = Box_::new(Some(f));
51            ffi::gtk_menu_popup(
52                self.as_ref().to_glib_none().0,
53                parent_menu_shell.map(|p| p.as_ref()).to_glib_none().0,
54                parent_menu_item.map(|p| p.as_ref()).to_glib_none().0,
55                Some(position_callback::<Self, F>),
56                Box_::into_raw(f) as *mut _,
57                button,
58                activate_time,
59            )
60        }
61    }
62
63    #[doc(alias = "gtk_menu_popup_easy")]
64    fn popup_easy(&self, button: u32, activate_time: u32) {
65        unsafe {
66            ffi::gtk_menu_popup(
67                self.as_ref().to_glib_none().0,
68                ptr::null_mut(),
69                ptr::null_mut(),
70                None,
71                ptr::null_mut(),
72                button,
73                activate_time,
74            )
75        }
76    }
77}
78
79impl<O: IsA<Menu>> GtkMenuExtManual for O {}