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.
Related
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.
I have the following problem: In an Cocoa app, a submenu is defined and attached in the main menu. Now I need the exact same submenu as a context menu for a NSView.
Now, my goal is to avoid creating an exact duplicate of the main menu. I thought that I could reuse the already existing submenu. Indeed, I can just assign the corresponding menu to the NSView with Interface Builder and that seems to work.
But unfortunately, every time I select an item in the context menu now, the corresponding root main menu item flashes blue.
Is there any way to disable this behaviour? Or do you have other suggestions how this problem can be solved without duplicating the existing submenu?
I'm following the instructions for creating a ScrollView in the book 'Cocoa Programming for Mac OS X, 3rd Edition'. I'm using Xcode 3.2.3.
I've already created a view, into which I've drawn shapes and lines.
The next task is to convert this to a NSScrollView, which according to the book should be a simple case of selecting the existing view and choosing Layout -> Embed Objects In -> Scroll View.
However whatever object I select, the items in the 'Embed Objects In' menu are all disabled.
How can I enable the Embed Objects In -> Scroll View item?
Got it. The important thing here is not to try selecting the view in the MainMenu.xib window. Select the view in the actual document window and make sure the resize handles are visible. A little fiddly, but once you get the right object selected, then the embed objects menu items become enabled.
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.
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.