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

@ -1,3 +1,18 @@
2006-02-04 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSMenu.m:
* Source/NSApplication.m:
* Source/NSMenuItemCell.m:
* Source/NSMenuView.m:
* Headers/AppKit/NSMenuView.h:
* Headers/AppKit/NSMenu.h:
* Headers/AppKit/NSMenuItemCell.h:
Add support for horizontal main menu (as in MacOS-X) very heavily
based on the WildMenus bundle by Michael Hanni, but any errors in
the integration are entirely mine.
Horizontal menus are activated by setting the 'NSMenuInterfaceStyle'
user default to 'NSMacintoshInterfaceStyle'.
2006-02-03 Quentin Mathe <qmathe@club-internet.fr>
* Source/NSToolbarItem.m (-[GSToolbarButtonCell setImagePosition:]):

View file

@ -381,6 +381,8 @@ The displayed menus on the screen have the following structure:
// GNUstepExtra category
NSPopUpButtonCell *_popUpButtonCell;
BOOL _transient;
BOOL _horizontal;
char _pad1[2];
@private
NSWindow *_aWindow;

View file

@ -42,6 +42,9 @@ typedef void (*DrawingIMP)(id, SEL, NSRect, NSView*);
// Cache
BOOL _needs_sizing;
BOOL _horizontalMenu;
char _pad1[2];
float _imageWidth;
float _titleWidth;
float _keyEquivalentWidth;
@ -55,6 +58,7 @@ typedef void (*DrawingIMP)(id, SEL, NSRect, NSView*);
/* If we belong to a popupbutton, we display image on the extreme
right */
BOOL _mcell_belongs_to_popupbutton;
char _pad2[3];
@private
NSColor *_backgroundColor;

View file

@ -80,6 +80,7 @@
{
NSMutableArray *_itemCells;
BOOL _horizontal;
char _pad1[3];
NSFont *_font;
int _highlightedItemIndex;
float _horizontalEdgePad;
@ -90,6 +91,7 @@
float _keyEqOffset;
float _keyEqWidth;
BOOL _needsSizing;
char _pad2[3];
NSSize _cellSize;
@private

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];
/*