00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 @import <Foundation/CPCoder.j>
00024 @import <Foundation/CPObject.j>
00025 @import <Foundation/CPString.j>
00026
00027 @import <AppKit/CPImage.j>
00028 @import <AppKit/CPMenu.j>
00029 @import <AppKit/CPView.j>
00030
00037 @implementation CPMenuItem : CPObject
00038 {
00039 CPString _title;
00040
00041
00042 CPFont _font;
00043
00044 id _target;
00045 SEL _action;
00046
00047 BOOL _isEnabled;
00048 BOOL _isHidden;
00049
00050 int _tag;
00051 int _state;
00052
00053 CPImage _image;
00054 CPImage _alternateImage;
00055 CPImage _onStateImage;
00056 CPImage _offStateImage;
00057 CPImage _mixedStateImage;
00058
00059 CPMenu _submenu;
00060 CPMenu _menu;
00061
00062 CPString _keyEquivalent;
00063 unsigned _keyEquivalentModifierMask;
00064
00065 int _mnemonicLocation;
00066
00067 BOOL _isAlternate;
00068 int _indentationLevel;
00069
00070 CPString _toolTip;
00071 id _representedObject;
00072 CPView _view;
00073
00074 _CPMenuItemView _menuItemView;
00075 }
00076
00084 - (id)initWithTitle:(CPString)aTitle action:(SEL)anAction keyEquivalent:(CPString)aKeyEquivalent
00085 {
00086 self = [super init];
00087
00088 if (self)
00089 {
00090 _title = aTitle;
00091 _action = anAction;
00092
00093 _isEnabled = YES;
00094
00095 _state = CPOffState;
00096
00097 _keyEquivalent = aKeyEquivalent || @"";
00098 _keyEquivalentModifierMask = CPPlatformActionKeyMask;
00099
00100 _mnemonicLocation = CPNotFound;
00101 }
00102
00103 return self;
00104 }
00105
00106
00111 - (void)setEnabled:(BOOL)isEnabled
00112 {
00113 if ([_menu autoenablesItems])
00114 return;
00115
00116 _isEnabled = isEnabled;
00117
00118 [_menuItemView setDirty];
00119
00120 [_menu itemChanged:self];
00121 }
00122
00126 - (BOOL)isEnabled
00127 {
00128 return _isEnabled;
00129 }
00130
00131
00136 - (void)setHidden:(BOOL)isHidden
00137 {
00138 if (_isHidden == isHidden)
00139 return;
00140
00141 _isHidden = isHidden;
00142
00143 [_menu itemChanged:self];
00144 }
00145
00149 - (BOOL)isHidden
00150 {
00151 return _isHidden;
00152 }
00153
00157 - (BOOL)isHiddenOrHasHiddenAncestor
00158 {
00159 if (_isHidden)
00160 return YES;
00161
00162 var supermenu = [_menu supermenu];
00163
00164 if ([[supermenu itemAtIndex:[supermenu indexOfItemWithSubmenu:_menu]] isHiddenOrHasHiddenAncestor])
00165 return YES;
00166
00167 return NO;
00168 }
00169
00170
00175 - (void)setTarget:(id)aTarget
00176 {
00177 _target = aTarget;
00178 }
00179
00183 - (id)target
00184 {
00185 return _target;
00186 }
00187
00192 - (void)setAction:(SEL)anAction
00193 {
00194 _action = anAction;
00195 }
00196
00200 - (SEL)action
00201 {
00202 return _action;
00203 }
00204
00205
00210 - (void)setTitle:(CPString)aTitle
00211 {
00212 _mnemonicLocation = CPNotFound;
00213
00214 if (_title == aTitle)
00215 return;
00216
00217 _title = aTitle;
00218
00219 [_menuItemView setDirty];
00220
00221 [_menu itemChanged:self];
00222 }
00223
00227 - (CPString)title
00228 {
00229 return _title;
00230 }
00231
00236 - (void)setFont:(CPFont)aFont
00237 {
00238 if (_font == aFont)
00239 return;
00240
00241 _font = aFont;
00242
00243 [_menu itemChanged:self];
00244
00245 [_menuItemView setDirty];
00246 }
00247
00251 - (CPFont)font
00252 {
00253 return _font;
00254 }
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00271 - (void)setTag:(int)aTag
00272 {
00273 _tag = aTag;
00274 }
00275
00279 - (int)tag
00280 {
00281 return _tag;
00282 }
00283
00292 - (void)setState:(int)aState
00293 {
00294 if (_state == aState)
00295 return;
00296
00297 _state = aState;
00298
00299 [_menu itemChanged:self];
00300
00301 [_menuItemView setDirty];
00302 }
00303
00312 - (int)state
00313 {
00314 return _state;
00315 }
00316
00317
00322 - (void)setImage:(CPImage)anImage
00323 {
00324 if (_image == anImage)
00325 return;
00326
00327 _image = anImage;
00328
00329 [_menuItemView setDirty];
00330
00331 [_menu itemChanged:self];
00332 }
00333
00337 - (CPImage)image
00338 {
00339 return _image;
00340 }
00341
00346 - (void)setAlternateImage:(CPImage)anImage
00347 {
00348 _alternateImage = anImage;
00349 }
00350
00354 - (CPImage)alternateImage
00355 {
00356 return _alternateImage;
00357 }
00358
00364 - (void)setOnStateImage:(CPImage)anImage
00365 {
00366 if (_onStateImage == anImage)
00367 return;
00368
00369 _onStateImage = anImage;
00370 [_menu itemChanged:self];
00371 }
00372
00376 - (CPImage)onStateImage
00377 {
00378 return _onStateImage;
00379 }
00380
00385 - (void)setOffStateImage:(CPImage)anImage
00386 {
00387 if (_offStateImage == anImage)
00388 return;
00389
00390 _offStateImage = anImage;
00391 [_menu itemChanged:self];
00392 }
00393
00397 - (CPImage)offStateImage
00398 {
00399 return _offStateImage;
00400 }
00401
00406 - (void)setMixedStateImage:(CPImage)anImage
00407 {
00408 if (_mixedStateImage == anImage)
00409 return;
00410
00411 _mixedStateImage = anImage;
00412 [_menu itemChanged:self];
00413 }
00414
00419 - (CPImage)mixedStateImage
00420 {
00421 return _mixedStateImage;
00422 }
00423
00424
00429 - (void)setSubmenu:(CPMenu)aMenu
00430 {
00431 var supermenu = [_submenu supermenu];
00432
00433 if (supermenu == self)
00434 return;
00435
00436 if (supermenu)
00437 return alert("bad");
00438
00439 [_submenu setSupermenu:_menu];
00440
00441 _submenu = aMenu;
00442
00443 [_menuItemView setDirty];
00444
00445 [_menu itemChanged:self];
00446 }
00447
00451 - (CPMenu)submenu
00452 {
00453 return _submenu;
00454 }
00455
00459 - (BOOL)hasSubmenu
00460 {
00461 return _submenu ? YES : NO;
00462 }
00463
00464
00465
00469 + (CPMenuItem)separatorItem
00470 {
00471 return [[_CPMenuItemSeparator alloc] init];
00472 }
00473
00477 - (BOOL)isSeparatorItem
00478 {
00479 return NO;
00480 }
00481
00482
00487 - (void)setMenu:(CPMenu)aMenu
00488 {
00489 _menu = aMenu;
00490 }
00491
00495 - (CPMenu)menu
00496 {
00497 return _menu;
00498 }
00499
00500
00501
00506 - (void)setKeyEquivalent:(CPString)aString
00507 {
00508 _keyEquivalent = aString || @"";
00509 }
00510
00514 - (CPString)keyEquivalent
00515 {
00516 return _keyEquivalent;
00517 }
00518
00529 - (void)setKeyEquivalentModifierMask:(unsigned)aMask
00530 {
00531 _keyEquivalentModifierMask = aMask;
00532 }
00533
00544 - (unsigned)keyEquivalentModifierMask
00545 {
00546 return _keyEquivalentModifierMask;
00547 }
00548
00549
00555 - (void)setMnemonicLocation:(unsigned)aLocation
00556 {
00557 _mnemonicLocation = aLocation;
00558 }
00559
00563 - (unsigned)mnemonicLocation
00564 {
00565 return _mnemonicLocation;
00566 }
00567
00572 - (void)setTitleWithMnemonicLocation:(CPString)aTitle
00573 {
00574 var location = [aTitle rangeOfString:@"&"].location;
00575
00576 if (location == CPNotFound)
00577 [self setTitle:aTitle];
00578 else
00579 {
00580 [self setTitle:[aTitle substringToIndex:location] + [aTitle substringFromIndex:location + 1]];
00581 [self setMnemonicLocation:location];
00582 }
00583 }
00584
00588 - (CPString)mnemonic
00589 {
00590 return _mnemonicLocation == CPNotFound ? @"" : [_title characterAtIndex:_mnemonicLocation];
00591 }
00592
00593
00594
00599 - (void)setAlternate:(BOOL)isAlternate
00600 {
00601 _isAlternate = isAlternate;
00602 }
00603
00607 - (BOOL)isAlternate
00608 {
00609 return _isAlternate;
00610 }
00611
00612
00613
00619 - (void)setIndentationLevel:(unsigned)aLevel
00620 {
00621 if (aLevel < 0)
00622 [CPException raise:CPInvalidArgumentException reason:"setIndentationLevel: argument must be greater than 0."];
00623
00624 _indentationLevel = MIN(15, aLevel);
00625 }
00626
00630 - (unsigned)indentationLevel
00631 {
00632 return _indentationLevel;
00633 }
00634
00635
00640 - (void)setToolTip:(CPString)aToolTip
00641 {
00642 _toolTip = aToolTip;
00643 }
00644
00648 - (CPString)toolTip
00649 {
00650 return _toolTip;
00651 }
00652
00653
00654
00659 - (void)setRepresentedObject:(id)anObject
00660 {
00661 _representedObject = anObject;
00662 }
00663
00667 - (id)representedObject
00668 {
00669 return _representedObject;
00670 }
00671
00672
00673
00678 - (void)setView:(CPView)aView
00679 {
00680 if (_view == aView)
00681 return;
00682
00683 _view = aView;
00684
00685 [_menuItemView setDirty];
00686
00687 [_menu itemChanged:self];
00688 }
00689
00693 - (CPView)view
00694 {
00695 return _view;
00696 }
00697
00698
00699
00703 - (BOOL)isHighlighted
00704 {
00705 return [[self menu] highlightedItem] == self;
00706 }
00707
00708
00709
00710
00711
00712
00713 - (id)_menuItemView
00714 {
00715 if (!_menuItemView)
00716 _menuItemView = [[_CPMenuItemView alloc] initWithFrame:CGRectMakeZero() forMenuItem:self];
00717
00718 return _menuItemView;
00719 }
00720
00721 @end
00722
00723
00724 @implementation _CPMenuItemSeparator : CPMenuItem
00725 {
00726 }
00727
00728 - (id)init
00729 {
00730 return [super initWithTitle:@"" action:nil keyEquivalent:@""];
00731 }
00732
00733 - (BOOL)isSeparatorItem
00734 {
00735 return YES;
00736 }
00737
00738 @end
00739
00740 var CPMenuItemTitleKey = @"CPMenuItemTitleKey",
00741 CPMenuItemTargetKey = @"CPMenuItemTargetKey",
00742 CPMenuItemActionKey = @"CPMenuItemActionKey",
00743
00744 CPMenuItemIsEnabledKey = @"CPMenuItemIsEnabledKey",
00745 CPMenuItemIsHiddenKey = @"CPMenuItemIsHiddenKey",
00746
00747 CPMenuItemImageKey = @"CPMenuItemImageKey",
00748 CPMenuItemAlternateImageKey = @"CPMenuItemAlternateImageKey",
00749
00750 CPMenuItemSubmenuKey = @"CPMenuItemSubmenuKey",
00751 CPMenuItemMenuKey = @"CPMenuItemMenuKey",
00752
00753 CPMenuItemRepresentedObjectKey = @"CPMenuItemRepresentedObjectKey";
00754
00755 @implementation CPMenuItem (CPCoding)
00761 - (id)initWithCoder:(CPCoder)aCoder
00762 {
00763 self = [super init];
00764
00765 if (self)
00766 {
00767 _title = [aCoder decodeObjectForKey:CPMenuItemTitleKey];
00768
00769
00770
00771 _target = [aCoder decodeObjectForKey:CPMenuItemTargetKey];
00772 _action = [aCoder decodeObjectForKey:CPMenuItemActionKey];
00773
00774 _isEnabled = [aCoder decodeObjectForKey:CPMenuItemIsEnabledKey];
00775 _isHidden = [aCoder decodeObjectForKey:CPMenuItemIsHiddenKey];
00776
00777
00778
00779
00780 _image = [aCoder decodeObjectForKey:CPMenuItemImageKey];
00781 _alternateImage = [aCoder decodeObjectForKey:CPMenuItemAlternateImageKey];
00782
00783
00784
00785
00786 _submenu = [aCoder decodeObjectForKey:CPMenuItemSubmenuKey];
00787 _menu = [aCoder decodeObjectForKey:CPMenuItemMenuKey];
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799 _representedObject = [aCoder decodeObjectForKey:CPMenuItemRepresentedObjectKey];
00800
00801
00802 }
00803
00804 return self;
00805 }
00806
00811 - (void)encodeWithCoder:(CPCoder)aCoder
00812 {
00813 [aCoder encodeObject:_title forKey:CPMenuItemTitleKey];
00814
00815 [aCoder encodeObject:_target forKey:CPMenuItemTargetKey];
00816 [aCoder encodeObject:_action forKey:CPMenuItemActionKey];
00817
00818 [aCoder encodeObject:_isEnabled forKey:CPMenuItemIsEnabledKey];
00819 [aCoder encodeObject:_isHidden forKey:CPMenuItemIsHiddenKey];
00820
00821 [aCoder encodeObject:_image forKey:CPMenuItemImageKey];
00822 [aCoder encodeObject:_alternateImage forKey:CPMenuItemAlternateImageKey];
00823
00824 [aCoder encodeObject:_submenu forKey:CPMenuItemSubmenuKey];
00825 [aCoder encodeObject:_menu forKey:CPMenuItemMenuKey];
00826
00827 [aCoder encodeObject:_representedObject forKey:CPMenuItemRepresentedObjectKey];
00828 }
00829
00830 @end
00831
00832 var LEFT_MARGIN = 3.0,
00833 RIGHT_MARGIN = 16.0,
00834 STATE_COLUMN_WIDTH = 14.0,
00835 INDENTATION_WIDTH = 17.0;
00836
00837 var _CPMenuItemSelectionColor = nil,
00838
00839 _CPMenuItemDefaultStateImages = [],
00840 _CPMenuItemDefaultStateHighlightedImages = [];
00841
00842
00843
00844
00845 @implementation _CPMenuItemView : CPView
00846 {
00847 CPMenuItem _menuItem;
00848
00849 CPFont _font;
00850 CPColor _textColor;
00851
00852 CGSize _minSize;
00853 BOOL _isDirty;
00854 BOOL _showsStateColumn;
00855 BOOL _belongsToMenuBar;
00856
00857 CPImageView _stateView;
00858 _CPImageAndTitleView _imageAndTitleView;
00859 CPView _submenuView;
00860 }
00861
00862 + (void)initialize
00863 {
00864 if (self != [_CPMenuItemView class])
00865 return;
00866
00867 _CPMenuItemSelectionColor = [CPColor colorWithCalibratedRed:81.0 / 255.0 green:83.0 / 255.0 blue:109.0 / 255.0 alpha:1.0];
00868
00869 var bundle = [CPBundle bundleForClass:self];
00870
00871 _CPMenuItemDefaultStateImages[CPOffState] = nil;
00872 _CPMenuItemDefaultStateHighlightedImages[CPOffState] = nil;
00873
00874 _CPMenuItemDefaultStateImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnState.png"] size:CGSizeMake(14.0, 14.0)];
00875 _CPMenuItemDefaultStateHighlightedImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnStateHighlighted.png"] size:CGSizeMake(14.0, 14.0)];
00876
00877 _CPMenuItemDefaultStateImages[CPMixedState] = nil;
00878 _CPMenuItemDefaultStateHighlightedImages[CPMixedState] = nil;
00879 }
00880
00881 + (float)leftMargin
00882 {
00883 return LEFT_MARGIN + STATE_COLUMN_WIDTH;
00884 }
00885
00886 - (id)initWithFrame:(CGRect)aFrame forMenuItem:(CPMenuItem)aMenuItem
00887 {
00888 self = [super initWithFrame:aFrame];
00889
00890 if (self)
00891 {
00892 _menuItem = aMenuItem;
00893 _showsStateColumn = YES;
00894 _isDirty = YES;
00895
00896 [self setAutoresizingMask:CPViewWidthSizable];
00897
00898 [self synchronizeWithMenuItem];
00899 }
00900
00901 return self;
00902 }
00903
00904 - (CGSize)minSize
00905 {
00906 return _minSize;
00907 }
00908
00909 - (void)setDirty
00910 {
00911 _isDirty = YES;
00912 }
00913
00914 - (void)synchronizeWithMenuItem
00915 {
00916 if (!_isDirty)
00917 return;
00918
00919 _isDirty = NO;
00920
00921 var view = [_menuItem view];
00922
00923 if (view)
00924 {
00925 [_imageAndTitleView removeFromSuperview];
00926 _imageAndTitleView = nil;
00927
00928 [_stateView removeFromSuperview];
00929 _stateView = nil;
00930
00931 [_submenuView removeFromSuperview];
00932 _submenuView = nil;
00933
00934 _minSize = [view frame].size;
00935
00936 [self setFrameSize:_minSize];
00937
00938 [self addSubview:view];
00939
00940 return;
00941 }
00942
00943
00944 var x = _belongsToMenuBar ? 0.0 : (LEFT_MARGIN + [_menuItem indentationLevel] * INDENTATION_WIDTH);
00945
00946 if (_showsStateColumn)
00947 {
00948 if (!_stateView)
00949 {
00950 _stateView = [[CPImageView alloc] initWithFrame:CGRectMake(x, (CGRectGetHeight([self frame]) - STATE_COLUMN_WIDTH) / 2.0, STATE_COLUMN_WIDTH, STATE_COLUMN_WIDTH)];
00951
00952 [_stateView setAutoresizingMask:CPViewMinYMargin | CPViewMaxYMargin];
00953
00954 [self addSubview:_stateView];
00955 }
00956
00957 var state = [_menuItem state];
00958
00959 switch (state)
00960 {
00961 case CPOffState:
00962 case CPOnState:
00963 case CPMixedState: [_stateView setImage:_CPMenuItemDefaultStateImages[state]];
00964 break;
00965
00966 default: [_stateView setImage:nil];
00967 }
00968
00969 x += STATE_COLUMN_WIDTH;
00970 }
00971 else
00972 {
00973 [_stateView removeFromSuperview];
00974
00975 _stateView = nil;
00976 }
00977
00978
00979
00980 if (!_imageAndTitleView)
00981 {
00982 _imageAndTitleView = [[_CPImageAndTitleView alloc] initWithFrame:CGRectMake(0.0, 0.0, 0.0, 0.0)];
00983
00984 [_imageAndTitleView setImagePosition:CPImageLeft];
00985
00986 [self addSubview:_imageAndTitleView];
00987 }
00988
00989 var font = [_menuItem font];
00990
00991 if (!font)
00992 font = _font;
00993
00994 [_imageAndTitleView setFont:font];
00995 [_imageAndTitleView setImage:[_menuItem image]];
00996 [_imageAndTitleView setTitle:[_menuItem title]];
00997 [_imageAndTitleView setTextColor:[self textColor]];
00998 [_imageAndTitleView setFrameOrigin:CGPointMake(x, 0.0)];
00999
01000 [_imageAndTitleView sizeToFit];
01001
01002 var frame = [_imageAndTitleView frame];
01003
01004 x += CGRectGetWidth(frame);
01005
01006
01007 if ([_menuItem hasSubmenu])
01008 {
01009 if (!_submenuView)
01010 {
01011 _submenuView = [[_CPMenuItemArrowView alloc] initWithFrame:CGRectMake(0.0, 0.0, 10.0, 10.0)];
01012
01013 [self addSubview:_submenuView];
01014 }
01015
01016 [_submenuView setHidden:NO];
01017 [_submenuView setColor:_belongsToMenuBar ? [self textColor] : nil];
01018 [_submenuView setFrameOrigin:CGPointMake(x, (CGRectGetHeight(frame) - 10.0) / 2.0)];
01019
01020 x += 10.0;
01021 }
01022 else
01023 [_submenuView setHidden:YES];
01024
01025 _minSize = CGSizeMake(x + (_belongsToMenuBar ? 0.0 : RIGHT_MARGIN), CGRectGetHeight(frame));
01026
01027 [self setFrameSize:_minSize];
01028 }
01029
01030 - (float)calculatedLeftMargin
01031 {
01032 if (_belongsToMenuBar)
01033 return 0.0;
01034
01035 return LEFT_MARGIN + ([[_menuItem menu] showsStateColumn] ? STATE_COLUMN_WIDTH : 0.0) + [_menuItem indentationLevel] * INDENTATION_WIDTH;
01036 }
01037
01038 - (void)setShowsStateColumn:(BOOL)shouldShowStateColumn
01039 {
01040 _showsStateColumn = shouldShowStateColumn;
01041 }
01042
01043 - (void)setBelongsToMenuBar:(BOOL)shouldBelongToMenuBar
01044 {
01045 _belongsToMenuBar = shouldBelongToMenuBar;
01046 }
01047
01048 - (void)highlight:(BOOL)shouldHighlight
01049 {
01050
01051
01052 if (_belongsToMenuBar)
01053 [_imageAndTitleView setImage:shouldHighlight ? [_menuItem alternateImage] : [_menuItem image]];
01054
01055 else
01056 {
01057 [_imageAndTitleView setTextColor:shouldHighlight ? [CPColor whiteColor] : [self textColor]];
01058
01059 if (shouldHighlight)
01060 [self setBackgroundColor:_CPMenuItemSelectionColor];
01061 else
01062 [self setBackgroundColor:nil];
01063
01064 var state = [_menuItem state];
01065
01066 switch (state)
01067 {
01068 case CPOffState:
01069 case CPOnState:
01070 case CPMixedState: [_stateView setImage:shouldHighlight ? _CPMenuItemDefaultStateHighlightedImages[state] : _CPMenuItemDefaultStateImages[state]];
01071 break;
01072
01073 default: [_stateView setImage:nil];
01074 }
01075 }
01076 }
01077
01078 - (void)activate:(BOOL)shouldActivate
01079 {
01080 [_imageAndTitleView setImage:[_menuItem image]];
01081
01082 if (shouldActivate)
01083 {
01084 [_imageAndTitleView setTextColor:[CPColor whiteColor]];
01085 [_submenuView setColor:[CPColor whiteColor]];
01086 }
01087 else
01088 {
01089 [_imageAndTitleView setTextColor:[self textColor]];
01090 [_submenuView setColor:[self textColor]];
01091 }
01092 }
01093
01094 - (BOOL)eventOnSubmenu:(CPEvent)anEvent
01095 {
01096 if (![_menuItem hasSubmenu])
01097 return NO;
01098
01099 return CGRectContainsPoint([_submenuView frame], [self convertPoint:[anEvent locationInWindow] fromView:nil]);
01100 }
01101
01102 - (BOOL)isHidden
01103 {
01104 return [_menuItem isHidden];
01105 }
01106
01107 - (CPMenuItem)menuItem
01108 {
01109 return _menuItem;
01110 }
01111
01112 - (void)setFont:(CPFont)aFont
01113 {
01114 if (_font == aFont)
01115 return;
01116
01117 _font = aFont;
01118
01119 [self setDirty];
01120 }
01121
01122 - (void)setTextColor:(CPColor)aColor
01123 {
01124 if (_textColor == aColor)
01125 return;
01126
01127 _textColor = aColor;
01128
01129 [_imageAndTitleView setTextColor:[self textColor]];
01130 [_submenuView setColor:[self textColor]];
01131 }
01132
01133 - (CPColor)textColor
01134 {
01135 return [_menuItem isEnabled] ? (_textColor ? _textColor : [CPColor blackColor]) : [CPColor darkGrayColor];
01136 }
01137
01138 @end
01139
01140 @implementation _CPMenuItemArrowView : CPView
01141 {
01142 CPColor _color;
01143 }
01144
01145 - (void)setColor:(CPColor)aColor
01146 {
01147 if (_color == aColor)
01148 return;
01149
01150 _color = aColor;
01151
01152 [self setNeedsDisplay:YES];
01153 }
01154
01155 - (void)drawRect:(CGRect)aRect
01156 {
01157 var context = [[CPGraphicsContext currentContext] graphicsPort];
01158
01159 CGContextBeginPath(context);
01160
01161 CGContextMoveToPoint(context, 1.0, 4.0);
01162 CGContextAddLineToPoint(context, 9.0, 4.0);
01163 CGContextAddLineToPoint(context, 5.0, 8.0);
01164 CGContextAddLineToPoint(context, 1.0, 4.0);
01165
01166 CGContextClosePath(context);
01167
01168 CGContextSetFillColor(context, _color);
01169 CGContextFillPath(context);
01170 }
01171
01172 @end