Menubar

Hi scripters,

I’ve been trying to make a Menubar like this:

but not a Manubar App, just implement a Menubar in my app.
I tried to follow the post #9 in this topic (broken link), but Xcode says the code is wrong…

Can anyone explain how to do?
Any reply would be appreciated!
Thanks

That’s called an NSStatusItem. I’m pretty sure that if you hunt around here, you’ll see some example code. You should also search the Xcode docs for “Introduction to Status Bars”.

I found some example in Objective-C, and I managed to do it in a Cocoa project, so then I could translate (thanks to your book).

This is the code in Objective-C:

– Header

– Implementation

This is how I translated:


property statusMenu : missing value
property statusItem : missing value

on awakeFromNib()
       set statusItem to current application's NSStatusBar's systemStatusBar()
       tell statusItem
              its setMenu_(statusMenu)
              its setTitle_("Status")
              its setHighlightMode_(true)
        end tell
end awakeFromNib

In this way I get the Menu I dragged in IB and connected to “stausMenu” Outlet. That’s fine, but If I want to make something better, for instance, a custom view instead of a Menu, how could I do?

P.S.: when typing an applescript syntax in a topic in this forum how can I make spaces?

Hi,

Here’s an example of a simple Cocoa-AppleScript Applet posted by DJ Bazzie Wazzie:

-- main.scpt
-- Cocoa-AppleScript Applet
--
-- Copyright 2011 {Your Company}. All rights reserved.

-- This is the main script for a Cocoa-AppleScript Applet.
-- You can put the usual script applet handlers here.
--create a menu item
set myMenuItem to current application's class "NSMenuItem"'s alloc()'s init()
tell myMenuItem to setTitle:"Hello World"
tell myMenuItem to setTarget:me
tell myMenuItem to setAction:"helloWorld:"
--create a menu
set myMenu to current application's class "NSMenu"'s alloc()'s init()
tell myMenu to addItem:myMenuItem
set myBar to current application's class "NSStatusBar"'s systemStatusBar()

--add the menu to the system's status bar
set theItem to myBar's statusItemWithLength:(current application's NSVariableStatusItemLength)
tell theItem to setTitle:"MyMenu"
tell theItem to setHighlightMode:true
tell theItem to setMenu:myMenu

--actions
on helloWorld:info
	display dialog "Hello World!"
end helloWorld:

You can use this to search for the post.

gl,
kel

With considerable difficulty, is my guess. I think you have to fake it with windows. You can se an image for the menu title itself easily, though.

First thanks kel1 for your script!
To set the image I think it’s:


tell statusItem to setImage:myImage

And to set the window how can I do?

Thanks!

Google is your friend. Try these:

blog.shpakovski.com/2011/07/cocoa-popup-window-in-status-bar.html

undefinedvalue.com/2009/07/07/adding-custom-view-nsstatusitem

But to be honest, I wouldn’t be surprised if it’s not really something to attempt in ASObjC.

I did this before and used NSPopOver and a NSViewController to get the result I needed. Basically the status item, when clicked, would invoke the popover which held my custom view. It was pretty straightforward doing it this way, as opposed to adding a custom view into an NSMenu (which I eventually did accomplish, though it didn’t work well). I would expect that the any issue of difficulty of doing this in ASObjC would overshadowed by the fact that most of NSStatusItem has been deprecated in 10.10:

https://developer.apple.com/librarY/prerelease/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSStatusItem_Class/index.html

Thank you x74353! I figured out how to set up the NSPopover!
For anyone else who’s trying to attempt this, the following is how to do:

  1. Drag a “Popover and View Controller” to your IB.
  2. Drag a Custom View, which is the view displayed by the Popover.
  3. In the “Popover View Controller” object, connect the “view” outlet to your Custom View.
  4. Create a new outlet in the AppDelegate and connect it to the Popover in IB.
  5. Create an action which display the Popover like the following:

