Icon in menubar - a working solution [NSStatusItem]

Cheers Captainhams, I did that at a guess, as that’s where I see all the images in an app package, But the icon does not show in the menu?

Hi Mark,

Try the following:

When in Xcode double click “MainMenu.nib (English)”, this should open the program Interface Builder with your interface (which is not really used for the above purpose). In the newly opened window “MainMenu.nib (English)” you should see several tabs on top (Instances, Classes, Images, etc.). Click on the ‘Images’ tab. If you see your image file you should be ok, if not drag it into this window. I used a TIFF file, I don’t know whether it works with other file formats.

Hope this works for you,

S.

I moved NSStatusItem *statusItem; to menulet.m, because I received warnings while building.

Side note: I believe it’s proper to capitalize class names (e.g. Menulet instead of menulet).

Edit: This does work for me. Thanks for sharing, Stadsman. :cool:

After having received so much help from this forum, I’m happy to give a little back… :slight_smile:

I did not get this working,
So I tried this Menulet introduction.
Which I think is the same type of thing this thread is about, (noob talking)

Please let me know if I should start this as a new thread.

I got most of it working, but I am stuck with the drop down menu from the icon.

I can not tell if my Ipmenulet is connected to the NSMenu1 which I suspect is the problem.
It say’s

I build and Go - no errors.

But the menu does not drop down from the icon??

Also I changed the Ip url to “http://www.whatismyip.org” as the one provided did not work that well.
I could not build withou errors with (dealloc:) in, so I took it out.

Thanks

Hi Mark,

Your link is one of the sources I based my script on. Being a total cocoa noob I managed to get various scripts together to get what I wanted :stuck_out_tongue:

You have to make sure you click on ‘connect’ in the NSMenuInspector window (bottom right button).

Thats spooky :smiley:

When I drag from the Ipmenulet is connected to the NSMenu1 I do not seem to get anything show up in the inspector to select and connect to???

what is it supposed to say?

Thanks

Hi Mark,

Hopefully this screenshot explains it clearly…

Thanks Stadsman.

I do not get that.

I must have type something wrong some where, Most likely my omission of (dealloc :slight_smile:

I did add a Outlet (myOutlet) manually and change the name to theMenu, I then set the id to NSMenu
Did the drag thing, selected connect.

But still no menu.

Is it possible for you to post the .m and .h files for this so I can compare.

Thanks

Hi Mark,

Here they are, I also had to comment out (dealloc:) to get rid of the warning but it seems not to make a difference.

IPMenulet.h:

#import <Cocoa/Cocoa.h>


@interface IPMenulet : NSObject {
    NSStatusItem *statusItem;
	IBOutlet NSMenu *theMenu;
	NSMenuItem *ipMenuItem;
	NSImage *menuIcon;
}

-(IBAction)updateIPAddress:(id)sender;
@end

IPMenulet.m:

#import "IPMenulet.h"


@implementation IPMenulet
-(void)dealloc
{
    [statusItem release];
      [super dealloc];
}
- (void)awakeFromNib
{
   statusItem = [[[NSStatusBar systemStatusBar] 
      statusItemWithLength:NSVariableStatusItemLength]
      retain];
   [statusItem setHighlightMode:YES];
   [statusItem setEnabled:YES];
   [statusItem setToolTip:@"IPMenulet"];

//   [statusItem setAction:@selector(updateIPAddress:)];
//   [statusItem setTarget:self];
   [statusItem setMenu:theMenu];
   ipMenuItem = [[NSMenuItem alloc] initWithTitle:@"0.0.0.0" 
      action:@selector(updateIPAddress:) keyEquivalent:@""];
	  [ipMenuItem setTarget:self];
	[theMenu insertItem:ipMenuItem atIndex:1];
	NSBundle *bundle = [NSBundle bundleForClass:[self class]];
	NSString *path = [bundle pathForResource:@"IPMenuIcon" ofType:@"tif"];
	menuIcon= [[NSImage alloc] initWithContentsOfFile:path];

	[statusItem setTitle:[NSString stringWithString:@""]]; 
  
	[statusItem setImage];

//(dealloc:)
	[menuIcon release];
}
-(IBAction)updateIPAddress:(id)sender
{
   NSString *ipAddr = [NSString stringWithContentsOfURL:
         [NSURL URLWithString:
         @"http://www.whatismyip.org"]];
   if(ipAddr != NULL)
       [ipMenuItem setTitle:
            [NSString stringWithString:ipAddr]]; 
}
@end

Thank You.
I had three issues.

First I put

#import <Cocoa/Cocoa.h>

@interface IPMenulet : NSObject {
    NSStatusItem *statusItem;
}
-(IBAction)updateIPAddress:(id)sender;
IBOutlet NSMenu *theMenu;
NSMenuItem *ipMenuItem;
NSImage *menuIcon;
@end

As you can see the icon menu is outside the function (that may sound like I know what I am talking about, don’t be fooled. :), when I put it inside I got the correct info in the inspector.

I then found I had

[statusItem setMenu:theMenu];
ipMenuItem = [[NSMenuItem alloc] initWithTitle:@"0.0.0.0"
action:@selector(updateIPAddress:) keyEquivalent:@""];
[ipMenuItem setTarget:self];
[theMenu insertItem:ipMenuItem atIndex:1];

Above

statusItem = [[[NSStatusBar systemStatusBar] 
statusItemWithLength:NSVariableStatusItemLength]
retain];
[statusItem setHighlightMode:YES];
[statusItem setEnabled:YES];
[statusItem setToolTip:@"IPMenulet"];

// [statusItem setAction:@selector(updateIPAddress:)];
// [statusItem setTarget:self];

Once I change these the menu came up but was greyed out.

Found a missing “d” in

action:@selector(updateIPAddress:) keyEquivalent:@""];

