1use 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 {}