mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-23 07:00:46 +00:00
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:
parent
24af0ec222
commit
3d2503f2e3
8 changed files with 1036 additions and 422 deletions
15
ChangeLog
15
ChangeLog
|
@ -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:]):
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
320
Source/NSMenu.m
320
Source/NSMenu.m
|
@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -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];
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue