Simulate a mouse click on a menu item in Cocoa? - objective-c

For example, I have an NSMenuItem type variable whose title is "History". I need a keyboard shortcut Meta+h to do the same thing as to click this menu item (pop up a submenu list)..
I think there might be two ways to implement this:
1.bind this menu item to a keyboard shortcut, then the Cocoa will fire the execute the action belongs to the item when the shortcut is fired
2.not binding keyboard shortcut to the item. Create an EventHandler for Meta+h, when the event activated, simulate a mouse click on the menu item.
However, both methods don't work for now.
For the keyboard shortcut, there is a method called setKeyEquivalent, but it uses Command instead of Meta as the modifier. And its result is executing the action binds to the menu item, instead of poping up a submenu.
For the simulating of mouse click, in Cocoa's NSMenuItem reference, I haven't see how to send event like click to a NSMenuItem..
Does anyone have ideas about this? Thanks!

[menuItem setKeyEquivalent:#" "];
[menuItem setKeyEquivalentModifierMask:0];
with any of these modifier key masks (combined using the C bitwise OR operator):
NSShiftKeyMask
NSAlternateKeyMask
NSCommandKeyMask
NSControlKeyMask
(BTW, Apple's docs can be really useful!)

Your question is slightly unclear -
If you set a shortcut Cocoa will invoke the command for you and your code will never know whether the user used the mouse or hit the key equivalent.
If you'd like to invoke the same command by some other means (key in an NSView, etc). you'd want to manually call the same method that's hooked up to your menu definition.

Related

How to disable context menus with right mouse click in an NSTextField (Cocoa)?

I'm working on a Cocoa application that has editable text fields. These text fields need to accept values but don't need to be spell checked or use any of the other options given in the default context menu. I've read that the easiest way to remove the right click/ opt + click context menu is to override the function:
rightMouseDown:(NSEvent *)
I've done this in a custom NSTextfield class. This fix blocks the user from right clicking when the text box is enabled and unselected, but as soon as the user double clicks/enters the text field for editing the default right click functionality returns.
Is this because the firstResponder switches to a class in the inheritance chain upon trying to edit the field? Is this approach the right way to disable all context menu functionality for this NSTextField?
Thanks!
When a text field is editing, the actual first responder is the "field editor", an NSTextView supplied by the window. The field editor always uses the control on whose behalf it is acting as its delegate.
So, in order to influence its behavior with respect to the contextual menu, you need to use a custom subclass of NSTextField. (I guess you already are to override -rightMouseDown:.) Then, implement the text view delegate method -textView:menu:forEvent:atIndex: and return nil (i.e. no menu).

How do i add a right-click option to a menulet in Xcode and Interface Builder?

I'm trying to have a menulet that acts different on left-click and on right-click (and maybe combinations in the future like control-click, option-click or command-click).
Right now I have a menulet with a statusMenu attached to it that opens on left- and on right-click. In the statusMenu are five options: one execution item, three preference-setting-items and one quit item.
I'd like to separate the behavior somewhat as the menulet is designed to be a one trick pony. Left-clicking it should execute the function, right-clicking should open the menu exactly as it is (including the execution).
Any ideas how to do this?
Right now I'm calling the statusMenu from the code as is usual with statusMenus
[statusItem setMenu:statusMenu];
To do this, you will need to display the menu manually. One way to do it is to create a custom view and place that in the status item, and then use the mouseUp: and rightMouseUp: event handlers to perform your actions. You can also get the modifier keys from the event to perform other actions. It may also be possible to use the built-in target-action mechanism of the status item, and get the information from the NSEvent class methods +pressedMouseButtons and +modifierFlags. Either way, you can display your menu using NSStatusItem's -popUpStatusItemMenu: method.
For an example of handling left and right clicks with a custom view, see my answer to this question.

Growl notification like nswindow level

I am writing a notification system just like growl. The notification is a window and it's level is set to NSModalPanelWindowLevel. The only problem is, I have a button in that window and when the user wants to click that button, he/she has to click it twice. But, for example, in growl, no matter what window you have opened, you just simply click the notification and it registers a click.
So is it a level problem? If so, what should I set it to? Thanks
In your custom controls that make up the view content of the window, you will likely want to override NSView's -acceptsFirstMouse: method to return YES:
Discussion
The receiver can either
return a value unconditionally or use
the location of theEvent to determine
whether or not it wants the event. The
default implementation ignores
theEvent and returns NO.
Override this method in a subclass to
allow instances to respond to
click-through. This allows the user to
click on a view in an inactive window,
activating the view with one click,
instead of clicking first to make the
window active and then clicking the
view. Most view objects refuse a
click-through attempt, so the event
simply activates the window. Many
control objects, however, such as
instances of NSButton and NSSlider, do
accept them, so the user can
immediately manipulate the control
without having to release the mouse
button.
Not sure if this is what Growl does, but you might be able to listen for mouse over events in the window and use them to activate/deactivate the window prior to the click. I suspect your issue is that the first click is being eaten by the activation of the window.
Just a guess on that though.
To learn how to handle mouse over events, check out this documentation:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/EventOverview/TrackingAreaObjects/TrackingAreaObjects.html

Capture key press events while NSMenu is open

I'm interested in capturing key presses while a NSMenu is open. For example, if the menu is open and the user presses "e", or "1" on the keyboard, send a particular message (preferably passing an event object which contains reference to which key was pressed).
I've looked into alternate menus, but I'm under the impression that can only be used to capture the option key.
Currently I'm not using any custom views, just NSStatusBar (where the menu spawns from) and NSMenu.
I'm new to Objective-C so my apologies if I'm wording anything incorrectly.
Really appreciate the help!
I assume you are searching for this: Cocoa NSStatusBar Global HotKey

How would you make a Button display a Menu when clicked?

I am looking for some code to make a Menu appear next to a button when it is clicked.
What code would I need for this?
Sorry if this sounds a bit vague.
Why not use NSPopUpButton?
NSPopupButton was my first thought as well. It's how apps with the "action gear" buttons accomplish their menus.
If you do have something else in mind though, look at NSMenu's +popUpContextMenu:withEvent:forView:. Just hook an action method up to your button, create an NSMenu and populate it with NSMenuItems, and send it to this method along the the current event from NSApplication's currentEvent getter.
If you really need to roll this yourself, rather than using one of the built-in controls that shows a menu, you can create an NSPopupButtonCell and use that to show the NSMenu:
NSPopUpButtonCell *popupCell = [[NSPopUpButtonCell alloc] initTextCell:#"" pullsDown:YES];
[popupCell setMenu:yourMenu];
[popupCell trackMouse:event inRect:[yourButton bounds] ofView:yourButton untilMouseUp:YES];
[popupCell release];
You'd want to adjust the pullsDown:, inRect:, and ofView: arguments as necessary to position the menu the way you want.