Integrate horizontal main menu support.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@22426 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2006-02-04 19:58:55 +00:00
parent 24af0ec222
commit 3d2503f2e3
8 changed files with 1036 additions and 422 deletions

View file

@ -363,6 +363,10 @@ struct _NSModalSession {
- (void) setImage: (NSImage *)anImage;
@end
@interface NSMenu (HorizontalPrivate)
- (void) _organizeMenu;
@end
/*
* Class variables
*/
@ -2159,6 +2163,8 @@ image.</p><p>See Also: -applicationIconImage</p>
[anImage setName: @"NSApplicationIcon"];
ASSIGN(_app_icon, anImage);
[_main_menu _organizeMenu];
if (_app_icon_window != nil)
{
[(NSAppIconView *)[_app_icon_window contentView] setImage: anImage];
@ -2638,6 +2644,23 @@ image.</p><p>See Also: -applicationIconImage</p>
{
[_main_menu setMain: YES];
}
/*
* If necessary,. rebuild menu for macintosh (horizontal) style
*/
if (NSInterfaceStyleForKey(@"NSMenuInterfaceStyle", nil)
== NSMacintoshInterfaceStyle)
{
NSMenuView *rep = [[NSMenuView alloc] initWithFrame: NSZeroRect];
[rep setHorizontal: YES];
[_main_menu setMenuRepresentation: rep];
RELEASE(rep);
[_main_menu _organizeMenu];
[[_main_menu window] setTitle: [[NSProcessInfo processInfo] processName]];
[[_main_menu window] setLevel: NSMainMenuWindowLevel];
[_main_menu setGeometry];
}
}
/*

View file

@ -142,6 +142,11 @@ static NSNotificationCenter *nc;
- (NSString*) _locationKey
{
if (NSInterfaceStyleForKey(@"NSMenuInterfaceStyle", nil)
== NSMacintoshInterfaceStyle)
{
return nil;
}
if (_superMenu == nil)
{
if ([NSApp mainMenu] == self)
@ -197,61 +202,182 @@ static NSNotificationCenter *nc;
forModes: [NSArray arrayWithObject: NSDefaultRunLoopMode]];
}
- (void) _organizeMenu
{
if (_horizontal == YES)
{
NSString *title = [[NSProcessInfo processInfo] processName];
NSMenu *appMenu = [[self itemWithTitle: title] submenu];
if (![self isEqual: [NSApp mainMenu]])
return;
if (appMenu == nil)
{
int i;
NSMutableArray *itemsToMove = [NSMutableArray new];
NSMenuItem *appItem;
NSImage *ti = [[NSApp applicationIconImage] copy];
float bar = [NSMenuView menuBarHeight] - 4;
appMenu = [NSMenu new];
for (i = 0; i < [_items count]; i++)
{
NSMenuItem *anItem = [_items objectAtIndex: i];
NSString *title = [anItem title];
if (![anItem submenu])
{
[itemsToMove addObject: anItem];
}
if ([title isEqual: NSLocalizedString (@"Info",
@"Info")])
{
[itemsToMove addObject: anItem];
}
}
for (i = 0; i < [itemsToMove count]; i++)
{
[self removeItem: [itemsToMove objectAtIndex: i]];
[appMenu addItem: [itemsToMove objectAtIndex: i]];
}
[self insertItemWithTitle: [[NSProcessInfo processInfo] processName]
action: NULL
keyEquivalent: @""
atIndex: 0];
appItem = (NSMenuItem *)[self itemWithTitle: title];
if (!ti)
ti = [[NSImage imageNamed: @"GNUstep.tiff"] copy];
[ti setScalesWhenResized: YES];
[ti setSize: NSMakeSize(bar, bar)];
[appItem setImage: ti];
RELEASE (ti);
[self setSubmenu: appMenu forItem: appItem];
[itemsToMove release];
}
else
{
int i;
NSMutableArray *itemsToMove = [NSMutableArray new];
NSMenuItem *appItem = [self itemWithTitle: [[NSProcessInfo processInfo] processName]];
int index = [self indexOfItem: appItem];
NSImage *ti = [[NSApp applicationIconImage] copy];
float bar = [NSMenuView menuBarHeight] - 4;
if (!ti)
ti = [[NSImage imageNamed: @"GNUstep.tiff"] copy];
[ti setScalesWhenResized: YES];
[ti setSize: NSMakeSize(bar, bar)];
[appItem setImage: ti];
RELEASE (ti);
if (index != 0)
{
RETAIN (appItem);
[self removeItemAtIndex: index];
[self insertItem: appItem atIndex: 0];
RELEASE (appItem);
}
for (i = 0; i < [_items count]; i++)
{
NSMenuItem *anItem = [_items objectAtIndex: i];
NSString *title = [anItem title];
if (![anItem submenu])
{
[itemsToMove addObject: anItem];
}
if ([title isEqual: NSLocalizedString (@"Info",
@"Info")])
{
[itemsToMove addObject: anItem];
}
}
for (i = 0; i < [itemsToMove count]; i++)
{
[self removeItem: [itemsToMove objectAtIndex: i]];
[appMenu addItem: [itemsToMove objectAtIndex: i]];
}
[itemsToMove release];
}
}
}
/**
Save the current menu position in the standard user defaults
*/
- (void) _updateUserDefaults: (id) notification
{
NSString *key;
NSDebugLLog (@"NSMenu", @"Synchronizing user defaults");
key = [self _locationKey];
if (key != nil)
if (_horizontal == NO)
{
NSUserDefaults *defaults;
NSMutableDictionary *menuLocations;
NSString *locString;
NSString *key;
defaults = [NSUserDefaults standardUserDefaults];
menuLocations = [defaults objectForKey: NSMenuLocationsKey];
if ([menuLocations isKindOfClass: [NSDictionary class]])
menuLocations = [menuLocations mutableCopy];
else
menuLocations = nil;
NSDebugLLog (@"NSMenu", @"Synchronizing user defaults");
key = [self _locationKey];
if (key != nil)
{
NSUserDefaults *defaults;
NSMutableDictionary *menuLocations;
NSString *locString;
if ([_aWindow isVisible]
&& ([self isTornOff] || ([NSApp mainMenu] == self)))
{
if (menuLocations == nil)
{
menuLocations = AUTORELEASE([[NSMutableDictionary alloc]
initWithCapacity: 2]);
}
locString = [[self window] stringWithSavedFrame];
[menuLocations setObject: locString forKey: key];
}
else
{
[menuLocations removeObjectForKey: key];
}
defaults = [NSUserDefaults standardUserDefaults];
menuLocations = [defaults objectForKey: NSMenuLocationsKey];
if ([menuLocations isKindOfClass: [NSDictionary class]])
menuLocations = [menuLocations mutableCopy];
else
menuLocations = nil;
if ([menuLocations count] > 0)
{
[defaults setObject: menuLocations forKey: NSMenuLocationsKey];
}
else
{
[defaults removeObjectForKey: NSMenuLocationsKey];
}
[defaults synchronize];
if ([_aWindow isVisible]
&& ([self isTornOff] || ([NSApp mainMenu] == self)))
{
if (menuLocations == nil)
{
menuLocations = AUTORELEASE([[NSMutableDictionary alloc]
initWithCapacity: 2]);
}
locString = [[self window] stringWithSavedFrame];
[menuLocations setObject: locString forKey: key];
}
else
{
[menuLocations removeObjectForKey: key];
}
if ([menuLocations count] > 0)
{
[defaults setObject: menuLocations
forKey: NSMenuLocationsKey];
}
else
{
[defaults removeObjectForKey: NSMenuLocationsKey];
}
[defaults synchronize];
}
}
}
- (void) _rightMouseDisplay: (NSEvent*)theEvent
{
[self displayTransient];
[_view mouseDown: theEvent];
[self closeTransient];
if (_horizontal == NO)
{
[self displayTransient];
[_view mouseDown: theEvent];
[self closeTransient];
}
}
@end
@ -875,7 +1001,7 @@ static NSNotificationCenter *nc;
if (![item isEnabled])
return;
// Send the actual action and the estipulated notifications.
// Send the actual action and the stipulated notifications.
d = [NSDictionary dictionaryWithObject: item forKey: @"MenuItem"];
[nc postNotificationName: NSMenuWillSendActionNotification
object: self
@ -939,6 +1065,8 @@ static NSNotificationCenter *nc;
return;
}
_horizontal = [menuRep isHorizontal];
if (_view == menuRep)
{
return;
@ -1177,6 +1305,11 @@ static NSNotificationCenter *nc;
- (void) _showTornOffMenuIfAny: (NSNotification*)notification
{
if (NSInterfaceStyleForKey(@"NSMenuInterfaceStyle", nil)
== NSMacintoshInterfaceStyle)
{
return;
}
if ([NSApp mainMenu] != self)
{
NSString *key;
@ -1325,36 +1458,47 @@ static NSNotificationCenter *nc;
- (void) setGeometry
{
NSString *key;
NSPoint origin;
if (nil != (key = [self _locationKey]))
if (_horizontal == YES)
{
NSUserDefaults *defaults;
NSDictionary *menuLocations;
NSString *location;
defaults = [NSUserDefaults standardUserDefaults];
menuLocations = [defaults objectForKey: NSMenuLocationsKey];
if ([menuLocations isKindOfClass: [NSDictionary class]])
location = [menuLocations objectForKey: key];
else
location = nil;
if (location && [location isKindOfClass: [NSString class]])
{
[_aWindow setFrameFromString: location];
[_bWindow setFrameFromString: location];
return;
}
origin = NSMakePoint (0, [[NSScreen mainScreen] frame].size.height
- [_aWindow frame].size.height);
[_aWindow setFrameOrigin: origin];
[_bWindow setFrameOrigin: origin];
}
origin = NSMakePoint(0, [[_aWindow screen] visibleFrame].size.height
- [_aWindow frame].size.height);
else
{
NSString *key;
if (nil != (key = [self _locationKey]))
{
NSUserDefaults *defaults;
NSDictionary *menuLocations;
NSString *location;
defaults = [NSUserDefaults standardUserDefaults];
menuLocations = [defaults objectForKey: NSMenuLocationsKey];
if ([menuLocations isKindOfClass: [NSDictionary class]])
location = [menuLocations objectForKey: key];
else
location = nil;
if (location && [location isKindOfClass: [NSString class]])
{
[_aWindow setFrameFromString: location];
[_bWindow setFrameFromString: location];
return;
}
}
[_aWindow setFrameOrigin: origin];
[_bWindow setFrameOrigin: origin];
origin = NSMakePoint(0, [[_aWindow screen] visibleFrame].size.height
- [_aWindow frame].size.height);
[_aWindow setFrameOrigin: origin];
[_bWindow setFrameOrigin: origin];
}
}
- (void) close
@ -1479,6 +1623,10 @@ static NSNotificationCenter *nc;
NSPoint vector = {0.0, 0.0};
BOOL moveIt = NO;
// If we are the main menu forget about moving.
if ([self isEqual: [NSApp mainMenu]])
return;
// 1 - determine the amount we need to shift in the y direction.
if (NSMinY (frameRect) < 0)
{
@ -1509,23 +1657,33 @@ static NSNotificationCenter *nc;
if (moveIt)
{
NSMenu *candidateMenu;
NSMenu *masterMenu;
NSPoint masterLocation;
NSPoint destinationPoint;
// Look for the "master" menu, i.e. the one to move from.
for (candidateMenu = masterMenu = self;
(candidateMenu = masterMenu->_superMenu)
&& (!masterMenu->_is_tornoff
|| masterMenu->_transient);
masterMenu = candidateMenu);
masterLocation = [[masterMenu window] frame].origin;
destinationPoint.x = masterLocation.x + vector.x;
destinationPoint.y = masterLocation.y + vector.y;
[masterMenu nestedSetFrameOrigin: destinationPoint];
if (_horizontal)
{
masterLocation = [[self window] frame].origin;
destinationPoint.x = masterLocation.x + vector.x;
destinationPoint.y = masterLocation.y + vector.y;
[self nestedSetFrameOrigin: destinationPoint];
}
else
{
NSMenu *candidateMenu;
NSMenu *masterMenu;
// Look for the "master" menu, i.e. the one to move from.
for (candidateMenu = masterMenu = self;
(candidateMenu = masterMenu->_superMenu)
&& (!masterMenu->_is_tornoff
|| masterMenu->_transient);
masterMenu = candidateMenu);
masterLocation = [[masterMenu window] frame].origin;
destinationPoint.x = masterLocation.x + vector.x;
destinationPoint.y = masterLocation.y + vector.y;
[masterMenu nestedSetFrameOrigin: destinationPoint];
}
}
}

View file

@ -41,6 +41,7 @@
#include "AppKit/NSMenu.h"
#include "AppKit/NSMenuItemCell.h"
#include "AppKit/NSMenuView.h"
#include "AppKit/NSParagraphStyle.h"
#include "GNUstepGUI/GSDrawFunctions.h"
@ -88,7 +89,7 @@ static NSImage *arrowImage = nil; /* Cache arrow image. */
return _cell.is_highlighted;
}
- (void) setMenuItem:(NSMenuItem *)item
- (void) setMenuItem: (NSMenuItem *)item
{
ASSIGN (_menuItem, item);
[self setEnabled: [_menuItem isEnabled]];
@ -99,10 +100,23 @@ static NSImage *arrowImage = nil; /* Cache arrow image. */
return _menuItem;
}
- (void) setMenuView:(NSMenuView *)menuView
- (void) setMenuView: (NSMenuView *)menuView
{
/* The menu view is retaining us, we should not retain it. */
_menuView = menuView;
/*
* Determine whether we have horizontal or vertical layout and adjust.
*/
if ([_menuView isHorizontal])
{
_horizontalMenu = YES;
[self setAlignment: NSCenterTextAlignment];
}
else
{
_horizontalMenu = NO;
[self setAlignment: NSLeftTextAlignment];
}
}
- (NSMenuView *) menuView
@ -249,47 +263,81 @@ static NSImage *arrowImage = nil; /* Cache arrow image. */
//
- (NSRect) imageRectForBounds:(NSRect)cellFrame
{
if (_mcell_belongs_to_popupbutton && _cell.image_position)
if (_horizontalMenu == YES)
{
// Special case: draw image on the extreme right
cellFrame.origin.x += cellFrame.size.width - _imageWidth - 4;
cellFrame.size.width = _imageWidth;
return cellFrame;
switch (_cell.image_position)
{
case NSNoImage:
cellFrame = NSZeroRect;
break;
case NSImageOnly:
case NSImageOverlaps:
break;
case NSImageLeft:
cellFrame.origin.x += 4.; // _horizontalEdgePad
cellFrame.size.width = _imageWidth;
break;
case NSImageRight:
cellFrame.origin.x += _titleWidth;
cellFrame.size.width = _imageWidth;
break;
case NSImageBelow:
cellFrame.size.height /= 2;
break;
case NSImageAbove:
cellFrame.size.height /= 2;
cellFrame.origin.y += cellFrame.size.height;
break;
}
}
// Calculate the image part of cell frame from NSMenuView
cellFrame.origin.x += [_menuView imageAndTitleOffset];
cellFrame.size.width = [_menuView imageAndTitleWidth];
switch (_cell.image_position)
else
{
case NSNoImage:
cellFrame = NSZeroRect;
break;
if (_mcell_belongs_to_popupbutton && _cell.image_position)
{
// Special case: draw image on the extreme right
cellFrame.origin.x += cellFrame.size.width - _imageWidth - 4;
cellFrame.size.width = _imageWidth;
return cellFrame;
}
case NSImageOnly:
case NSImageOverlaps:
break;
// Calculate the image part of cell frame from NSMenuView
cellFrame.origin.x += [_menuView imageAndTitleOffset];
cellFrame.size.width = [_menuView imageAndTitleWidth];
case NSImageLeft:
cellFrame.size.width = _imageWidth;
break;
switch (_cell.image_position)
{
case NSNoImage:
cellFrame = NSZeroRect;
break;
case NSImageRight:
cellFrame.origin.x += _titleWidth + GSCellTextImageXDist;
cellFrame.size.width = _imageWidth;
break;
case NSImageOnly:
case NSImageOverlaps:
break;
case NSImageBelow:
cellFrame.size.height /= 2;
break;
case NSImageLeft:
cellFrame.size.width = _imageWidth;
break;
case NSImageAbove:
cellFrame.size.height /= 2;
cellFrame.origin.y += cellFrame.size.height;
break;
case NSImageRight:
cellFrame.origin.x += _titleWidth + GSCellTextImageXDist;
cellFrame.size.width = _imageWidth;
break;
case NSImageBelow:
cellFrame.size.height /= 2;
break;
case NSImageAbove:
cellFrame.size.height /= 2;
cellFrame.origin.y += cellFrame.size.height;
break;
}
}
return cellFrame;
}
@ -313,39 +361,76 @@ static NSImage *arrowImage = nil; /* Cache arrow image. */
- (NSRect) titleRectForBounds:(NSRect)cellFrame
{
// Calculate the image part of cell frame from NSMenuView
cellFrame.origin.x += [_menuView imageAndTitleOffset];
cellFrame.size.width = [_menuView imageAndTitleWidth];
switch (_cell.image_position)
if (_horizontalMenu == YES)
{
case NSNoImage:
case NSImageOverlaps:
break;
/* This adjust will center us within the menubar. */
case NSImageOnly:
cellFrame = NSZeroRect;
break;
cellFrame.size.height -= 2;
case NSImageLeft:
cellFrame.origin.x += _imageWidth + GSCellTextImageXDist;
cellFrame.size.width = _titleWidth;
break;
switch (_cell.image_position)
{
case NSNoImage:
case NSImageOverlaps:
break;
case NSImageOnly:
cellFrame = NSZeroRect;
break;
case NSImageLeft:
cellFrame.origin.x += _imageWidth + GSCellTextImageXDist + 4;
cellFrame.size.width = _titleWidth;
break;
case NSImageRight:
cellFrame.size.width = _titleWidth;
break;
case NSImageBelow:
cellFrame.size.height /= 2;
cellFrame.origin.y += cellFrame.size.height;
break;
case NSImageRight:
cellFrame.size.width = _titleWidth;
break;
case NSImageBelow:
cellFrame.size.height /= 2;
cellFrame.origin.y += cellFrame.size.height;
break;
case NSImageAbove:
cellFrame.size.height /= 2;
break;
case NSImageAbove:
cellFrame.size.height /= 2;
break;
}
}
else
{
// Calculate the image part of cell frame from NSMenuView
cellFrame.origin.x += [_menuView imageAndTitleOffset];
cellFrame.size.width = [_menuView imageAndTitleWidth];
switch (_cell.image_position)
{
case NSNoImage:
case NSImageOverlaps:
break;
case NSImageOnly:
cellFrame = NSZeroRect;
break;
case NSImageLeft:
cellFrame.origin.x += _imageWidth + GSCellTextImageXDist;
cellFrame.size.width = _titleWidth;
break;
case NSImageRight:
cellFrame.size.width = _titleWidth;
break;
case NSImageBelow:
cellFrame.size.height /= 2;
cellFrame.origin.y += cellFrame.size.height;
break;
case NSImageAbove:
cellFrame.size.height /= 2;
break;
}
}
return cellFrame;
}
@ -355,6 +440,9 @@ static NSImage *arrowImage = nil; /* Cache arrow image. */
- (void) drawBorderAndBackgroundWithFrame: (NSRect)cellFrame
inView: (NSView *)controlView
{
if (_horizontalMenu == YES)
return;
if (!_cell.is_bordered)
return;
@ -485,8 +573,35 @@ static NSImage *arrowImage = nil; /* Cache arrow image. */
- (void) drawTitleWithFrame:(NSRect)cellFrame
inView:(NSView *)controlView
{
[self _drawText: [_menuItem title]
inFrame: [self titleRectForBounds: cellFrame]];
if (_horizontalMenu == YES)
{
id value = [NSMutableParagraphStyle defaultParagraphStyle];
NSDictionary *attr;
NSRect cf = [self titleRectForBounds: cellFrame];
if (!_imageWidth)
[value setAlignment: NSCenterTextAlignment];
attr = [[NSDictionary alloc] initWithObjectsAndKeys:
value, NSParagraphStyleAttributeName,
_font, NSFontAttributeName,
[NSColor controlTextColor], NSForegroundColorAttributeName,
nil];
if ([_menuItem isEnabled])
_cell.is_disabled = NO;
else
_cell.is_disabled = YES;
[[_menuItem title] drawInRect: cf withAttributes: attr];
RELEASE(attr);
}
else
{
[self _drawText: [_menuItem title]
inFrame: [self titleRectForBounds: cellFrame]];
}
}
- (void) drawWithFrame: (NSRect)cellFrame inView: (NSView*)controlView
@ -517,87 +632,164 @@ static NSImage *arrowImage = nil; /* Cache arrow image. */
if (_buttoncell_is_transparent)
return;
cellFrame = [self drawingRectForBounds: cellFrame];
if (_cell.is_highlighted)
if (_horizontalMenu == YES)
{
mask = _highlightsByMask;
NSColor *backgroundColor = nil;
if (_cell.state)
mask &= ~_showAltStateMask;
}
else if (_cell.state)
mask = _showAltStateMask;
else
mask = NSNoCellMask;
cellFrame = [self drawingRectForBounds: cellFrame];
// pushed in buttons contents are displaced to the bottom right 1px
if (_cell.is_bordered && (mask & NSPushInCellMask))
{
cellFrame = NSOffsetRect(cellFrame, 1., [controlView isFlipped] ? 1. : -1.);
}
if (_cell.is_highlighted)
{
mask = _highlightsByMask;
/*
* Determine the background color and cache it in an ivar so that the
* low-level drawing methods don't need to do it again.
*/
if (mask & (NSChangeGrayCellMask | NSChangeBackgroundCellMask))
{
_backgroundColor = [NSColor selectedMenuItemColor];
}
if (_backgroundColor == nil)
_backgroundColor = [NSColor controlBackgroundColor];
if (_cell.state)
mask &= ~_showAltStateMask;
}
else if (_cell.state)
mask = _showAltStateMask;
else
mask = NSNoCellMask;
// Set cell's background color
[_backgroundColor set];
NSRectFill(cellFrame);
/*
* Determine the background color and cache it in an ivar so that the
* low-level drawing methods don't need to do it again.
*/
if (mask & (NSChangeGrayCellMask | NSChangeBackgroundCellMask))
{
backgroundColor = [NSColor selectedMenuItemColor];
}
if (backgroundColor == nil)
backgroundColor = [NSColor controlBackgroundColor];
/*
* Determine the image and the title that will be
* displayed. If the NSContentsCellMask is set the
* image and title are swapped only if state is 1 or
* if highlighting is set (when a button is pushed it's
* content is changed to the face of reversed state).
* The results are saved in two ivars for use in other
* drawing methods.
*/
if (mask & NSContentsCellMask)
{
_imageToDisplay = _altImage;
if (!_imageToDisplay)
_imageToDisplay = [_menuItem image];
_titleToDisplay = _altContents;
if (_titleToDisplay == nil || [_titleToDisplay isEqual: @""])
_titleToDisplay = [_menuItem title];
// Set cell's background color
[backgroundColor set];
NSRectFill(cellFrame);
if (mask & NSContentsCellMask)
{
_imageToDisplay = _altImage;
if (!_imageToDisplay)
_imageToDisplay = [_menuItem image];
_titleToDisplay = _altContents;
if (_titleToDisplay == nil || [_titleToDisplay isEqual: @""])
_titleToDisplay = [_menuItem title];
}
else
{
_imageToDisplay = [_menuItem image];
_titleToDisplay = [_menuItem title];
}
if (_imageToDisplay)
{
_imageWidth = [_imageToDisplay size].width;
[self setImagePosition: NSImageLeft];
}
// Draw the image
if (_imageWidth > 0)
[self drawImageWithFrame: cellFrame inView: controlView];
// Draw the title
if (_titleWidth > 0)
[self drawTitleWithFrame: cellFrame inView: controlView];
}
else
{
_imageToDisplay = [_menuItem image];
_titleToDisplay = [_menuItem title];
}
cellFrame = [self drawingRectForBounds: cellFrame];
if (_imageToDisplay)
if (_cell.is_highlighted)
{
mask = _highlightsByMask;
if (_cell.state)
mask &= ~_showAltStateMask;
}
else if (_cell.state)
mask = _showAltStateMask;
else
mask = NSNoCellMask;
// pushed in buttons contents are displaced to the bottom right 1px
if (_cell.is_bordered && (mask & NSPushInCellMask))
{
cellFrame = NSOffsetRect(cellFrame, 1., [controlView isFlipped] ? 1. : -1.);
}
/*
* Determine the background color and cache it in an ivar so that the
* low-level drawing methods don't need to do it again.
*/
if (mask & (NSChangeGrayCellMask | NSChangeBackgroundCellMask))
{
_backgroundColor = [NSColor selectedMenuItemColor];
}
if (_backgroundColor == nil)
_backgroundColor = [NSColor controlBackgroundColor];
// Set cell's background color
[_backgroundColor set];
NSRectFill(cellFrame);
/*
* Determine the image and the title that will be
* displayed. If the NSContentsCellMask is set the
* image and title are swapped only if state is 1 or
* if highlighting is set (when a button is pushed it's
* content is changed to the face of reversed state).
* The results are saved in two ivars for use in other
* drawing methods.
*/
if (mask & NSContentsCellMask)
{
_imageToDisplay = _altImage;
if (!_imageToDisplay)
_imageToDisplay = [_menuItem image];
_titleToDisplay = _altContents;
if (_titleToDisplay == nil || [_titleToDisplay isEqual: @""])
_titleToDisplay = [_menuItem title];
}
else
{
_imageToDisplay = [_menuItem image];
_titleToDisplay = [_menuItem title];
}
if (_imageToDisplay)
{
_imageWidth = [_imageToDisplay size].width;
}
// Draw the state image
if (_stateImageWidth > 0)
[self drawStateImageWithFrame: cellFrame inView: controlView];
// Draw the image
if (_imageWidth > 0)
[self drawImageWithFrame: cellFrame inView: controlView];
// Draw the title
if (_titleWidth > 0)
[self drawTitleWithFrame: cellFrame inView: controlView];
// Draw the key equivalent
if (_keyEquivalentWidth > 0)
[self drawKeyEquivalentWithFrame: cellFrame inView: controlView];
_backgroundColor = nil;
}
}
- (NSRect) drawingRectForBounds: (NSRect)theRect
{
if (_horizontalMenu == YES)
{
_imageWidth = [_imageToDisplay size].width;
return NSMakeRect (theRect.origin.x, theRect.origin.y + 2,
theRect.size.width, theRect.size.height - 2);
}
else
{
return [super drawingRectForBounds: theRect];
}
// Draw the state image
if (_stateImageWidth > 0)
[self drawStateImageWithFrame: cellFrame inView: controlView];
// Draw the image
if (_imageWidth > 0)
[self drawImageWithFrame: cellFrame inView: controlView];
// Draw the title
if (_titleWidth > 0)
[self drawTitleWithFrame: cellFrame inView: controlView];
// Draw the key equivalent
if (_keyEquivalentWidth > 0)
[self drawKeyEquivalentWithFrame: cellFrame inView: controlView];
_backgroundColor = nil;
}
//

View file

@ -42,6 +42,27 @@
#include "GNUstepGUI/GSTitleView.h"
#include <Foundation/Foundation.h>
typedef struct _GSCellRect {
NSRect rect;
} GSCellRect;
#define GSI_ARRAY_TYPES 0
#define GSI_ARRAY_TYPE GSCellRect
#define GSI_ARRAY_NO_RETAIN
#define GSI_ARRAY_NO_RELEASE
#ifdef GSIArray
#undef GSIArray
#endif
#include <GNUstepBase/GSIArray.h>
static NSMapTable *viewInfo = 0;
#define cellRects ((GSIArray)NSMapGet(viewInfo, self))
/*
NSMenuView contains:
@ -66,6 +87,16 @@ _addLeftBorderOffsetToRect(NSRect aRect)
/*
* Class methods.
*/
+ (void) initialize
{
if (viewInfo == 0)
{
viewInfo = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
NSNonOwnedPointerMapValueCallBacks, 20);
}
}
+ (float) menuBarHeight
{
static float height = 0.0;
@ -121,7 +152,7 @@ _addLeftBorderOffsetToRect(NSRect aRect)
return self;
}
- (id)initAsTearOff
- (id) initAsTearOff
{
[self initWithFrame: NSZeroRect];
@ -148,6 +179,20 @@ _addLeftBorderOffsetToRect(NSRect aRect)
RELEASE(_itemCells);
RELEASE(_font);
/*
* Get rid of any cached cell rects.
*/
{
GSIArray a = NSMapGet(viewInfo, self);
if (a != 0)
{
GSIArrayEmpty(a);
NSZoneFree(NSDefaultMallocZone(), a);
NSMapRemove(viewInfo, self);
}
}
[super dealloc];
}
@ -191,6 +236,24 @@ _addLeftBorderOffsetToRect(NSRect aRect)
[self update];
}
if (_horizontal)
{
unsigned count = [[[self menu] itemArray] count];
unsigned i;
for (i = 0; i < count; i++)
{
NSNumber *n = [NSNumber numberWithInt: i];
NSDictionary *d;
d = [NSDictionary dictionaryWithObject: n forKey: @"NSMenuItemIndex"];
[self itemAdded: [NSNotification
notificationWithName: NSMenuDidAddItemNotification
object: self
userInfo: d]];
}
}
}
- (NSMenu*) menu
@ -200,6 +263,25 @@ _addLeftBorderOffsetToRect(NSRect aRect)
- (void) setHorizontal: (BOOL)flag
{
if (flag == YES && _horizontal == NO)
{
GSIArray a = NSZoneMalloc(NSDefaultMallocZone(), sizeof(GSIArray_t));
GSIArrayInitWithZoneAndCapacity(a, NSDefaultMallocZone(), 8);
NSMapInsert(viewInfo, self, a);
}
else if (flag == NO && _horizontal == YES)
{
GSIArray a = NSMapGet(viewInfo, self);
if (a != 0)
{
GSIArrayEmpty(a);
NSZoneFree(NSDefaultMallocZone(), a);
NSMapRemove(viewInfo, self);
}
}
_horizontal = flag;
}
@ -346,6 +428,7 @@ _addLeftBorderOffsetToRect(NSRect aRect)
id aCell = [NSMenuItemCell new];
int wasHighlighted = _highlightedItemIndex;
// FIXME do we need to differentiate between popups and non popups
[aCell setMenuItem: anItem];
[aCell setMenuView: self];
[aCell setFont: _font];
@ -458,36 +541,44 @@ _addLeftBorderOffsetToRect(NSRect aRect)
*/
- (void) update
{
NSDebugLLog (@"NSMenu", @"update called on menu view");
if (![_attachedMenu _ownedByPopUp] && !_titleView)
if (NSInterfaceStyleForKey(@"NSMenuInterfaceStyle", self)
== NSMacintoshInterfaceStyle)
{
// Add title view. If this menu not owned by popup
_titleView = [[GSTitleView alloc] initWithOwner:_attachedMenu];
[self addSubview: _titleView];
RELEASE(_titleView);
}
else if ([_attachedMenu _ownedByPopUp] && _titleView)
{
// Remove title view if this menu owned by popup
[_titleView removeFromSuperview];
_titleView = nil;
}
// Resize it anyway.
[self sizeToFit];
// Just quit here if we are a popup.
if ([_attachedMenu _ownedByPopUp])
return;
if ([_attachedMenu isTornOff] && ![_attachedMenu isTransient])
{
[_titleView addCloseButtonWithAction:@selector(_performMenuClose:)];
[self sizeToFit];
}
else
{
[_titleView removeCloseButton];
NSDebugLLog (@"NSMenu", @"update called on menu view");
/*
* Ensure that a title view exists only if needed.
*/
if (![_attachedMenu _ownedByPopUp] && !_titleView)
{
_titleView = [[GSTitleView alloc] initWithOwner:_attachedMenu];
[self addSubview: _titleView];
RELEASE(_titleView);
}
else if ([_attachedMenu _ownedByPopUp] && _titleView)
{
[_titleView removeFromSuperview];
_titleView = nil;
}
[self sizeToFit];
if ([_attachedMenu _ownedByPopUp] == NO)
{
if ([_attachedMenu isTornOff] && ![_attachedMenu isTransient])
{
[_titleView
addCloseButtonWithAction: @selector(_performMenuClose:)];
}
else
{
[_titleView removeCloseButton];
}
}
}
}
@ -503,163 +594,214 @@ _addLeftBorderOffsetToRect(NSRect aRect)
- (void) sizeToFit
{
unsigned i;
unsigned howMany = [_itemCells count];
unsigned wideTitleView = 1;
float neededImageAndTitleWidth = 0.0;
float neededKeyEquivalentWidth = 0.0;
float neededStateImageWidth = 0.0;
float accumulatedOffset = 0.0;
float popupImageWidth = 0.0;
float menuBarHeight = 0.0;
// Popup menu doesn't need title bar
if (![_attachedMenu _ownedByPopUp] && _titleView)
if (_horizontal == YES)
{
menuBarHeight = [[self class] menuBarHeight];
neededImageAndTitleWidth = [_titleView titleSize].width;
unsigned i;
unsigned howMany = [_itemCells count];
float currentX = 8;
NSRect scRect = [[NSScreen mainScreen] frame];
GSIArrayRemoveAllItems(cellRects);
scRect.size.height = [NSMenuView menuBarHeight];
[self setFrameSize: scRect.size];
_cellSize.height = scRect.size.height;
for (i = 0; i < howMany; i++)
{
GSCellRect elem;
NSMenuItemCell *aCell = [_itemCells objectAtIndex: i];
float titleWidth = [aCell titleWidth];
if ([aCell imageWidth])
{
titleWidth += [aCell imageWidth] + GSCellTextImageXDist;
}
elem.rect = NSMakeRect (currentX,
0,
(titleWidth + (2 * _horizontalEdgePad)),
_cellSize.height);
GSIArrayAddItem(cellRects, (GSIArrayItem)elem);
currentX += titleWidth + (2 * _horizontalEdgePad);
}
}
else
{
menuBarHeight += _leftBorderOffset;
}
for (i = 0; i < howMany; i++)
{
float aStateImageWidth;
float aTitleWidth;
float anImageWidth;
float anImageAndTitleWidth;
float aKeyEquivalentWidth;
NSMenuItemCell *aCell = [_itemCells objectAtIndex: i];
// State image area.
aStateImageWidth = [aCell stateImageWidth];
// Title and Image area.
aTitleWidth = [aCell titleWidth];
anImageWidth = [aCell imageWidth];
// Key equivalent area.
aKeyEquivalentWidth = [aCell keyEquivalentWidth];
switch ([aCell imagePosition])
{
case NSNoImage:
anImageAndTitleWidth = aTitleWidth;
break;
case NSImageOnly:
anImageAndTitleWidth = anImageWidth;
break;
case NSImageLeft:
case NSImageRight:
anImageAndTitleWidth = anImageWidth + aTitleWidth + GSCellTextImageXDist;
break;
case NSImageBelow:
case NSImageAbove:
case NSImageOverlaps:
default:
if (aTitleWidth > anImageWidth)
anImageAndTitleWidth = aTitleWidth;
else
anImageAndTitleWidth = anImageWidth;
break;
}
if (aStateImageWidth > neededStateImageWidth)
neededStateImageWidth = aStateImageWidth;
if (anImageAndTitleWidth > neededImageAndTitleWidth)
neededImageAndTitleWidth = anImageAndTitleWidth;
if (aKeyEquivalentWidth > neededKeyEquivalentWidth)
neededKeyEquivalentWidth = aKeyEquivalentWidth;
// Title view width less than item's left part width
if ((anImageAndTitleWidth + aStateImageWidth)
> neededImageAndTitleWidth)
wideTitleView = 0;
// Popup menu has only one item with nibble or arrow image
if (anImageWidth)
popupImageWidth = anImageWidth;
}
// Cache the needed widths.
_stateImageWidth = neededStateImageWidth;
_imageAndTitleWidth = neededImageAndTitleWidth;
_keyEqWidth = neededKeyEquivalentWidth;
accumulatedOffset = _horizontalEdgePad;
if (howMany)
{
// Calculate the offsets and cache them.
if (neededStateImageWidth)
{
_stateImageOffset = accumulatedOffset;
accumulatedOffset += neededStateImageWidth += _horizontalEdgePad;
}
if (neededImageAndTitleWidth)
{
_imageAndTitleOffset = accumulatedOffset;
accumulatedOffset += neededImageAndTitleWidth;
}
if (wideTitleView)
{
_keyEqOffset = accumulatedOffset = neededImageAndTitleWidth
+ (3 * _horizontalEdgePad);
}
unsigned i;
unsigned howMany = [_itemCells count];
unsigned wideTitleView = 1;
float neededImageAndTitleWidth = 0.0;
float neededKeyEquivalentWidth = 0.0;
float neededStateImageWidth = 0.0;
float accumulatedOffset = 0.0;
float popupImageWidth = 0.0;
float menuBarHeight = 0.0;
// Popup menu doesn't need title bar
if (![_attachedMenu _ownedByPopUp] && _titleView)
{
if ([_attachedMenu supermenu] != nil)
{
NSMenuItemCell *msr;
msr = [[[_attachedMenu supermenu] menuRepresentation]
menuItemCellForItemAtIndex:
[[_attachedMenu supermenu] indexOfItemWithTitle:
[_attachedMenu title]]];
neededImageAndTitleWidth
+= [msr titleWidth] + GSCellTextImageXDist;
}
if (_titleView)
menuBarHeight = [[self class] menuBarHeight];
else
menuBarHeight += 3; // 2 on bottom, 1 on top
}
else
{
_keyEqOffset = accumulatedOffset += (2 * _horizontalEdgePad);
}
accumulatedOffset += neededKeyEquivalentWidth + _horizontalEdgePad;
{
menuBarHeight += _leftBorderOffset;
}
if ([_attachedMenu supermenu] != nil && neededKeyEquivalentWidth < 8)
{
accumulatedOffset += 8 - neededKeyEquivalentWidth;
}
}
else
{
accumulatedOffset += neededImageAndTitleWidth + 3 + 2;
if ([_attachedMenu supermenu] != nil)
accumulatedOffset += 15;
}
// Calculate frame size.
if (![_attachedMenu _ownedByPopUp])
{
// Add the border width: 1 for left, 2 for right sides
_cellSize.width = accumulatedOffset + 3;
}
else
{
_keyEqOffset = _cellSize.width - _keyEqWidth - popupImageWidth;
}
for (i = 0; i < howMany; i++)
{
float aStateImageWidth;
float aTitleWidth;
float anImageWidth;
float anImageAndTitleWidth;
float aKeyEquivalentWidth;
NSMenuItemCell *aCell = [_itemCells objectAtIndex: i];
// State image area.
aStateImageWidth = [aCell stateImageWidth];
// Title and Image area.
aTitleWidth = [aCell titleWidth];
anImageWidth = [aCell imageWidth];
// Key equivalent area.
aKeyEquivalentWidth = [aCell keyEquivalentWidth];
switch ([aCell imagePosition])
{
case NSNoImage:
anImageAndTitleWidth = aTitleWidth;
break;
case NSImageOnly:
anImageAndTitleWidth = anImageWidth;
break;
case NSImageLeft:
case NSImageRight:
anImageAndTitleWidth
= anImageWidth + aTitleWidth + GSCellTextImageXDist;
break;
case NSImageBelow:
case NSImageAbove:
case NSImageOverlaps:
default:
if (aTitleWidth > anImageWidth)
anImageAndTitleWidth = aTitleWidth;
else
anImageAndTitleWidth = anImageWidth;
break;
}
if (aStateImageWidth > neededStateImageWidth)
neededStateImageWidth = aStateImageWidth;
if (anImageAndTitleWidth > neededImageAndTitleWidth)
neededImageAndTitleWidth = anImageAndTitleWidth;
if (aKeyEquivalentWidth > neededKeyEquivalentWidth)
neededKeyEquivalentWidth = aKeyEquivalentWidth;
// Title view width less than item's left part width
if ((anImageAndTitleWidth + aStateImageWidth)
> neededImageAndTitleWidth)
wideTitleView = 0;
// Popup menu has only one item with nibble or arrow image
if (anImageWidth)
popupImageWidth = anImageWidth;
}
// Cache the needed widths.
_stateImageWidth = neededStateImageWidth;
_imageAndTitleWidth = neededImageAndTitleWidth;
_keyEqWidth = neededKeyEquivalentWidth;
accumulatedOffset = _horizontalEdgePad;
if (howMany)
{
// Calculate the offsets and cache them.
if (neededStateImageWidth)
{
_stateImageOffset = accumulatedOffset;
accumulatedOffset += neededStateImageWidth += _horizontalEdgePad;
}
if (neededImageAndTitleWidth)
{
_imageAndTitleOffset = accumulatedOffset;
accumulatedOffset += neededImageAndTitleWidth;
}
if (wideTitleView)
{
_keyEqOffset = accumulatedOffset = neededImageAndTitleWidth
+ (3 * _horizontalEdgePad);
}
else
{
_keyEqOffset = accumulatedOffset += (2 * _horizontalEdgePad);
}
accumulatedOffset += neededKeyEquivalentWidth + _horizontalEdgePad;
if ([_attachedMenu supermenu] != nil && neededKeyEquivalentWidth < 8)
{
accumulatedOffset += 8 - neededKeyEquivalentWidth;
}
}
else
{
accumulatedOffset += neededImageAndTitleWidth + 3 + 2;
if ([_attachedMenu supermenu] != nil)
accumulatedOffset += 15;
}
// Calculate frame size.
if (![_attachedMenu _ownedByPopUp])
{
// Add the border width: 1 for left, 2 for right sides
_cellSize.width = accumulatedOffset + 3;
}
else
{
_keyEqOffset = _cellSize.width - _keyEqWidth - popupImageWidth;
}
if (_horizontal == NO)
{
[self setFrameSize: NSMakeSize(_cellSize.width + _leftBorderOffset,
(howMany * _cellSize.height)
+ menuBarHeight)];
[_titleView setFrame: NSMakeRect (0, howMany * _cellSize.height,
NSWidth (_bounds), menuBarHeight)];
if (_horizontal == NO)
{
[self setFrameSize: NSMakeSize(_cellSize.width + _leftBorderOffset,
(howMany * _cellSize.height)
+ menuBarHeight)];
[_titleView setFrame: NSMakeRect (0, howMany * _cellSize.height,
NSWidth (_bounds), menuBarHeight)];
}
else
{
[self setFrameSize: NSMakeSize(((howMany + 1) * _cellSize.width),
_cellSize.height + _leftBorderOffset)];
[_titleView setFrame: NSMakeRect (0, 0,
_cellSize.width, _cellSize.height + 1)];
}
_needsSizing = NO;
}
else
{
[self setFrameSize: NSMakeSize(((howMany + 1) * _cellSize.width),
_cellSize.height + _leftBorderOffset)];
[_titleView setFrame: NSMakeRect (0, 0,
_cellSize.width, _cellSize.height + 1)];
}
_needsSizing = NO;
}
- (float) stateImageOffset
@ -730,33 +872,62 @@ _addLeftBorderOffsetToRect(NSRect aRect)
- (NSRect) rectOfItemAtIndex: (int)index
{
NSRect theRect;
if (_needsSizing == YES)
if (_horizontal == YES)
{
[self sizeToFit];
}
GSCellRect aRect;
/* Fiddle with the origin so that the item rect is shifted 1 pixel over
* so we do not draw on the heavy line at origin.x = 0.
*/
if (_horizontal == NO)
{
theRect.origin.y = _cellSize.height * ([_itemCells count] - index - 1);
theRect.origin.x = _leftBorderOffset;
if (_needsSizing == YES)
{
[self sizeToFit];
}
aRect = GSIArrayItemAtIndex(cellRects, index).ext;
/* FIXME: handle vertical case? */
return aRect.rect;
}
else
{
theRect.origin.x = _cellSize.width * (index + 1);
theRect.origin.y = 0;
}
theRect.size = _cellSize;
NSRect theRect;
/* NOTE: This returns the correct NSRect for drawing cells, but nothing
* else (unless we are a popup). This rect will have to be modified for
* event calculation, etc..
*/
return theRect;
if (_needsSizing == YES)
{
[self sizeToFit];
}
/* Fiddle with the origin so that the item rect is shifted 1 pixel over
* so we do not draw on the heavy line at origin.x = 0.
*/
if (_horizontal == NO)
{
if (![_attachedMenu _ownedByPopUp])
{
theRect.origin.y
= 2 + (_cellSize.height * ([_itemCells count] - index - 1));
theRect.origin.x = 1;
theRect.size.width -= 2;
}
else
{
theRect.origin.y
= _cellSize.height * ([_itemCells count] - index - 1);
theRect.origin.x = _leftBorderOffset;
}
}
else
{
theRect.origin.x = _cellSize.width * (index + 1);
theRect.origin.y = 0;
}
theRect.size = _cellSize;
/* NOTE: This returns the correct NSRect for drawing cells, but nothing
* else (unless we are a popup). This rect will have to be modified for
* event calculation, etc..
*/
return theRect;
}
}
- (int) indexOfItemAtPoint: (NSPoint)point
@ -811,13 +982,13 @@ _addLeftBorderOffsetToRect(NSRect aRect)
NSMakePoint(aRect.origin.x, aRect.origin.y)];
return NSMakePoint (NSMaxX(frame),
subOrigin.y - NSHeight(submenuFrame) - 3 +
2*[NSMenuView menuBarHeight]);
subOrigin.y - NSHeight(submenuFrame) - 3 +
2*[NSMenuView menuBarHeight]);
}
else
{
return NSMakePoint(NSMaxX(frame),
NSMaxY(frame) - NSHeight(submenuFrame));
NSMaxY(frame) - NSHeight(submenuFrame));
}
}
else
@ -915,11 +1086,29 @@ _addLeftBorderOffsetToRect(NSRect aRect)
{
int i;
int howMany = [_itemCells count];
NSRectEdge sides[] = {NSMinXEdge, NSMaxYEdge};
NSRectEdge sides[2];
float grays[] = {NSDarkGray, NSDarkGray};
// Draw the dark gray upper left lines.
NSDrawTiledRects(rect, rect, sides, grays, 2);
if (_horizontal == YES)
{
sides[0] = NSMinYEdge;
sides[1] = NSMinYEdge;
NSDrawTiledRects(_bounds, rect, sides, grays, 2);
}
else
{
if (![_attachedMenu _ownedByPopUp])
{
NSDrawButton (_bounds, rect);
}
else
{
sides[0] = NSMinXEdge;
sides[1] = NSMaxYEdge;
// Draw the dark gray upper left lines.
NSDrawTiledRects(_bounds, rect, sides, grays, 2);
}
}
// Draw the menu cells.
for (i = 0; i < howMany; i++)
@ -1117,6 +1306,8 @@ _addLeftBorderOffsetToRect(NSRect aRect)
&& NSMouseInRect (locationInScreenCoordinates,
[[candidateMenu window] frame], NO))
{
BOOL candidateMenuResult;
// The call to fetch attachedMenu is not needed. But putting
// it here avoids flicker when we go back to an ancestor
// menu and the attached menu is already correct.
@ -1129,8 +1320,9 @@ _addLeftBorderOffsetToRect(NSRect aRect)
[[[candidateMenu attachedMenu] menuRepresentation]
setHighlightedItemIndex: -1];
return [[candidateMenu menuRepresentation]
candidateMenuResult = [[candidateMenu menuRepresentation]
trackWithEvent: original];
return candidateMenuResult;
}
// 3b - Check if we enter the attached submenu
@ -1144,7 +1336,8 @@ _addLeftBorderOffsetToRect(NSRect aRect)
subMenuResult
= [[self attachedMenuView] trackWithEvent: original];
if (subMenuResult && wasTransient == [_attachedMenu isTransient])
if (subMenuResult
&& wasTransient == [_attachedMenu isTransient])
{
[self detachSubmenu];
}
@ -1223,8 +1416,7 @@ _addLeftBorderOffsetToRect(NSRect aRect)
currentMenu = [currentMenu attachedMenu];
}
while ([currentMenu isTransient] &&
[currentMenu supermenu])
while ([currentMenu isTransient] && [currentMenu supermenu])
{
currentMenu = [currentMenu supermenu];
}
@ -1244,9 +1436,19 @@ _addLeftBorderOffsetToRect(NSRect aRect)
}
if (indexOfActionToExecute >= 0
&& [_attachedMenu attachedMenu] != nil && [_attachedMenu attachedMenu] ==
[[_items_link objectAtIndex: indexOfActionToExecute] submenu])
&& [_attachedMenu attachedMenu] != nil && [_attachedMenu attachedMenu] ==
[[_items_link objectAtIndex: indexOfActionToExecute] submenu])
{
if (NSInterfaceStyleForKey(@"NSMenuInterfaceStyle", nil)
== NSMacintoshInterfaceStyle)
{
/*
* FIXME ... always remove submenus in mac mode ... this is not
* quite the way the mac behaves, but it's closer than the normal
* behavior.
*/
subMenusNeedRemoving = YES;
}
if (subMenusNeedRemoving)
{
[self detachSubmenu];
@ -1255,6 +1457,22 @@ _addLeftBorderOffsetToRect(NSRect aRect)
return NO;
}
if (NSInterfaceStyleForKey(@"NSMenuInterfaceStyle", nil)
== NSMacintoshInterfaceStyle)
{
NSMenu *tmp = _attachedMenu;
do
{
if ([tmp isEqual: [NSApp mainMenu]] == NO)
{
[tmp close];
}
tmp = [tmp supermenu];
}
while (tmp != nil);
}
[_attachedMenu performActionForItemAtIndex: indexOfActionToExecute];
/*