Show NSStatusItem menu only if App is active - objective-c

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.

Related

Custom Created Window Getting Closed Automatically By Selecting Contextual Menu Option Automatically

I have builded a custom window; in this window I am showing nsbuttons.
I am showing a contextual menu if button clicked.
The problem is I don't want to close my window but somehow mouse exited event is getting triggered as soon as I choose option from nsmenu.
I want to prevent this effect.
I am not able to figure it out.
Any help would be appreciated.
Thanks in Advance
-(void)rightMouseDown:(NSEvent *)theEvent
{
NSMenu *theMenu = [[NSMenu alloc] initWithTitle:#"Contextual Menu"];
[[theMenu addItemWithTitle:#"Remove From List" action:#selector(removeWithIdentifier) keyEquivalent:#""] setTarget:self];
[[theMenu addItemWithTitle:#"Open" action:#selector(openAppWithIdentifier) keyEquivalent:#""] setTarget:self];
[theMenu popUpMenuPositioningItem:nil atLocation:NSMakePoint(self.bounds.size.width-20, self.bounds.size.height-10) inView:self];
}
-(void)removeWithIdentifier
{
//My custom view is getting mouse exited event from here
//I want prevent it.
}
Hey Friends I have got the answer.
I have found that If your window level is "NSPopUpMenuWindowLevel" and its
view has implemented any context menu over it then this view will always gets mouse exited event.
posting it for future reference.
thanks.

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 to put a tableView's Edit button in the toolbar when a search bar is shown (as in Apple's mail app)?

I would like to put the Edit button in the toolbar at the bottom. The Edit button is usually instantiated with self.navigationItem.rightBarButtonItem = self.editButtonItem in viewDidLoad and normally placed in the navigation bar.
When trying to put the Edit button (= self.editButtonItem) in the toolbar (by adding it to the toolbar items), the buttom does not appear. However, all other toolbar items, which I have added using Interface Builder are presented correctly.
How would you recommend adding this button to the toolbar?
The reason for adding the Edit button to the toolbar is to be enable the table's edit mode when a UISearchBar enabled search is currently active and the searchbar hides the edit button in the navigation bar.
I would like to get the same behavior as in Apple's email app, where the Edit button is shown in the toolbar when search is active.
I would appreciate any suggestions.
Thank you for your help!!
You can add a Edit button to the toolbar this way:
self.editButton =
[[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit
target:nil
action:nil]
autorelease];
NSArray *toolbarItems =
[NSArray arrayWithObjects:self.editButton,nil];
self.toolbar.items = toolbarItems;
If you want to hide/show it, just toggle its hidden property:
self.editButton.hidden = YES;
You could do it manually, by creating a new UIBarButtonItem with style UIBarButtonSystemItemEdit. Then simply add it to the tabbar, assign a target and action and call [tableView setEditing:YES animated:YES];.

Displaying an action sheet over a disabled tab bar in tab bar partially enables it

I think I found a bug in UIKit, but first I want to be sure I'm not insane.
I have a tab bar with a disabled tabBarItem in it. If I present an action sheet from the tab bar, then cancel/press any button in it, after the action sheet dismisses the tab bar item appears enabled, but cannot be clicked.
I want it to stay disabled.
I uploaded an example project here. Run it in the simulator and press the action sheet button on the first view controller. Note the state of the second tab bar item before and after the sheet appears. The project itself is a standard "Tabbed Application" template with one tab item disabled and an IBAction for the button added.
Is this a bug, or am I misusing the APIs?
Looks like a bug it is...
As a quick and safe workaround add this to the view controller (assuming it will be an UIActionSheet's delegate)
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex {
for (UITabBarItem *item in self.tabBarController.tabBar.items) {
item.enabled = !item.enabled;
item.enabled = !item.enabled;
}
}
I have checked your Project and found a way to make it work. But I don't know actually is it a bug or not. I just find out, it is happening only when you show the actionsheet from the method using showFromTabbar: method.
[sheet showFromTabBar:self.tabBarController.tabBar];
When i changed it to show in this view only, then its not changing the tabBarItem image.
[sheet showInView:self.view];
Hope this could help you to continue to work on that project.

How to open a window on click on NSStatusItem?

I'm pretty new to cocoa, so please excuse me for any stupid mistakes I make.
I have a NSStatusItem, which I want to use to open up a menu. However as far as I know and have heard across different forms, without a custom view you are restricted to just a pop down menu. Is this true? And if so how do you make a custom view to do something (e.g. open a window in my case)? Thanks for any help.
No, it is not true. You need to set up the target and action for the status item to call a method which does what you want (opens the window).
// This goes where you set up the status item
NSStatusItem *statusItem; // You need to get this from the status bar
[statusItem setTarget:self];
[statusItem setAction:#selector(openWindow:)];
// This method is called when the status item is clicked
- (void)openWindow:(id)sender {
NSWindow *window = [self window]; // Get the window to open
[window makeKeyAndOrderFront:nil];
}
You may also want to call [NSApp activateIgnoringOtherApps:nil]; to your openWindow: method to ensure that the window you open is not behind some other application's window.