Almost total reimplementation of the menuing code.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@5207 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
David Lazaro Saz 1999-11-16 22:25:07 +00:00
parent 021c583cd3
commit 198c3258a1
11 changed files with 2207 additions and 1245 deletions

View file

@ -44,8 +44,12 @@
@class NSMatrix;
@class NSMenuView;
@class NSMenuWindow;
@class NSPopUpButton;
@interface NSMenuWindow : NSPanel
- (void)moveToPoint:(NSPoint)aPoint;
@end
@interface NSMenu : NSObject <NSCoding, NSCopying>
@ -54,19 +58,20 @@
NSMutableArray *menu_items;
NSMenuView *menu_view;
NSMenu *menu_supermenu;
NSMenu *menu_attached_menu;
id menu_rep;
BOOL menu_ChangedMessagesEnabled;
NSMenu *menu_attachedMenu;
BOOL menu_changedMessagesEnabled;
NSMutableArray *menu_notifications;
BOOL menu_autoenable;
BOOL menu_changed;
BOOL menu_is_tornoff;
id menu_popb;
// Private.
// GNUstepExtra category
BOOL menu_is_beholdenToPopUpButton;
BOOL menu_follow_transient;
BOOL menu_is_visible;
BOOL menu_isPartlyOffScreen;
// Reserved for back-end use
void *be_menu_reserved;
@ -75,35 +80,40 @@
NSMenuWindow *aWindow;
NSMenuWindow *bWindow;
id titleView;
NSMenu *_oldAttachedMenu;
}
/* Controlling allocation zones */
+ (void)setMenuZone:(NSZone*)zone;
+ (NSZone*)menuZone;
/* Controlling Allocation Zones */
+ (void) setMenuZone: (NSZone*)zone;
+ (NSZone*) menuZone;
/* Setting the menu cell class */
+ (void)setCellClass:(Class)aClass;
+ (Class)cellClass;
/* Creating an NSMenu */
- (id) initWithTitle: (NSString*)aTitle;
- (id) initWithPopUpButton: (NSPopUpButton*)popb;
/* Initializing a new NSMenu */
- (id)initWithTitle:(NSString*)aTitle;
/* Setting up the menu commands */
/* Setting Up the Menu Commands */
- (void) addItem: (id <NSMenuItem>)newItem;
- (id <NSMenuItem>) addItemWithTitle: (NSString *)aString
action: (SEL)aSelector
keyEquivalent: (NSString *)keyEquiv;
- (void) insertItem: (id <NSMenuItem>)newItem
atIndex: (int)index;
- (id <NSMenuItem>) insertItemWithTitle: (NSString *)aString
action: (SEL)aSelector
keyEquivalent: (NSString *)charCode
atIndex: (unsigned int)index;
- (void) addItem: (id <NSMenuItem>)newItem;
- (id <NSMenuItem>) addItemWithTitle: (NSString *)aString
action: (SEL)aSelector
keyEquivalent: (NSString *)keyEquiv;
- (void) itemChanged: (id <NSMenuItem>)anObject;
- (void) removeItem: (id <NSMenuItem>)anItem;
- (void) removeItemAtIndex: (int)index;
- (NSArray*)itemArray;
/* Finding menu items */
- (NSArray*) itemArray;
- (id <NSMenuItem>) itemAtIndex: (int)index;
- (id <NSMenuItem>) itemWithTag: (int)aTag;
- (id <NSMenuItem>) itemWithTitle: (NSString*)aString;
- (int) numberOfItems;
/* Finding Indices of Menu Items */
- (int) indexOfItem: (id <NSMenuItem>)anObject;
- (int) indexOfItemWithTitle: (NSString *)aTitle;
- (int) indexOfItemWithTag: (int)aTag;
@ -112,79 +122,90 @@
- (int) indexOfItemWithRepresentedObject: (id)anObject;
- (int) indexOfItemWithSubmenu: (NSMenu *)anObject;
/* Finding menu items */
- (id <NSMenuItem>)itemWithTag:(int)aTag;
- (id <NSMenuItem>)itemWithTitle:(NSString*)aString;
/* Managing submenus */
- (void)setSubmenu:(NSMenu*)aMenu forItem:(id <NSMenuItem>)anItem;
- (void)submenuAction:(id)sender;
- (NSMenu*)attachedMenu;
- (BOOL)isAttached;
- (BOOL)isTornOff;
- (NSPoint)locationForSubmenu:(NSMenu*)aSubmenu;
- (NSMenu*)supermenu;
- (void) setSubmenu: (NSMenu*)aMenu forItem: (id <NSMenuItem>)anItem;
- (void) submenuAction: (id)sender;
- (NSMenu*) attachedMenu;
- (BOOL) isAttached;
- (BOOL) isTornOff;
- (NSPoint) locationForSubmenu:(NSMenu*)aSubmenu;
- (NSMenu*) supermenu;
- (void) setSupermenu: (NSMenu *)supermenu;
/* Enabling and disabling menu items */
- (void)setAutoenablesItems:(BOOL)flag;
- (BOOL)autoenablesItems;
- (void)update;
/* Perform a menu item action (not an OpenStep method) */
- (void)performActionForItem:(id <NSMenuItem>)anItem;
- (BOOL) autoenablesItems;
- (void) setAutoenablesItems: (BOOL)flag;
- (void) update;
/* Handling keyboard equivalents */
- (BOOL)performKeyEquivalent:(NSEvent*)theEvent;
- (BOOL) performKeyEquivalent: (NSEvent*)theEvent;
/* Updating menu layout */
- (void)setMenuChangedMessagesEnabled:(BOOL)flag;
- (BOOL)menuChangedMessagesEnabled;
- (void)sizeToFit;
/* Simulating Mouse Clicks */
- (void) performActionForItemAtIndex: (int)index;
/* Getting and setting the menu title */
- (void)setTitle:(NSString*)aTitle;
- (NSString*)title;
/* Setting the Title */
- (void) setTitle: (NSString*)aTitle;
- (NSString*) title;
/* Getting the menu cells matrix */
- (NSMenuView *)menuView;
/* Setting the representing object */
- (void) setMenuRepresentation: (id)menuRep;
- (id) menuRepresentation;
// non OS spec methods
- (void)_rightMouseDisplay;
/* Updating Menu Layout */
- (void) setMenuChangedMessagesEnabled: (BOOL)flag;
- (BOOL) menuChangedMessagesEnabled;
- (void) sizeToFit;
/* Displaying Context-Sensitive Help */
- (void) helpRequested: (NSEvent*)event;
@end
@interface NSObject (NSMenuActionResponder)
- (BOOL)validateMenuItem:(NSMenuItem*)aMenuItem;
@end
@interface NSMenu (PrivateMethods)
- (BOOL) isFollowTransient;
@interface NSMenu (GNUstepExtra)
- (BOOL)isFollowTransient;
- (NSWindow *)window;
/* Shows the menu window on screen */
- (void)display;
- (void)displayTransient;
/* Close the associated window menu */
- (void)close;
- (void)closeTransient;
/* Moving menus */
- (void)nestedSetFrameOrigin:(NSPoint)aPoint;
/* Shift partly off-screen menus */
- (BOOL)isPartlyOffScreen;
- (void)nestedCheckOffScreen;
- (void)shiftOnScreen;
@end
/* A menu's title is an instance of this class */
@interface NSMenuWindowTitleView : NSView
{
// a menu's title
int titleHeight;
// is an instance
id menu;
// of this class
NSButton* button;
NSButtonCell* buttonCell;
int titleHeight;
id menu;
NSButton* button;
NSButtonCell* buttonCell;
}
- (void) _addCloseButton;
- (void) _releaseCloseButton;
- (void) windowBecomeTornOff;
- (void) setMenu: (NSMenu*)menu;
- (NSMenu*) menu;
@end
extern NSString* const NSMenuDidSendActionNotification;