on showPopover:sender
        popOver's showRelativeToRect:(sender's |bounds|()) ofView:sender preferredEdge:(current application's NSMaxXEdge)
    end showPopover:

  1. In the Status Item method add setAction:

set statusItem to current application's NSStatusBar's systemStatusBar()'s statusItemWithLength:NSVariableStatusItemLength
        tell statusItem
            --its setMenu:statusMenu
            its setAction:"showPopover:"
            its setHighlightMode:true
            its setImage:current application's NSImage's imageNamed:"YourImage.png"
            its setAlternateImage:current application's NSImage's imageNamed:"YourImage2.png"
        end tell

And that’s it!

Thank you again x74353!

In OS X 10.10 Yosemite, due to a linker error, NSVariableStatusItemLenght has to be substituted with (-1), so the whole code becomes:


set statusItem to current application's NSStatusBar's systemStatusBar()'s statusItemWithLength:(-1)
tell statusItem
its setAction:"showPopover:"
its setHighlightMode:true
its setImage:current application's NSImage's imageNamed:"YourImage.png"
its setAlternateImage:current application's NSImage's imageNamed:"YourImage2.png"
end tell

That’s not a linker error – it’s a case of forgetting to address the current application. Try:

set statusItem to current application's NSStatusBar's systemStatusBar()'s statusItemWithLength:(current application's NSVariableStatusItemLength)

I’ve already tried with that, but I get a long error:

2014-10-19 10:34:08.107 Test[622:7633] *** -[AppDelegate awakeFromNib]: unable to set argument 2 - the AppleScript value <NSAppleEventDescriptor: 'obj '{ 'form':'usrp', 'want':'prop', 'seld':'utxt'("NSVariableStatusItemLength"), 'from':null() }> could not be coerced to type d. (error -10000)

I’ve read somewhere that it’s a bug…

You’re right – it doesn’t work. For some odd reason, NSVariableStatusItemLength has been declared as a preprocessor macro rather than an enum. Weird.

It seems that the enumerated constants of NSStatusItem are broken during the Swift transition under some circumstances.

They aren’t recognized in Swift, too

That explains a lot

Pretty weird. I don’t think I’ve seen it anywhere else.

Hello,

I’m trying to show a window below the status item, but I can’t get the status item’s coordinates.
I’ve tried with:


sender's frame()

but I get x: 0 y: 0

I haven’t tried it, but someone on stackoverflow suggests putting something like this in your action method:

set itsWindow to current application's NSApp's currentEvent()'s |window|()
set theFrame to itsWindow's frame()

Thank you, it worked!

Actually I have seen a lot of posts regarding this matter, but translating into AppleScriptObjC I forgot the pipes for the word window, and got an error.

For anyone who’d like to attempt this, here’s the code I have used:


    on showWindow:sender
        
        set itsWindow to current application's NSApp's currentEvent()'s |window|()
        set theFrame to itsWindow's frame()
        set xy to {x: theFrame's origin's x, y: theFrame's origin's y}

        statusWindow's setFrameTopLeftPoint:xy --statusWindow is the outlet connected to the window I show
        
        if statusWindow's isVisible() = 0 then
            statusWindow's makeKeyAndOrderFront:statusWindow
        else
            statusWindow's orderOut:statusWindow
        end if
        
    end showWindow:


Any solution for this error? That is, to use the script as a menu.

I’ve been using this script for some time now, its awesome! Using it in 10.11, 10.12. But, because of a speed issue I’ve downgraded back to 10.10 and menu no longer works. If I use “-1” doesn’t work as well: the menu hangs at any choice.

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

property itemStatus : missing value

on run
	init() of me
end run

on init()
	set menuList to {"????	Apply Filters", "????	Clean Filters", "", "❐	Hide Ui", "⇆ 	Change Wally", "", "⧱	CMS Admin On", "⧰	CMS Admin Off", "", "⧗	Mampalon Up", "⧖	Mampalon Dn", "", "⏏	Eject Disks", "Ω	Hidden Files", "♻	Zap Trash", "", "⨁	Dozer R/W", "⨀	Dozer RO", "", "❖	Preferences", "⎋	Quit"}
	
	#set itemStatus to current application's NSStatusBar's systemStatusBar()'s statusItemWithLength:{current application's NSVariableStatusItemLength}
	set itemStatus to current application's NSStatusBar's systemStatusBar()'s statusItemWithLength:(-1)
	itemStatus's setTitle:"????"
	itemStatus's setHighlightMode:true
	itemStatus's setMenu:(createMenu(menuList) of me)