00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 @import "_CPImageAndTitleView.j"
00024 @import "CGGeometry.j"
00025
00026 @import "CPControl.j"
00027
00028 #include "CoreGraphics/CGGeometry.h"
00029
00030
00031 CPScaleProportionally = 0;
00032 CPScaleToFit = 1;
00033 CPScaleNone = 2;
00034
00035
00036
00037
00038
00039 CPNoImage = 0;
00040
00041
00042
00043
00044 CPImageOnly = 1;
00045
00046
00047
00048
00049 CPImageLeft = 2;
00050
00051
00052
00053
00054 CPImageRight = 3;
00055
00056
00057
00058
00059 CPImageBelow = 4;
00060
00061
00062
00063
00064 CPImageAbove = 5;
00065
00066
00067
00068
00069 CPImageOverlaps = 6;
00070
00071
00072
00073
00074
00075 CPOnState = 1;
00076
00077
00078
00079
00080 CPOffState = 0;
00081
00082
00083
00084
00085 CPMixedState = -1;
00086
00087
00088
00089
00090
00091 CPRoundedBezelStyle = 1;
00092
00093
00094
00095
00096 CPRegularSquareBezelStyle = 2;
00097
00098
00099
00100
00101 CPThickSquareBezelStyle = 3;
00102
00103
00104
00105
00106 CPThickerSquareBezelStyle = 4;
00107
00108
00109
00110
00111 CPDisclosureBezelStyle = 5;
00112
00113
00114
00115
00116 CPShadowlessSquareBezelStyle = 6;
00117
00118
00119
00120
00121 CPCircularBezelStyle = 7;
00122
00123
00124
00125
00126 CPTexturedSquareBezelStyle = 8;
00127
00128
00129
00130
00131 CPHelpButtonBezelStyle = 9;
00132
00133
00134
00135
00136 CPSmallSquareBezelStyle = 10;
00137
00138
00139
00140
00141 CPTexturedRoundedBezelStyle = 11;
00142
00143
00144
00145
00146 CPRoundRectBezelStyle = 12;
00147
00148
00149
00150
00151 CPRecessedBezelStyle = 13;
00152
00153
00154
00155
00156 CPRoundedDisclosureBezelStyle = 14;
00157
00158
00159
00160
00161 CPHUDBezelStyle = -1;
00162
00163
00164
00165
00166
00167
00168 CPMomentaryLightButton = 0;
00169
00170
00171
00172
00173 CPPushOnPushOffButton = 1;
00174
00175
00176
00177
00178 CPToggleButton = 2;
00179
00180
00181
00182
00183 CPSwitchButton = 3;
00184
00185
00186
00187
00188 CPRadioButton = 4;
00189
00190
00191
00192
00193 CPMomentaryChangeButton = 5;
00194
00195
00196
00197
00198 CPOnOffButton = 6;
00199
00200
00201
00202
00203 CPMomentaryPushInButton = 7;
00204
00205
00206
00207
00208 CPMomentaryPushButton = 0;
00209
00210
00211
00212
00213 CPMomentaryLight = 7;
00214
00215
00216 var CPHUDBezelStyleTextColor = nil;
00217
00218 var _CPButtonClassName = nil,
00219 _CPButtonBezelStyleSizes = {},
00220 _CPButtonBezelStyleIdentifiers = {},
00221 _CPButtonBezelStyleHighlightedIdentifier = @"Highlighted";
00222
00229 @implementation CPButton : CPControl
00230 {
00231 int _tag;
00232 int _state;
00233 BOOL _allowsMixedState;
00234 BOOL _isHighlighted;
00235
00236 CPImage _image;
00237 CPImage _alternateImage;
00238
00239 CPCellImagePosition _imagePosition;
00240 CPImageScaling _imageScaling;
00241
00242 CPString _title;
00243 CPString _alternateTitle;
00244
00245 CPBezelStyle _bezelStyle;
00246 BOOL _isBordered;
00247 CPControlSize _controlSize;
00248
00249 BOOL _bezelBorderNeedsUpdate;
00250
00251 _CPImageAndTitleView _imageAndTitleView;
00252 }
00253
00258 + (void)initialize
00259 {
00260 if (self != [CPButton class])
00261 return;
00262
00263 _CPButtonClassName = [CPButton className];
00264
00265
00266 _CPButtonBezelStyleIdentifiers[CPRoundedBezelStyle] = @"Rounded";
00267 _CPButtonBezelStyleIdentifiers[CPRegularSquareBezelStyle] = @"RegularSquare";
00268 _CPButtonBezelStyleIdentifiers[CPThickSquareBezelStyle] = @"ThickSquare";
00269 _CPButtonBezelStyleIdentifiers[CPThickerSquareBezelStyle] = @"ThickerSquare";
00270 _CPButtonBezelStyleIdentifiers[CPDisclosureBezelStyle] = @"Disclosure";
00271 _CPButtonBezelStyleIdentifiers[CPShadowlessSquareBezelStyle] = @"ShadowlessSquare";
00272 _CPButtonBezelStyleIdentifiers[CPCircularBezelStyle] = @"Circular";
00273 _CPButtonBezelStyleIdentifiers[CPTexturedSquareBezelStyle] = @"TexturedSquare";
00274 _CPButtonBezelStyleIdentifiers[CPHelpButtonBezelStyle] = @"HelpButton";
00275 _CPButtonBezelStyleIdentifiers[CPSmallSquareBezelStyle] = @"SmallSquare";
00276 _CPButtonBezelStyleIdentifiers[CPTexturedRoundedBezelStyle] = @"TexturedRounded";
00277 _CPButtonBezelStyleIdentifiers[CPRoundRectBezelStyle] = @"RoundRect";
00278 _CPButtonBezelStyleIdentifiers[CPRecessedBezelStyle] = @"Recessed";
00279 _CPButtonBezelStyleIdentifiers[CPRoundedDisclosureBezelStyle] = @"RoundedDisclosure";
00280 _CPButtonBezelStyleIdentifiers[CPHUDBezelStyle] = @"HUD";
00281
00282 var regularIdentifier = _CPControlIdentifierForControlSize(CPRegularControlSize),
00283 smallIdentifier = _CPControlIdentifierForControlSize(CPSmallControlSize),
00284 miniIdentifier = _CPControlIdentifierForControlSize(CPMiniControlSize);
00285
00286
00287 var prefix = _CPButtonClassName + _CPButtonBezelStyleIdentifiers[CPRoundRectBezelStyle];
00288
00289 _CPButtonBezelStyleSizes[prefix + regularIdentifier] = [_CGSizeMake(10.0, 18.0), _CGSizeMake(1.0, 18.0), _CGSizeMake(10.0, 18.0)];
00290 _CPButtonBezelStyleSizes[prefix + regularIdentifier + _CPButtonBezelStyleHighlightedIdentifier] = [_CGSizeMake(10.0, 18.0), _CGSizeMake(1.0, 18.0), _CGSizeMake(10.0, 18.0)];
00291
00292
00293 var prefix = _CPButtonClassName + _CPButtonBezelStyleIdentifiers[CPHUDBezelStyle];
00294
00295 _CPButtonBezelStyleSizes[prefix + regularIdentifier] = [_CGSizeMake(13.0, 20.0), _CGSizeMake(1.0, 20.0), _CGSizeMake(13.0, 20.0)];
00296 _CPButtonBezelStyleSizes[prefix + regularIdentifier + _CPButtonBezelStyleHighlightedIdentifier] = [_CGSizeMake(13.0, 20.0), _CGSizeMake(1.0, 20.0), _CGSizeMake(13.0, 20.0)];
00297
00298 CPHUDBezelStyleTextColor = [CPColor whiteColor];
00299
00300
00301 var prefix = _CPButtonClassName + _CPButtonBezelStyleIdentifiers[CPTexturedRoundedBezelStyle];
00302
00303 _CPButtonBezelStyleSizes[prefix + regularIdentifier] = [_CGSizeMake(7.0, 20.0), _CGSizeMake(1.0, 20.0), _CGSizeMake(7.0, 20.0)];
00304 _CPButtonBezelStyleSizes[prefix + regularIdentifier + _CPButtonBezelStyleHighlightedIdentifier] = [_CGSizeMake(7.0, 20.0), _CGSizeMake(1.0, 20.0), _CGSizeMake(7.0, 20.0)];
00305 }
00306
00307
00312 - (void)setButtonType:(CPButtonType)aButtonType
00313 {
00314 if (aButtonType == CPSwitchButton)
00315 {
00316 [self setBordered:NO];
00317 [self setImage:nil];
00318 [self setAlternateImage:nil];
00319 [self setAlignment:CPLeftTextAlignment];
00320 }
00321 }
00322
00323 - (id)initWithFrame:(CGRect)aFrame
00324 {
00325 self = [super initWithFrame:aFrame];
00326
00327 if (self)
00328 {
00329 _imagePosition = CPNoImage;
00330 _imageScaling = CPScaleNone;
00331
00332 _controlSize = CPRegularControlSize;
00333
00334 [self setBezelStyle:CPRoundRectBezelStyle];
00335 [self setBordered:YES];
00336
00337 [self setAlignment:CPCenterTextAlignment];
00338 }
00339
00340 return self;
00341 }
00342
00347 - (void)setImagePosition:(CPCellImagePosition)anImagePosition
00348 {
00349 if (_imagePosition == anImagePosition)
00350 return;
00351
00352 _imagePosition = anImagePosition;
00353
00354 [self drawContentsWithHighlight:_isHighlighted];
00355 }
00356
00360 - (CPCellImagePosition)imagePosition
00361 {
00362 return _imagePosition;
00363 }
00364
00369 - (void)setImageScaling:(CPImageScaling)anImageScaling
00370 {
00371 if (_imageScaling == anImageScaling)
00372 return;
00373
00374 _imageScaling = anImageScaling;
00375
00376 [self drawContentsWithHighlight:_isHighlighted];
00377 }
00378
00382 - (CPImageScaling)imageScaling
00383 {
00384 return _imageScaling;
00385 }
00386
00391 - (void)setTextColor:(CPColor)aColor
00392 {
00393 [super setTextColor:aColor];
00394
00395 [self drawContentsWithHighlight:_isHighlighted];
00396 }
00397
00402 - (void)setFont:(CPFont)aFont
00403 {
00404 [super setFont:aFont];
00405
00406 [self drawContentsWithHighlight:_isHighlighted];
00407 }
00408
00409
00413 - (BOOL)allowsMixedState
00414 {
00415 return _allowsMixedState;
00416 }
00417
00422 - (void)setAllowsMixedState:(BOOL)aFlag
00423 {
00424 _allowsMixedState = aFlag;
00425 }
00426
00430 - (void)setNextState
00431 {
00432 if (_state == CPOffState)
00433 _state = CPOnState;
00434 else
00435 _state = (_state >= CPOnState && _allowsMixedState) ? CPMixedState : CPOffState;
00436 }
00437
00443 - (void)setState:(int)aState
00444 {
00445 _state = aState;
00446 }
00447
00451 - (int)state
00452 {
00453 return _state;
00454 }
00455
00460 - (void)setAlignment:(CPTextAlignment)anAlignment
00461 {
00462 [super setAlignment:anAlignment];
00463
00464 [self drawContentsWithHighlight:_isHighlighted];
00465 }
00466
00471 - (void)setImage:(CPImage)anImage
00472 {
00473 if (_image == anImage)
00474 return;
00475
00476 _image = anImage;
00477
00478 [self drawContentsWithHighlight:_isHighlighted];
00479 }
00480
00484 - (CPImage)image
00485 {
00486 return _image;
00487 }
00488
00493 - (void)setAlternateImage:(CPImage)anImage
00494 {
00495 _alternateImage = anImage;
00496 }
00497
00501 - (CPImage)alternateImage
00502 {
00503 return _alternateImage;
00504 }
00505
00510 - (void)setTitle:(CPString)aTitle
00511 {
00512 if (_title == aTitle)
00513 return;
00514
00515 _title = aTitle;
00516
00517 [self drawContentsWithHighlight:_isHighlighted];
00518 }
00519
00523 - (CPString)title
00524 {
00525 return _title;
00526 }
00527
00531 - (void)tile
00532 {
00533 var size = [self bounds].size;
00534
00535 if (_isBordered)
00536 {
00537 var imageAndTitleSize = CGSizeMakeCopy(size);
00538
00539 if (_bezelStyle == CPHUDBezelStyle)
00540 imageAndTitleSize.height -= 4.0;
00541 else if (_bezelStyle == CPRoundRectBezelStyle)
00542 imageAndTitleSize.height -= 2.0;
00543 else if (_bezelStyle == CPTexturedRoundedBezelStyle)
00544 imageAndTitleSize.height -= 2.0;
00545
00546 [_imageAndTitleView setFrameSize:imageAndTitleSize];
00547 }
00548 else
00549 [_imageAndTitleView setFrameSize:size];
00550 }
00551
00555 - (void)sizeToFit
00556 {
00557 [_imageAndTitleView sizeToFit];
00558
00559 var frame = [_imageAndTitleView frame],
00560 height = CGRectGetHeight(frame);
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570 [self setFrameSize:CGSizeMake(CGRectGetWidth(frame), height)];
00571 }
00572
00577 - (void)setFrameSize:(CGSize)aSize
00578 {
00579 [super setFrameSize:aSize];
00580
00581 [self tile];
00582 }
00583
00588 - (void)highlight:(BOOL)aFlag
00589 {
00590 [self drawBezelWithHighlight:aFlag];
00591 [self drawContentsWithHighlight:aFlag];
00592 }
00593
00598 - (void)setTag:(int)aTag
00599 {
00600 _tag = aTag;
00601 }
00602
00606 - (int)tag
00607 {
00608 return _tag;
00609 }
00610
00615 - (void)mouseDown:(CPEvent)anEvent
00616 {
00617 _isHighlighted = YES;
00618
00619 [self highlight:_isHighlighted];
00620 }
00621
00626 - (void)mouseDragged:(CPEvent)anEvent
00627 {
00628 _isHighlighted = CGRectContainsPoint([self bounds], [self convertPoint:[anEvent locationInWindow] fromView:nil]);
00629
00630 [self highlight:_isHighlighted];
00631 }
00632
00637 - (void)mouseUp:(CPEvent)anEvent
00638 {
00639 _isHighlighted = NO;
00640
00641 [self highlight:_isHighlighted];
00642
00643 [super mouseUp:anEvent];
00644 }
00645
00650 - (void)setControlSize:(CPControlSize)aControlSize
00651 {
00652 if (_controlSize == aControlSize)
00653 return;
00654
00655 _controlSize = aControlSize;
00656
00657 [self drawBezelWithHighlight:_isHighlighted];
00658 [self _updateTextAttributes];
00659 }
00660
00664 - (CPControlSize)controlSize
00665 {
00666 return _controlSize;
00667 }
00668
00673 - (void)setBordered:(BOOL)isBordered
00674 {
00675 if (_isBordered == isBordered)
00676 return;
00677
00678 _isBordered = isBordered;
00679
00680 [self updateBackgroundColors];
00681 [self drawBezelWithHighlight:_isHighlighted];
00682
00683 [self tile];
00684 }
00685
00689 - (BOOL)isBordered
00690 {
00691 return _isBordered;
00692 }
00693
00698 - (void)setBezelStyle:(CPBezelStyle)aBezelStyle
00699 {
00700
00701 if (aBezelStyle == CPRoundedBezelStyle ||
00702 aBezelStyle == CPRoundedBezelStyle ||
00703 aBezelStyle == CPRegularSquareBezelStyle ||
00704 aBezelStyle == CPThickSquareBezelStyle ||
00705 aBezelStyle == CPThickerSquareBezelStyle ||
00706 aBezelStyle == CPDisclosureBezelStyle ||
00707 aBezelStyle == CPShadowlessSquareBezelStyle ||
00708 aBezelStyle == CPCircularBezelStyle ||
00709 aBezelStyle == CPTexturedSquareBezelStyle ||
00710 aBezelStyle == CPHelpButtonBezelStyle ||
00711 aBezelStyle == CPSmallSquareBezelStyle ||
00712 aBezelStyle == CPRecessedBezelStyle ||
00713 aBezelStyle == CPRoundedDisclosureBezelStyle)
00714 aBezelStyle = CPRoundRectBezelStyle;
00715
00716 if (_bezelStyle == aBezelStyle)
00717 return;
00718
00719 _bezelStyle = aBezelStyle;
00720
00721 [self updateBackgroundColors];
00722 [self drawBezelWithHighlight:_isHighlighted];
00723
00724 [self _updateTextAttributes];
00725 [self tile];
00726 }
00727
00731 - (int)bezelStyle
00732 {
00733 return _bezelStyle;
00734 }
00735
00736
00737 - (void)updateBackgroundColors
00738 {
00739 if (_isBordered)
00740 {
00741 [self setBackgroundColor:_CPControlThreePartImagePattern(
00742 NO,
00743 _CPButtonBezelStyleSizes,
00744 _CPButtonClassName,
00745 _CPButtonBezelStyleIdentifiers[_bezelStyle],
00746 _CPControlIdentifierForControlSize(_controlSize)) forName:CPControlNormalBackgroundColor];
00747
00748 [self setBackgroundColor:_CPControlThreePartImagePattern(
00749 NO,
00750 _CPButtonBezelStyleSizes,
00751 _CPButtonClassName,
00752 _CPButtonBezelStyleIdentifiers[_bezelStyle],
00753 _CPControlIdentifierForControlSize(_controlSize),
00754 _CPButtonBezelStyleHighlightedIdentifier) forName:CPControlHighlightedBackgroundColor];
00755 }
00756 else
00757 {
00758 [self setBackgroundColor:nil forName:CPControlNormalBackgroundColor];
00759 [self setBackgroundColor:nil forName:CPControlHighlightedBackgroundColor];
00760 }
00761 }
00762
00763
00764 - (void)drawBezelWithHighlight:(BOOL)shouldHighlight
00765 {
00766 _bezelBorderNeedsUpdate = ![self window];
00767
00768 if (_bezelBorderNeedsUpdate)
00769 return;
00770
00771 [self setBackgroundColorWithName:shouldHighlight ? CPControlHighlightedBackgroundColor : CPControlNormalBackgroundColor];
00772 }
00773
00774
00775 - (void)drawContentsWithHighlight:(BOOL)isHighlighted
00776 {
00777 if (!_title && !_image && !_alternateTitle && !_alternateImage && !_imageAndTitleView)
00778 return;
00779
00780 if (!_imageAndTitleView)
00781 {
00782 _imageAndTitleView = [[_CPImageAndTitleView alloc] initWithFrame:[self bounds]];
00783
00784 [self addSubview:_imageAndTitleView];
00785
00786 [self tile];
00787 }
00788
00789 [_imageAndTitleView setFont:[self font]];
00790 [_imageAndTitleView setTextColor:[self textColor]];
00791 [_imageAndTitleView setAlignment:[self alignment]];
00792 [_imageAndTitleView setImagePosition:_imagePosition];
00793 [_imageAndTitleView setImageScaling:_imageScaling];
00794
00795 [_imageAndTitleView setTitle:isHighlighted && _alternateTitle ? _alternateTitle : _title];
00796 [_imageAndTitleView setImage:isHighlighted && _alternateImage ? _alternateImage : _image];
00797 }
00798
00799 - (void)viewDidMoveToWindow
00800 {
00801 if (_bezelBorderNeedsUpdate)
00802 [self drawBezelWithHighlight:_isHighlighted];
00803 }
00804
00805
00806 - (void)_updateTextAttributes
00807 {
00808 if (_bezelStyle == CPHUDBezelStyle)
00809 [self setTextColor:CPHUDBezelStyleTextColor];
00810
00811 if (_controlSize == CPRegularControlSize)
00812 [self setFont:[CPFont systemFontOfSize:11.0]];
00813 }
00814
00815 @end
00816
00817
00818 var CPButtonImageKey = @"CPButtonImageKey",
00819 CPButtonAlternateImageKey = @"CPButtonAlternateImageKey",
00820 CPButtonTitleKey = @"CPButtonTitleKey",
00821 CPButtonAlteranteTitleKey = @"CPButtonAlternateTitleKey",
00822 CPButtonImageAndTitleViewKey = @"CPButtonImageAndTitleViewKey",
00823 CPButtonImagePositionKey = @"CPButtonImagePositionKey",
00824 CPButtonImageScalingKey = @"CPButtonImageScalingKey",
00825 CPButtonIsBorderedKey = @"CPButtonIsBorderedKey",
00826 CPButtonBezelStyleKey = @"CPButtonBezelStyleKey",
00827 CPButtonImageAndTitleViewKey = @"CPButtonImageAndTitleViewKey";
00828
00829 @implementation CPButton (CPCoding)
00830
00835 - (id)initWithCoder:(CPCoder)aCoder
00836 {
00837 self = [super initWithCoder:aCoder];
00838
00839 if (self)
00840 {
00841 _controlSize = CPRegularControlSize;
00842
00843 [self setImage:[aCoder decodeObjectForKey:CPButtonImageKey]];
00844 [self setAlternateImage:[aCoder decodeObjectForKey:CPButtonAlternateImageKey]];
00845
00846 [self setTitle:[aCoder decodeObjectForKey:CPButtonTitleKey]];
00847
00848 [self setImagePosition:[aCoder decodeIntForKey:CPButtonImagePositionKey]];
00849 [self setImageScaling:[aCoder decodeIntForKey:CPButtonImageScalingKey]];
00850
00851 [self setBezelStyle:[aCoder decodeIntForKey:CPButtonBezelStyleKey]];
00852 [self setBordered:[aCoder decodeBoolForKey:CPButtonIsBorderedKey]];
00853 }
00854
00855 return self;
00856 }
00857
00862 - (void)encodeWithCoder:(CPCoder)aCoder
00863 {
00864
00865
00866 var actualSubviews = _subviews;
00867
00868 _subviews = [_subviews copy];
00869 [_subviews removeObjectIdenticalTo:_imageAndTitleView];
00870
00871 [super encodeWithCoder:aCoder];
00872
00873 _subviews = actualSubviews;
00874
00875 [aCoder encodeObject:_image forKey:CPButtonImageKey];
00876 [aCoder encodeObject:_alternateImage forKey:CPButtonAlternateImageKey];
00877
00878 [aCoder encodeObject:_title forKey:CPButtonTitleKey];
00879
00880 [aCoder encodeInt:_imagePosition forKey:CPButtonImagePositionKey];
00881 [aCoder encodeInt:_imageScaling forKey:CPButtonImageScalingKey];
00882
00883 [aCoder encodeBool:_isBordered forKey:CPButtonIsBorderedKey];
00884 [aCoder encodeInt:_bezelStyle forKey:CPButtonBezelStyleKey];
00885 }
00886
00887 @end