View file

@ -5,6 +5,9 @@
Copyright (C) 1996 Free Software Foundation, Inc.
Author: David Lazaro Saz <khelekir@encomix.es>
Date: Sep 1999
Author: Ovidiu Predescu <ovidiu@net-community.com>
Date: May 1997
@ -33,60 +36,157 @@
@protocol NSMenuItem <NSCopying, NSCoding>
- (void)setTarget:(id)anObject;
- (id)target;
- (void)setAction:(SEL)aSelector;
- (SEL)action;
+ (void)setUsesUserKeyEquivalents:(BOOL)flag;
+ (BOOL)usesUserKeyEquivalents;
+ (id <NSMenuItem>)separatorItem;
- (id)initWithTitle:(NSString *)aString
action:(SEL)aSelector
keyEquivalent:(NSString *)charCode;
- (void)setMenu:(NSMenu *)menu;
- (NSMenu *)menu;
- (BOOL)hasSubmenu;
- (void)setSubmenu:(NSMenu *)submenu;
- (NSMenu *)submenu;
- (void)setTitle:(NSString*)aString;
- (NSString*)title;
- (void)setTag:(int)anInt;
- (int)tag;
- (void)setEnabled:(BOOL)flag;
- (BOOL)isEnabled;
- (BOOL)hasSubmenu;
- (BOOL)isSeparatorItem;
- (void)setKeyEquivalent:(NSString*)aKeyEquivalent;
- (NSString*)keyEquivalent;
- (void)setKeyEquivalentModifierMask:(unsigned int)mask;
- (unsigned int)keyEquivalentModifierMask;
+ (void)setUsesUserKeyEquivalents:(BOOL)flag;
+ (BOOL)usesUserKeyEquivalents;
- (NSString*)userKeyEquivalent;
- (void)setMnemonicLocation:(unsigned) location;
- (unsigned)mnemonicLocation;
- (NSString *)mnemonic;
- (void)setTitleWithMnemonic:(NSString *)stringWithAmpersand;
- (void)setImage:(NSImage *)menuImage;
- (NSImage *)image;
- (void)setState:(int)state;
- (int)state;
- (void)setOnStateImage:(NSImage *)image;
- (NSImage *)onStateImage;
- (void)setOffStateImage:(NSImage *)image;
- (NSImage *)offStateImage;
- (void)setMixedStateImage:(NSImage *)image;
- (NSImage *)mixedStateImage;
- (void)setEnabled:(BOOL)flag;
- (BOOL)isEnabled;
- (void)setTarget:(id)anObject;
- (id)target;
- (void)setAction:(SEL)aSelector;
- (SEL)action;
- (void)setTag:(int)anInt;
- (int)tag;
- (void)setRepresentedObject:(id)anObject;
- (id)representedObject;
@end
@interface NSMenuItem : NSButtonCell <NSMenuItem>
@interface NSMenuItem : NSObject <NSMenuItem>
{
id representedObject;
BOOL hasSubmenu;
NSMenu *mi_menu;
NSString *mi_title;
NSString *mi_keyEquivalent;
unsigned int mi_keyEquivalentModifierMask;
unsigned mi_mnemonicLocation;
int mi_state;
BOOL mi_enabled;
NSImage *mi_image;
NSImage *mi_onStateImage;
NSImage *mi_offStateImage;
NSImage *mi_mixedStateImage;
id mi_target;
SEL mi_action;
int mi_tag;
id mi_representedObject;
BOOL mi_hasSubmenu;
NSMenu *mi_submenu;
BOOL mi_changesState;
// Reserved for back-end use
void *be_mi_reserved;
}
- (void)setTitle:(NSString*)aString;
- (NSString*)title;
- (BOOL)hasSubmenu;
+ (void)setUsesUserKeyEquivalents:(BOOL)flag;
+ (BOOL)usesUserKeyEquivalents;
- (NSString*)userKeyEquivalent;
+ (id <NSMenuItem>)separatorItem;
- (id)initWithTitle:(NSString *)aString
action:(SEL)aSelector
keyEquivalent:(NSString *)charCode;
- (void)setMenu:(NSMenu *)menu;
- (NSMenu *)menu;
- (BOOL)hasSubmenu;
- (void)setSubmenu:(NSMenu *)submenu;
- (NSMenu *)submenu;
- (void)setTitle:(NSString *)aString;
- (NSString *)title;
- (BOOL)isSeparatorItem;
- (void)setKeyEquivalent:(NSString *)aKeyEquivalent;
- (NSString *)keyEquivalent;
- (void)setKeyEquivalentModifierMask:(unsigned int)mask;
- (unsigned int)keyEquivalentModifierMask;
- (NSString *)userKeyEquivalent;
- (void)setMnemonicLocation:(unsigned) location;
- (unsigned)mnemonicLocation;
- (NSString *)mnemonic;
- (void)setTitleWithMnemonic:(NSString *)stringWithAmpersand;
- (void)setImage:(NSImage *)menuImage;
- (NSImage *)image;
- (void)setState:(int)state;
- (int)state;
- (void)setOnStateImage:(NSImage *)image;
- (NSImage *)onStateImage;
- (void)setOffStateImage:(NSImage *)image;
- (NSImage *)offStateImage;
- (void)setMixedStateImage:(NSImage *)image;
- (NSImage *)mixedStateImage;
- (void)setEnabled:(BOOL)flag;
- (BOOL)isEnabled;
- (void)setTarget:(id)anObject;
- (id)target;
- (void)setAction:(SEL)aSelector;
- (SEL)action;
- (void)setTag:(int)anInt;
- (int)tag;
- (void)setRepresentedObject:(id)anObject;
- (id)representedObject;
@end
@interface NSMenuItem (GNUstepExtra)
- (void)setChangesState:(BOOL)flag;
- (BOOL)changesState;
@end
/* Private stuff; it should be in a private header file but it really doesn't
worth the effort. */

