NSTextField without the Services menu item - macos

I have a custom subclass of NSTextField. I want to display a context menu on right-click but the menu displays a completely irrelevant Services menu. I understand this is added due to OS settings, but the options are of no use at all in my scenario (e.g. the text fields contain numeric values) and it just adds clutter.
I have overridden textView:menu:forEvent:atIndex: to currently return nil. This means no menu is displayed, which is preferable to the Services menu in my view. However if I try to return an NSMenu instance containing items I actually want, then a Services menu item gets added.
Is there any way for my application or individual text fields to opt out of this?

See allowsContextMenuPlugIns
Indicates whether the pop-up menu allows appending of contextual menu plug-in items.

Related

Drop-down menu in NSToolbar like Mail.app

I'd like a toolbar button with an attached dropdown menu, like the "Flag" button in the toolbar in Mail.app:
I'd hoped that making a normal NSMenuItem and adding a menu as the menuFormRepresentation would do the trick, but that menu only appears when the button goes into overflow mode.
I had also hoped that adding an NSPopupButton as a custom view would work, but that makes the whole view a menu, whereas I want the left part of the component to behave like a normal button, and the right dropdown part bring up the menu.
Is there some trick to making the NSToolbarItem show a component like this, or is this two custom views stuck together?
There's nothing magical about NSToolbar here. That's just one of the ways you can set up NSSegmentedControl, regardless of whether it appears as a toolbar item's custom view or on its own.
You can't set this up in Interface Builder (storyboard), but NSSegmentedControl has APIs for assigning menus to segments:
segmentControl.setMenu(myMenu, forSegment: 1)
segmentControl.setShowsMenuIndicator(true, forSegment: 1) // for the little arrow
You probably want to set the tracking mode to momentary, since your segment control is acting as a set of visually-connected buttons, not a choose-one-of-N selector.
When the user clicks either segment, your action method will need to use the selectedSegment to decide whether to perform the action associated with the "button" side or ignore the click (letting the menu show for the other side).

Different menubar in document based apps

I've a cocoa app based on NSDocument, I've two types of document.
Every document type has its own menu items, all items are defined in mainmenu.xib.
As defined in Apple UI guidelines the menu items irrelevant for a doc type are shown grayed.
I have too much menu items so I want to show only relevant items per doc type, another problem is created by the key bindings, for doc type A a particular key binding is associated to a menu item but for doc type B the same key bindind is associated to another menu item but this isn't possible because XCode detects the same key is already used and it removes (correctly) from previous item definition.
I want to create a menu similar to XCode's 'Editor' menu, it shows some items when focus is on a text window and a totally different item set when focus is on a IB file.
Are there best practices? For example splitting menus.
How can I easily create a menu similar to XCode's 'Editor' menu?
Which API cocoa gives us to do it?
You can create the separate menu(s) in the MainMenu.xib and create outlets to them from the App Controller. Then when your document gains focus (see windowDidBecomeMain (reference)), you tell the App controller to switch-out the relevant parts of the main menu.
Switching-out the parts of the main menu is done by trawling the main menu hierarchy and assigning the separate menu at the right place (i.e. [NSMenuItem setSubmenu:] (reference)). You can make this easier for yourself by setting tags, using Interface Builder, in those menu items and then using [NSMenu itemWithTag:] (reference) to find them programmatically.

Facing issue with internationalize MainMenu.xib for Cocoa based Mac OS X Application

