Up
Authors
- Fred Kiefer (
FredKiefer@gmx.de
)
-
- David Lazaro Saz (
khelekir@encomix.es
)
-
- Michael Hanni (
mhanni@sprintmail.com
)
-
- Felipe A. Rodriguez (
far@ix.netcom.com
)
-
- Ovidiu Predescu (
ovidiu@net-community.com
)
-
Copyright: (C) 1999 Free Software Foundation, Inc.
- Declared in:
- AppKit/NSMenu.h
- Conforms to:
- NSCoding
- NSCopying
Availability: OpenStep
Menus provide the user with a list of actions and/or
submenus. Submenus themselves are full fledged
menus and so a heirarchical structure of appears.
Every application has one special menu, the so called
Application menu. This menu is always visible
on the screen when the application is active. This menu
normally contains items like, info,
services, print, hide and
quit.
After the info item normally some submenus
follow containing the application specific actions.
On GNUstep the content of the menu is stacked vertically
as oppossed to the Windows and Mac world, where they are
stacked horizontally. Also because the menus are
not part of any normal window they can be dragged
around opened and closed independend of the
application windows.
This can lead to a few menus being open
simultanuously. The collection of open
menus is remembered, when the program is started
again, all the torn off menus aka detached menus,
are displayed at their last known position.
The menu behaviour is richer than in most other
environments and bear some explanation. This
explanation is aimed at users of Menus but more
so at the developer of custom menus.
- Application menu
-
There alwasy at least one menu present and visible
while the application is active. This is the
application menu. This window can never be
closed.
- Attached menu
-
Normally when you click in a menu on a submenu
item, the submenu is shown directly next to the
menu you click in. The submenu is now called an
attached menu. It is attached to the menu
that was clicked in.
- Detached menu
-
A menu is detached when it is not attached to its
parent menu. A menu can become detached when the
user drags a submenu away from its parents. A
detached window contains in its title a close
button.
- Transient menu
-
A transient menu is a menu that dissappears as soon as
the user stops interacting with the menus. Typically
a transient menu is created when a right mouse click
appears in an application window. The right mouse
click will bring up the Application menu at the
place the user clicks. While keeping the mouse
button down the user can select items by moving
around. When releasing the button, all transient
menus will be removed from the screen and the
action will be executed.
It is important to note that it is impossible to
click in transient menus.
- Attached transient menu
-
This is a menu that is attached and transient at the
same time.
A single NSMenu instance can be displayed zero or one times
when the user is not interaction with the menus. When
the user is interaction with the menus it can occur that
the same NSMenu is displayed in two locations at the same
time. This is only possible when one of the displayed
instances is a transient menu. To understand how
the diffent kind of menus are created lets look at some
user actions:
Customizing the look of Menus
There are basically three ways of customizing
the look of NSMenu
-
Using custom NSMenuItemCell's. This you should do
when you want to influence the look of the items
displayed in the menu.
-
Using custom NSMenuView. This is the class to
modify if you want to change the way the menu is
layout on the screen. So if you want to stack the
menu items horizontally, you should change this
class. This should be rarely needed.
-
Reimplement NSMenu. This you should not do.
But, if you implement everything yourself you can
achieve anything.
Information for implementing custom NSMenuView
class
When implementing a custom NSMenuView class it
is important to keep the following information in mind.
-
The menus (or the menu items) form a tree. Navigating
through this tree is done with the methods
[NSMenu -supermenu]
, which returns the parent menu of the receiver, and
with
[NSMenu -itemAtIndex:]
which returns a NSMenuItem on which we can call
[<NSMenuItem>-submenu]
for a child menu.
-
The menus as displayed on the screen do NOT form a
tree. This because detached and transient menus
lead to duplicate menus on the screen.
The displayed menus on the screen have the following
structure:
-
The ordered graph of displayed menus (note, NOT the
set of NSMenus) form a collection of line graphs.
-
The attached menus are precisely the non root
vertices in this graph.
-
An attached menu of a transient menu is itself a
transient menu.
-
The collection of transient menus form connect
subgraph of the menu graph.
Instance Variables
Method summary
+ (NSZone*)
menuZone;
Availability: OpenStep
Description forthcoming.
+ (void)
popUpContextMenu: (
NSMenu*)menu
withEvent: (
NSEvent*)event
forView: (
NSView*)view;
Availability: OpenStep
Description forthcoming.
+ (void)
setMenuZone: (NSZone*)zone;
Availability: OpenStep
Description forthcoming.
- (void)
addItem: (id<
NSMenuItem>)newItem;
Availability: OpenStep
Description forthcoming.
- (id<
NSMenuItem>)
addItemWithTitle: (NSString*)aString
action: (SEL)aSelector
keyEquivalent: (NSString*)keyEquiv;
Availability: OpenStep
Description forthcoming.
- (
NSMenu*)
attachedMenu;
Availability: OpenStep
Returns the menu that is attached to this menu.
If two instances of this menu are visible, return the
attached window of the transient version of this
menu.
If no menu is attached return nil
.
- (BOOL)
autoenablesItems;
Availability: OpenStep
Description forthcoming.
- (void)
helpRequested: (
NSEvent*)event;
Availability: OpenStep
Description forthcoming.
- (int)
indexOfItem: (id<
NSMenuItem>)anObject;
Availability: OpenStep
Description forthcoming.
- (int)
indexOfItemWithRepresentedObject: (id)anObject;
Availability: OpenStep
Description forthcoming.
- (int)
indexOfItemWithSubmenu: (
NSMenu*)anObject;
Availability: OpenStep
Description forthcoming.
- (int)
indexOfItemWithTag: (int)aTag;
Availability: OpenStep
Description forthcoming.
- (int)
indexOfItemWithTarget: (id)anObject
andAction: (SEL)actionSelector;
Availability: OpenStep
Description forthcoming.
- (int)
indexOfItemWithTitle: (NSString*)aTitle;
Availability: OpenStep
Description forthcoming.
- (id)
initWithTitle: (NSString*)aTitle;
Availability: OpenStep
This is a designated initialiser for the class.
Description forthcoming.
- (void)
insertItem: (id<
NSMenuItem>)newItem
atIndex: (int)index;
Availability: OpenStep
Description forthcoming.
- (id<
NSMenuItem>)
insertItemWithTitle: (NSString*)aString
action: (SEL)aSelector
keyEquivalent: (NSString*)charCode
atIndex: (unsigned int)index;
Availability: OpenStep
Description forthcoming.
- (BOOL)
isAttached;
Availability: OpenStep
Returns if this menu is attached to its supermenu,
return
nil
if it does not have a parent
menu.
If two instances of this menu are visible, return the
outcome of the check for the transient version of
the menu.
Look for the semantics in the header. Note that this
implementation works because there are...
cases:
-
This menu is transient, its supermenu is also
transient. In this case we just do the check
between the transient windows and everything is
fine
-
The menu is transient, its supermenu is not
transient. This can go WRONG
- (BOOL)
isTornOff;
Availability: OpenStep
If there are two instances of this menu visible, return
NO
. Otherwise, return YES
if we are a detached menu and visible.
- (NSArray*)
itemArray;
Availability: OpenStep
Returns an array containing all menu items in this
menu.
- (id<
NSMenuItem>)
itemAtIndex: (int)index;
Availability: OpenStep
Description forthcoming.
- (void)
itemChanged: (id<
NSMenuItem>)anObject;
Availability: OpenStep
Description forthcoming.
- (id<
NSMenuItem>)
itemWithTag: (int)aTag;
Availability: OpenStep
Description forthcoming.
- (id<
NSMenuItem>)
itemWithTitle: (NSString*)aString;
Availability: OpenStep
Description forthcoming.
- (NSPoint)
locationForSubmenu: (
NSMenu*)aSubmenu;
Availability: OpenStep
Returns the position where submenu will be
displayed when it will be displayed as an
attached menu of this menu. The result is
undefined when aSubmenu is not
actually a submenu of this menu.
- (BOOL)
menuChangedMessagesEnabled;
Availability: OpenStep
Description forthcoming.
- (id)
menuRepresentation;
Availability: OpenStep
Return the NSView that is used for drawing the menu.
It is the view set with
[NSMenu -setMenuRepresentation:]
and therefore it should be safe to assume it is an NSView implementing the NSMenuView protocol.
- (int)
numberOfItems;
Availability: OpenStep
Description forthcoming.
- (void)
performActionForItemAtIndex: (int)index;
Availability: OpenStep
Description forthcoming.
- (BOOL)
performKeyEquivalent: (
NSEvent*)theEvent;
Availability: OpenStep
Description forthcoming.
- (void)
removeItem: (id<
NSMenuItem>)anItem;
Availability: OpenStep
Description forthcoming.
- (void)
removeItemAtIndex: (int)index;
Availability: OpenStep
Description forthcoming.
- (void)
setAutoenablesItems: (BOOL)flag;
Availability: OpenStep
Description forthcoming.
- (void)
setMenuChangedMessagesEnabled: (BOOL)flag;
Availability: OpenStep
Description forthcoming.
- (void)
setMenuRepresentation: (id)menuRep;
Availability: OpenStep
Set the View that should be used to display the menu.
The default is NSMenuView, but a user can supply its
own NSView object as long as it
-
Inherits from NSView
-
Implements NSMenuView protocol
- (void)
setSubmenu: (
NSMenu*)aMenu
forItem: (id<
NSMenuItem>)anItem;
Availability: OpenStep
Description forthcoming.
- (void)
setSupermenu: (
NSMenu*)supermenu;
Availability: OpenStep
Set the supermenu of this menu. TODO: add
explanation if this will change remove this
menu from the old supermenu or if it does
not.
- (void)
setTitle: (NSString*)aTitle;
Availability: OpenStep
Change the title of the menu.
- (void)
sizeToFit;
Availability: OpenStep
Description forthcoming.
- (void)
submenuAction: (id)sender;
Availability: OpenStep
Description forthcoming.
- (
NSMenu*)
supermenu;
Availability: OpenStep
Returns the supermenu of this menu. Return
nil
if this is the application menu.
- (NSString*)
title;
Availability: OpenStep
Returns the current title.
- (void)
update;
Availability: OpenStep
Description forthcoming.
Instance Variables for NSMenu Class
@protected NSMenu* _attachedMenu;
Warning the underscore at the start of the
name of this instance variable indicates that, even
though it is not technically private, it is
intended for internal use within the package, and
you should not use the variable in other code.
@protected BOOL _autoenable;
Warning the underscore at the start of the
name of this instance variable indicates that, even
though it is not technically private, it is
intended for internal use within the package, and
you should not use the variable in other code.
@protected BOOL _changedMessagesEnabled;
Warning the underscore at the start of the
name of this instance variable indicates that, even
though it is not technically private, it is
intended for internal use within the package, and
you should not use the variable in other code.
@protected BOOL _horizontal;
Warning the underscore at the start of the
name of this instance variable indicates that, even
though it is not technically private, it is
intended for internal use within the package, and
you should not use the variable in other code.
@protected BOOL _is_tornoff;
Warning the underscore at the start of the
name of this instance variable indicates that, even
though it is not technically private, it is
intended for internal use within the package, and
you should not use the variable in other code.
@protected NSMutableArray* _items;
Warning the underscore at the start of the
name of this instance variable indicates that, even
though it is not technically private, it is
intended for internal use within the package, and
you should not use the variable in other code.
@protected BOOL _needsSizing;
Warning the underscore at the start of the
name of this instance variable indicates that, even
though it is not technically private, it is
intended for internal use within the package, and
you should not use the variable in other code.
@protected NSMutableArray* _notifications;
Warning the underscore at the start of the
name of this instance variable indicates that, even
though it is not technically private, it is
intended for internal use within the package, and
you should not use the variable in other code.
@protected char _pad1;
Warning the underscore at the start of the
name of this instance variable indicates that, even
though it is not technically private, it is
intended for internal use within the package, and
you should not use the variable in other code.
@protected NSPopUpButtonCell* _popUpButtonCell;
Warning the underscore at the start of the
name of this instance variable indicates that, even
though it is not technically private, it is
intended for internal use within the package, and
you should not use the variable in other code.
@protected NSMenu* _superMenu;
Warning the underscore at the start of the
name of this instance variable indicates that, even
though it is not technically private, it is
intended for internal use within the package, and
you should not use the variable in other code.
@protected NSString* _title;
Warning the underscore at the start of the
name of this instance variable indicates that, even
though it is not technically private, it is
intended for internal use within the package, and
you should not use the variable in other code.
@protected BOOL _transient;
Warning the underscore at the start of the
name of this instance variable indicates that, even
though it is not technically private, it is
intended for internal use within the package, and
you should not use the variable in other code.
@protected NSView* _view;
Warning the underscore at the start of the
name of this instance variable indicates that, even
though it is not technically private, it is
intended for internal use within the package, and
you should not use the variable in other code.
- Declared in:
- AppKit/NSMenu.h
Availability: Gui
This interface exist contains methods that are meant for
the NSMenuView. If you write your own implementation of
the NSMenuView interface you can use these methods to
popup other menus or close them.
Method summary
- (BOOL)
_ownedByPopUp;
Availability: Gui
Warning the underscore at the start of the
name of this method indicates that it is private, for
internal use only, and you should not use the
method in your code.
- (void)
_setOwnedByPopUp: (
NSPopUpButtonCell*)popUp;
Availability: Gui
Warning the underscore at the start of the
name of this method indicates that it is private, for
internal use only, and you should not use the
method in your code.
- (void)
close;
Availability: Gui
Remove the window from the screen. This method
can/should be used by the menurepresentation to
remove a submenu from the screen.
- (void)
closeTransient;
Availability: Gui
Remove the transient version of the window from the
screen. This method is used by NSMenuView
implementations that need to open/close
transient menus.
- (void)
display;
Availability: Gui
Show menu on the screen. This method can/should be
used by the menurepresentation to display a submenu on
the screen.
- (void)
displayTransient;
Availability: Gui
Display the transient version of the menu.
- (BOOL)
isPartlyOffScreen;
Availability: Gui
Description forthcoming.
- (BOOL)
isTransient;
Availability: Gui
Returns YES
if there is a transient
version of this menu displayed on the screen.
- (void)
nestedSetFrameOrigin: (NSPoint)aPoint;
Availability: Gui
Set the frame origin of the receiver to
aPoint. If a submenu of the receiver is
attached. The frame origin of the submenu is set
appropriately.
- (void)
setGeometry;
Availability: Gui
Positions the menu according to the standard user
defaults. If the position is not found in the
defaults revert to positioning the window in the
upper left corner.
- (void)
setMain: (BOOL)isMain;
Availability: Gui
Flag this menu to be the main menu of the application,
when isMain is YES
. Flag it as
no longer being the main menu when NO
is
handed in.
- (void)
setTornOff: (BOOL)flag;
Availability: Gui
When the flag is YES
this
method will detach the receiver from its parent and
update the menurepresentation so it will display a
close button if appropriate. If the flag
is NO
this method will update the
menurepresentation so it will be able to
remove the close button if needed. Note that it will
not reattach to its parent menu.
- (void)
shiftOnScreen;
Availability: Gui
Description forthcoming.
- (
NSWindow*)
window;
Availability: Gui
Returns the window in which this menu is displayed.
If there is a transient version it will return the
window in which the transient version is displayed.
If the Menu is not displayed at all the result is
meaningless.
- Declared in:
- AppKit/NSMenu.h
Availability: Gui
Description forthcoming.
Method summary
- (BOOL)
validateMenuItem: (id<
NSMenuItem>)aMenuItem;
Availability: Gui
Description forthcoming.
- Declared in:
- AppKit/NSMenu.h
Availability: OpenStep
Specifies the protocol to which an object must
confirm if it is to be used to validate menu items
(in order to implement automatic enabling and disabling
of menu items).
Method summary
- (BOOL)
validateMenuItem: (id<
NSMenuItem>)menuItem;
Availability: OpenStep
The receiver should return YES
if the
menuItem is valid... and should be
enabled in the menu, NO
if it is
invalid and the user should not be able to select
it.
This method is invoked automatically to determine
whether menu items should be enabled or disabled
automatically whenever
[NSMenu -update]
is invoked (usually by the applications event loop).
- Declared in:
- AppKit/NSMenu.h
Availability: OpenStep
Description forthcoming.
Method summary
- (void)
detachSubmenu;
Availability: OpenStep
This should ensure that if there is an attached
submenu this submenu will be detached. Detaching
means that this particular menu representation should
be removed from the screen. It should implement a deep
detach, that is, all attached submenus of this menu
should also be detached.
- (int)
highlightedItemIndex;
Availability: OpenStep
Returns the currently highlighted item. Returns -1
if no item is highlighted.
- (float)
imageAndTitleOffset;
Availability: OpenStep
Method used by NSMenuItemCell to draw itself
correctly and nicely lined up with the other menu
items
- (float)
imageAndTitleWidth;
Availability: OpenStep
Methos used by NSMenuItemCell to draw itself
correctly and nicely lined up with the other menu
items.
- (float)
keyEquivalentOffset;
Availability: OpenStep
Methos used by NSMenuItemCell to draw itself
correctly and nicely lined up with the other menu
items.
- (float)
keyEquivalentWidth;
Availability: OpenStep
Used by NSItemCell to...
- (NSPoint)
locationForSubmenu: (
NSMenu*)aSubmenu;
Availability: OpenStep
Used by the NSMenu to determine where to position a
submenu.
- (void)
performActionWithHighlightingForItemAtIndex: (int)index;
Availability: OpenStep
Description forthcoming.
- (void)
setHighlightedItemIndex: (int)index;
Availability: OpenStep
Set the currently highlighted item. This is used by the
NSMenu class to restore the selected item when it is
temporary set to another item. This happens when
both the regular version and the transient version are
on the screen. A value of -1 means that no item will be
highlighted.
- (void)
setMenu: (
NSMenu*)menu;
Availability: OpenStep
Set the menu that this view object will be
drawing. This method will NOT retain the
menu. In normal usage an instance of
NSMenu will use this method to supply the NSMenuView
with reference to itself. The NSMenu will retain the
NSMenuView.
- (void)
sizeToFit;
Availability: OpenStep
Hm, why is this method needed? Shouldn't this be done
by the update method?
- (float)
stateImageWidth;
Availability: OpenStep
Method used by NSMenuItemCell to draw itself
correctly and nicely lined up with the other menu
items.
- (BOOL)
trackWithEvent: (
NSEvent*)event;
Availability: OpenStep
This is method is responsible for handling all
events while the user is interacting with this
menu. It should pass on this call to another
menurepresentation when the user moves
the mouse cursor over either a submenu or over the
supermenu.
The method returns when the interaction from the user
with the menu system is over.
The method returns NO
when the user
releases the mouse button above a submenu item
and YES
in all other cases.
This return value can be used to determine if
submenus should be removed from the screen or
that they are supposed to stay.
The implementation should roughly follow the
following logic:
{
while (have not released mouse button)
{
if (mouse hovers over submenu, or supermenu)
{
if ([(menurepresentation under mouse)
trackWithEvent: the event])
{
[self detachSubmenu];
return YES;
}
return NO;
}
//highlight item under mouse
if (highlighting submenu item)
{
[self attachSubmenuAtIndex:..];
}
else
{
[self detachSubmenu];
}
get next event.
}
execute the menu action if applicable;
return YES | NO depending on the situation;
}
Note that actual implementations tend to be more
complicated because because of all kind of
useability issues. Useabilities issues to look
out for are:
-
Menus that are only partly on the screen. Those
need to be moved while navigation the menu.
-
Submenus that are hard to reach. If the
natural route to the content of a submenu
travels through other menu items you do not
want to remove the submenu immediately.
-
Transient menus require slightly different
behaviour from the normal menus. For example,
when selecting a action from a transient menu that
brings up a modal panel you would expect the
transient menu to dissappear. However in the
normal menu system you want it to stay, so you
still have feedback on which menu action
triggered the modal panel.
- (void)
update;
Availability: OpenStep
This will relayout the NSMenuView. It should be called
when the menu changes. Changes include becoming
detached, adding or removing submenu items
etcetera. However, normally it does not need to
be called directly because Because the NSMenuView is
supposed to listen to the NSMenu notifications for
the item added, removed and change notifications. It
should be called explicitly when other changes
occur, such as becoming detached or changing the
title.
Up