Creating a NSStatusItem - ObjectiveC
Written by semaja2.net
While working on my first few projects in ObjectiveC i quickly learnt that although having documentations it is always nice to have a tutorial or guide on how to implement a system such a NSStatusItem. So here i present my first guide to “Creating a NSStatusItem in ObjectiveC”
This tutorial will hopefully result in the reader making their own application that will have a basic menu with a item of “Hello World” and “Quit” it will also explain how to remove the dock icon.
First off we will begin by creating a empty project in XCode:
We will be using the “Application > Cocoa Application” template in this tutorial
We will then name it “Insert Name’s Menu Item” :
After creating the project we will create a class called “AppController”:
While we are here, we will drag 2 png files into our project, these 2 files will be our icons for our menu, their size is 18x18:
Now here comes the real coding, in the first sections we simply created the base for a Objective C application, in this next small section we will create the code for the class and interface it will the menu item which we will create using “Interface Builder”
Open the AppController.h file from the list of files:
When you open the file you should receive a empty implementation for our class, we will be using this file to add the required information to move onto building the menu in “Interface Builder”
Now inside the @interface AppController : NSObject { we will add the IBOutlets which will allow the application to interfact with the interface:
IBOutlet NSMenu *statusMenu;
Below the IBOutlet we will add the OTHER STUFF, these are used for BLANK:
NSStatusItem *statusItem;
NSImage *statusImage;
NSImage *statusHighlightImage;
Now we are almost there, after the } line and just before the @end we will add the IBAction which will allow our menu item to call the corosponding method in our application:
-(IBAction)helloWorld:(id)sender;
Once you have done that you should have a file similair to the one below
// AppController.h
// Andrew's Menu Item
//
// Created by Andrew James on 3/02/07.
// Copyright 2007 semaja2.net All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface AppController : NSObject {
/* Our outlets which allow us to access the interface */
IBOutlet NSMenu *statusMenu;
/* The other stuff :P */
NSStatusItem *statusItem;
NSImage *statusImage;
NSImage *statusHighlightImage;
}
/* Our IBAction which will call the helloWorld method when our connected Menu Item is pressed */
-(IBAction)helloWorld:(id)sender;
@end
Save this file and open the MainMenu.nib file much like you opened the AppController.h class file before, Once the “Interface Builder” is finished loading we will start by creating the NSMenu item that will be used for our menu. To do this drag a NSMenu into our project:
Rename the “NSMenu1” to “StatusItem”, following this in “Interface Builder” choose from the menu “Classes > Read Files..” now select the AppController.h file, Once the file has been read it should change out project view to “Classes” from here find the AppController item and right click on it and select “Instantiate AppController”:
Now we are almost there, change the view back to “Instances” and hold down “control” and drag your mouse so that a blue line connects “AppController” and “StatusItem” once the line is complete, let go of the mouse and it should open the “Inspector” from here we will select the “statusMenu” item and press the connect button:
Now onto the last bit of this section, we will edit our “StatusMenu” item and have two buttons one that says “Hello Mac” and one that is “Quit” we will then attach the “Hello Mac” to our IBAction “helloWorld” after that we will attach “Quit” to “First Responder” and select “terminate:”
Congratulations you have finished creating the interface, we will now move onto coding the menu and disabling the dock icon.
In this section we will finish our project by adding the final lines of code which will enable us to put our menu into the menu bar as well as make the “Hello Mac” menu item respond to us.
Open the file AppController.m in XCode, you will notice it looks familiar to the previous file we edited but this one is not, this one is where we store our methods and what out application actually does:
//
// AppController.m
// Andrew's Menu Item
//
// Created by Andrew James on 3/02/07.
// Copyright 2007 semaja2.net. All rights reserved.
//
#import "AppController.h"
@implementation AppController
@end
We will be adding our code in-between the @implementation AppController and the @end
It is now time to add out first method which is called automatically by the interface when the NIB file (The interface) is opened by the application, this method we will be adding will go in as a chuck but each line is commented instead so you should be able to understand whats going on:
- (void) awakeFromNib{
//Create the NSStatusBar and set its length
statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength] retain];
//Used to detect where our files are
NSBundle *bundle = [NSBundle mainBundle];
//Allocates and loads the images into the application which will be used for our NSStatusItem
statusImage = [[NSImage alloc] initWithContentsOfFile:[bundle pathForResource:@"icon" ofType:@"png"]];
statusHighlightImage = [[NSImage alloc] initWithContentsOfFile:[bundle pathForResource:@"icon-alt" ofType:@"png"]];
//Sets the images in our NSStatusItem
[statusItem setImage:statusImage];
[statusItem setAlternateImage:statusHighlightImage];
//Tells the NSStatusItem what menu to load
[statusItem setMenu:statusMenu];
//Sets the tooptip for our item
[statusItem setToolTip:@"Andrews Menu Item"];
//Enables highlighting
[statusItem setHighlightMode:YES];
}
We have now allocated and created the NSStatusItem, we must also make sure it is unallocated and destroyed when we close the application to prevent memory leaks:
- (void) dealloc {
//Releases the 2 images we loaded into memory
[statusImage release];
[statusHighlightImage release];
[super dealloc];
}
Now onto the last few bits, this next section of code will make the application respond to us clicking the “Hello Mac” item in our menu:
-(IBAction)helloWorld:(id)sender{
NSLog(@"Hello Andrew James")
}
You should now have a file that looks almost like the one below:
//
// AppController.m
// Andrew's Menu Item
//
// Created by Andrew James on 3/02/07.
// Copyright 2007 semaja2.net. All rights reserved.
//
#import "AppController.h"
@implementation AppController
- (void) awakeFromNib{
//Create the NSStatusBar and set its length
statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength] retain];
//Used to detect where our files are
NSBundle *bundle = [NSBundle mainBundle];
//Allocates and loads the images into the application which will be used for our NSStatusItem
statusImage = [[NSImage alloc] initWithContentsOfFile:[bundle pathForResource:@"icon" ofType:@"png"]];
statusHighlightImage = [[NSImage alloc] initWithContentsOfFile:[bundle pathForResource:@"icon-alt" ofType:@"png"]];
//Sets the images in our NSStatusItem
[statusItem setImage:statusImage];
[statusItem setAlternateImage:statusHighlightImage];
//Tells the NSStatusItem what menu to load
[statusItem setMenu:statusMenu];
//Sets the tooptip for our item
[statusItem setToolTip:@"Andrews Menu Item"];
//Enables highlighting
[statusItem setHighlightMode:YES];
}
- (void) dealloc {
//Releases the 2 images we loaded into memory
[statusImage release];
[statusHighlightImage release];
[super dealloc];
}
-(IBAction)helloWorld:(id)sender{
NSLog(@"Hello Andrew James");
}
@end
And for the last step we simply click the “Build and Go” button, it will ask to save all our files click OK:
Congratulations, if everything went smoothly we should now have a NSStatusItem running in our menu bar along with the icon you chose, in my case i used the growl icons:
You will notice if you click on “Hello Mac” it will respond in our Xcode window with a message saying “Hello Your Name”, as well as if you click the “Quit” button it exits out.