Icon in menubar - a working solution [NSStatusItem]

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

Did you get the Timer to build?? I keep getting errors.

EDIT Forget that, got the first part of it working.
the had IPMenulet.m (awakeFromNib:) in part of the code , but it was not in bold so I thought it was part of the code to add, rather than where to add it.

I’m still trying to get an AppleScript hooked to a menu item, but the menu item is always greyed out…

Did anyone manage to come up with a way to add to this Menulet after it has been created, via AppleScript? That would be extremely useful for me right now!

Thanks,
Ryan

I got one working …but not using NSMenu1

Since the application is a menulet and the main menu and dock icon aren’t shown, I just connected the menu outlet to the main menu instead of NSMenu1 Then I modified the main menu to be what I needed. AppleScript works just fine with that menu.

Got Applescript to work from the menubar.

Basically, follow the menulet tutorial from here to the fullest and then use the info from Apple’s Technical Note to use Applescript inside a Cocoa app.

EDIT: Able to use simple iTunes controls like “Next Track” and so on through the Menu. If anyone wants the files to view, I’ll gladly email them.
EDIT#2: Added support for multiple menu items, all using applescript.

Now to see what more I can do with Applescript through the Menu!

I have a functioning menulet application, and I’ve figured out how to add menu items from the obj-c code, but I would rather work with them in the applescript code, so I thought why not add items in interface builder and then use “on choose menu item” as with the regular application menu. But I get an error when choosing the item in the built app:

Applescript Error
Can’t get «class menI» id 5 of item id 6. (-1728)

This is without any code in “on choose menu item theObject”.

After this I would also want to change the title of the menu item from the applescript code, if that’s possible.

EDIT: Oh, I didn’t see there was a page 2. So I guess that’s the way to do it. Can it be connected to the main applescript so that it can access the other variables used in the code?

I’ll try this out.