![]() |
API 0.9.5
|
00001 /* 00002 * CPControl.j 00003 * AppKit 00004 * 00005 * Created by Francisco Tolmasky. 00006 * Copyright 2008, 280 North, Inc. 00007 * 00008 * This library is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * This library is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 */ 00022 00023 #import "../Foundation/Ref.h" 00024 00025 00026 CPLeftTextAlignment = 0; 00027 CPRightTextAlignment = 1; 00028 CPCenterTextAlignment = 2; 00029 CPJustifiedTextAlignment = 3; 00030 CPNaturalTextAlignment = 4; 00031 00032 CPRegularControlSize = 0; 00033 CPSmallControlSize = 1; 00034 CPMiniControlSize = 2; 00035 00036 CPLineBreakByWordWrapping = 0; 00037 CPLineBreakByCharWrapping = 1; 00038 CPLineBreakByClipping = 2; 00039 CPLineBreakByTruncatingHead = 3; 00040 CPLineBreakByTruncatingTail = 4; 00041 CPLineBreakByTruncatingMiddle = 5; 00042 00043 CPTopVerticalTextAlignment = 1; 00044 CPCenterVerticalTextAlignment = 2; 00045 CPBottomVerticalTextAlignment = 3; 00046 00047 CPScaleProportionally = 0; 00048 CPScaleToFit = 1; 00049 CPScaleNone = 2; 00050 00051 CPNoImage = 0; 00052 CPImageOnly = 1; 00053 CPImageLeft = 2; 00054 CPImageRight = 3; 00055 CPImageBelow = 4; 00056 CPImageAbove = 5; 00057 CPImageOverlaps = 6; 00058 00059 CPOnState = 1; 00060 CPOffState = 0; 00061 CPMixedState = -1; 00062 00063 CPControlNormalBackgroundColor = "CPControlNormalBackgroundColor"; 00064 CPControlSelectedBackgroundColor = "CPControlSelectedBackgroundColor"; 00065 CPControlHighlightedBackgroundColor = "CPControlHighlightedBackgroundColor"; 00066 CPControlDisabledBackgroundColor = "CPControlDisabledBackgroundColor"; 00067 00068 CPControlTextDidBeginEditingNotification = "CPControlTextDidBeginEditingNotification"; 00069 CPControlTextDidChangeNotification = "CPControlTextDidChangeNotification"; 00070 CPControlTextDidEndEditingNotification = "CPControlTextDidEndEditingNotification"; 00071 00072 var CPControlBlackColor = [CPColor blackColor]; 00073 00080 @implementation CPControl : CPView 00081 { 00082 id _value; 00083 CPFormatter _formatter; 00084 00085 // Target-Action Support 00086 id _target; 00087 SEL _action; 00088 int _sendActionOn; 00089 BOOL _sendsActionOnEndEditing; 00090 00091 // Mouse Tracking Support 00092 BOOL _continuousTracking; 00093 BOOL _trackingWasWithinFrame; 00094 unsigned _trackingMouseDownFlags; 00095 CGPoint _previousTrackingLocation; 00096 } 00097 00098 + (CPDictionary)themeAttributes 00099 { 00100 return [CPDictionary dictionaryWithObjects:[CPLeftTextAlignment, 00101 CPTopVerticalTextAlignment, 00102 CPLineBreakByClipping, 00103 [CPColor blackColor], 00104 [CPFont systemFontOfSize:12.0], 00105 [CPNull null], 00106 _CGSizeMakeZero(), 00107 CPImageLeft, 00108 CPScaleToFit, 00109 _CGSizeMakeZero(), 00110 _CGSizeMake(-1.0, -1.0)] 00111 forKeys:[@"alignment", 00112 @"vertical-alignment", 00113 @"line-break-mode", 00114 @"text-color", 00115 @"font", 00116 @"text-shadow-color", 00117 @"text-shadow-offset", 00118 @"image-position", 00119 @"image-scaling", 00120 @"min-size", 00121 @"max-size"]]; 00122 } 00123 00124 + (void)initialize 00125 { 00126 if (self === [CPControl class]) 00127 { 00128 [self exposeBinding:@"value"]; 00129 [self exposeBinding:@"objectValue"]; 00130 [self exposeBinding:@"stringValue"]; 00131 [self exposeBinding:@"integerValue"]; 00132 [self exposeBinding:@"intValue"]; 00133 [self exposeBinding:@"doubleValue"]; 00134 [self exposeBinding:@"floatValue"]; 00135 00136 [self exposeBinding:@"enabled"]; 00137 } 00138 } 00139 00140 + (Class)_binderClassForBinding:(CPString)theBinding 00141 { 00142 if (theBinding === CPValueBinding) 00143 return [_CPValueBinder class]; 00144 00145 return [super _binderClassForBinding:theBinding]; 00146 } 00147 00151 - (void)_continuouslyReverseSetBinding 00152 { 00153 var binderClass = [[self class] _binderClassForBinding:CPValueBinding], 00154 theBinding = [binderClass getBinding:CPValueBinding forObject:self]; 00155 00156 if ([theBinding continuouslyUpdatesValue]) 00157 [theBinding reverseSetValueFor:@"objectValue"]; 00158 } 00159 00160 - (void)_reverseSetBinding 00161 { 00162 var binderClass = [[self class] _binderClassForBinding:CPValueBinding], 00163 theBinding = [binderClass getBinding:CPValueBinding forObject:self]; 00164 00165 [theBinding reverseSetValueFor:@"objectValue"]; 00166 } 00167 00168 - (id)initWithFrame:(CGRect)aFrame 00169 { 00170 self = [super initWithFrame:aFrame]; 00171 00172 if (self) 00173 { 00174 _sendActionOn = CPLeftMouseUpMask; 00175 _trackingMouseDownFlags = 0; 00176 } 00177 00178 return self; 00179 } 00180 00186 - (void)setAction:(SEL)anAction 00187 { 00188 _action = anAction; 00189 } 00190 00194 - (SEL)action 00195 { 00196 return _action; 00197 } 00198 00204 - (void)setTarget:(id)aTarget 00205 { 00206 _target = aTarget; 00207 } 00208 00212 - (id)target 00213 { 00214 return _target; 00215 } 00216 00223 - (BOOL)sendAction:(SEL)anAction to:(id)anObject 00224 { 00225 [self _reverseSetBinding]; 00226 00227 return [CPApp sendAction:anAction to:anObject from:self]; 00228 } 00229 00230 - (int)sendActionOn:(int)mask 00231 { 00232 var previousMask = _sendActionOn; 00233 00234 _sendActionOn = mask; 00235 00236 return previousMask; 00237 } 00238 00242 - (BOOL)isContinuous 00243 { 00244 // Some subclasses should redefine this with CPLeftMouseDraggedMask 00245 return (_sendActionOn & CPPeriodicMask) !== 0; 00246 } 00247 00251 - (void)setContinuous:(BOOL)flag 00252 { 00253 // Some subclasses should redefine this with CPLeftMouseDraggedMask 00254 if (flag) 00255 _sendActionOn |= CPPeriodicMask; 00256 else 00257 _sendActionOn &= ~CPPeriodicMask; 00258 } 00259 00263 - (BOOL)tracksMouseOutsideOfFrame 00264 { 00265 return NO; 00266 } 00267 00268 - (void)trackMouse:(CPEvent)anEvent 00269 { 00270 var type = [anEvent type], 00271 currentLocation = [self convertPoint:[anEvent locationInWindow] fromView:nil], 00272 isWithinFrame = [self tracksMouseOutsideOfFrame] || CGRectContainsPoint([self bounds], currentLocation); 00273 00274 if (type === CPLeftMouseUp) 00275 { 00276 [self stopTracking:_previousTrackingLocation at:currentLocation mouseIsUp:YES]; 00277 00278 _trackingMouseDownFlags = 0; 00279 00280 if (isWithinFrame) 00281 [self setThemeState:CPThemeStateHovered]; 00282 } 00283 else 00284 { 00285 [self unsetThemeState:CPThemeStateHovered]; 00286 00287 if (type === CPLeftMouseDown) 00288 { 00289 _trackingMouseDownFlags = [anEvent modifierFlags]; 00290 _continuousTracking = [self startTrackingAt:currentLocation]; 00291 } 00292 else if (type === CPLeftMouseDragged) 00293 { 00294 if (isWithinFrame) 00295 { 00296 if (!_trackingWasWithinFrame) 00297 _continuousTracking = [self startTrackingAt:currentLocation]; 00298 00299 else if (_continuousTracking) 00300 _continuousTracking = [self continueTracking:_previousTrackingLocation at:currentLocation]; 00301 } 00302 else 00303 [self stopTracking:_previousTrackingLocation at:currentLocation mouseIsUp:NO]; 00304 } 00305 00306 [CPApp setTarget:self selector:@selector(trackMouse:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES]; 00307 } 00308 00309 if ((_sendActionOn & (1 << type)) && isWithinFrame) 00310 [self sendAction:_action to:_target]; 00311 00312 _trackingWasWithinFrame = isWithinFrame; 00313 _previousTrackingLocation = currentLocation; 00314 } 00315 00316 - (void)setState:(int)state 00317 { 00318 } 00319 00320 - (int)nextState 00321 { 00322 return 0; 00323 } 00324 00330 - (void)performClick:(id)sender 00331 { 00332 if (![self isEnabled]) 00333 return; 00334 00335 [self highlight:YES]; 00336 [self setState:[self nextState]]; 00337 00338 try 00339 { 00340 [self sendAction:[self action] to:[self target]]; 00341 } 00342 catch (e) 00343 { 00344 throw e; 00345 } 00346 finally 00347 { 00348 [CPTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(unhighlightButtonTimerDidFinish:) userInfo:nil repeats:NO]; 00349 } 00350 } 00351 00356 - (void)unhighlightButtonTimerDidFinish:(id)sender 00357 { 00358 [self highlight:NO]; 00359 } 00360 00364 - (unsigned)mouseDownFlags 00365 { 00366 return _trackingMouseDownFlags; 00367 } 00368 00369 - (BOOL)startTrackingAt:(CGPoint)aPoint 00370 { 00371 [self highlight:YES]; 00372 00373 return (_sendActionOn & CPPeriodicMask) || (_sendActionOn & CPLeftMouseDraggedMask); 00374 } 00375 00376 - (BOOL)continueTracking:(CGPoint)lastPoint at:(CGPoint)aPoint 00377 { 00378 return (_sendActionOn & CPPeriodicMask) || (_sendActionOn & CPLeftMouseDraggedMask); 00379 } 00380 00381 - (void)stopTracking:(CGPoint)lastPoint at:(CGPoint)aPoint mouseIsUp:(BOOL)mouseIsUp 00382 { 00383 [self highlight:NO]; 00384 } 00385 00386 - (void)mouseDown:(CPEvent)anEvent 00387 { 00388 if (![self isEnabled]) 00389 return; 00390 00391 [self trackMouse:anEvent]; 00392 } 00393 00394 - (void)mouseEntered:(CPEvent)anEvent 00395 { 00396 if (![self isEnabled]) 00397 return; 00398 00399 [self setThemeState:CPThemeStateHovered]; 00400 } 00401 00402 - (void)mouseExited:(CPEvent)anEvent 00403 { 00404 var currentLocation = [self convertPoint:[anEvent locationInWindow] fromView:nil], 00405 isWithinFrame = [self tracksMouseOutsideOfFrame] || CGRectContainsPoint([self bounds], currentLocation); 00406 00407 // Make sure we're not still in the frame because Cappuccino will sent mouseExited events 00408 // for all of the (ephemeral) subviews of a view as well. 00409 if (!isWithinFrame) 00410 [self unsetThemeState:CPThemeStateHovered]; 00411 } 00412 00416 - (id)objectValue 00417 { 00418 return _value; 00419 } 00420 00424 - (void)setObjectValue:(id)anObject 00425 { 00426 _value = anObject; 00427 00428 [self setNeedsLayout]; 00429 [self setNeedsDisplay:YES]; 00430 } 00431 00435 - (float)floatValue 00436 { 00437 var floatValue = parseFloat(_value, 10); 00438 return isNaN(floatValue) ? 0.0 : floatValue; 00439 } 00440 00444 - (void)setFloatValue:(float)aValue 00445 { 00446 [self setObjectValue:aValue]; 00447 } 00448 00452 - (double)doubleValue 00453 { 00454 var doubleValue = parseFloat(_value, 10); 00455 return isNaN(doubleValue) ? 0.0 : doubleValue; 00456 } 00457 00461 - (void)setDoubleValue:(double)anObject 00462 { 00463 [self setObjectValue:anObject]; 00464 } 00465 00469 - (int)intValue 00470 { 00471 var intValue = parseInt(_value, 10); 00472 return isNaN(intValue) ? 0.0 : intValue; 00473 } 00474 00478 - (void)setIntValue:(int)anObject 00479 { 00480 [self setObjectValue:anObject]; 00481 } 00482 00486 - (int)integerValue 00487 { 00488 var intValue = parseInt(_value, 10); 00489 return isNaN(intValue) ? 0.0 : intValue; 00490 } 00491 00495 - (void)setIntegerValue:(int)anObject 00496 { 00497 [self setObjectValue:anObject]; 00498 } 00499 00503 - (CPString)stringValue 00504 { 00505 if (_formatter && _value !== undefined && _value !== nil) 00506 { 00507 var formattedValue = [self hasThemeState:CPThemeStateEditing] ? [_formatter editingStringForObjectValue:_value] : [_formatter stringForObjectValue:_value]; 00508 00509 if (formattedValue !== nil && formattedValue !== undefined) 00510 return formattedValue; 00511 } 00512 00513 return (_value === undefined || _value === nil) ? "" : String(_value); 00514 } 00515 00519 - (void)setStringValue:(CPString)aString 00520 { 00521 // Cocoa raises an invalid parameter assertion and returns if you pass nil. 00522 if (aString === nil || aString === undefined) 00523 { 00524 CPLog.warn("nil sent to CPControl -setStringValue"); 00525 return; 00526 } 00527 00528 var value; 00529 00530 if (_formatter) 00531 { 00532 value = nil; 00533 00534 if ([_formatter getObjectValue:AT_REF(value) forString:aString errorDescription:nil] === NO) 00535 { 00536 // If the given string is non-empty and doesn't work, Cocoa tries an empty string. 00537 if (!aString || [_formatter getObjectValue:AT_REF(value) forString:@"" errorDescription:nil] === NO) 00538 value = undefined; // Means the value is invalid 00539 } 00540 } 00541 else 00542 value = aString; 00543 00544 [self setObjectValue:value]; 00545 } 00546 00547 - (void)takeDoubleValueFrom:(id)sender 00548 { 00549 if ([sender respondsToSelector:@selector(doubleValue)]) 00550 [self setDoubleValue:[sender doubleValue]]; 00551 } 00552 00553 00554 - (void)takeFloatValueFrom:(id)sender 00555 { 00556 if ([sender respondsToSelector:@selector(floatValue)]) 00557 [self setFloatValue:[sender floatValue]]; 00558 } 00559 00560 - (void)takeIntegerValueFrom:(id)sender 00561 { 00562 if ([sender respondsToSelector:@selector(integerValue)]) 00563 [self setIntegerValue:[sender integerValue]]; 00564 } 00565 00566 - (void)takeIntValueFrom:(id)sender 00567 { 00568 if ([sender respondsToSelector:@selector(intValue)]) 00569 [self setIntValue:[sender intValue]]; 00570 } 00571 00572 - (void)takeObjectValueFrom:(id)sender 00573 { 00574 if ([sender respondsToSelector:@selector(objectValue)]) 00575 [self setObjectValue:[sender objectValue]]; 00576 } 00577 00578 - (void)takeStringValueFrom:(id)sender 00579 { 00580 if ([sender respondsToSelector:@selector(stringValue)]) 00581 [self setStringValue:[sender stringValue]]; 00582 } 00583 00584 - (void)textDidBeginEditing:(CPNotification)note 00585 { 00586 //this looks to prevent false propagation of notifications for other objects 00587 if ([note object] != self) 00588 return; 00589 00590 [[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidBeginEditingNotification object:self userInfo:[CPDictionary dictionaryWithObject:[note object] forKey:"CPFieldEditor"]]; 00591 } 00592 00593 - (void)textDidChange:(CPNotification)note 00594 { 00595 //this looks to prevent false propagation of notifications for other objects 00596 if ([note object] != self) 00597 return; 00598 00599 [[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidChangeNotification object:self userInfo:[CPDictionary dictionaryWithObject:[note object] forKey:"CPFieldEditor"]]; 00600 } 00601 00602 - (void)textDidEndEditing:(CPNotification)note 00603 { 00604 //this looks to prevent false propagation of notifications for other objects 00605 if ([note object] != self) 00606 return; 00607 00608 [self _reverseSetBinding]; 00609 00610 [[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidEndEditingNotification object:self userInfo:[CPDictionary dictionaryWithObject:[note object] forKey:"CPFieldEditor"]]; 00611 } 00612 00624 - (void)setAlignment:(CPTextAlignment)alignment 00625 { 00626 [self setValue:alignment forThemeAttribute:@"alignment"]; 00627 } 00628 00632 - (CPTextAlignment)alignment 00633 { 00634 return [self valueForThemeAttribute:@"alignment"]; 00635 } 00636 00646 - (void)setVerticalAlignment:(CPTextVerticalAlignment)alignment 00647 { 00648 [self setValue:alignment forThemeAttribute:@"vertical-alignment"]; 00649 } 00650 00654 - (CPTextVerticalAlignment)verticalAlignment 00655 { 00656 return [self valueForThemeAttribute:@"vertical-alignment"]; 00657 } 00658 00671 - (void)setLineBreakMode:(CPLineBreakMode)mode 00672 { 00673 [self setValue:mode forThemeAttribute:@"line-break-mode"]; 00674 } 00675 00679 - (CPLineBreakMode)lineBreakMode 00680 { 00681 return [self valueForThemeAttribute:@"line-break-mode"]; 00682 } 00683 00689 - (void)setTextColor:(CPColor)aColor 00690 { 00691 [self setValue:aColor forThemeAttribute:@"text-color"]; 00692 } 00693 00697 - (CPColor)textColor 00698 { 00699 return [self valueForThemeAttribute:@"text-color"]; 00700 } 00701 00705 - (void)setTextShadowColor:(CPColor)aColor 00706 { 00707 [self setValue:aColor forThemeAttribute:@"text-shadow-color"]; 00708 } 00709 00713 - (CPColor)textShadowColor 00714 { 00715 return [self valueForThemeAttribute:@"text-shadow-color"]; 00716 } 00717 00723 - (void)setTextShadowOffset:(CGSize)offset 00724 { 00725 [self setValue:offset forThemeAttribute:@"text-shadow-offset"]; 00726 } 00727 00731 - (CGSize)textShadowOffset 00732 { 00733 return [self valueForThemeAttribute:@"text-shadow-offset"]; 00734 } 00735 00739 - (void)setFont:(CPFont)aFont 00740 { 00741 [self setValue:aFont forThemeAttribute:@"font"]; 00742 } 00743 00747 - (CPFont)font 00748 { 00749 return [self valueForThemeAttribute:@"font"]; 00750 } 00751 00765 - (void)setImagePosition:(CPCellImagePosition)position 00766 { 00767 [self setValue:position forThemeAttribute:@"image-position"]; 00768 } 00769 00773 - (CPCellImagePosition)imagePosition 00774 { 00775 return [self valueForThemeAttribute:@"image-position"]; 00776 } 00777 00787 - (void)setImageScaling:(CPImageScaling)scaling 00788 { 00789 [self setValue:scaling forThemeAttribute:@"image-scaling"]; 00790 } 00791 00795 - (CPImageScaling)imageScaling 00796 { 00797 return [self valueForThemeAttribute:@"image-scaling"]; 00798 } 00799 00806 - (void)setEnabled:(BOOL)isEnabled 00807 { 00808 if (isEnabled) 00809 [self unsetThemeState:CPThemeStateDisabled]; 00810 else 00811 [self setThemeState:CPThemeStateDisabled]; 00812 } 00813 00817 - (BOOL)isEnabled 00818 { 00819 return ![self hasThemeState:CPThemeStateDisabled]; 00820 } 00821 00827 - (void)highlight:(BOOL)shouldHighlight 00828 { 00829 [self setHighlighted:shouldHighlight]; 00830 } 00831 00837 - (void)setHighlighted:(BOOL)isHighlighted 00838 { 00839 if (isHighlighted) 00840 [self setThemeState:CPThemeStateHighlighted]; 00841 else 00842 [self unsetThemeState:CPThemeStateHighlighted]; 00843 } 00844 00848 - (BOOL)isHighlighted 00849 { 00850 return [self hasThemeState:CPThemeStateHighlighted]; 00851 } 00852 00853 @end 00854 00855 var CPControlValueKey = "CPControlValueKey", 00856 CPControlControlStateKey = @"CPControlControlStateKey", 00857 CPControlIsEnabledKey = "CPControlIsEnabledKey", 00858 00859 CPControlTargetKey = "CPControlTargetKey", 00860 CPControlActionKey = "CPControlActionKey", 00861 CPControlSendActionOnKey = "CPControlSendActionOnKey", 00862 00863 CPControlSendsActionOnEndEditingKey = "CPControlSendsActionOnEndEditingKey"; 00864 00865 var __Deprecated__CPImageViewImageKey = @"CPImageViewImageKey"; 00866 00867 @implementation CPControl (CPCoding) 00868 00869 /* 00870 Initializes the control by unarchiving it from a coder. 00871 00872 @param aCoder the coder from which to unarchive the control 00873 @return the initialized control 00874 */ 00875 - (id)initWithCoder:(CPCoder)aCoder 00876 { 00877 self = [super initWithCoder:aCoder]; 00878 00879 if (self) 00880 { 00881 [self setObjectValue:[aCoder decodeObjectForKey:CPControlValueKey]]; 00882 00883 [self setTarget:[aCoder decodeObjectForKey:CPControlTargetKey]]; 00884 [self setAction:[aCoder decodeObjectForKey:CPControlActionKey]]; 00885 00886 [self sendActionOn:[aCoder decodeIntForKey:CPControlSendActionOnKey]]; 00887 [self setSendsActionOnEndEditing:[aCoder decodeBoolForKey:CPControlSendsActionOnEndEditingKey]]; 00888 } 00889 00890 return self; 00891 } 00892 00893 /* 00894 Archives the control to the provided coder. 00895 00896 @param aCoder the coder to which the control will be archived. 00897 */ 00898 - (void)encodeWithCoder:(CPCoder)aCoder 00899 { 00900 [super encodeWithCoder:aCoder]; 00901 00902 if (_sendsActionOnEndEditing) 00903 [aCoder encodeBool:_sendsActionOnEndEditing forKey:CPControlSendsActionOnEndEditingKey]; 00904 00905 var objectValue = [self objectValue]; 00906 00907 if (objectValue !== nil) 00908 [aCoder encodeObject:objectValue forKey:CPControlValueKey]; 00909 00910 if (_target !== nil) 00911 [aCoder encodeConditionalObject:_target forKey:CPControlTargetKey]; 00912 00913 if (_action !== nil) 00914 [aCoder encodeObject:_action forKey:CPControlActionKey]; 00915 00916 [aCoder encodeInt:_sendActionOn forKey:CPControlSendActionOnKey]; 00917 } 00918 00919 @end 00920 00921 var _CPControlSizeIdentifiers = [], 00922 _CPControlCachedColorWithPatternImages = {}, 00923 _CPControlCachedThreePartImagePattern = {}; 00924 00925 _CPControlSizeIdentifiers[CPRegularControlSize] = "Regular"; 00926 _CPControlSizeIdentifiers[CPSmallControlSize] = "Small"; 00927 _CPControlSizeIdentifiers[CPMiniControlSize] = "Mini"; 00928 00929 function _CPControlIdentifierForControlSize(aControlSize) 00930 { 00931 return _CPControlSizeIdentifiers[aControlSize]; 00932 } 00933 00934 function _CPControlColorWithPatternImage(sizes, aClassName) 00935 { 00936 var index = 1, 00937 count = arguments.length, 00938 identifier = ""; 00939 00940 for (; index < count; ++index) 00941 identifier += arguments[index]; 00942 00943 var color = _CPControlCachedColorWithPatternImages[identifier]; 00944 00945 if (!color) 00946 { 00947 var bundle = [CPBundle bundleForClass:[CPControl class]]; 00948 00949 color = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:aClassName + "/" + identifier + ".png"] size:sizes[identifier]]]; 00950 00951 _CPControlCachedColorWithPatternImages[identifier] = color; 00952 } 00953 00954 return color; 00955 } 00956 00957 function _CPControlThreePartImagePattern(isVertical, sizes, aClassName) 00958 { 00959 var index = 2, 00960 count = arguments.length, 00961 identifier = ""; 00962 00963 for (; index < count; ++index) 00964 identifier += arguments[index]; 00965 00966 var color = _CPControlCachedThreePartImagePattern[identifier]; 00967 00968 if (!color) 00969 { 00970 var bundle = [CPBundle bundleForClass:[CPControl class]], 00971 path = aClassName + "/" + identifier; 00972 00973 sizes = sizes[identifier]; 00974 00975 color = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:[ 00976 [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:path + "0.png"] size:sizes[0]], 00977 [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:path + "1.png"] size:sizes[1]], 00978 [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:path + "2.png"] size:sizes[2]] 00979 ] isVertical:isVertical]]; 00980 00981 _CPControlCachedThreePartImagePattern[identifier] = color; 00982 } 00983 00984 return color; 00985 } 00986 00987 @implementation CPControl (CPSynthesizedAccessors) 00988 00992 - (CPFormatter)formatter 00993 { 00994 return _formatter; 00995 } 00996 01000 - (void)setFormatter:(CPFormatter)aValue 01001 { 01002 _formatter = aValue; 01003 } 01004 01008 - (BOOL)sendsActionOnEndEditing 01009 { 01010 return _sendsActionOnEndEditing; 01011 } 01012 01016 - (void)setSendsActionOnEndEditing:(BOOL)aValue 01017 { 01018 _sendsActionOnEndEditing = aValue; 01019 } 01020 01021 @end