Intercept Menus with MBS Xojo Plugins

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:

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.

4 Likes