I am working in a Cocoa based Mac OS X project and facing one issue with internationalize MainMenu.xib.
In the menu items, all titles are need to be internationalized programmatically. All the menu items like “cut”, ”copy”, ”paste” can be internationalized using setTitle except the undo and redo menu item title. Adding to this, after typing anything in the text fields of the project forms, the undo menu item title dynamically changed to “Undo Typing”. The same happens for “Redo” also.
I can set the titles of other menu and menuitems' title using,
[[[[NSApp mainMenu] itemAtIndex:1] submenu]setTitle:#"Edit_Test"]
for MainMenu.xib "Edit" menu and similarly,
[[[[[NSApp mainMenu] itemAtIndex:1] submenu]itemAtIndex:4]setTitle:#"Copy_Test"]
for NSMenuItem "Copy" which is in under "Edit" menu.
But If I use the same piece of code,
[[[[[NSApp mainMenu] itemAtIndex:1] submenu]itemAtIndex:0]setTitle:#"Undo_Test"]
the menuItem title still remain as "Undo"
NSUndoManager provides the methods undoMenuItemTitle and redoMenuItemTitle, but NSUndoManager does not send the -setTitle: messages to the "Undo" and "Redo" menu items.
So how can I track that dynamic change in title and make that "Undo Typing" internationalized also?
Is it possible to manually get the First responder of the MainMenu.xib and from that get the undomanager object? So that i can unbind the undo action that is currently present in the first responder with the undo menu item and perform undo operation manually or is it possible to just change the title programmatically without doing all these.
Please let me know if any one had come across this problem and resolved the issue.
Make a subclass of NSUndoManager and override the undoMenuTitleForUndoActionName: method and the redoMenuTitleForUndoActionName: method. Create instances of this subclass for each document (or managed object context, or other thing) that needs an undo manager.

Multiple documents open at the same time, each with different menu item states

In a Cocoa document-based application, what's the best way to keep the menu item states in the menu bar in sync with the currently visible document?
For example, say you have a document with a ruler view that can be hidden/shown via "Show Rulers" (off state) and "Hide Rulers" (on state) menu items. The user has two documents open at the same time. He/she has hidden the rulers in one document, but not on the other. When the user moves between the documents the menu item should reflect the state for that document, not for the application as a whole.
How does one do this cleanly? I've googled around but it doesn't seem like there's a predefined "out of the box" way to do this. It would be nice if NSDocument had some sort of "didRegainFocus" type method where such logic can be added.
My actual implementation is a bit trickier since it's actually a NSViewController inside my NSDocument that deals with these particular menu items.
#interface MyDocument : NSDocument {
SomeViewController *myCustomizedTextViewController;
}
When MyDocument is the currently active document, I need methods in myCustomizedTextViewController to ensure the state of a couple of NSMenuItems in the application's main menu. One is genuinely a ruler. The other is a similar temporary setting.
Have the target of the menu items implement the validateUserInterfaceItem: method to enable/disable them. See the User Interface Validation reference for more info.

Confusion with popUpMenuPositioningItem:atLocation:inView:

The documentation for this method says: "Pops up the menu at the specified location." but the pamameters seem to describe a different situations:
item
The menu item to be positioned at the specified location in the view.
location
The location in the view coordinate system to display the menu item.
view
The view to display the menu item over.
The parameters seem to imply that you will only be popping up a MenuItem. What does this method actually do?
I don't know how you get that it might just pop up a menu item — there isn't even such a thing as a pop-up menu item. Nowhere in the parameter descriptions does it say it won't show a pop-up menu. The parameter descriptions all mention the item because they all relate to its positioning. It works as documented.
For convenience, you can set the coordinates of a single menu item. Your menu will be positioned accordingly around that single menu item.
You'll notice that this is how NSPopUpButton behaves: the selected menu item is always positioned directly overtop the button.
If you don't want your menu to behave like that, just pass in your top-most menu item.
You're forgetting something: This is a message you send to the menu object.
In English, the message is:
“Hey menu! Pop up yourself, positioning this item at this location relative to this view.”
The parameters describe where the whole pop-up menu should appear, in terms of positioning a specific item from the menu at a specific location. The whole menu appears as the pop-up, not just the positioning item. Popping up only a single item would be quite useless.
One other thing: This convenient method was introduced in Snow Leopard, so if you're targeting Leopard or earlier, you can't depend on it. You'll have to use another solution, such as the NSPopUpButtonCell I suggested in an answer on one of your earlier questions.

Resources