which fixed that :smiley:

It is annoying that it compiles with no errors when there are, but I guess thats the nature of the beast.
I also notice that the intro url doe not really help in the structure of how the script should be laid out.

Thanks you for your help.

mark

Glad I could be of help, Mark.

Now another question for the Cocoa savvy:

Can I replace the ‘NULL’ statement in the following line with an action to terminate the app?

[theMenu addItemWithTitle:@"This application is active!" action:NULL keyEquivalent:@""];

I tried various variations, such as ‘NSApplication terminate’, ‘NSApp terminate’, ‘NSTerminateNow’, etc, but all to no avail… :frowning:

Ha, a new Google search did the trick:

[theMenu addItemWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@"q"];

Hi Stadsman,
Do you know any good links to show me how I attach an applescript script to the menu.
Also my applescript opens up in Script Editor? I can not find a pref to keep it in xcode??

thanks again

mark

Hi Mark,

Do you want an AppleScript connected to the Menulet menu? Or to do that within a Xcode project. The first I don’t know, the second one is set in Xcode using ‘on choose menu item’.

To make an AppleScript with Xcode you have to select >New Project>AppleScript Application. Xcode can’t work with just the AppleScript. Once you are in Xcode, you can double click the Applescript file within Xcode which then opens its own AS editor.

S.

Edit: Check out the Task List example is Xcode’s ApleScript Studio examples for setting menu items.

Thats the one,

Thanks I will have a look there.

Mark

Hi Mark,

That example is not for adding menu items to the menulet. There is a Apple Technical Note that describes the howto, but I can’t get it working. What I did manage is to get an AppleScript using ‘on should quit theObject’. If you then use the ‘terminate:’ action the script embedded in ‘on should quit theObject’ gets called. It works but is not a proper solution.

I also found this link, but also couldn’t get it to work.

Also found this which looks promising, haven’t tried it yet…

Hi Stadsman,
I will have a look at does links, thanks

Because I wanted the app to be dock-less, I had a play in adding a ‘Quit’ menu item at the bottom.
it could not be easier.
(from the intro url I added this <key>LSUIElement</key> <string>1</string>
in the info.plist

In the MainMenu.nib

select (in this case) the ‘External Ip’ item and while holding down the option key drag it down to create a new item
Rename it ‘Quit’
while holding down the ctrl key, drag it to the first responder class.
In the inspector, connect it to the ‘terminate’

save

thats it

Mark, could you email me a copy of the IPMenulet project? Somehow I’m unable to get it going again and I can’t find my error.

You can download it here, the email does not let you put files in and the are no code tags so I suspect it would be a mess.

Remember to add your tif