SOLVED Easy way to replicate Scripts menu bar?



  • I'd like to partition my Scripts folder, and have another application menu bar item alongside Extensions, Scripts, Window etc. with another menu corresponding to a directory on my HD. I've got the bare bones of a custom menu ready, but not sure if there's a stock function for linking the menu structure to a local directory.

    TIA!
    Ryan



  • Ah! Ok I rewrote Gustavo’s script to rebuild the menu each time it's run. So I can just rerun the script when I want it to update.

    # menuTitle: _ Add / Update Custom Scripts Menu
    
    from AppKit import NSApp, NSMenu, NSMenuItem
    from lib.UI.fileBrowser import RFPathItem
    
    def addMenu(name, path):
    	'''Creates a new menu item in RoboFont’s main application menu.'''
    
    	# create a new menu
    	menu = NSMenu.alloc().initWithTitle_(name)
    
    	# create a path item that will build the menu and connect all the callbacks
    	pathItem = RFPathItem(path, ['.py'], isRoot=True)
    	pathItem.getMenu(title=name, parentMenu=menu)
    
    	# get the main menu
    	menubar = NSApp().mainMenu()
    
    	# search if the menu item already exists
    	newItem = menubar.itemWithTitle_(name)
    	if newItem:
    	    menubar.removeItem_(newItem)
    	
    	newItem = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(name, '', '')
    	menubar.insertItem_atIndex_(newItem, menubar.numberOfItems()-3)
    
    	# set the menu as submenu
    	newItem.setSubmenu_(menu)
    	
    addMenu('menu name', '/path/to/folder/')
    

    Key lines:

    if newItem:
      menubar.removeItem_(newItem)
    

  • admin

    yeah, "Update Menu" only updates from the script folder as set in the preferences.

    In Gustavo's example you'll need to add menu item with a callback to a script that is populating that menu. Hope that makes sense :)



  • Thanks @frederik

    When I hit the native Update Menu, it doesn't update my custom menu item (if I added a new script, etc.)
    b1903a44-2506-4564-b3ff-5572998c762f-image.png

    Is there a way to update the custom menu without having to restart RF?
    The following little script seems to not work:

    import AppKit
    menu = AppKit.NSApp().mainMenu()
    menu.update()
    

    P.S. I did end up using @gferreira ’s menu-building script because it was already replicating a folder's pathing. Is there a way to mirror a folder with MenuBuilder?


  • admin

    the preferred way is to use mojo.UI.MenuBuilder

    from mojo.UI import MenuBuilder
    
    def callback(sender):
        pass
    
    builder = MenuBuilder([("test", callback), ("test 2", callback)])
    
    menu = builder.getMenu()
    print(menu)
    
    name = "My Menu"
    
    # get the menu bar
    menubar = NSApp().mainMenu()
    
    newItem = menubar.itemWithTitle_(name)
    if not newItem:
        # if not, create one and append it before `Help`
        newItem = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(name, '', '')
        menubar.insertItem_atIndex_(newItem, menubar.numberOfItems()-1)
    
    # set the menu as submenu
    newItem.setSubmenu_(menu)
    

  • admin

    • for the AppKit Apple docs opt for the objc version and replace : by _ for the python version.
    • use print(dir(nsObject)) to find all the methods and attributes


  • Thanks, @gferreira! This is exactly what I was looking for. Do you know of any resources that explain how to work with AppKit? Apple’s documentation feels less accessible/thorough to me, but I could be missing something.

    Thanks again,
    Ryan



  • hello @ryan,

    here’s a function to create a new menu item for a folder structure with .py files:

    from AppKit import NSApp, NSMenu, NSMenuItem
    from lib.UI.fileBrowser import RFPathItem
    
    def addMenu(name, path):
        '''Creates a new menu item in RoboFont’s main application menu.'''
    
        # create a new menu
        menu = NSMenu.alloc().initWithTitle_(name)
    
        # create a path item that will build the menu and connect all the callbacks
        pathItem = RFPathItem(path, ['.py'], isRoot=True)
        pathItem.getMenu(title=name, parentMenu=menu)
    
        # get the main menu
        menubar = NSApp().mainMenu()
    
        # search if the menu item already exists
        newItem = menubar.itemWithTitle_(name)
        if not newItem:
            # if not, create one and append it before `Help`
            newItem = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(name, '', '')
            menubar.insertItem_atIndex_(newItem, menubar.numberOfItems()-1)
    
        # set the menu as submenu
        newItem.setSubmenu_(menu)
        
    addMenu('My Menu', '/path/to/scripts/folder')
    

    you can set it as a start-up script, so the menu will always be there when you open RoboFont.

    (will be added to the docs soon… thanks!)