2

I am trying to create a menubar app in OS X Yosemite that simply consists of a dropdown menu with submenus. This menu and its submenus would be populated by an applescript script.

I have found tutorials on something similar before, but they all seem to be fairly outdated and don't properly work in Xcode 6.2, such as this one:

MenuApp_ASOC

I'm fairly experienced in Applescript, but haven't had much time to code in Objective C.

Where would be a good place to find a template of sorts for what I want to create?

yannikrock
  • 55
  • 2
  • 5
  • 1
    Have a look at my answer here http://stackoverflow.com/a/29194549/261305 – markhunte Mar 23 '15 at 09:28
  • @markhunte Thank you! That is almost exactly what I am looking for. In the example you have, the number of items in the dropdown list seem to be static.
    I would be populating the dropdown with items gathered from a parsed shell script output. How could I do this? My current, non-menubar application populates its list as follows (stripped down example): `repeat with theItem in myInstances's items 1 through -1 ... copy {title:text item 2 of theNewItem} to end of library ... end repeat loadDataSource_(library)` Is it possible to use this method in your code as well?
    – yannikrock Mar 23 '15 at 16:25
  • Apologies for the bad formatting in the last comment. – yannikrock Mar 23 '15 at 16:31
  • 1
    I have posted an answer which I think is what you are asking let me know otherwise – markhunte Mar 23 '15 at 18:30
  • 1
    I have updated the answer to better illustrate the menu items being dynamic – markhunte Mar 23 '15 at 19:05

2 Answers2

8

This is a quick example of creating a menu system on the fly. Which is what I think you are after.

In this example each time you click the Status bar menu the menu items will be different.

(Yosemite required)

Paste this code in a new Script Editor Applescript document.

Save it as a Stay open Application using the Save as… menu option.

Then run the app as a normal application.

    use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property StatusItem : missing value
property selectedMenu : "" -- each menu action will set this to a number, this will determin which IP is shown

property theDisplay : ""
property defaults : class "NSUserDefaults"
property internalMenuItem : class "NSMenuItem"
property externalMenuItem : class "NSMenuItem"
property newMenu : class "NSMenu"

property theList : "Jackson Aiden Liam Lucas Noah Mason Ethan Caden Jacob Logan Jayden Elijah Jack Luke Michael Benjamin Alexander "
-- example list for the menu items that can be used. Ideally you will have your list created dynamically 


-- check we are running in foreground - YOU MUST RUN AS APPLICATION. to be thread safe and not crash
if not (current application's NSThread's isMainThread()) as boolean then
    display alert "This script must be run from the main thread." buttons {"Cancel"} as critical
    error number -128
end if

on menuNeedsUpdate:(menu)
    (* NSMenu's delegates method, when the menu is clicked this is called.

    We use it here to call the method makeMenus(). Which removes the old menuItems and builds new ones.

    This means the menu items can be changed dynamically.

    *)

    my makeMenus()
end menuNeedsUpdate:

on makeMenus()

    newMenu's removeAllItems() -- remove existing menu items

    -----< (* this is just to show in this example a dynamic list for the menu items
    set someListInstances to {}
    set counter to count of word of theList
    repeat until (count of someListInstances) is (random number from 3 to counter)

        set rnd to random number from 1 to counter
        set thisItem to word rnd of theList
        if thisItem is not in someListInstances then
            copy thisItem to end of someListInstances
        end if
    end repeat
    ----  <

    repeat with i from 1 to number of items in someListInstances
        set this_item to item i of someListInstances
        set thisMenuItem to (current application's NSMenuItem's alloc()'s initWithTitle:this_item action:"someAction:" keyEquivalent:"")

        (newMenu's addItem:thisMenuItem)

        (thisMenuItem's setTarget:me) -- required for enabling the menu item
        if i is equal to 3 then
            (newMenu's addItem:(current application's NSMenuItem's separatorItem)) -- add a seperator
        end if
    end repeat

end makeMenus



--menuItems  action is requied for the menu to be enabled
on someAction:sender
    --MenuItem --do some thing 
end someAction:

-- create an NSStatusBar
on makeStatusBar()
    set bar to current application's NSStatusBar's systemStatusBar

    set StatusItem to bar's statusItemWithLength:-1.0

    -- set up the initial NSStatusBars title
    StatusItem's setTitle:"IP"
    -- set up the initial NSMenu of the statusbar
    set newMenu to current application's NSMenu's alloc()'s initWithTitle:"Custom"

    newMenu's setDelegate:me (*
    Requied delegation for when the Status bar Menu is clicked  the menu will use the delegates method (menuNeedsUpdate:(menu)) to run dynamically update.


    *)

    StatusItem's setMenu:newMenu

end makeStatusBar


my makeStatusBar()
markhunte
  • 6,805
  • 2
  • 25
  • 44
  • 1
    This is brilliant, thank you! Would you by chance have a tutorial on adding submenus as well? @markhunte – yannikrock Mar 24 '15 at 18:24
  • @yannikrock Not to hand. But you can read the documentation https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSMenuItem_Class/index.html and https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSMenu_Class/index.html – markhunte Mar 24 '15 at 18:41
  • any suggestion on how to show a picture in the menu? something like click the menu and you get shown a picture ... [https://developer.apple.com/documentation/appkit/nsmenuitem/1514819-image](https://developer.apple.com/documentation/appkit/nsmenuitem/1514819-image) seems evocative, but may be for some other use ... – Rho Phi Dec 05 '17 at 13:36
0

I encourage you to visit the ASOC forum at http://macscripters.net there are people there, that may answer your questions, on how to get it working with XCode 6.2. But you have to put in the efforts of documenting your problems/errors you get of course, simply "not working" isn't good enough in order to solve your problems.

And this is what you will have to do anyway, unless you are so happy that you'll find a menu app that works for an XCode project.

Inside macscripters, http://macscripter.net/viewtopic.php?id=38891&p=1 there is a much smaller, menu app project that is made by DJ Bazzie Wazzie, that may be much easier to make work. You could address any problems in that thread, or in the ASOC forum.

Shane Stanley, the author of two good ASOC books, and an ASOC editor frequently visits the fora there, and is a really helpful and kind guy!

McUsr
  • 1,400
  • 13
  • 10