I try to connect a DesktopSegmentedButton with a DesktopMenuItem via AppKit Declare setMenu:forSegment:. Sadly the App crashes using this code. Where’s the error?
Var menu As New DesktopMenuItem
menu.AddMenu(New DesktopMenuItem("Import"))
menu.AddMenu(New DesktopMenuItem("Export"))
menu.AddMenu(New DesktopMenuItem(DesktopMenuItem.TextSeparator))
menu.AddMenu(New DesktopMenuItem("Cut"))
menu.AddMenu(New DesktopMenuItem("Copy"))
menu.AddMenu(New DesktopMenuItem("Paste"))
' https://developer.apple.com/documentation/appkit/nssegmentedcontrol/1528853-setmenu?language=objc
Declare Sub setMenuForSegment Lib "AppKit" Selector "setMenu:forSegment:" (id As Ptr, menu As Ptr, segment As Int64)
setMenuForSegment(SegmentedButton1.Handle, menu.Handle, 1)
*** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘+[NSMenuItem _recursivelyUnregisterMenuForKeyEquivalentUniquing:]: unrecognized selector sent to class 0x7ff85c83c080’
abort() called
terminating with uncaught exception of type NSException
You can remedy this by just using an array and making your own NSMenu
Var items() As DesktopMenuItem
items.Add(New DesktopMenuItem("Import"))
items.Add(New DesktopMenuItem("Export"))
items.Add(New DesktopMenuItem(DesktopMenuItem.TextSeparator))
items.Add(New DesktopMenuItem("Cut"))
items.Add(New DesktopMenuItem("Copy"))
items.Add(New DesktopMenuItem("Paste"))
// make an NSMenu
Declare Function alloc Lib "Foundation" selector "alloc" (cls as ptr) as ptr
Declare Function init Lib "Foundation" selector "init" (cls as ptr) as ptr
Declare Function NSClassFromString Lib "Foundation" (name as cfstringref) as ptr
// - (void)addItem:(NSMenuItem *)newItem;
Declare Sub addItem Lib "AppKit" Selector "addItem:" ( obj as ptr , newItem as Ptr )
var NSMenu as ptr = init(alloc(NSClassFromString("NSMenu")))
for i as integer = 0 to UBound(items)
addItem(NSMenu, items(i).Handle)
next i
' https://developer.apple.com/documentation/appkit/nssegmentedcontrol/1528853-setmenu?language=objc
Declare Sub setMenuForSegment Lib "AppKit" Selector "setMenu:forSegment:" (id As Ptr, menu As Ptr, segment As Int64)
setMenuForSegment(SegmentedButton1.Handle, NSMenu, 1)
Keep in mind that according to the Apple docs, if the segment has an action on it (which in Xojo they do), the user will have to press and hold for the menu to appear.
Thanks @Greg_O for the explanations and the code example. The next question is how to activate the menu entries? Currently all are disabled and how to catch the click event and react to it?