How to get location of NSStatusItem on the screen - objective-c

I have a app with NSStatusItem on the menu bar. Now i want to use shortcut keys to call up the NSWindow which should be displayed right bellow the NSStatusItem. With mouse click i just get the position of status item with:
CGRect eventFrame = [[[NSApp currentEvent] window] frame];
But i have no idea how to get this position if i use shortcut to call the window. The NSStatusItem has a custom view.
A similar question is here How to get the on-screen location of an NSStatusItem but no one could give a solution.

Related

NSEvent from a NSButton

I have a NSTableView and each row contains a button. I also have a menu associated with the table.
The issue is : I want to show the menu on click of button. If possible do not show on right click.
The action method is :
- (IBAction)showMenu:(NSButton *)button {
NSLog(#"show menu");
NSMenu *menu = [self.tableView menu];
NSEvent *event = [[NSEvent alloc] init];
[NSMenu popUpContextMenu:menu
withEvent:event
forView:button];
}
Here what to do with event? If I use nil then the menu is showed at bottom left corner, not next to the button.
Any guidance would be appreciated.
You could try using -[NSMenu popUpMenuPositioningItem:atLocation:inView:]. This method doesn't take an NSEvent argument. Instead, you give it a view and a location in the view's coordinate system, and the menu positions itself (or one of its items) over that location.
But I would suggest you don't use an NSButton at all. If you use an NSPopUpButton instead, it will take care of showing the menu at the correct location on a left-click.

NSPanel Sheet Not Receiving Mouse Events

SIMPLIFIED:
I have the following:
NSWindow (this is the main window of the app)
NSPanel (this is presented as a sheet, over the main NSWindow, using [NSApp beginSheet:)
The main NSWindow has a subclassed NSButton that uses mouse events, including mouseEntered, mouseExited. This changes the background color of the button as I hover over it.
I present my NSPanel, this also has an NSButton of the same subclass, to change color on hover.
Mouse events still occur in the main NSWindow while my NSPanel is presented. I can tell this, as hovering over the buttons still works.
However, hovering over the buttons in the presented NSPanel does not work, despite them being no different from the other buttons. I can click on them and they receive an action. But they do not call the mouse events.
ORIGINAL:
I have a simple setup in my Mac app. I have a main NSWindow, as any usual mac app, then I run the following code which displays my detail view.
My detail view is an NSWindowController subclass and I am displaying it as a sheet. This is setup as an NSPanel in the xib and just displays a detail view for me over my main window.
APDetailWindowController *vc = [[APDetailWindowController alloc] initWithWindowNibName:#"APDetailWindowController"];
self.detailWindowController = vc;
self.detailWindowController.delegate = self;
APAppDelegate *appDelegate = [[NSApplication sharedApplication] delegate];
[NSApp beginSheet:self.detailWindowController.window modalForWindow:appDelegate.window modalDelegate:self didEndSelector:nil contextInfo:nil];
In my main window (of the AppDelegate), I have my views played out as any app, including some NSButtons. These buttons are subclassed so that when they receive mouseEntered and mouseExited events, they change colour. Basically creating a rollover effect.
In my detail view, I also have buttons of the same subclass. However, they are not receiving the mouse events at all. I can see when moving my mouse over them nothing happens. Even when the detail view is displayed, the rollover works on the main window buttons in the background, but not in my detail view.
I am thinking maybe some sort of focus is still on the main window and needs to be set to the detail window?

How I add a mouse right-down menu to the NSCollectionViewItem

I have a question.How I add a mouse right-down menu to the NSCollectionViewItem.
As an attempt I alse use the Apple's demo app IconCollection.I tryed drag a NSMenu to the IconViewPrototype.xib and connect it to the view's menu outlet in IB.but when build and run,click the mouse right click,nothing happened.I think the NSBox also a subclass for NSView,the mouse right-down menu should be support.
I ended up creating an NSView subclass to use as a View for the CollectionViewItem. In there I set a delegate (connected in IB), and used this to catch the right mouse click and open the menu:
-(void)rightMouseDown:(NSEvent *)theEvent {
NSMenu *menu = [self.delegate menuForCollectionItemView:self];
[menu popUpMenuPositioningItem:[[menu itemArray] objectAtIndex:0]
atLocation:NSZeroPoint
inView:self];
}
This still needs some code to position the menu where the user clicked, but it's a start.
If anyone has a cleaner method I'd love to hear it.

Show NSStatusItem menu only if App is active

I'm using this method to show the NSStatusItem menu only if application is Active.
-(void)menuWillOpen:(NSMenu*)menu{
if(![NSApp isActive]){
[menu cancelTracking];
}
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
[window makeKeyAndOrderFront:self];
}
It perfectly works, but cancelTracking seems to block the blue highlight of the NSStatusItem. So when i click on status menu item it doesn't show the submenu and it presents the main window, but the icon is not highlighted.
Is there a way to make it happen ?
I suggest creating a custom view if you need more precise control over when the status item highlights itself. Then you can use mouseDown: etc. This is a good example of putting your custom view in a status item.

How do I add a navigation bar's Done button to a popover's passthroughViews?

I'm working in an iPad app that has a split view with a navigation controller in the detail view. The deepest view that can be in the navigation stack is an edit view where the user can edit data. I put an edit button as the rightBarButtonItem and when editing starts, change it to a done button.
When editing commences and the user touches on a particular field, I present a popoverview with a list of possible choices filtered by what they are typing - a form of autofill based on all the values of that field in all other objects.
This works fine, except if you try touching on the done button. The popover eats this touch and dismisses itself. So the user has to touch done again.
I tried using the uipopovercontroller's passthroughViews property, but UIBarButtonItem is not a view and there is no documented way to get the view for the done button or even the navigation bar. I can access the variable in gdb, but it isn't accessible via KVC.
Any ideas on how I can prevent the need to tap done twice?
I've thought about a gesture recognizer on the window, but that seems messy and I'd have to handle rotation.
In case anyone gets here from google, copypaste from other question:
The only solution I found for now is to create UIBarButtonItem with custom UIButton using
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
//code for styling button
UIBarButtonItem *b = [[[UIBarButtonItem alloc]
initWithCustomView:button]
autorelease]
and then
popoverController.passthroughViews = [NSArray arrayWithObject:b.customView];
But be prepared - you cannot create UIButton that looks like UIBarButtoItem. I ended up with creating image that reassembled UIBarButtonItem.