diff --git a/examples/menu.rs b/examples/menu.rs index 76eeaf8..624db03 100644 --- a/examples/menu.rs +++ b/examples/menu.rs @@ -89,13 +89,20 @@ fn main() { //window.add_menu("Test", &menu).expect("Unable to add menu"); let mut menu = Menu::new("TestMenu").unwrap(); + let mut sub = Menu::new("SubMenu").unwrap(); menu.add_menu_item(&MenuItem::new("Item 1", 1).shortcut(Key::S, 0)); menu.add_menu_item(&MenuItem::new("Item 2", 2)); menu.add_menu_item(&MenuItem::new("Item 3", 3)); + sub.add_item("Test", 0).build(); + sub.add_item("Test 2", 0).build(); + + menu.add_item("", 0).separator().build(); menu.add_item("Some item", 2).shortcut(Key::Y, MENU_KEY_CTRL).build(); + menu.add_sub_menu("Sub Test", &sub); + let _ = window.add_menu(&menu); let color_mul = 1; diff --git a/src/lib.rs b/src/lib.rs index a7e4f05..974c227 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -525,8 +525,8 @@ impl Menu { } #[inline] - pub fn add_sub_menu(&mut self, _menu: &Menu) { - //self.0.add_sub_menu(menu) + pub fn add_sub_menu(&mut self, name: &str, menu: &Menu) { + self.0.add_sub_menu(name, &menu.0) } #[inline] diff --git a/src/native/macosx/MacMiniFB.m b/src/native/macosx/MacMiniFB.m index aae240c..39df473 100644 --- a/src/native/macosx/MacMiniFB.m +++ b/src/native/macosx/MacMiniFB.m @@ -605,10 +605,22 @@ uint64_t mfb_add_menu_item( NSMenuItem* newItem = [[NSMenuItem alloc] initWithTitle:name action:@selector(onMenuPress:) keyEquivalent:@""]; [newItem setTag:menu_id]; - if ((modfier & MENU_KEY_COMMAND) || - (modfier & MENU_KEY_COMMAND)) { + // This code may look a bit weird but is here for a reason: + // + // In order to make it easier to bulid cross-platform apps Ctrl is often used as + // default modifier on Windows/Nix* while it's Command on Mac. Now we when Ctrl + // is set we default to Command on Mac for that reason but if Command AND Ctrl is + // set we allow both Ctrl and Command to be used but then it's up to the developer + // to deal with diffrent shortcuts depending on OS. + // + + if ((modfier & MENU_KEY_CTRL)) { mask |= NSCommandKeyMask; } + if ((modfier & MENU_KEY_CTRL) && + (modfier & MENU_KEY_COMMAND)) { + mask |= NSControlKeyMask; + } if (modfier & MENU_KEY_SHIFT) { mask |= NSShiftKeyMask; } @@ -641,6 +653,18 @@ uint64_t mfb_add_menu_item( return 0; } +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void mfb_add_sub_menu(void* parent_menu, const char* menu_name, void* attach_menu) { + NSMenu* parent = (NSMenu*)parent_menu; + NSMenu* attach = (NSMenu*)attach_menu; + NSString* name = [NSString stringWithUTF8String: menu_name]; + + NSMenuItem* newItem = [[NSMenuItem alloc] initWithTitle:name action:NULL keyEquivalent:@""]; + [newItem setSubmenu:attach]; + + [parent addItem:newItem]; +} /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/os/macos/mod.rs b/src/os/macos/mod.rs index c987cbc..319aafc 100644 --- a/src/os/macos/mod.rs +++ b/src/os/macos/mod.rs @@ -181,6 +181,7 @@ extern { 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_sub_menu(parent_menu: *mut c_void, name: *const c_char, menu: *mut c_void); //fn mfb_remove_menu(window: *mut c_void, name: *const c_char); //fn mfb_update_menu(window: *mut c_void, name: *const c_char, menu: *mut c_void); //fn mfb_active_menu(window: *mut c_void) -> i32; @@ -616,6 +617,13 @@ impl Menu { } } + pub fn add_sub_menu(&mut self, name: &str, sub_menu: &Menu) { + unsafe { + let menu_name = CString::new(name).unwrap(); + mfb_add_sub_menu(self.menu_handle, menu_name.as_ptr(), sub_menu.menu_handle) + } + } + pub fn add_menu_item(&mut self, item: &MenuItem) -> MenuItemHandle { unsafe { let item_name = CString::new(item.label.as_str()).unwrap();