For MBS Xojo Plugins 25.0, we add a way to better use our NSMenuMBS and NSMenuItemMBS class with Xojo MenuItems class.
The NSMenuPopupEventsMBS class allows you to intercept a menu before the system shows it. These events are available:
- didCloseMenu(menu as NSMenuMBS, theEvent as NSEventMBS, view as NSViewMBS)
- popUpMenuAtPosition(menu as NSMenuMBS, item as NSMenuItemMBS, location as NSPointMBS, view as NSViewMBS) as Boolean
- willOpenMenu(menu as NSMenuMBS, theEvent as NSEventMBS, view as NSViewMBS)
For a popup menu, the popUpMenuAtPosition method fires first. Then for any context or popup menu, you may see a willOpenMenu event just before the menu shows. Later you get a didCloseMenu event for the menu closing.
Let’s make an example where you show a contextual menu in a button:
EventHandler Sub Pressed()
System.DebugLog CurrentMethodName
// build a context menu using Xojo methods
Var base As New DesktopMenuitem
' Add some items
base.AddMenu(New DesktopMenuItem("Test"))
base.AddMenu(New DesktopMenuItem("Test with Shift"))
base.AddMenu(New DesktopMenuItem("Test with option"))
// and show it!
Call base.PopUp
End EventHandler
Now you have three menu items and we like to add key equivalents with alternatives. In the willOpenMenu we get the three menu items and assign the shortcuts as well as the alternate flag. The alternate flag makes macOS only show the entry matching the currently pressed down modifier keys. This way only one of them shows up for the user.
EventHandler Sub willOpenMenu(menu as NSMenuMBS, theEvent as NSEventMBS, view as NSViewMBS)
// the menu opens and you can modify it
System.DebugLog CurrentMethodName
Var items() As NSMenuItemMBS = menu.items
Const NSShiftKeyMask = 131072
Const NSControlKeyMask = 262144
Const NSAlternateKeyMask = 524288
Const NSCommandKeyMask = 1048576
Var item0 As NSMenuItemMBS = items(0)
item0.KeyEquivalent="a" // command-A
item0.keyEquivalentModifierMask = 0
Var item1 As NSMenuItemMBS = items(1)
item1.Alternate = True
item1.KeyEquivalent="a" // command-shift-A
item1.keyEquivalentModifierMask = NSShiftKeyMask
Var item2 As NSMenuItemMBS = items(2)
item2.Alternate = True
item2.KeyEquivalent="a" // command-option-A
item2.keyEquivalentModifierMask = NSAlternateKeyMask
End EventHandler
Since you get the menu items, you can also trigger some directly. For this we add a PerformAction method to NSMenuItemMBS class. So if macOS adds a standard menu item, you could run it by finding the entry and performing it.