View file

@ -31,46 +31,45 @@
#include <AppKit/NSButtonCell.h>
#include <AppKit/NSMenuItem.h>
@interface NSMenuItemCell : NSButtonCell <NSMenuItem>
@class NSMenuView;
typedef void (*DrawingIMP)(id, SEL, NSRect, NSView*);
@interface NSMenuItemCell : NSButtonCell <NSCopying, NSCoding>
{
id representedObject;
BOOL mcell_highlighted;
BOOL mcell_has_submenu;
// Not used is GS.
NSMenuItem *mcell_item;
NSMenuView *mcell_menuView;
// Cache
BOOL mcell_needs_sizing;
float mcell_imageWidth;
float mcell_titleWidth;
float mcell_keyEqWidth;
float mcell_stateImgWidth;
float mcell_keyEquivalentWidth;
float mcell_stateImageWidth;
float mcell_menuItemHeight;
NSImage *mcell_imageToDisplay;
NSString *mcell_titleToDisplay;
NSSize mcell_imageSize;
@private
DrawingIMP _drawMethods[4];
}
// NSMenuItem Protocol demands these:
- (void)setTarget:(id)anObject;
- (void)setTitle:(NSString*)aString;
- (NSString*)title;
- (NSString*)keyEquivalent;
- (NSString*)userKeyEquivalent;
- (void)setRepresentedObject:(id)anObject;
- (id)representedObject;
// NSMenuItemCell from MacOSX API.
- (void)setHighlighted:(BOOL)flag;
- (BOOL)isHighlighted;
// These NSMenuItem calls are deprecated in GS. You should not use them
// under any circumstance (i.e. they don't do anything.)
- (void)highlight:(BOOL)flag
withFrame:(NSRect)cellFrame
inView:(NSView*)controlView;
- (void)setMenuItem:(NSMenuItem *)item;
- (NSMenuItem *)menuItem;
- (void)setMenuView:(NSMenuView *)menuView;
- (NSMenuView *)menuView;
- (void)calcSize;
- (void)setNeedsSizing:(BOOL)flag;
- (BOOL)needsSizing;

View file

@ -35,23 +35,24 @@
#include <Foundation/NSNotification.h>
#include <AppKit/NSMenu.h>
#include <AppKit/NSMenuItem.h>
#include <AppKit/NSMenuItemCell.h>
#include <AppKit/NSScreen.h>
#include <AppKit/NSView.h>
#include <AppKit/NSWindow.h>
@class NSColor;
@class NSPopUpButton;
@class NSFont;
@interface NSMenuView : NSView
@interface NSMenuView : NSView <NSCoding>
{
NSMenu *menuv_menu;
NSMutableArray *menuv_itemCells;
BOOL menuv_horizontal;
NSFont *menuv_font;
int menuv_highlightedItemIndex;
BOOL menuv_isAttached;
BOOL menuv_isTornOff;
float menuv_hEdgePad;
float menuv_horizontalEdgePad;
float menuv_stateImageOffset;
float menuv_stateImageWidth;
float menuv_imageAndTitleOffset;
@ -60,11 +61,12 @@
float menuv_keyEqWidth;
BOOL menuv_needsSizing;
NSSize cellSize;
float i_titleWidth;
@private
id menuv_popb;
id menuv_items_link;
BOOL menuv_keepAttachedMenus;
int _oldHighlightedItemIndex;
}
+ (float)menuBarHeight;
- (void)setMenu:(NSMenu *)menu;

View file

@ -44,9 +44,11 @@ common_ArrowUpH.tiff \
common_ArrowRightH.tiff \
common_3DArrowRightH.tiff \
common_ArrowLeftH.tiff \
common_2DCheckMark.tiff \
common_Close.tiff \
common_CloseH.tiff \
common_CloseBroken.tiff \
common_2DDash.tiff \
common_Home.tiff \
common_Mount.tiff \
common_Unmount.tiff \

Binary file not shown.

BIN
Images/common_2DDash.tiff Normal file

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

