diff --git a/examples/menu.rs b/examples/menu.rs index c6d3565..b4a9f5c 100644 --- a/examples/menu.rs +++ b/examples/menu.rs @@ -40,7 +40,7 @@ fn main() { menu.add_sub_menu("Sub Test", &sub); - let _ = window.add_menu(&menu); + let menu_handle = window.add_menu(&menu); let mut color_mul = 1; @@ -64,7 +64,7 @@ fn main() { } CLOSE_MENU_ID => { println!("remove menu"); - //window.remove_menu( + window.remove_menu(menu_handle); } _ => (), } diff --git a/src/lib.rs b/src/lib.rs index 12004c5..58ade2e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -464,27 +464,27 @@ impl Window { /// #[inline] - pub fn add_menu(&mut self, menu: &Menu) -> Result<()> { + pub fn add_menu(&mut self, menu: &Menu) -> MenuHandle { self.0.add_menu(&menu.0) } - /* /// /// Updates an existing menu created with [add_menu] /// + /* #[inline] pub fn update_menu(&mut self, menu_name: &str, menu: &Vec) -> Result<()> { self.0.update_menu(menu_name, menu) } + */ /// /// Remove a menu that has been added with [add_menu] /// #[inline] - pub fn remove_menu(&mut self, menu_name: &str) -> Result<()> { - self.0.remove_menu(menu_name) + pub fn remove_menu(&mut self, handle: MenuHandle) { + self.0.remove_menu(handle) } - */ /// /// Check if a menu item has been pressed @@ -511,9 +511,12 @@ const MENU_ID_SEPARATOR:usize = 0xffffffff; pub struct Menu(imp::Menu); -#[derive(Debug)] +#[derive(Copy, Clone)] pub struct MenuItemHandle(pub u64); +#[derive(Copy, Clone, PartialEq)] +pub struct MenuHandle(pub u64); + impl Menu { pub fn new(name: &str) -> Result { imp::Menu::new(name).map(Menu) diff --git a/src/native/macosx/MacMiniFB.m b/src/native/macosx/MacMiniFB.m index a22331f..8c06cae 100644 --- a/src/native/macosx/MacMiniFB.m +++ b/src/native/macosx/MacMiniFB.m @@ -416,7 +416,7 @@ void mfb_add_menu(void* window, const char* name, void* m) /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void mfb_add_menu(void* window, void* m) +uint64_t mfb_add_menu(void* window, void* m) { OSXWindow* win = (OSXWindow*)window; NSMenu* menu = (NSMenu*)m; @@ -426,6 +426,17 @@ void mfb_add_menu(void* window, void* m) NSMenuItem* windowMenuItem = [main_menu addItemWithTitle:@"" action:NULL keyEquivalent:@""]; [NSApp setWindowsMenu:menu]; [windowMenuItem setSubmenu:menu]; + + return (uint64_t)menu; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void mfb_remove_menu_at(void* window, int index) +{ + (void)window; + NSMenu* main_menu = [NSApp mainMenu]; + [main_menu removeItemAtIndex:index]; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/os/macos/mod.rs b/src/os/macos/mod.rs index 2be88ae..b90daaf 100644 --- a/src/os/macos/mod.rs +++ b/src/os/macos/mod.rs @@ -8,7 +8,7 @@ use Result; use InputCallback; use mouse_handler; use window_flags; -use {MenuItem, MenuItemHandle}; +use {MenuItem, MenuItemHandle, MenuHandle}; // use menu::Menu; use libc::{c_void, c_char, c_uchar}; @@ -171,12 +171,12 @@ extern "C" { fn mfb_should_close(window: *mut c_void) -> i32; fn mfb_get_screen_size() -> u32; fn mfb_is_active(window: *mut c_void) -> u32; - fn mfb_add_menu(window: *mut c_void, menu: *mut c_void); + fn mfb_add_menu(window: *mut c_void, menu: *mut c_void) -> u64; fn mfb_add_sub_menu(parent_menu: *mut c_void, name: *const c_char, menu: *mut c_void); fn mfb_active_menu(window: *mut c_void) -> i32; fn mfb_create_menu(name: *const c_char) -> *mut c_void; - // fn mfb_destroy_menu(menu_item: *mut c_void); + fn mfb_remove_menu_at(window: *mut c_void, index: i32); fn mfb_add_menu_item(menu_item: *mut c_void, menu_id: i32, @@ -206,6 +206,7 @@ pub struct Window { pub shared_data: SharedData, key_handler: KeyHandler, pub has_set_data: bool, + menus: Vec, } unsafe extern "C" fn key_callback(window: *mut c_void, key: i32, state: i32) { @@ -265,6 +266,7 @@ impl Window { }, key_handler: KeyHandler::new(), has_set_data: false, + menus: Vec::new(), }) } } @@ -392,12 +394,25 @@ impl Window { } } - pub fn add_menu(&mut self, menu: &Menu) -> Result<()> { + pub fn add_menu(&mut self, menu: &Menu) -> MenuHandle { unsafe { - mfb_add_menu(self.window_handle, menu.menu_handle); + let handle = MenuHandle(mfb_add_menu(self.window_handle, menu.menu_handle)); + self.menus.push(handle); + handle } + } - Ok(()) + pub fn remove_menu(&mut self, handle: MenuHandle) { + for i in 0..self.menus.len() { + if self.menus[i] == handle { + self.menus.remove(i); + unsafe { + // + 1 here as we always have a default menu we shouldn't remove + mfb_remove_menu_at(self.window_handle, (i + 1) as i32); + } + return; + } + } } #[inline] @@ -579,8 +594,6 @@ impl Menu { let item_name = CString::new(item.label.as_str()).unwrap(); let conv_key = Self::map_key_to_menu_key(item.key); - println!("menu id {}", item.id); - MenuItemHandle(mfb_add_menu_item(self.menu_handle, item.id as i32, item_name.as_ptr(), @@ -605,11 +618,3 @@ impl Drop for Window { } } -// impl Drop for Menu { -// fn drop(&mut self) { -// unsafe { -// mfb_destroy_menu(self.menu_handle); -// } -// } -// } -//