Attach NSMenu to NSStatusItem with Storyboard - xcode

I am trying to attach an NSMenu item to a NSStatusItem to have a menu when clicking on my Menu Bar App for Mac OS.
I am new to Mac programming and I searched tutorials on the Web. However, all the material I found involves the usage of the file Xib to add the NSMenu and linking it to the existing code. However, I don't have such a file in my project, it only includes the storyboard file.
I hope you can help.
Cheers

You can create a menu programmatically and set it to NSStatusItem like this.
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
_statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:30];
_statusItem.image = [NSImage imageNamed:#"..."];
// create menu
NSMenu *menu = [[NSMenu alloc] initWithTitle:#""];
NSMenuItem *item1 = [[NSMenuItem alloc] initWithTitle:#"menu1" action:#selector(menu1Action:) keyEquivalent:#""];
NSMenuItem *item2 = [[NSMenuItem alloc] initWithTitle:#"menu2" action:#selector(menu2Action:) keyEquivalent:#""];
[menu addItem:item1];
[menu addItem:item2];
[_statusItem setMenu:menu]; // attach
}
Of course, you can use NSMenu as outlet. To do that, drag NSMenu to Application Scene in the storyboard, and connect it to AppDelegate's outlet.

Related

Is there any way to open App when user click any button on Status bar Icon In Mac Desktop App

Is there any way to open my App when user click Open App button on Status bar Icon In Mac Desktop App?
NSStatusBar *systemStatusBar = [NSStatusBar systemStatusBar];
_statusItem = [systemStatusBar statusItemWithLength:NSVariableStatusItemLength];
[_statusItem setHighlightMode:NO];
[_statusItem setMenu:self.statusMenu];
[_statusItem setTarget:self];
NSMenu *menu = [[NSMenu alloc] init];
[menu addItemWithTitle:#"Open App" action:#selector(OpenAPp:) keyEquivalent:#""];
[menu addItem:[NSMenuItem separatorItem]]; // A thin grey line
[menu addItemWithTitle:#"Quit" action:#selector(terminate:) keyEquivalent:#""];
_statusItem.menu = menu;
-(IBAction)OpenAPp:(id)sender
{
NSLog(#"here");
[NSApp activateIgnoringOtherApps:YES];
}
i want to lunch app when user click OpenApp button even if app is closed or even App is running in background thanks
[NSApp activateIgnoringOtherApps:YES];
With the Above line i only able to make Application Window Active
I am able to solve my problem by adding these line
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
[_window makeKeyAndOrderFront:self];

why the subclass of NSMenu not responding?

I created a menu resource in a separate xib file, made it to be a subclass NSMenu like the following, and the file's owner to be the StatusMenu
#interface StatusMenu : NSMenu
{
#private
IBOutlet NSMenuItem *menuitem1;
IBOutlet NSMenuItem *menuitem2;
}
- (IBAction)action1:(id)sender;
- (IBAction)action2:(id)sender;
- (void)show;
#end
where show method is implemented in the following way
- (void)show
{
NSImage *menuImage = [[NSImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource:#"myicon" ofType:#"png"]];
statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength] retain];
[statusItem setImage:menuImage];
[statusItem setMenu:self];
[statusItem setHighlightMode:YES];
}
Then I created and launched the StatusMenu instance in the app delegate like the following
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
statusMenu = [[StatusMenu alloc] init];
statusMenu.user = self.user;
[statusMenu show];
}
Now, I can see the icon on the status bar. But when I click on the icon, no responding is happening. What could be wrong?
You don't usually subclass NSMenu to do what you're trying to do.
You can simply create another class (call It MenuController or something), put It in your storyboard/xib and have an outlet to It in your AppDelegate.
Here`s a sample project for you to check out.

Double status item icons appearing

I'm trying to make a simple menu bar only application on xcode 4. Everything actually works, but what I don't understand is that the icon is appearing twice in the menubar. One of the two icons actually works and gives the drop down menu with the working buttons, the other just changes to the highlighted icon images while clicked and goes back when released, without doing anything, not even the drop down menu appears.
This is the code I found and tested out:
- (void) awakeFromNib{
//Create the NSStatusBar and set its length
statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength] retain];
//Used to detect where the files are
NSBundle *bundle = [NSBundle mainBundle];
//Allocates and loads the images into the application which will be used for the NSStatusItem
statusImage = [[NSImage alloc] initWithContentsOfFile:[bundle pathForResource:#"icon" ofType:#"png"]];
statusHighlightImage = [[NSImage alloc] initWithContentsOfFile:[bundle pathForResource:#"icon-alt" ofType:#"png"]];
//Sets the images in the NSStatusItem
[statusItem setImage:statusImage];
[statusItem setAlternateImage:statusHighlightImage];
//Tells the NSStatusItem what menu to load
[statusItem setMenu:statusMenu];
//Sets the mouse over text
[statusItem setToolTip:#"My Custom Menu Item"];
//Enables highlighting
[statusItem setHighlightMode:YES];
then release the images
- (void) dealloc {
//Releases the 2 images we loaded into memory
[statusImage release];
[statusHighlightImage release];
[super dealloc];
and the header file:
#interface MenuletApp : NSObject <NSApplicationDelegate> {
NSWindow *window;
IBOutlet NSMenu *statusMenu;
NSStatusItem *statusItem;
NSImage *statusImage;
NSImage *statusHighlightImage;
with an IBAction to log Hello World when one of the items is clicked, and to terminate when the other is clicked.
I used a tutorial meant for XCode 3, so it might be that one of the steps is done differently, but looking at the code I have no idea where the second status item is getting created.
Thanks for the help.
Is it possible that -awakeFromNib is getting called twice? (Try putting a log message in there). Perhaps you have two objects of this class in your xib file?
Also, I'd recommend moving this to -applicationDidFinishLaunching:.

Hide NSMenu programmatically from NSStatusItem

I have this application that shows an item in the system's status bar, and one of the items is a custom view with a NSTextField and a NSButton. When the user clicks on the status bar item, it shows the menu, the user inputs some text and presses the button. This triggers an action that displays a window.
The problem I'm having now is, when the button is pressed it does trigger the action, but the menu remains visible. I want to hide the menu, because the action has already been processed.
I've searched through the API, but couldn't find how to do it.
Any ideas?
This is how I'm creating the menu:
NSStatusBar *bar = [NSStatusBar systemStatusBar];
self.statusItem = [bar statusItemWithLength:NSVariableStatusItemLength];
[statusItem setImage:[NSImage imageNamed:#"icon_status_bar.png"]];
[statusItem setHighlightMode:YES];
NSMenuItem *textInputItem = [[NSMenuItem alloc] initWithTitle:#"" action:nil keyEquivalent:#""];
[textInputItem setView:myCustomView]; // created on the Nib file...
NSMenu *menu = [[NSMenu alloc] initWithTitle:NSLocalizedString(#"statusBarMenuTitle", #"")];
[menu addItem:textInputItem];
[statusItem setMenu:menu];
[textInputItem release];
[menu release];
It's not obvious in the docs, but [menu cancelTracking] is what you want.
cancelTracking
Dismisses the menu and ends all menu tracking.
- (void)cancelTracking

adding NSSubmenu item in NSMenuItem

I want to add a drop down menu in one of the entries in the NSMenu Item. (eg. If you click on the Battery indicator on Finder bar, it has an option for Show->Icon,Time,Percentage).
Now I add a MenuItem using the following code:
menuItem = [menu addItemWithTitle:#"Start"
action:#selector(start:) keyEquivalent:#""];
[menuItem setTarget:self];
How do I add a submenu Item with this drop down list ? Thanks.
This is how I add a submenu to an NSMenu item:
NSMenuItem *mainItem = [[NSMenuItem alloc] init];
[mainItem setTitle:#"Main item"];
NSMenu *submenu = [[NSMenu alloc] init];
[submenu addItemWithTitle:#"Sub item" action:nil keyEquivalent:#""];
[mainItem setSubmenu:submenu];
Got it working. Created a NSPopuButton with contents from an array and then used that here.
[menu setSubmenu:[(NSPopupButton *array) menu] forItem:menuItem];

Resources