@ -5,6 +5,9 @@
Copyright (C) 1996 Free Software Foundation, Inc.
Author: David Lazaro Saz <khelekir@encomix.es>
Date: Sep 1999
Author: Ovidiu Predescu <ovidiu@net-community.com>
Date: May 1997
@ -33,7 +36,9 @@
#include <AppKit/NSMenuItem.h>
#include <AppKit/NSMenu.h>
static BOOL usesUserKeyEquivalents = YES;
static BOOL usesUserKeyEquivalents = NO;
static Class imageClass;
@implementation NSMenuItem
@ -43,6 +48,7 @@ static BOOL usesUserKeyEquivalents = YES;
{
// Initial version
[self setVersion:2];
imageClass = [NSImage class];
}
}
@ -56,63 +62,129 @@ static BOOL usesUserKeyEquivalents = YES;
return usesUserKeyEquivalents;
}
+ (id <NSMenuItem>)separatorItem
{
// FIXME: implementation needed (Lazaro).
return nil;
}
- init
{
[self setAlignment:NSLeftTextAlignment];
mi_hasSubmenu = NO;
mi_target = nil;
mi_menu = nil;
mi_mnemonicLocation = 255; // No mnemonic
mi_image = nil;
mi_onStateImage = nil;
mi_offStateImage = nil;
mi_mixedStateImage = nil;
mi_enabled = YES;
mi_state = NSOffState;
mi_changesState = NO;
[super init];
return self;
}
- (void)dealloc
- (void) dealloc
{
NSDebugLog (@"NSMenuItem '%@' dealloc", [self title]);
[representedObject release];
if (hasSubmenu)
[target release];
TEST_RELEASE(mi_title);
TEST_RELEASE(mi_keyEquivalent);
TEST_RELEASE(mi_image);
TEST_RELEASE(mi_onStateImage);
TEST_RELEASE(mi_offStateImage);
TEST_RELEASE(mi_mixedStateImage);
TEST_RELEASE(mi_representedObject);
if (mi_hasSubmenu)
[mi_submenu release];
[super dealloc];
}
- (id) copyWithZone: (NSZone*)zone
- (id)initWithTitle:(NSString *)aString
action:(SEL)aSelector
keyEquivalent:(NSString *)charCode
{
NSMenuItem *copy = [super copyWithZone: zone];
NSDebugLog (@"menu item '%@' copy", [self title]);
copy->representedObject = [representedObject retain];
copy->hasSubmenu = hasSubmenu;
if (hasSubmenu)
{
// recursive call
id submenu = [target copyWithZone: zone];
copy->target = submenu;
}
return copy;
[self init];
[self setTitle: aString];
mi_action = aSelector;
[self setKeyEquivalent: charCode];
// Set the images according to the spec. On: check mark; off: dash.
[self setOnStateImage: [NSImage imageNamed:@"common_2DCheckMark"]];
[self setMixedStateImage: [NSImage imageNamed:@"common_2DDash"]];
return self;
}
- (void)setTarget:(id)anObject
- (void)setMenu:(NSMenu *)menu
{
BOOL hadSubmenu = hasSubmenu;
hasSubmenu = anObject && [anObject isKindOfClass:[NSMenu class]];
if (hasSubmenu)
[anObject retain];
if (hadSubmenu)
[target release];
[super setTarget:anObject];
mi_menu = menu;
}
- (void)setTitle:(NSString*)aString
- (NSMenu *)menu
{
[super setStringValue:aString];
}
- (NSString*)title
{
return [self stringValue];
return mi_menu;
}
- (BOOL)hasSubmenu
{
return hasSubmenu;
return mi_hasSubmenu;
}
- (void)setSubmenu:(NSMenu *)submenu
{
if ([submenu supermenu] != nil)
[NSException raise: NSInvalidArgumentException
format: @"submenu already has supermenu: "];
mi_submenu = submenu;
if (mi_submenu == nil)
mi_hasSubmenu = NO;
else
mi_hasSubmenu = YES;
}
- (NSMenu *)submenu
{
return mi_submenu;
}
- (void)setTitle:(NSString*)aString
{
NSString *_string;
if (!aString)
_string = @"";
else
_string = [aString copy];
if (mi_title)
RELEASE(mi_title);
mi_title = _string;
}
- (NSString*)title
{
return mi_title;
}
- (BOOL)isSeparatorItem
{
// FIXME: This stuff only makes sense in MacOS or Windows alike
// interface styles. Maybe someone wants to implement this (Lazaro).
return NO;
}
- (void)setKeyEquivalent:(NSString *)aKeyEquivalent
{
NSString *_string;
if (!aKeyEquivalent)
_string = @"";
else
_string = [aKeyEquivalent copy];
if (mi_keyEquivalent)
RELEASE(mi_keyEquivalent);
mi_keyEquivalent = _string;
}
- (NSString*)keyEquivalent
@ -120,7 +192,17 @@ static BOOL usesUserKeyEquivalents = YES;
if (usesUserKeyEquivalents)
return [self userKeyEquivalent];
else
return [super keyEquivalent];
return mi_keyEquivalent;
}
- (void)setKeyEquivalentModifierMask:(unsigned int)mask
{
mi_keyEquivalentModifierMask = mask;
}
- (unsigned int)keyEquivalentModifierMask
{
return mi_keyEquivalentModifierMask;
}
- (NSString*)userKeyEquivalent
@ -128,22 +210,260 @@ static BOOL usesUserKeyEquivalents = YES;
NSString* userKeyEquivalent = [[[[NSUserDefaults standardUserDefaults]
persistentDomainForName:NSGlobalDomain]
objectForKey:@"NSCommandKeys"]
objectForKey:[self stringValue]];
objectForKey:mi_title];
if (!userKeyEquivalent)
userKeyEquivalent = [super keyEquivalent];
userKeyEquivalent = @"";
return userKeyEquivalent;
}
- (void)setMnemonicLocation:(unsigned)location
{
mi_mnemonicLocation = location;
}
- (unsigned)mnemonicLocation
{
if (mi_mnemonicLocation != 255)
return mi_mnemonicLocation;
else
return NSNotFound;
}
- (NSString *)mnemonic
{
if (mi_mnemonicLocation != 255)
return [[mi_title substringFromIndex: mi_mnemonicLocation]
substringToIndex: 1];
else
return @"";
}
- (void)setTitleWithMnemonic:(NSString *)stringWithAmpersand
{
// FIXME: Do something more than copy the string. Anyway this will only
// sense in Windows, so... (Lazaro).
NSString *_string;
if (!stringWithAmpersand)
_string = @"";
else
_string = [stringWithAmpersand copy];
if (mi_title)
RELEASE(mi_title);
mi_title = _string;
}
- (void)setImage:(NSImage *)image
{
NSAssert(image == nil || [image isKindOfClass: imageClass],
NSInvalidArgumentException);
ASSIGN(mi_image, image);
}
- (NSImage *)image
{
return mi_image;
}
- (void)setState:(int)state
{
mi_state = state;
mi_changesState = YES;
}
- (int)state
{
return mi_state;
}
- (void)setOnStateImage:(NSImage *)image
{
NSAssert(image == nil || [image isKindOfClass: imageClass],
NSInvalidArgumentException);
ASSIGN(mi_onStateImage, image);
}
- (NSImage *)onStateImage
{
return mi_onStateImage;
}
- (void)setOffStateImage:(NSImage *)image
{
NSAssert(image == nil || [image isKindOfClass: imageClass],
NSInvalidArgumentException);
ASSIGN(mi_offStateImage, image);
}
- (NSImage *)offStateImage
{
return mi_offStateImage;
}
- (void)setMixedStateImage:(NSImage *)image
{
NSAssert(image == nil || [image isKindOfClass: imageClass],
NSInvalidArgumentException);
ASSIGN(mi_mixedStateImage, image);
}
- (NSImage *)mixedStateImage
{
return mi_mixedStateImage;
}
- (void)setEnabled:(BOOL)flag
{
mi_enabled = flag;
}
- (BOOL)isEnabled
{
return mi_enabled;
}
- (void)setTarget:(id)anObject
{
mi_target = anObject;
}
- (id)target
{
return mi_target;
}
- (void)setAction:(SEL)aSelector
{
mi_action = aSelector;
}
- (SEL)action
{
return mi_action;
}
- (void)setTag:(int)anInt
{
mi_tag = anInt;
}
- (int)tag
{
return mi_tag;
}
- (void)setRepresentedObject:(id)anObject
{
ASSIGN(representedObject, anObject);
ASSIGN(mi_representedObject, anObject);
}
- (id)representedObject
{
return representedObject;
return mi_representedObject;
}
//
// NSCopying protocol
//
- (id) copyWithZone: (NSZone*)zone
{
NSMenuItem *copy = [[isa allocWithZone: zone] init];
NSDebugLog (@"menu item '%@' copy", [self title]);
copy->mi_menu = mi_menu;
copy->mi_title = [mi_title copyWithZone: zone];
copy->mi_keyEquivalent = [mi_keyEquivalent copyWithZone: zone];
copy->mi_keyEquivalentModifierMask = mi_keyEquivalentModifierMask;
copy->mi_mnemonicLocation = mi_mnemonicLocation;
copy->mi_state = mi_state;
copy->mi_enabled = mi_enabled;
ASSIGN(copy->mi_image, mi_image);
ASSIGN(copy->mi_onStateImage, mi_onStateImage);
ASSIGN(copy->mi_offStateImage, mi_offStateImage);
ASSIGN(copy->mi_mixedStateImage, mi_mixedStateImage);
copy->mi_changesState = mi_changesState;
copy->mi_target = mi_target;
copy->mi_action = mi_action;
copy->mi_tag = mi_tag;
copy->mi_representedObject = [mi_representedObject retain];
copy->mi_hasSubmenu = mi_hasSubmenu;
copy->mi_submenu = mi_submenu;
return copy;
}
//
// NSCoding protocol
//
- (void) encodeWithCoder: (NSCoder*)aCoder
{
[aCoder encodeConditionalObject: mi_menu];
[aCoder encodeObject: mi_title];
[aCoder encodeObject: mi_keyEquivalent];
[aCoder encodeValueOfObjCType: "I" at: &mi_keyEquivalentModifierMask];
[aCoder encodeValueOfObjCType: "I" at: &mi_mnemonicLocation];
[aCoder encodeValueOfObjCType: "i" at: &mi_state];
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &mi_enabled];
[aCoder encodeConditionalObject: mi_image];
[aCoder encodeConditionalObject: mi_onStateImage];
[aCoder encodeConditionalObject: mi_offStateImage];
[aCoder encodeConditionalObject: mi_mixedStateImage];
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &mi_changesState];
[aCoder encodeConditionalObject: mi_target];
[aCoder encodeValueOfObjCType: @encode(SEL) at: &mi_action];
[aCoder encodeValueOfObjCType: "i" at: &mi_tag];
[aCoder encodeConditionalObject: mi_representedObject];
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &mi_hasSubmenu];
[aCoder encodeConditionalObject: mi_submenu];
}
- (id) initWithCoder: (NSCoder*)aDecoder
{
mi_menu = [aDecoder decodeObject];
[aDecoder decodeValueOfObjCType: @encode(id) at: &mi_title];
[aDecoder decodeValueOfObjCType: @encode(id) at: &mi_keyEquivalent];
[aDecoder decodeValueOfObjCType: "I" at: &mi_keyEquivalentModifierMask];
[aDecoder decodeValueOfObjCType: "I" at: &mi_mnemonicLocation];
[aDecoder decodeValueOfObjCType: "i" at: &mi_state];
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &mi_enabled];
mi_image = [aDecoder decodeObject];
mi_onStateImage = [aDecoder decodeObject];
mi_offStateImage = [aDecoder decodeObject];
mi_mixedStateImage = [aDecoder decodeObject];
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &mi_changesState];
mi_target = [aDecoder decodeObject];
[aDecoder decodeValueOfObjCType: @encode(SEL) at: &mi_action];
[aDecoder decodeValueOfObjCType: "i" at: &mi_tag];
mi_representedObject = [aDecoder decodeObject];
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &mi_hasSubmenu];
mi_submenu = [aDecoder decodeObject];
return self;
}
@end
@implementation NSMenuItem (GNUstepExtra)
// This methods support the special arranging in columns of menu
// items in GNUstep. There's no need to use them outside but if
// they are used the display is more pleasant.
- (void) setChangesState: (BOOL)flag
{
mi_changesState = flag;
}
- (BOOL) changesState
{
return mi_changesState;
}
@end

