API 0.9.5
AppKit/CPStepper.j
Go to the documentation of this file.
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
 All Classes Files Functions Variables Defines