add customView to NSStatusItem - xcode

I would like to create a status bar application which has non-menu style. same as FaceTab for facebook (I mean only interface, not functional)... this is my codes:
-(void)awakeFromNib{
statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength] retain];
[statusItem setView:customView];
//[statusItem setMenu:menu];
[statusItem setTitle:#"Status"];
[statusItem setHighlightMode:YES];
}
.....
so once I Use NSMenu everything works fine but when I use NSView and CustomView outlet nothing appear on menu bar. Help plz!

There are several moving parts involved, so the best advice I can give is to check out this excellent example project from Vadim Shpakovski.

At the end of your awakeFromNib method, you may need to call retain on the statusItem so that it doesn't go out of scope. I was struggling with this same problem, and adding [statusItem retain]; fixed it so that I now see my Status menu in the Mac OS status bar.
-(void)awakeFromNib{
statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength] retain];
[statusItem setView:customView];
// in my code, this is uncommented, and menu is an instance variable.
//[statusItem setMenu:menu];
[statusItem setTitle:#"Status"];
[statusItem setHighlightMode:YES];
// this was needed to get the icon to display in the status bar.
[statusItem retain];
}

Related

NSTextField not active in NSPopOver

I have a menubar application, which open a popover. That popover contains NSTextField and few buttons. The problem is that the NSTextField is non-selectable, it's impossible to type anything in it. However, it's possible to click on it with mouse right button and paste something. Well, that's definitely odd behavior. Buttons works without any problems in that popover, btw.
Here's the code i use:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[NSApp activateIgnoringOtherApps:YES];
statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength] retain];
[statusItem setAction:#selector(showPopOver:)];
[statusItem setImage:[[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"icon" ofType:#"png"]]];
[statusItem setHighlightMode:YES];
}
and:
- (IBAction)showPopOver:(id)sender {
popover = [[NSPopover alloc] init];
[popover setContentViewController:popOverController];
popover.animates = YES;
popover.delegate = self;
[popover showRelativeToRect:[sender bounds]
ofView:sender
preferredEdge:NSMaxYEdge];
}
}
Any ideas what the problem exactly and how to fix it?
Seems is a bug.
http://openradar.appspot.com/9722231

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

Displaying NSProgressIndicatorSpinningStyle in NSStatusItem and then hiding it

I'm working on NSStatusItem. I've managed to use the setImage and setAlternateImage to work.
When user selects something, it takes a while for it to accomplish whatever it is doing. While it is doing something, I tried changing from the usual Image to a spinner. The way that I am doing it now is that I created a view, set the NSProgressIndicator to it, and then use
[statusItem setView: viewWithSpinner];
It seems to work until I try to remove it and display the original image. The only way I can hide it is to do
[statusItem setView: nil];
but that breaks everything, the original images don't come back. I guess cause there's no more view. I can't seem to save the original view before setting the viewWithSpinner.
Can someone advise me of a way of accomplishing this?
So...
NSStatusItem *myStatusItem;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[myStatusItem setImage:statusImage];
[myStatusItem setHighlightMode:YES];
[myStatusItem setAlternateImage:statusImageSel];
[myStatusItem setMenu:myStatusMenu];
etc...
[self createSpinner];
}
-(void)createSpinner
{
//to overcome the white border problem
NSView *progressIndicatorHolder = [[NSView alloc] init];
NSProgressIndicator *progressIndicator = [[NSProgressIndicator alloc] init];
[progressIndicator setBezeled: NO];
[progressIndicator setStyle: NSProgressIndicatorSpinningStyle];
[progressIndicator setControlSize: NSSmallControlSize];
[progressIndicator sizeToFit];
[progressIndicator setUsesThreadedAnimation:YES];
[progressIndicatorHolder addSubview:progressIndicator];
[progressIndicator startAnimation:self];
//for testing purposes
[[myStatusItem view] addSubview:progressIndicatorHolder];
spinnerView = progressIndicatorHolder;
}
I suggest save old view using [statusItem view] before setting to any other view. Before coming back to normal menu, set old saved view to statusItem using setView method.
If you're looking to just hide the NSStatusItem view, just call [yourStatusItem setLength:0].

Resources