View file

@ -43,11 +43,10 @@
#include <AppKit/NSMenuItemCell.h>
#include <AppKit/PSOperators.h>
static BOOL usesUserKeyEquivalents = YES;
@implementation NSMenuItemCell
+ (void)initialize
+ (void) initialize
{
if (self == [NSMenuItemCell class])
{
@ -56,113 +55,156 @@ static BOOL usesUserKeyEquivalents = YES;
}
}
- (id)init
- (id) init
{
mcell_has_submenu = NO;
[super init];
[super setTarget:nil];
[self setTarget:nil];
[self setHighlightsBy: NSChangeBackgroundCellMask];
[self setShowsStateBy: NSNoCellMask];
[self setImagePosition: NSNoImage];
[self setAlignment: NSLeftTextAlignment];
_drawMethods[0] = (DrawingIMP)
[self methodForSelector:@selector(drawStateImageWithFrame:inView:)];
_drawMethods[1] = (DrawingIMP)
[self methodForSelector:@selector(drawImageWithFrame:inView:)];
_drawMethods[2] = (DrawingIMP)
[self methodForSelector:@selector(drawTitleWithFrame:inView:)];
_drawMethods[3] = (DrawingIMP)
[self methodForSelector:@selector(drawKeyEquivalentWithFrame:inView:)];
return self;
}
// NSMenuitem protocol
- (void)setTarget:(id)anObject
{
BOOL hadSubmenu = mcell_has_submenu;
mcell_has_submenu = anObject && [anObject isKindOfClass:[NSMenu class]];
if (mcell_has_submenu)
[anObject retain];
if (hadSubmenu)
[target release];
[super setTarget:anObject];
}
- (BOOL)hasSubmenu
{
return mcell_has_submenu;
}
- (void)setTitle:(NSString*)aString
{
[super setStringValue:aString];
}
- (NSString*)title
{
return [super stringValue];
}
- (NSString*)keyEquivalent
{
if (usesUserKeyEquivalents)
return [self userKeyEquivalent];
else
return [super keyEquivalent];
}
- (NSString*)userKeyEquivalent
{
NSString* userKeyEquivalent = [[[[NSUserDefaults standardUserDefaults]
persistentDomainForName:NSGlobalDomain]
objectForKey:@"NSCommandKeys"]
objectForKey:[self stringValue]];
if (!userKeyEquivalent)
userKeyEquivalent = [super keyEquivalent];
return userKeyEquivalent;
}
- (void)setRepresentedObject:(id)anObject
{
ASSIGN(representedObject, anObject);
}
- (id)representedObject
{
return representedObject;
}
// NSMenuItemCell methods as defined by MacOSX API.
- (void)setHighlighted:(BOOL)flag
- (void) setHighlighted:(BOOL)flag
{
mcell_highlighted = flag;
}
- (BOOL)isHighlighted
- (BOOL) isHighlighted
{
return mcell_highlighted;
}
- (void)setMenuItem:(NSMenuItem *)item
- (void) highlight: (BOOL)flag
withFrame: (NSRect)cellFrame
inView: (NSView*)controlView
{
if (mcell_highlighted != flag)
{
mcell_highlighted = flag;
[self drawInteriorWithFrame: cellFrame inView: controlView];
}
}
- (void) setMenuItem:(NSMenuItem *)item
{
ASSIGN(mcell_item, item);
}
- (NSMenuItem *)menuItem
- (NSMenuItem *) menuItem
{
return mcell_item;
}
- (void)calcSize
- (void) setMenuView:(NSMenuView *)menuView
{
//calc sizes of images, title, and cache.
ASSIGN(mcell_menuView, menuView);
}
- (NSMenuView *) menuView
{
return mcell_menuView;
}
- (void) calcSize
{
NSSize componentSize;
NSImage *anImage = nil;
float neededMenuItemHeight = 20;
NSFont *aFont;
// State Image
if ([mcell_item changesState])
{
// NSOnState
componentSize = [[mcell_item onStateImage] size];
mcell_stateImageWidth = componentSize.width;
if (componentSize.height > neededMenuItemHeight)
neededMenuItemHeight = componentSize.height;
// NSOffState
componentSize = [[mcell_item offStateImage] size];
if (componentSize.width > mcell_stateImageWidth)
mcell_stateImageWidth = componentSize.width;
if (componentSize.height > neededMenuItemHeight)
neededMenuItemHeight = componentSize.height;
// NSMixedState
componentSize = [[mcell_item mixedStateImage] size];
if (componentSize.width > mcell_stateImageWidth)
mcell_stateImageWidth = componentSize.width;
if (componentSize.height > neededMenuItemHeight)
neededMenuItemHeight = componentSize.height;
}
else
{
mcell_stateImageWidth = 0.0;
}
// Image
if ((anImage = [mcell_item image]))
[self setImagePosition: NSImageLeft];
componentSize = [anImage size];
mcell_imageWidth = componentSize.width;
if (componentSize.height > neededMenuItemHeight)
neededMenuItemHeight = componentSize.height;
// Title and Key Equivalent
// FIXME: Calculate height (Lazaro).
aFont = [self font];
if (aFont)
{
mcell_titleWidth = [aFont widthOfString:[mcell_item title]];
mcell_keyEquivalentWidth =
[aFont widthOfString:[mcell_item keyEquivalent]];
}
else
{
mcell_titleWidth = [[NSFont menuFontOfSize:12]
widthOfString:[mcell_item title]];
mcell_keyEquivalentWidth = [[NSFont menuFontOfSize:12]
widthOfString:[mcell_item keyEquivalent]];
}
// Submenu Arrow
if ([mcell_item hasSubmenu])
{
componentSize = [[NSImage imageNamed:@"common_3DArrowRight"] size];
mcell_keyEquivalentWidth = componentSize.width;
if (componentSize.height > neededMenuItemHeight)
neededMenuItemHeight = componentSize.height;
}
// Cache definitive height
mcell_menuItemHeight = neededMenuItemHeight;
// At the end we set sizing to NO.
mcell_needs_sizing = NO;
}
- (void)setNeedsSizing:(BOOL)flag
- (void) setNeedsSizing:(BOOL)flag
{
mcell_needs_sizing = flag;
}
- (BOOL)needsSizing
- (BOOL) needsSizing
{
return mcell_needs_sizing;
}
- (float)imageWidth
- (float) imageWidth
{
if (mcell_needs_sizing)
[self calcSize];
@ -170,164 +212,424 @@ static BOOL usesUserKeyEquivalents = YES;
return mcell_imageWidth;
}
- (float)titleWidth
- (float) titleWidth
{
if (mcell_needs_sizing)
[self calcSize];
// return mcell_titleWidth;
return [[NSFont systemFontOfSize:12] widthOfString:[self title]];
return mcell_titleWidth;
}
- (float)keyEquivalentWidth
- (float) keyEquivalentWidth
{
if (mcell_needs_sizing)
[self calcSize];
return mcell_keyEqWidth;
return mcell_keyEquivalentWidth;
}
- (float)stateImageWidth
- (float) stateImageWidth
{
if (mcell_needs_sizing)
[self calcSize];
return mcell_stateImgWidth;
return mcell_stateImageWidth;
}
//
// Sizes for drawing taking into account NSMenuView adjustments.
//
- (NSRect) imageRectForBounds:(NSRect)cellFrame
{
// Calculate the image part of cell frame from NSMenuView
cellFrame.origin.x += [mcell_menuView imageAndTitleOffset];
cellFrame.size.width = [mcell_menuView imageAndTitleWidth];
if ([mcell_item changesState])
cellFrame.origin.x += [mcell_menuView stateImageWidth]
+ 2 * [mcell_menuView horizontalEdgePadding];
switch ([self imagePosition])
{
case NSNoImage:
cellFrame = NSZeroRect;
break;
case NSImageOnly:
case NSImageOverlaps:
break;
case NSImageLeft:
cellFrame.size.width = mcell_imageWidth;
break;
case NSImageRight:
cellFrame.origin.x += mcell_titleWidth + xDist;
cellFrame.size.width = mcell_imageWidth;
break;
case NSImageBelow:
cellFrame.size.height /= 2;
break;
case NSImageAbove:
cellFrame.size.height /= 2;
cellFrame.origin.y += cellFrame.size.height;
break;
}
return cellFrame;
}
- (NSRect) keyEquivalentRectForBounds:(NSRect)cellFrame
{
// Calculate the image part of cell frame from NSMenuView
cellFrame.origin.x += [mcell_menuView keyEquivalentOffset];
cellFrame.size.width = [mcell_menuView keyEquivalentWidth];
return cellFrame;
}
- (NSRect) stateImageRectForBounds:(NSRect)cellFrame
{
// Calculate the image part of cell frame from NSMenuView
cellFrame.origin.x += [mcell_menuView stateImageOffset];
cellFrame.size.width = [mcell_menuView stateImageWidth];
return cellFrame;
}
- (NSRect) titleRectForBounds:(NSRect)cellFrame
{
// Calculate the image part of cell frame from NSMenuView
cellFrame.origin.x += [mcell_menuView imageAndTitleOffset];
cellFrame.size.width = [mcell_menuView imageAndTitleWidth];
if ([mcell_item changesState])
cellFrame.origin.x += [mcell_menuView stateImageWidth]
+ 2 * [mcell_menuView horizontalEdgePadding];
switch ([self imagePosition])
{
case NSNoImage:
case NSImageOverlaps:
break;
case NSImageOnly:
cellFrame = NSZeroRect;
break;
case NSImageLeft:
cellFrame.origin.x += mcell_imageWidth + xDist;
cellFrame.size.width = mcell_titleWidth;
break;
case NSImageRight:
cellFrame.size.width = mcell_titleWidth;
break;
case NSImageBelow:
cellFrame.size.height /= 2;
cellFrame.origin.y += cellFrame.size.height;
break;
case NSImageAbove:
cellFrame.size.height /= 2;
break;
}
return cellFrame;
}
//
// Drawing.
- (NSRect)imageRectForBounds:(NSRect)cellFrame
{
return NSZeroRect;
}
- (NSRect)keyEquivalentRectForBounds:(NSRect)cellFrame
{
return NSZeroRect;
}
- (NSRect)stateImageRectForBounds:(NSRect)cellFrame
{
return NSZeroRect;
}
- (NSRect)titleRectForBounds:(NSRect)cellFrame
{
return NSZeroRect;
}
// Real drawing,
- (void)drawBorderAndBackgroundWithFrame:(NSRect)cellFrame
//
- (void) drawBorderAndBackgroundWithFrame:(NSRect)cellFrame
inView:(NSView *)controlView
{
}
- (void)drawImageWithFrame:(NSRect)cellFrame
inView:(NSView *)controlView
{
}
- (void)drawKeyEquivalentWithFrame:(NSRect)cellFrame
inView:(NSView *)controlView
{
}
- (void)drawSeparatorItemWithFrame:(NSRect)cellFrame
inView:(NSView *)controlView
{
}
- (void)drawStateImageWithFrame:(NSRect)cellFrame
inView:(NSView *)controlView
{
}
- (void)drawTitleWithFrame:(NSRect)cellFrame
inView:(NSView *)controlView
{
}
- (void) drawWithFrame: (NSRect)cellFrame
inView: (NSView *)controlView
{
NSGraphicsContext *ctxt;
NSRect floodRect = cellFrame;
NSString *keyQ = nil;
NSColor *backColor;
[controlView lockFocus];
ctxt = GSCurrentContext();
NSDrawButton(cellFrame, cellFrame);
floodRect.origin.x += 1;
floodRect.origin.y += 2;
floodRect.size.height -= 3;
floodRect.size.width -= 2;
if (cell_highlighted)
if ([self isHighlighted] && ([self highlightsBy] & NSPushInCellMask))
{
backColor = [NSColor selectedMenuItemColor];
NSDrawGrayBezel(cellFrame, NSZeroRect);
}
else
{
backColor = [NSColor controlColor];
NSDrawButton(cellFrame, NSZeroRect);
}
[backColor set];
NSRectFill(floodRect);
}
if ([self isEnabled])
- (void) drawImageWithFrame:(NSRect)cellFrame
inView:(NSView *)controlView
{
NSSize size;
NSPoint position;
cellFrame = [self imageRectForBounds: cellFrame];
size = [mcell_imageToDisplay size];
position.x = MAX(NSMidX(cellFrame) - (size.width/2.), 0.);
position.y = MAX(NSMidY(cellFrame) - (size.height/2.), 0.);
/*
* Images are always drawn with their bottom-left corner at the origin
* so we must adjust the position to take account of a flipped view.
*/
if ([control_view isFlipped])
position.y += size.height;
[mcell_imageToDisplay compositeToPoint: position operation: NSCompositeCopy];
}
- (void) drawKeyEquivalentWithFrame:(NSRect)cellFrame
inView:(NSView *)controlView
{
cellFrame = [self keyEquivalentRectForBounds: cellFrame];
if ([mcell_item hasSubmenu])
{
if (cell_highlighted)
{
[[NSColor selectedMenuItemTextColor] set];
}
else
{
[[NSColor controlTextColor] set];
}
}
else
{
[[NSColor disabledControlTextColor] set];
}
NSSize size;
NSPoint position;
NSImage *arrowImage = [NSImage imageNamed:@"common_3DArrowRight"];
[[NSFont systemFontOfSize:12] set];
DPSmoveto(ctxt, cellFrame.origin.x + 5, cellFrame.origin.y + 6);
DPSshow(ctxt, [[self title] cString]);
if (mcell_has_submenu)
{
NSSize size;
NSPoint position;
NSImage *im = [NSImage imageNamed:@"common_3DArrowRight"];
floodRect.origin.x = cellFrame.size.width - 12;
floodRect.origin.y += 5;
floodRect.size.height = 7;
floodRect.size.width = 7;
[im setBackgroundColor: backColor];
size = [im size];
position.x = MAX(NSMidX(floodRect) - (size.width/2.),0.);
position.y = MAX(NSMidY(floodRect) - (size.height/2.),0.);
size = [arrowImage size];
position.x = cellFrame.origin.x + cellFrame.size.width - size.width;
position.y = MAX(NSMidY(cellFrame) - (size.height/2.), 0.);
/*
* Images are always drawn with their bottom-left corner at the origin
* so we must adjust the position to take account of a flipped view.
*/
if ([control_view isFlipped])
position.y += size.height;
[im compositeToPoint: position operation: NSCompositeCopy];
[arrowImage compositeToPoint: position operation: NSCompositeCopy];
}
else if (keyQ = [self keyEquivalent]) {
floodRect.origin.x = cellFrame.size.width - 12;
floodRect.origin.y += 5;
floodRect.size.height = 7;
floodRect.size.width = 7;
else
[self _drawText: [mcell_item keyEquivalent] inFrame: cellFrame];
}
- (void) drawSeparatorItemWithFrame:(NSRect)cellFrame
inView:(NSView *)controlView
{
// FIXME: This only has sense in MacOS or Windows interface styles.
// Maybe somebody wants to support this (Lazaro).
}
- (void) drawStateImageWithFrame:(NSRect)cellFrame
inView:(NSView *)controlView
{
NSSize size;
NSPoint position;
NSImage *imageToDisplay;
cellFrame = [self stateImageRectForBounds: cellFrame];
switch ([mcell_item state])
{
case NSOnState:
imageToDisplay = [mcell_item onStateImage];
break;
case NSMixedState:
imageToDisplay = [mcell_item mixedStateImage];
break;
case NSOffState:
default:
imageToDisplay = [mcell_item offStateImage];
break;
}
size = [imageToDisplay size];
position.x = MAX(NSMidX(cellFrame) - (size.width/2.),0.);
position.y = MAX(NSMidY(cellFrame) - (size.height/2.),0.);
/*
* Images are always drawn with their bottom-left corner at the origin
* so we must adjust the position to take account of a flipped view.
*/
if ([control_view isFlipped])
position.y += size.height;
[imageToDisplay compositeToPoint: position operation: NSCompositeCopy];
}
- (void) drawTitleWithFrame:(NSRect)cellFrame
inView:(NSView *)controlView
{
if ([mcell_item isEnabled])
[self setEnabled: YES];
else
[self setEnabled: NO];
[self _drawText: [mcell_item title]
inFrame: [self titleRectForBounds: cellFrame]];
}
- (void) drawWithFrame: (NSRect)cellFrame inView: (NSView*)controlView
{
// Save last view drawn to
[self setControlView: controlView];
// Transparent buttons never draw
if ([self isTransparent])
return;
// Do nothing if cell's frame rect is zero
if (NSIsEmptyRect(cellFrame))
return;
[controlView lockFocus];
// Draw the border if needed
if ([self isBordered])
[self drawBorderAndBackgroundWithFrame: cellFrame inView: controlView];
[self drawInteriorWithFrame: cellFrame inView: controlView];
[self _drawText:keyQ inFrame:floodRect];
}
[controlView unlockFocus];
}
- (void) drawInteriorWithFrame: (NSRect)cellFrame inView: (NSView*)controlView
{
BOOL showAlternate = NO;
unsigned mask;
NSColor *backgroundColor = nil;
// Transparent buttons never draw
if ([self isTransparent])
return;
cellFrame = [self drawingRectForBounds: cellFrame];
// Pushed in buttons contents are displaced to the bottom right 1px
if ([self isBordered] && mcell_highlighted
&& ([self highlightsBy] & NSPushInCellMask))
PStranslate(1., [control_view isFlipped] ? 1. : -1.);
// Determine the background color
if ([self state])
{
if ([self showsStateBy]
& (NSChangeGrayCellMask | NSChangeBackgroundCellMask) )
backgroundColor = [NSColor selectedMenuItemColor];
}
if (mcell_highlighted)
{
if ([self highlightsBy]
& (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 (mcell_highlighted)
mask = [self highlightsBy];
else
mask = [self showsStateBy];
if (mask & NSContentsCellMask)
showAlternate = [self state];
if (mcell_highlighted || showAlternate)
{
mcell_imageToDisplay = [self alternateImage];
if (!mcell_imageToDisplay)
mcell_imageToDisplay = [mcell_item image];
mcell_titleToDisplay = [self alternateTitle];
if (mcell_titleToDisplay == nil || [mcell_titleToDisplay isEqual: @""])
mcell_titleToDisplay = [mcell_item title];
}
else
{
mcell_imageToDisplay = [mcell_item image];
mcell_titleToDisplay = [mcell_item title];
}
if (mcell_imageToDisplay)
{
mcell_imageSize = [mcell_imageToDisplay size];
[mcell_imageToDisplay setBackgroundColor: backgroundColor];
}
// Draw the state image
if (mcell_stateImageWidth > 0)
_drawMethods[0](self, @selector(drawStateImageWithFrame:inView:),
cellFrame, controlView);
// Draw the image
if (mcell_imageWidth > 0)
_drawMethods[1](self, @selector(drawImageWithFrame:inView:),
cellFrame, controlView);
// Draw the title
if (mcell_titleWidth > 0)
_drawMethods[2](self, @selector(drawTitleWithFrame:inView:),
cellFrame, controlView);
// Draw the key equivalent
if (mcell_keyEquivalentWidth > 0)
_drawMethods[3](self, @selector(drawKeyEquivalentWithFrame:inView:),
cellFrame, controlView);
}
//
// NSCopying protocol
//
- (id) copyWithZone: (NSZone*)zone
{
NSMenuItemCell *c = [super copyWithZone: zone];
c->mcell_highlighted = mcell_highlighted;
c->mcell_has_submenu = mcell_has_submenu;
if (mcell_item)
c->mcell_item = [mcell_item copyWithZone: zone];
c->mcell_menuView = mcell_menuView;
c->mcell_needs_sizing = mcell_needs_sizing;
memcpy(c->_drawMethods, _drawMethods, sizeof(DrawingIMP) * 4);
return c;
}
//
// NSCoding protocol
//
- (void) encodeWithCoder: (NSCoder*)aCoder
{
[super encodeWithCoder: aCoder];
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &mcell_highlighted];
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &mcell_has_submenu];
[aCoder encodeConditionalObject: mcell_item];
[aCoder encodeConditionalObject: mcell_menuView];
}
- (id) initWithCoder: (NSCoder*)aDecoder
{
[super initWithCoder: aDecoder];
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &mcell_highlighted];
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &mcell_has_submenu];
mcell_item = [aDecoder decodeObject];
mcell_menuView = [aDecoder decodeObject];
mcell_needs_sizing = YES;
_drawMethods[0] = (DrawingIMP)
[self methodForSelector:@selector(drawStateImageWithFrame:inView:)];
_drawMethods[1] = (DrawingIMP)
[self methodForSelector:@selector(drawImageWithFrame:inView:)];
_drawMethods[2] = (DrawingIMP)
[self methodForSelector:@selector(drawTitleWithFrame:inView:)];
_drawMethods[3] = (DrawingIMP)
[self methodForSelector:@selector(drawKeyEquivalentWithFrame:inView:)];
return self;
}
@end

File diff suppressed because it is too large Load diff