Adding menu items dynamically possible?

Mac OSX specific forum
Justin
Addict
Addict
Posts: 829
Joined: Sat Apr 26, 2003 2:49 pm

Adding menu items dynamically possible?

Post by Justin »

I tried to add menu items programmatically to the main menu but it does not work, the item seems to be added because numberOfItems returns the new item count but it is not shown in the menu bar, any hints? Also MenuID() returns a __NSArrayM which I is the items array?, instead of NSMenu

Code: Select all

EnableExplicit

Procedure main()
	Protected.i win, menu, hmenuPB, hmenuApp, menItem
	Protected.l ev
	
	win = OpenWindow(#PB_Any, 10, 10, 400, 300, "test", #PB_Window_SystemMenu | #PB_Window_SizeGadget | 
	                                                    #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget)
	
	menu = CreateMenu(#PB_Any, WindowID(win))
	hmenuPB = MenuID(menu) ; __NSArrayM ?
	hmenuApp = CocoaMessage(0, CocoaMessage(0, 0, "NSApplication sharedApplication"), "mainMenu") ; NSMenu
	
	MenuTitle("Title1")
	
	Debug "items " + 	CocoaMessage(0, hmenuApp, "numberOfItems")
	
	menItem = CocoaMessage(0, hmenuApp, "addItemWithTitle:$", @"Title 2", "action:", 0, "keyEquivalent:$", @"")
	
	; 	Debug CocoaMessage(0, hmenuPB, "addObject:", menItem) 
	
	Debug "items " + 	CocoaMessage(0, hmenuApp, "numberOfItems")

	Repeat
		ev = WaitWindowEvent()
		
	Until ev = #PB_Event_CloseWindow
EndProcedure

main()
Justin
Addict
Addict
Posts: 829
Joined: Sat Apr 26, 2003 2:49 pm

Re: Adding menu items dynamically possible?

Post by Justin »

The new menu item title needs a submenu assigned to show, this works. Item 1 is disabled because there is no action assigned to it.

Code: Select all

EnableExplicit	

Procedure main()
	Protected.i win, menu, hmenuPB, hmenuApp, menItem, app
	Protected.i subMenu
	Protected.l ev
	
	win = OpenWindow(#PB_Any, 10, 10, 400, 300, "test", #PB_Window_SystemMenu | #PB_Window_SizeGadget | 
	                                                    #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget)
	
	menu = CreateMenu(#PB_Any, WindowID(win))

	app = CocoaMessage(0, 0, "NSApplication sharedApplication")
	hmenuApp = CocoaMessage(0, app, "mainMenu") ; NSMenu

	menItem = CocoaMessage(0, 0, "NSMenuItem new")
; 	CocoaMessage(0, menItem, "initWithTitle:$", @"", "action:", 0, "keyEquivalent:$", @"")
	
	subMenu = CocoaMessage(0, 0, "NSMenu new")
	CocoaMessage(0, subMenu, "setTitle:$", @"Title")
	CocoaMessage(0, subMenu, "addItemWithTitle:$", @"Item 1", "action:", 0, "keyEquivalent:$", @"a")
	
	CocoaMessage(0, menItem, "setSubmenu:", subMenu)
	
	CocoaMessage(0, hmenuApp, "addItem:", menItem)

	Debug "items " + 	CocoaMessage(0, hmenuApp, "numberOfItems")

	Repeat
		ev = WaitWindowEvent()
		
	Until ev = #PB_Event_CloseWindow
EndProcedure

main()
collectordave
Addict
Addict
Posts: 1309
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

Re: Adding menu items dynamically possible?

Post by collectordave »

Maybe I am missing the point but I use PB to create the menus etc including adding new titles and or sub items.

Using a procedure to create the menu each time.

I normally store the menu items I want in a structured list.

Hope this helps.

Tested on Mac with M1 chip running Bigsur and latest PB version

Code: Select all

Global Window_0
Global Event.i
Global btn3Items, btn2Items
Global Main_Menu.i


Procedure CreateMainMenu()
  
  If IsMenu(Main_Menu)
    FreeMenu(Main_Menu)
  EndIf
  
  Main_Menu = CreateMenu(#PB_Any, WindowID(Window_0))
  MenuTitle("Item 1")
    MenuItem(1, "Open"   +Chr(9)+"Ctrl+O")
  MenuTitle("Item 2")
    MenuItem(5, "Open Again"   +Chr(9)+"Ctrl+O")
  
EndProcedure


Procedure CreateMainMenu_1()
  
  If IsMenu(Main_Menu)
    FreeMenu(Main_Menu)
  EndIf
  
  Main_Menu = CreateMenu(#PB_Any, WindowID(Window_0))
  MenuTitle("Item 1")
  MenuTitle("Item 2")
  MenuTitle("Item 3")
  
EndProcedure

  Window_0 = OpenWindow(#PB_Any, 0, 0, 600, 400, "", #PB_Window_SystemMenu)
  CreateMainMenu()
  btn3Items = ButtonGadget(#PB_Any, 160, 110, 70, 30, "3 Items")
  btn2Items = ButtonGadget(#PB_Any, 160, 70, 70, 30, "2 Items")
  
  Repeat

    
      Event = WaitWindowEvent()
      
      If EventGadget() = btn3Items
        CreateMainMenu_1()
      EndIf
      If EventGadget() = btn2Items
        CreateMainMenu()
      EndIf      
      
      If Event = #PB_Event_Menu
        
        If EventMenu() >2
        
        Debug "Menu Item 2"
        
        Debug GetMenuTitleText(Main_Menu,1)
        
      Else
        
        Debug "Menu Item 1"
        
        Debug GetMenuTitleText(Main_Menu,0)
        
        EndIf
        
      EndIf
      
      
      
      
      
      If event = #PB_Event_CloseWindow
        End
      EndIf
      
    ForEver
Any intelligent fool can make things bigger and more complex. It takes a touch of genius — and a lot of courage to move in the opposite direction.
Justin
Addict
Addict
Posts: 829
Joined: Sat Apr 26, 2003 2:49 pm

Re: Adding menu items dynamically possible?

Post by Justin »

Hi cd,
the point was to add and remove items without recreating the whole menu, but if that is ok for you your workaround is a good option too.
User avatar
skywalk
Addict
Addict
Posts: 3960
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Adding menu items dynamically possible?

Post by skywalk »

Recreating the entire menu plus changes or deletions or different looks based on user interaction is the way to go.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Post Reply