![]() |
API 0.9.5
|
00001 /* 00002 * CPStepper.j 00003 * AppKit 00004 * 00005 * Created by Antoine Mercadal 00006 * Copyright 2009, Antoine Mercadal 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 00024 00025 00031 @implementation CPStepper: CPControl 00032 { 00033 BOOL _valueWraps; 00034 int _increment; 00035 int _maxValue; 00036 int _minValue; 00037 00038 CPButton _buttonDown; 00039 CPButton _buttonUp; 00040 } 00041 00042 #pragma mark - 00043 #pragma mark Initialization 00044 00052 + (CPStepper)stepperWithInitialValue:(float)aValue minValue:(float)aMinValue maxValue:(float)aMaxValue 00053 { 00054 var stepper = [[CPStepper alloc] initWithFrame:_CGRectMake(0, 0, 19, 25)]; 00055 [stepper setDoubleValue:aValue]; 00056 [stepper setMinValue:aMinValue]; 00057 [stepper setMaxValue:aMaxValue]; 00058 00059 return stepper; 00060 } 00061 00070 + (CPStepper)stepper 00071 { 00072 return [CPStepper stepperWithInitialValue:0.0 minValue:0.0 maxValue:59.0]; 00073 } 00074 00080 - (id)initWithFrame:(CGRect)aFrame 00081 { 00082 if (self = [super initWithFrame:aFrame]) 00083 { 00084 _maxValue = 59.0; 00085 _minValue = 0.0; 00086 _increment = 1.0; 00087 _valueWraps = YES; 00088 00089 [self setDoubleValue:0.0]; 00090 00091 _buttonUp = [[CPButton alloc] initWithFrame:_CGRectMakeZero()]; 00092 [_buttonUp setContinuous:YES]; 00093 [_buttonUp setTarget:self]; 00094 [_buttonUp setAction:@selector(_buttonDidClick:)]; 00095 [_buttonUp setAutoresizingMask:CPViewNotSizable]; 00096 [self addSubview:_buttonUp]; 00097 00098 _buttonDown = [[CPButton alloc] initWithFrame:_CGRectMakeZero()]; 00099 [_buttonDown setContinuous:YES]; 00100 [_buttonDown setTarget:self]; 00101 [_buttonDown setAction:@selector(_buttonDidClick:)]; 00102 [_buttonDown setAutoresizingMask:CPViewNotSizable]; 00103 [self addSubview:_buttonDown]; 00104 00105 [self setNeedsLayout]; 00106 } 00107 00108 return self; 00109 } 00110 00111 #pragma mark - 00112 #pragma mark Superclass overrides 00113 00118 - (void)setEnabled:(BOOL)shouldEnabled 00119 { 00120 [super setEnabled:shouldEnabled]; 00121 00122 [_buttonUp setEnabled:shouldEnabled]; 00123 [_buttonDown setEnabled:shouldEnabled]; 00124 } 00125 00126 00127 - (void)setFrame:(CGRect)aFrame 00128 { 00129 var upSize = [self valueForThemeAttribute:@"up-button-size"], 00130 downSize = [self valueForThemeAttribute:@"down-button-size"], 00131 minSize = _CGSizeMake(upSize.width, upSize.height + downSize.height), 00132 frame = _CGRectMakeCopy(aFrame); 00133 00134 frame.size.width = Math.max(minSize.width, frame.size.width); 00135 frame.size.height = Math.max(minSize.height, frame.size.height); 00136 [super setFrame:frame]; 00137 } 00138 00140 - (void)layoutSubviews 00141 { 00142 var aFrame = [self frame], 00143 upSize = [self valueForThemeAttribute:@"up-button-size"], 00144 downSize = [self valueForThemeAttribute:@"down-button-size"], 00145 upFrame = _CGRectMake(aFrame.size.width - upSize.width, 0, upSize.width, upSize.height), 00146 downFrame = _CGRectMake(aFrame.size.width - downSize.width, upSize.height, downSize.width, downSize.height); 00147 [_buttonUp setFrame:upFrame]; 00148 [_buttonDown setFrame:downFrame]; 00149 00150 [_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:CPThemeStateBordered] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered]; 00151 [_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:CPThemeStateBordered | CPThemeStateDisabled] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateDisabled]; 00152 [_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:CPThemeStateBordered | CPThemeStateHighlighted] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateHighlighted]; 00153 [_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:CPThemeStateBordered] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered]; 00154 [_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:CPThemeStateBordered | CPThemeStateDisabled] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateDisabled]; 00155 [_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:CPThemeStateBordered | CPThemeStateHighlighted] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateHighlighted]; 00156 } 00157 00162 - (void)setAutorepeat:(BOOL)shouldAutoRepeat 00163 { 00164 [_buttonUp setContinuous:shouldAutoRepeat]; 00165 [_buttonDown setContinuous:shouldAutoRepeat]; 00166 } 00167 00172 - (void)setDoubleValue:(float)aValue 00173 { 00174 if (aValue > _maxValue) 00175 [super setDoubleValue:_valueWraps ? _minValue : _maxValue]; 00176 else if (aValue < _minValue) 00177 [super setDoubleValue:_valueWraps ? _maxValue : _minValue]; 00178 else 00179 [super setDoubleValue:aValue]; 00180 } 00181 00182 #pragma mark - 00183 #pragma mark Actions 00184 00186 - (IBAction)_buttonDidClick:(id)aSender 00187 { 00188 if (![self isEnabled]) 00189 return; 00190 00191 if (aSender == _buttonUp) 00192 [self setDoubleValue:([self doubleValue] + _increment)]; 00193 else 00194 [self setDoubleValue:([self doubleValue] - _increment)]; 00195 00196 if (_target && _action && [_target respondsToSelector:_action]) 00197 [self sendAction:_action to:_target]; 00198 } 00199 00204 - (IBAction)performClickUp:(id)aSender 00205 { 00206 [_buttonUp performClick:aSender]; 00207 } 00208 00213 - (IBAction)performClickDown:(id)aSender 00214 { 00215 [_buttonDown performClick:aSender]; 00216 } 00217 00218 00219 #pragma mark - 00220 #pragma mark Theming 00221 00222 + (CPString)defaultThemeClass 00223 { 00224 return @"stepper"; 00225 } 00226 00227 + (id)themeAttributes 00228 { 00229 return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], _CGSizeMakeZero(), _CGSizeMakeZero()] 00230 forKeys:[@"bezel-color-up-button", @"bezel-color-down-button", @"up-button-size", @"down-button-size"]]; 00231 } 00232 00233 @end 00234 00235 00236 @implementation CPStepper (CPCodingCompliance) 00237 00238 - (id)initWithCoder:(CPCoder)aCoder 00239 { 00240 if (self = [super initWithCoder:aCoder]) 00241 { 00242 _maxValue = [aCoder decodeObjectForKey:@"_maxValue"]; 00243 _minValue = [aCoder decodeObjectForKey:@"_minValue"]; 00244 _increment = [aCoder decodeObjectForKey:@"_increment"]; 00245 _buttonUp = [aCoder decodeObjectForKey:@"_buttonUp"]; 00246 _buttonDown = [aCoder decodeObjectForKey:@"_buttonDown"]; 00247 } 00248 return self; 00249 } 00250 00251 - (void)encodeWithCoder:(CPCoder)aCoder 00252 { 00253 [super encodeWithCoder:aCoder]; 00254 00255 [aCoder encodeObject:_maxValue forKey:@"_maxValue"]; 00256 [aCoder encodeObject:_minValue forKey:@"_minValue"]; 00257 [aCoder encodeObject:_increment forKey:@"_increment"]; 00258 [aCoder encodeObject:_buttonUp forKey:@"_buttonUp"]; 00259 [aCoder encodeObject:_buttonDown forKey:@"_buttonDown"]; 00260 } 00261 00262 @end 00263 00264 @implementation CPStepper (CPSynthesizedAccessors) 00265 00269 - (BOOL)valueWraps 00270 { 00271 return _valueWraps; 00272 } 00273 00277 - (void)setValueWraps:(BOOL)aValue 00278 { 00279 _valueWraps = aValue; 00280 } 00281 00285 - (int)increment 00286 { 00287 return _increment; 00288 } 00289 00293 - (void)setIncrement:(int)aValue 00294 { 00295 _increment = aValue; 00296 } 00297 00301 - (int)maxValue 00302 { 00303 return _maxValue; 00304 } 00305 00309 - (void)setMaxValue:(int)aValue 00310 { 00311 _maxValue = aValue; 00312 } 00313 00317 - (int)minValue 00318 { 00319 return _minValue; 00320 } 00321 00325 - (void)setMinValue:(int)aValue 00326 { 00327 _minValue = aValue; 00328 } 00329 00330 @end