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