1 /*
2    NSMenu.h
3 
4    Copyright (C) 1996 Free Software Foundation, Inc.
5 
6    Author:  Ovidiu Predescu <ovidiu@net-community.com>
7    Date: May 1997
8    A completely rewritten version of the original source by Scott Christley.
9 
10    This file is part of the GNUstep GUI Library.
11 
12    This library is free software; you can redistribute it and/or
13    modify it under the terms of the GNU Lesser General Public
14    License as published by the Free Software Foundation; either
15    version 2 of the License, or (at your option) any later version.
16 
17    This library is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
20    Lesser General Public License for more details.
21 
22    You should have received a copy of the GNU Lesser General Public
23    License along with this library; see the file COPYING.LIB.
24    If not, see <http://www.gnu.org/licenses/> or write to the
25    Free Software Foundation, 51 Franklin Street, Fifth Floor,
26    Boston, MA 02110-1301, USA.
27 */
28 
29 #ifndef _GNUstep_H_NSMenu
30 #define _GNUstep_H_NSMenu
31 #import <GNUstepBase/GSVersionMacros.h>
32 
33 #import <Foundation/NSObject.h>
34 #import <Foundation/NSGeometry.h>
35 
36 #import <AppKit/NSMenuItem.h>
37 #import <AppKit/AppKitDefines.h>
38 
39 @class NSString;
40 @class NSEvent;
41 @class NSFont;
42 @class NSMatrix;
43 @class NSPopUpButton;
44 @class NSPopUpButtonCell;
45 @class NSView;
46 @class NSWindow;
47 @class NSMutableArray;
48 @class NSScreen;
49 
50 /* ******************* */
51 /* NSMenuView Protocol */
52 /* ******************* */
53 @protocol NSMenuView
54 /** Set the menu that this view object will be drawing.
55  *  This method will NOT retain the menu.
56  *  In normal usage an instance of NSMenu will
57  *  use this method to supply the NSMenuView with reference
58  *  to itself.  The NSMenu will retain the NSMenuView.
59  */
60 - (void) setMenu: (NSMenu *)menu;
61 
62 /** Set the currently highlighted item.
63  *  This is used by the NSMenu class to restore
64  *  the selected item when it is temporary set to
65  *  another item.  This happens when both the regular
66  *  version and the transient version are on the screen.
67  *  A value of -1 means that no item will be highlighted.
68  */
69 - (void) setHighlightedItemIndex: (NSInteger)index;
70 
71 /** Returns the currently highlighted item.  Returns -1
72  *  if no item is highlighted.
73  */
74 - (NSInteger) highlightedItemIndex;
75 
76 /** This should ensure that if there is an attached
77  *  submenu this submenu will be detached.
78  *  Detaching means that this particular menu representation
79  *  should be removed from the screen.
80  *  It should implement a deep detach, that is, all
81  *  attached submenus of this menu should also be detached.
82  */
83 - (void) detachSubmenu;
84 
85 /** This will relayout the NSMenuView.
86  *  It should be called when the menu changes.  Changes include
87  *  becoming detached, adding or removing submenu items etcetera.
88  *  However, normally it does not need to be called directly because
89  *  Because the NSMenuView is supposed to listen to the NSMenu notifications
90  *  for the item added, removed and change notifications.
91  *  It should be called explicitly when other changes occur, such as
92  *  becoming detached or changing the title.
93  */
94 - (void) update;
95 
96 /** Hm, why is this method needed?  Shouldn't this be done by
97  *  the update method?
98  */
99 - (void) sizeToFit;  //!!!
100 
101 /** Method used by NSMenuItemCell to draw itself correctly and nicely
102  *  lined up with the other menu items.
103  */
104 - (float) stateImageWidth;
105 /** Method used by NSMenuItemCell to draw itself correctly and nicely
106  *  lined up with the other menu items
107  */
108 - (float) imageAndTitleOffset;
109 /** Methos used by NSMenuItemCell to draw itself correctly and nicely
110  *  lined up with the other menu items.
111  */
112 - (float) imageAndTitleWidth;
113 /** Methos used by NSMenuItemCell to draw itself correctly and nicely
114  *  lined up with the other menu items.
115  */
116 - (float) keyEquivalentOffset;
117 /** Used by NSItemCell to ...
118  */
119 - (float) keyEquivalentWidth;
120 
121 /** Used by the NSMenu to determine where to position a
122  *  submenu.
123  */
124 - (NSPoint) locationForSubmenu: (NSMenu *)aSubmenu;
125 
126 - (void) performActionWithHighlightingForItemAtIndex: (NSInteger)index; //????
127 
128 /** <p>This is method is responsible for handling all events while
129  *  the user is interacting with this menu.  It should pass on this
130  *  call to another menurepresentation when the user moves the
131  *  mouse cursor over either a submenu or over the supermenu.
132  *  </p>
133  *  <p>The method returns when the interaction from the user with the
134  *  menu system is over.
135  *  </p>
136  *  <p>The method returns NO when the user releases the mouse button
137  *  above a submenu item and  YES in all other cases.
138  *  </p>
139  *  <p>This return value can be used to determine if submenus should
140  *  be removed from the screen or that they are supposed to stay.
141  *  </p>
142  *  <p>The implementation should roughly follow the following logic:
143  *  </p>
144  *  <code>
145  *  {
146  *    while (have not released mouse button)
147  *      {
148  *        if (mouse hovers over submenu, or supermenu)
149  *          {
150  *             if ([(menurepresentation under mouse)
151  *                          trackWithEvent: the event])
152  *                {
153  *                   [self detachSubmenu];
154  *                   return YES;
155  *                }
156  *             return NO;
157  *          }
158  *          //highlight item under  mouse
159  *
160  *          if (highlighting submenu item)
161  *            {
162  *              [self attachSubmenuAtIndex:..];
163  *            }
164  *          else
165  *            {
166  *              [self detachSubmenu];
167  *            }
168  *          get next event.
169  *      }
170  *
171  *    execute the menu action if applicable;
172  *
173  *    return YES | NO depending on the situation;
174  *  }
175  *  </code>
176  *
177  *  Note that actual implementations tend to be more complicated because
178  *  because of all kind of useability issues.   Useabilities issues to
179  *  look out for are:
180  *  <list>
181  *   <item>Menus that are only partly on the screen.  Those need to be
182  *         moved while navigation the menu.</item>
183  *   <item>Submenus that are hard to reach.  If the natural route to
184  *         the content of a submenu travels through other menu items
185  *         you do not want to remove the submenu immediately.</item>
186  *   <item>Transient menus require slightly different behaviour from
187  *         the normal menus.  For example, when selecting a action from
188  *         a transient menu that brings up a modal panel you would
189  *         expect the transient menu to dissappear.  However in the
190  *         normal menu system you want it to stay, so you still have
191  *         feedback on which menu action triggered the modal panel.</item>
192  *  </list>
193  */
194 - (BOOL) trackWithEvent: (NSEvent *)event;
195 
196 @end
197 
198 /**
199  * The NSMenuDelegate protocol defines optional methods implemented
200  * by delegates of NSMenu objects.
201  */
202 @protocol NSMenuDelegate <NSObject>
203 
204 /**
205  * Allows the delegate to return the target and action for a key-down event.
206  */
207 - (BOOL) menuHasKeyEquivalent: (NSMenu *)menu
208                      forEvent: (NSEvent *)event
209                        target: (id *)target
210                        action: (SEL *)action;
211 
212 /**
213  * Invoked on the delegate to allow changes before the menu opens.
214  */
215 - (void) menuWillOpen: (NSMenu *)menu;
216 
217 /**
218  * Invoked when the menu is about to be displayed.
219  */
220 - (NSInteger) numberOfItemsInMenu: (NSMenu *)menu;
221 
222 /**
223  * Invoked to indicate that the menu is about to be updated.
224  */
225 - (void) menuNeedsUpdate: (NSMenu *)menu;
226 
227 /**
228  * Invoked to inform the delegate that the menu did close.
229  */
230 - (void) menuDidClose: (NSMenu *)menu;
231 
232 /**
233  * Invoked too notify the delegate that the item will be highlighted.
234  */
235 - (void) menu: (NSMenu *)menu
236          willHighlightItem: (NSMenuItem *)item;
237 
238 /**
239  * Invoked to allow the delegate to update an item before
240  * it is displayed.
241  */
242 - (BOOL) menu: (NSMenu *)menu
243    updateItem: (NSMenuItem *)item
244       atIndex: (NSInteger)index
245  shouldCancel: (BOOL)shouldCancel;
246 
247 /**
248  * Specify a display location for the menu
249  */
250 - (NSRect)confinementRectForMenu: (NSMenu *)menu
251                         onScreen: (NSScreen *)screen;
252 
253 @end
254 
255 /** <p>Menus provide the user with a list of actions and/or submenus.
256  *  Submenus themselves are full fledged menus and so a heirarchical
257  *  structure of appears.</p>
258  *  <p>Every application has one special menu, the so called Application
259  *  menu.  This menu is always visible on the screen when the application
260  *  is active.  This menu normally contains items like, <em>info</em>,
261  *  <em>services</em>, <em>print</em>, <em>hide</em> and <em>quit</em>.</p>
262  *  <p>After the <em>info</em> item normally some submenus follow containing
263  *  the application specific actions.</p>
264  *  <p>On GNUstep the content of the menu is stacked vertically as
265  *  oppossed to the Windows and Mac world, where they are stacked
266  *  horizontally.  Also because the menus are not part of any normal
267  *  window they can be dragged around opened and closed independend of
268  *  the application windows.</p>
269  *  <p>This can lead to a few menus being open simultanuously.
270  *  The collection of open menus is remembered,
271  *  when the program is started again, all the torn off menus aka
272  *  detached menus, are displayed at their last known position.</p>
273  *  <p>The menu behaviour is richer than in most other environments and
274  *  bear some explanation.  This explanation is aimed at users of Menus
275  *  but more so at the developer of custom menus.</p>
276  *  <deflist>
277  *   <term>Application menu</term>
278  *    <desc>There alwasy at least one menu present and visible while the
279  *          application is active.  This is the application menu. This
280  *          window can never be closed.</desc>
281  *   <term>Attached menu</term>
282  *    <desc>Normally when you click in a menu on a submenu item, the
283  *          submenu is shown directly next to the menu you click in.
284  *          The submenu is now called an <em>attached</em> menu.   It is
285  *          attached to the menu that was clicked in.</desc>
286  *   <term>Detached menu</term>
287  *    <desc>A menu is detached when it is not attached to its parent
288  *          menu.  A menu can become detached when the user drags a
289  *          submenu away from its parents. A detached window contains in
290  *          its title a close button.</desc>
291  *   <term>Transient menu</term>
292  *    <desc>A transient menu is a menu that dissappears as
293  *          soon as the user stops interacting with the menus.
294  *          Typically a transient menu is created when a right mouse
295  *          click appears in an application window.  The right mouse
296  *          click will bring up the Application menu at the place the
297  *          user clicks.  While keeping the mouse button down the
298  *          user can select items by moving around.  When releasing the
299  *          button, all transient menus will be removed from the screen
300  *          and the action will be executed.
301  *          <p>It is important to note that it is impossible to click
302  *          in transient menus.</p></desc>
303  *   <term>Attached transient menu</term>
304  *    <desc>This is a menu that is attached and transient at the same
305  *          time.</desc>
306  *  </deflist>
307  *
308  *  A single NSMenu instance can be displayed zero or one times when the
309  *  user is not interaction with the menus.
310  *  When the user is interaction with the menus it can occur that the
311  *  same NSMenu is displayed in two locations at the same time.  This is
312  *  only possible when one of the displayed instances is a transient
313  *  menu.
314  *  <br/>
315  *  To understand how the diffent kind of menus are created lets look
316  *  at some user actions:
317  *
318  *  <list>
319  *   <item>The user clicks on an item which is not a submenu.<br/>
320  *         The item is highlighted until the action corresponding with
321  *         the item is completed.  More precisely,  the application
322  *         highlights the menu item, performs the action, and
323  *         unhighlights the item.</item>
324  *   <item>The user clicks on a submenu item which is not highlighted
325  *         already<br/> If the submenu is not a detached menu, the
326  *         submenu will become an attached menu to the menu that is
327  *         clicked in.  The item that is clicked in will
328  *         become highlighted and stays highlighted.
329  *         <p>If the submenu is a detached menu, the transient version
330  *         of the submenu will be shown</p></item>
331  *   <item>The user clicks on a submenu item which is highlighted<br/>
332  *         This means that the submenu is an attached submenu for this
333  *         menu.  After clicking the submenu item will no be no longer
334  *         highlighted and the submenu will be removed from the screen.</item>
335  *   <item>The user drags over a menu item<br/>
336  *         The item will be highlighted, if the item is a submenu item,
337  *         the submenu will be shown as an attached submenu.  This can
338  *         be transient, or non transient.</item>
339  *  </list>
340  *
341  *  <br/>
342  *  <strong>Customizing the look of Menus</strong>
343  *  <br/>
344  *
345  *  There are basically three ways of customizing the look of NSMenu
346  *  <enum>
347  *   <item>Using custom NSMenuItemCell's.  This you should do when you
348  *         want to influence the look of the items displayed in the
349  *         menu.</item>
350  *   <item>Using custom NSMenuView.  This is the class to modify if
351  *         you want to change the way the menu is layout on the screen.
352  *         So if you want to stack the menu items horizontally, you
353  *         should change this class.  This should be rarely needed.</item>
354  *   <item>Reimplement NSMenu.  This you should not do. But, if you
355  *         implement everything yourself you can achieve anything.</item>
356  *  </enum>
357  *
358  *  <br/>
359  *  <strong>Information for implementing custom NSMenuView class</strong>
360  *  <br/>
361  *  When implementing a custom NSMenuView class it is important
362  *  to keep the following information in mind.
363  *
364  *  <list>
365  *   <item>The menus (or the menu items) form a tree.  Navigating
366  *         through this tree is done with the methods
367  *         [NSMenu-supermenu], which returns the parent menu
368  *         of the receiver, and with [NSMenu-itemAtIndex:] which returns
369  *         a NSMenuItem on which we can call [(NSMenuItem)-submenu] for
370  *         a child menu.</item>
371  *   <item>The menus as displayed on the screen do NOT form a tree.
372  *         This because detached and transient menus lead to duplicate
373  *         menus on the screen.</item>
374  *  </list>
375  *
376  *  The displayed menus on the screen have the following structure:
377  *  <enum>
378  *   <item>The ordered graph of displayed menus (note, NOT the set of
379  *         NSMenus) form a collection of line graphs.</item>
380  *   <item>The attached menus are precisely the non root vertices in
381  *         this graph.</item>
382  *   <item>An attached menu of a transient menu is itself a transient
383  *         menu.</item>
384  *   <item>The collection of transient menus form connect subgraph of
385  *         the menu graph.</item>
386  *  </enum>
387  *
388  */
389 @interface NSMenu : NSObject <NSCoding, NSCopying>
390 {
391   NSString *_title;
392   NSMutableArray *_items;
393   NSView<NSMenuView>* _view;
394   NSMenu *_superMenu;
395   NSMenu *_attachedMenu;
396   NSMutableArray *_notifications;
397   id _delegate;
398 
399   // GNUstepExtra category
400   NSPopUpButtonCell *_popUpButtonCell;
401   struct GSMenuFlags {
402     unsigned int changedMessagesEnabled: 1;
403     unsigned int autoenable: 1;
404     unsigned int needsSizing: 1;
405     unsigned int is_tornoff: 1;
406     unsigned int transient: 1;
407     unsigned int horizontal: 1;
408     unsigned int mainMenuChanged: 1;
409 		unsigned int unused: 25;
410   } _menu;
411 
412 @private
413   NSWindow *_aWindow;
414   NSWindow *_bWindow;
415   NSMenu *_oldAttachedMenu;
416   int     _oldHiglightedIndex;
417   NSString *_name;
418 }
419 
420 /** Returns the memory allocation zone used to create instances of this class.
421  */
422 + (NSZone*) menuZone;
423 /** Specifies the memory allocation zone used to create instances of this class.
424  */
425 + (void) setMenuZone: (NSZone*)zone;
426 
427 + (void) popUpContextMenu: (NSMenu*)menu
428 		withEvent: (NSEvent*)event
429 		  forView: (NSView*)view;
430 #if OS_API_VERSION(MAC_OS_X_VERSION_10_3, GS_API_LATEST)
431 + (void) popUpContextMenu: (NSMenu *)menu
432                 withEvent: (NSEvent *)event
433                   forView: (NSView *)view
434                  withFont: (NSFont *)font;
435 #endif
436 
437 #if OS_API_VERSION(MAC_OS_X_VERSION_10_2, GS_API_LATEST)
438 + (BOOL) menuBarVisible;
439 + (void) setMenuBarVisible: (BOOL)flag;
440 #endif
441 
442 /** Add newItem to the menu.
443  */
444 - (void) addItem: (id <NSMenuItem>)newItem;
445 
446 /** Prefered method for inserting a menu item.  This method calls
447  *  [NSMenu-insertItemWithTitle:-action:-keyEquivalent:-atIndex:]
448  *  <deflist>
449  *   <term>aString</term>
450  *    <desc>The title of the specific menu item.</desc>
451  *   <term>aSelector</term>
452  *    <desc>The action taken by selecting this menu item, or NULL.</desc>
453  *   <term>keyEquiv</term>
454  *    <desc>The shortcut key for this menu item.  If none is needed,
455  *          specify and empty NSString, ie: @"".</desc>
456  *  </deflist>
457  *  <p>See Also: -insertItemWithTitle:-action:-keyEquivalent:-atIndex</p>
458  */
459 - (id <NSMenuItem>) addItemWithTitle: (NSString *)aString
460                               action: (SEL)aSelector
461                        keyEquivalent: (NSString *)keyEquiv;
462 
463 /** Returns the menu that is attached to this menu.
464  *  <p>
465  *  If two instances of this menu are visible,
466  *  return the attached window of the transient version
467  *  of this menu.</p>
468  *  <p>
469  *  If no menu is attached return nil.</p>
470  */
471 - (NSMenu*) attachedMenu;
472 
473 /** Returns YES if item does autoenable (default value) and NO otherwise.
474  *  <p>See Also:
475  *  </p>
476  *  <list>
477  *   <item>-setAutoenablesItems:</item>
478  *  </list>
479  */
480 - (BOOL) autoenablesItems;
481 
482 #if OS_API_VERSION(MAC_OS_X_VERSION_10_0, MAC_OS_X_VERSION_10_1)
483 - (id) contextMenuRepresentation;
484 #endif
485 
486 #if OS_API_VERSION(MAC_OS_X_VERSION_10_3, GS_API_LATEST)
487 - (id) delegate;
488 #endif
489 
490 /* Displaying Context-Sensitive Help */
491 - (void) helpRequested: (NSEvent*)event;
492 
493 /** Returns the index of item anObject.
494  */
495 - (NSInteger) indexOfItem: (id <NSMenuItem>)anObject;
496 
497 /** Returns the index of an item with the tag aTag.
498  */
499 - (NSInteger) indexOfItemWithTag: (NSInteger)aTag;
500 
501 /** Returns the index of an item with the target anObject
502  * and the actionSelector.
503  */
504 - (NSInteger) indexOfItemWithTarget: (id)anObject
505                    andAction: (SEL)actionSelector;
506 
507 /** Returns the index of an item with the represented object anObject.
508  */
509 - (NSInteger) indexOfItemWithRepresentedObject: (id)anObject;
510 
511 /** Returns the index of an item with the submenu anObject.
512  */
513 - (NSInteger) indexOfItemWithSubmenu: (NSMenu *)anObject;
514 
515 /** Returns the index of an item with the title aTitle.
516  */
517 - (NSInteger) indexOfItemWithTitle: (NSString *)aTitle;
518 
519 /** <init/>
520  */
521 - (id) initWithTitle: (NSString*)aTitle;
522 
523 /** Insert newItem at position index.
524  */
525 - (void) insertItem: (id <NSMenuItem>)newItem
526             atIndex: (NSInteger)index;
527 
528 /** Inserts a new menu item at position index.
529  *  <p>See Also:
530  *  </p>
531  *  <list>
532  *   <item>-addItemWithTitle:-action:-keyEquivalent-atIndex:</item>
533  *  </list>
534  */
535 - (id <NSMenuItem>) insertItemWithTitle: (NSString *)aString
536                                  action: (SEL)aSelector
537                           keyEquivalent: (NSString *)charCode
538                                 atIndex: (NSInteger)index;
539 
540 /** Returns if this menu is attached to its supermenu,
541  *  return nil if it does not have a parent menu.
542  *  <p>
543  *  If two instances of this menu are visible, return
544  *  the outcome of the check for the transient version
545  *  of the menu.</p>
546  */
547 - (BOOL) isAttached;
548 
549 /** If there are two instances of this menu visible, return NO.
550  *  Otherwise, return YES if we are a detached menu and visible.
551  */
552 - (BOOL) isTornOff;
553 
554 /**
555  * Returns an array containing all menu items in this menu.
556  */
557 - (NSArray*) itemArray;
558 
559 /** Returns an item located at index.
560  */
561 - (NSMenuItem *) itemAtIndex: (NSInteger)index;
562 
563 /** Informs the menu that the specified item has changed.
564  */
565 - (void) itemChanged: (id <NSMenuItem>)anObject;
566 
567 /** Retuns an item referenced by aTag.
568  *  <p>See Also:
569  *  </p>
570  *  <list>
571  *   <item>-indexOfItemWithTag:</item>
572  *   <item>[(NSMenuItem)-tag]</item>
573  *  </list>
574  */
575 - (id <NSMenuItem>) itemWithTag: (NSInteger)aTag;
576 
577 /** Returns an item with aString as its title.
578  */
579 - (id <NSMenuItem>) itemWithTitle: (NSString*)aString;
580 
581 /** Returns the position where submenu will be displayed
582  *  when it will be displayed as an attached menu of this menu.
583  *  The result is undefined when aSubmenu is not actually a submenu
584  *  of this menu.
585  */
586 - (NSPoint) locationForSubmenu: (NSMenu*)aSubmenu;
587 
588 #if OS_API_VERSION(MAC_OS_X_VERSION_10_4, GS_API_LATEST)
589 - (float)menuBarHeight;
590 #endif
591 
592 - (BOOL) menuChangedMessagesEnabled;
593 
594 /** Return the NSView that is used for drawing
595  *  the menu.
596  *  It is the view set with [NSMenu-setMenuRepresentation:] and
597  *  therefore it should be safe to assume it is an NSView
598  *  implementing the NSMenuView protocol.
599  */
600 - (id) menuRepresentation;
601 
602 /** Returns the numbers of items on the menu
603  */
604 - (NSInteger) numberOfItems;
605 
606 /** Simulates a mouse click on item located at index.
607  *  <p>See Also:
608  *  </p>
609  *  <list>
610  *   <item>-indexOfItem:</item>
611  *   <item>-indexOfItemWithTitle:</item>
612  *  </list>
613  */
614 - (void) performActionForItemAtIndex: (NSInteger)index;
615 
616 /** Looks for a menu item that responds to theEvent on the receiver.  If
617  *  the receiver is a submenu, the method is performed on it.
618  */
619 - (BOOL) performKeyEquivalent: (NSEvent*)theEvent;
620 
621 /** Calls -removeItemAtIndex: for anItem.
622  */
623 - (void) removeItem: (id <NSMenuItem>)anItem;
624 
625 /** Removes item at position index.
626  */
627 - (void) removeItemAtIndex: (NSInteger)index;
628 
629 /** Sets if a menu does autoenable.
630  */
631 - (void) setAutoenablesItems: (BOOL)flag;
632 
633 #if OS_API_VERSION(MAC_OS_X_VERSION_10_0, MAC_OS_X_VERSION_10_1)
634 - (void) setContextMenuRepresentation: (id)representation;
635 #endif
636 
637 #if OS_API_VERSION(MAC_OS_X_VERSION_10_3, GS_API_LATEST)
638 - (void) setDelegate:(id) delegate;
639 #endif
640 
641 - (void) setMenuChangedMessagesEnabled: (BOOL)flag;
642 
643 /** Set the View that should be used to display the menu.
644  *  <p>
645  *  The default is NSMenuView, but a user can supply its
646  *  own NSView object as long as it
647  *  </p>
648  *  <list>
649  *   <item>Inherits from NSView</item>
650  *   <item>Implements NSMenuView protocol</item>
651  *  </list>
652  */
653 - (void) setMenuRepresentation: (id) menuRep;
654 
655 /** Set a submenu of a menu.
656  *  <deflist>
657  *   <term>aMenu</term>
658  *    <desc>The submenu to be inserted.</desc>
659  *   <term>anItem</term>
660  *    <desc>Item to be turned into a submenu.</desc>
661  *  </deflist>
662  *  <p>See Also:
663  *  </p>
664  *  <list>
665  *   <item>[(NSMenuItem)-setSubmenu:]</item>
666  *  </list>
667  */
668 - (void) setSubmenu: (NSMenu*)aMenu forItem: (id <NSMenuItem>)anItem;
669 
670 /** Set the supermenu of this menu.
671  *  TODO:  add explanation if this will change remove this menu
672  *  from the old supermenu or if it does not.
673  */
674 - (void) setSupermenu: (NSMenu *)supermenu;
675 
676 #if OS_API_VERSION(MAC_OS_X_VERSION_10_0, MAC_OS_X_VERSION_10_1)
677 - (void) setTearOffMenuRepresentation: (id)representation;
678 #endif
679 
680 /** Change the title of the menu.
681  */
682 - (void) setTitle: (NSString*)aTitle;
683 
684 - (void) sizeToFit;
685 
686 - (void) submenuAction: (id)sender;
687 
688 /** Returns the supermenu of this menu.  Return nil
689  *  if this is the application menu.
690  */
691 - (NSMenu*) supermenu;
692 
693 #if OS_API_VERSION(MAC_OS_X_VERSION_10_0, MAC_OS_X_VERSION_10_1)
694 - (id) tearOffMenuRepresentation;
695 #endif
696 
697 /** Returns the current title.
698  */
699 - (NSString*) title;
700 
701 - (void) update;
702 
703 @end
704 
705 
706 /**
707  * Specifies the protocol to which an object must confirm if it is to be
708  * used to validate menu items (in order to implement automatic enabling
709  * and disabling of menu items).
710  */
711 
712 @protocol	NSMenuValidation
713 /** <p>The receiver should return YES if the menuItem is valid ... and should
714  *  be enabled in the menu, NO if it is invalid and the user should not be
715  *  able to select it.</p>
716  *  <p>This method is invoked automatically to determine whether menu items
717  *  should be enabled or disabled automatically whenever [NSMenu-update] is
718  *  invoked (usually by the applications event loop).</p>
719  */
720 - (BOOL) validateMenuItem: (id<NSMenuItem>)menuItem;
721 @end
722 
723 #if OS_API_VERSION(MAC_OS_X_VERSION_10_3, GS_API_LATEST)
724 @interface NSObject (NSMenuDelegate)
725 - (void) menuNeedsUpdate: (NSMenu *)menu;
726 - (NSInteger) numberOfItemsInMenu: (NSMenu *)menu;
727 - (BOOL) menu: (NSMenu *)menu
728    updateItem: (NSMenuItem *)item
729       atIndex: (NSInteger)index
730  shouldCancel: (BOOL)shouldCancel;
731 - (BOOL) menuHasKeyEquivalent: (NSMenu *)menu
732                      forEvent: (NSEvent *)event
733                        target: (id *)target
734                       action: (SEL *)action;
735 @end
736 #endif
737 
738 #if OS_API_VERSION(GS_API_NONE, GS_API_NONE)
739 @interface NSObject (NSMenuActionResponder)
740 - (BOOL) validateMenuItem: (id<NSMenuItem>)aMenuItem;
741 @end
742 
743 /** This interface exist contains methods that are meant
744  *  for the NSMenuView.  If you write your own implementation
745  *  of the NSMenuView interface you can use these methods
746  *  to popup other menus or close them.
747  */
748 @interface NSMenu (GNUstepExtra)
749 
750 /** Remove the window from the screen.  This method can/should be
751  *  used by the menurepresentation to remove a submenu from the screen.
752  */
753 - (void) close;
754 
755 /** Remove the transient version of the window from the screen.
756  *  This method is used by NSMenuView implementations that need
757  *  to open/close transient menus.
758  */
759 - (void) closeTransient;
760 
761 /** Show menu on the screen.  This method can/should be used by
762  *  the menurepresentation to display a submenu on the screen.
763  */
764 - (void) display;
765 
766 /** Display the transient version of the menu.
767  */
768 - (void) displayTransient;
769 
770 - (BOOL) isPartlyOffScreen;
771 
772 /** Returns YES if there is a transient version
773  *  of this menu displayed on the screen.
774  */
775 - (BOOL) isTransient;
776 
777 /* Moving menus */
778 - (void) nestedSetFrameOrigin: (NSPoint)aPoint;
779 
780 /** Flag this menu to be the main menu of the application,
781  *  when isMain is YES. Flag it as no longer being the main
782  *  menu when NO is handed in.
783  *  <p>This method also checks the user defaults to determine how
784  *  the menu is to be displayed (eg vertical or horizontal) and can
785  *  therefore be used to change window geometry.</p>
786  */
787 - (void) setMain: (BOOL)isMain;
788 
789 /** When the flag is YES
790  *  this method will detach the receiver from its parent and
791  *  update the menurepresentation so it will display a close
792  *  button if appropriate.
793  *  <p>
794  *  If the flag is NO this method will update the menurepresentation
795  *  so it will be able to remove the close button if needed.
796  *  Note that it will not reattach to its parent menu.</p>
797  */
798 - (void) setTornOff: (BOOL) flag;
799 
800 /* Shift partly off-screen menus */
801 - (void) shiftOnScreen;
802 
803 /** Returns the window in which this menu is displayed.
804  *  If there is a transient version it will return the
805  *  window in which the transient version is displayed.
806  *  If the Menu is not displayed at all the result
807  *  is meaningless.
808  */
809 - (NSWindow*) window;
810 
811 /* Popup behaviour */
812 - (BOOL) _ownedByPopUp;
813 - (NSPopUpButtonCell *)_owningPopUp;
814 - (void) _setOwnedByPopUp: (NSPopUpButtonCell*)popUp;
815 @end
816 #endif
817 
818 APPKIT_EXPORT NSString* const NSMenuDidSendActionNotification;
819 APPKIT_EXPORT NSString* const NSMenuWillSendActionNotification;
820 APPKIT_EXPORT NSString* const NSMenuDidAddItemNotification;
821 APPKIT_EXPORT NSString* const NSMenuDidRemoveItemNotification;
822 APPKIT_EXPORT NSString* const NSMenuDidChangeItemNotification;
823 APPKIT_EXPORT NSString* const NSMenuDidBeginTrackingNotification;
824 APPKIT_EXPORT NSString* const NSMenuDidEndTrackingNotification;
825 
826 #endif // _GNUstep_H_NSMenu
827