Thursday, January 12, 2012

Getting NSStatusItem co-ordinates (Position in the NSStatusBar)

You can achieve this by setting an NSView to the NSStatusItem and getting its frame when needed.

NSRect rect = [[[statusItem view] window ] frame];

statusItem is a NSStatusItem object. You can get the current item as follows,

NSStatusBar *statusBar = [NSStatusBar systemStatusBar];
statusItem = [[statusBar statusItemWithLength:21]retain];

To handle any actions you will have to add a NSButton to this view. Everything works fine but there is a small drawback. This button will not have the default behavior as in the blue highlighting you get when you click on standard NSStatusItem. We'll see how we could achieve this.

1. Set the NSStatusItem the normal way

NSStatusBar *statusBar = [NSStatusBar systemStatusBar];
//statusItem is my NSStatusItem object. I have declared it in the header
statusItem = [[statusBar statusItemWithLength:21]retain];


[statusItem setHighlightMode:TRUE];
[statusItem setImage:[NSImage imageNamed:@"appIcon.png"]];
[statusItem setAction:@selector(statusBarItemClicked)];

2. In the selector you handle the click event set a NSView temporary to the NSStatusItem get the frame and remove it as follows.

- (void)statusBarItemClicked{

NSView *statusBarView = [[NSView alloc]initWithFrame:NSRectFromCGRect(CGRectMake(0, 0, 25, 21))];
[statusItem setView:statusBarView];
[statusBarView release];
statusBarView = nil;

NSRect rect = [[[statusItem view] window ] frame];
rect.origin.y = rect.origin.y - 533;
rect.origin.x = rect.origin.x - 280;
int y = rect.origin.y;
int x = rect.origin.x;
//I'm printing the co-ordinates of the NSStatusItem
NSLog(@"status bar co-ordinates");
NSLog(@"y %d",y);
NSLog(@"x %d",x);

[statusItem setView:NULL];
[statusItem setHighlightMode:TRUE];
[statusItem setImage:[NSImage imageNamed:@"appIcon.png"]];
[statusItem setAction:@selector(statusBarItemClicked)];

//anything you want to do when the NSStatusItem is clicked goes here

}

1 comment:

kappe said...

Nice! thank you :)