81 unsigned _keyEquivalentModifierMask;
83 int _mnemonicLocation;
86 int _indentationLevel;
89 id _representedObject;
94 _CPMenuItemView _menuItemView;
109 - (id)initWithTitle:(
CPString)aTitle action:(
SEL)anAction keyEquivalent:(
CPString)aKeyEquivalent
127 _keyEquivalent = aKeyEquivalent ||
@"";
130 _indentationLevel = 0;
143 - (void)setEnabled:(BOOL)isEnabled
145 if (_isEnabled === isEnabled)
148 _isEnabled = !!isEnabled;
150 [_menuItemView setDirty];
151 [_menu itemChanged:self];
167 - (void)setHidden:(BOOL)isHidden
169 if (_isHidden == isHidden)
172 _isHidden = isHidden;
174 [_menu itemChanged:self];
188 - (BOOL)isHiddenOrHasHiddenAncestor
193 var supermenu = [_menu supermenu];
195 if ([[supermenu itemAtIndex:[supermenu indexOfItemWithSubmenu:_menu]] isHiddenOrHasHiddenAncestor])
206 - (void)setTarget:(
id)aTarget
223 - (void)setAction:(
SEL)anAction
245 if (_title == aTitle)
250 [_menuItemView setDirty];
252 [_menu itemChanged:self];
282 [_menu itemChanged:self];
284 [_menuItemView setDirty];
310 - (void)setTag:(
int)aTag
331 - (void)setState:(
int)aState
333 if (_state == aState)
338 [_menu itemChanged:self];
340 [_menuItemView setDirty];
363 if (_image == anImage)
368 [_menuItemView setDirty];
370 [_menu itemChanged:self];
387 _alternateImage = anImage;
395 return _alternateImage;
405 if (_onStateImage == anImage)
408 _onStateImage = anImage;
409 [_menu itemChanged:self];
417 return _onStateImage;
426 if (_offStateImage == anImage)
429 _offStateImage = anImage;
430 [_menu itemChanged:self];
438 return _offStateImage;
447 if (_mixedStateImage == anImage)
450 _mixedStateImage = anImage;
451 [_menu itemChanged:self];
460 return _mixedStateImage;
470 if (_submenu === aMenu)
473 var supermenu = [_submenu supermenu];
477 reason: @"Can't add submenu \"" + [aMenu
title] + "\" to item \"" + [
self title] + "\", because it is already submenu of \"" + [[aMenu
supermenu]
title] + "\""];
483 [_submenu setSupermenu:_menu];
484 [_submenu setTitle:[
self title]]
495 [_menuItemView setDirty];
497 [_menu itemChanged:self];
513 return _submenu ? YES : NO;
525 separatorItem._isSeparator = YES;
527 return separatorItem;
533 - (BOOL)isSeparatorItem
564 _keyEquivalent = aString ||
@"";
572 return _keyEquivalent;
585 - (void)setKeyEquivalentModifierMask:(
unsigned)aMask
587 _keyEquivalentModifierMask = aMask;
600 - (unsigned)keyEquivalentModifierMask
602 return _keyEquivalentModifierMask;
607 if (![_keyEquivalent length])
610 var
string = _keyEquivalent.toUpperCase(),
612 (
string === _keyEquivalent && _keyEquivalent.toLowerCase() !== _keyEquivalent.toUpperCase());
615 string = [CPMenuItemStringRepresentationDictionary objectForKey:string];
620 string =
"\u2318" + string;
623 string =
"\u21E7" + string;
626 string =
"\u2325" + string;
629 string =
"\u2303" + string;
634 string =
"Shift-" + string;
637 string =
"Alt-" + string;
640 string =
"Ctrl-" + string;
652 - (void)setMnemonicLocation:(
unsigned)aLocation
654 _mnemonicLocation = aLocation;
660 - (unsigned)mnemonicLocation
662 return _mnemonicLocation;
669 - (void)setTitleWithMnemonicLocation:(
CPString)aTitle
687 return _mnemonicLocation ==
CPNotFound ?
@"" : [_title characterAtIndex:_mnemonicLocation];
696 - (void)setAlternate:(BOOL)isAlternate
698 _isAlternate = isAlternate;
716 - (void)setIndentationLevel:(
unsigned)aLevel
719 [
CPException raise:CPInvalidArgumentException
reason:"setIndentationLevel: argument must be greater than or equal to 0."];
721 _indentationLevel = MIN(15, aLevel);
727 - (unsigned)indentationLevel
729 return _indentationLevel;
756 - (void)setRepresentedObject:(
id)anObject
758 _representedObject = anObject;
764 - (id)representedObject
766 return _representedObject;
782 [_menuItemView setDirty];
784 [_menu itemChanged:self];
800 - (BOOL)isHighlighted
805 #pragma mark CPObject Overrides
815 item._isSeparator = _isSeparator;
817 [item setTitle:_title];
818 [item setFont:_font];
819 [item setTarget:_target];
820 [item setAction:_action];
821 [item setEnabled:_isEnabled];
822 [item setHidden:_isHidden]
824 [item setState:_state];
825 [item setImage:_image];
826 [item setAlternateImage:_alternateImage];
827 [item setOnStateImage:_onStateImage];
828 [item setOffStateImage:_offStateImage];
829 [item setMixedStateImage:_mixedStateImage];
830 [item setKeyEquivalent:_keyEquivalent];
831 [item setKeyEquivalentModifierMask:_keyEquivalentModifierMask];
832 [item setMnemonicLocation:_mnemonicLocation];
833 [item setAlternate:_isAlternate];
834 [item setIndentationLevel:_indentationLevel];
835 [item setToolTip:_toolTip];
836 [item setRepresentedObject:_representedObject];
846 #pragma mark Internal
854 _menuItemView = [[_CPMenuItemView alloc] initWithFrame:CGRectMakeZero() forMenuItem:self];
856 return _menuItemView;
859 - (BOOL)_isSelectable
861 return ![
self submenu] || [
self action] !==
@selector(submenuAction:) || [
self target] !== [
self menu];
864 - (BOOL)_isMenuBarButton
866 return ![
self submenu] && [
self menu] === [CPApp mainMenu];
902 #define DEFAULT_VALUE(aKey, aDefaultValue) [aCoder containsValueForKey:(aKey)] ? [aCoder decodeObjectForKey:(aKey)] : (aDefaultValue)
903 #define ENCODE_IFNOT(aKey, aValue, aDefaultValue) if ((aValue) !== (aDefaultValue)) [aCoder encodeObject:(aValue) forKey:(aKey)];
918 _isSeparator = [aCoder containsValueForKey:CPMenuItemIsSeparatorKey] && [aCoder decodeBoolForKey:CPMenuItemIsSeparatorKey];
920 _title = [aCoder decodeObjectForKey:CPMenuItemTitleKey];
924 _target = [aCoder decodeObjectForKey:CPMenuItemTargetKey];
925 _action = [aCoder decodeObjectForKey:CPMenuItemActionKey];
928 _isHidden = [aCoder decodeBoolForKey:CPMenuItemIsHiddenKey];
929 _tag = [aCoder decodeIntForKey:CPMenuItemTagKey];
930 _state = [aCoder decodeIntForKey:CPMenuItemStateKey];
932 _image = [aCoder decodeObjectForKey:CPMenuItemImageKey];
933 _alternateImage = [aCoder decodeObjectForKey:CPMenuItemAlternateImageKey];
939 _menu = [aCoder decodeObjectForKey:CPMenuItemMenuKey];
940 [
self setSubmenu:[aCoder decodeObjectForKey:CPMenuItemSubmenuKey]];
942 _keyEquivalent = [aCoder decodeObjectForKey:CPMenuItemKeyEquivalentKey] ||
@"";
943 _keyEquivalentModifierMask = [aCoder decodeIntForKey:CPMenuItemKeyEquivalentModifierMaskKey];
953 _representedObject = [aCoder decodeObjectForKey:CPMenuItemRepresentedObjectKey];
954 _view = [aCoder decodeObjectForKey:CPMenuItemViewKey];
967 [aCoder encodeBool:_isSeparator forKey:CPMenuItemIsSeparatorKey];
969 [aCoder encodeObject:_title forKey:CPMenuItemTitleKey];
971 [aCoder encodeObject:_target forKey:CPMenuItemTargetKey];
972 [aCoder encodeObject:_action forKey:CPMenuItemActionKey];
986 if (_keyEquivalent && _keyEquivalent.
length)
987 [aCoder encodeObject:_keyEquivalent forKey:CPMenuItemKeyEquivalentKey];
989 if (_keyEquivalentModifierMask)
990 [aCoder encodeObject:_keyEquivalentModifierMask forKey:CPMenuItemKeyEquivalentModifierMaskKey];
992 if (_indentationLevel > 0)
993 [aCoder encodeInt:_indentationLevel forKey:CPMenuItemIndentationLevelKey];