00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 @import "CPControl.j"
00024
00025 #include "CoreGraphics/CGGeometry.h"
00026
00027
00028
00029 CPScrollerNoPart = 0;
00030 CPScrollerDecrementPage = 1;
00031 CPScrollerKnob = 2;
00032 CPScrollerIncrementPage = 3;
00033 CPScrollerDecrementLine = 4;
00034 CPScrollerIncrementLine = 5;
00035 CPScrollerKnobSlot = 6;
00036
00037 CPScrollerIncrementArrow = 0;
00038 CPScrollerDecrementArrow = 1;
00039
00040 CPNoScrollerParts = 0;
00041 CPOnlyScrollerArrows = 1;
00042 CPAllScrollerParts = 2;
00043
00044 var _CPScrollerWidths = [],
00045 _CPScrollerKnobMinimumHeights = [],
00046 _CPScrollerArrowHeights = [],
00047 _CPScrollerArrowUsableHeights = [];
00048
00049 _CPScrollerWidths[CPRegularControlSize] = 14.0;
00050 _CPScrollerWidths[CPSmallControlSize] = 11.0;
00051 _CPScrollerWidths[CPMiniControlSize] = 11.0;
00052
00053 _CPScrollerKnobMinimumHeights[CPRegularControlSize] = 18.0;
00054 _CPScrollerKnobMinimumHeights[CPSmallControlSize] = 12.0;
00055 _CPScrollerKnobMinimumHeights[CPMiniControlSize] = 12.0;
00056
00057 _CPScrollerArrowHeights[CPRegularControlSize] = 21.0;
00058 _CPScrollerArrowHeights[CPSmallControlSize] = 16.0;
00059 _CPScrollerArrowHeights[CPMiniControlSize] = 16.0;
00060
00061 _CPScrollerArrowUsableHeights[CPRegularControlSize] = 16.0
00062 _CPScrollerArrowUsableHeights[CPSmallControlSize] = 10.0;
00063 _CPScrollerArrowUsableHeights[CPMiniControlSize] = 10.0;
00064
00065 var _CPScrollerKnobIdentifier = @"Knob",
00066 _CPScrollerKnobSlotIdentifier = @"KnobSlot",
00067 _CPScrollerDecrementArrowIdentifier = @"DecrementArrow",
00068 _CPScrollerIncrementArrowIdentifier = @"IncrementArrow",
00069 _CPScrollerHorizontalIdentifier = @"Horizontal",
00070 _CPScrollerVerticalIdentifier = @"Vertical",
00071 _CPScrollerHighlightedIdentifier = @"Highlighted",
00072 _CPScrollerDisabledIdentifier = @"Disabled";
00073
00074 var _CPScrollerClassName = nil,
00075 _CPScrollerPartSizes = {};
00076
00081 @implementation CPScroller : CPControl
00082 {
00083 CPControlSize _controlSize;
00084 CPUsableScrollerParts _usableParts;
00085 CPArray _partRects;
00086
00087 BOOL _isHorizontal;
00088 float _knobProportion;
00089
00090 CPScrollerPart _hitPart;
00091
00092 CPScrollerPart _trackingPart;
00093 float _trackingFloatValue;
00094 CGPoint _trackingStartPoint;
00095
00096 CPView _knobView;
00097 CPView _knobSlotView;
00098
00099 CPView _decrementArrowView;
00100 CPView _incrementArrowView;
00101 }
00102
00103
00104
00105
00106 + (void)initialize
00107 {
00108 if (self != [CPScroller class])
00109 return;
00110
00111 _CPScrollerClassName = [self className];
00112
00113 var regularIdentifier = _CPControlIdentifierForControlSize(CPRegularControlSize),
00114 smallIdentifier = _CPControlIdentifierForControlSize(CPSmallControlSize),
00115 miniIdentifier = _CPControlIdentifierForControlSize(CPMiniControlSize);
00116
00117
00118 var prefix = _CPScrollerClassName + _CPScrollerKnobIdentifier + _CPScrollerHorizontalIdentifier;
00119
00120 _CPScrollerPartSizes[prefix + regularIdentifier] = [_CGSizeMake(9.0, _CPScrollerWidths[CPRegularControlSize]), _CGSizeMake(1.0, _CPScrollerWidths[CPRegularControlSize]), _CGSizeMake(9.0, _CPScrollerWidths[CPRegularControlSize])];
00121 _CPScrollerPartSizes[prefix + smallIdentifier] = [_CGSizeMake(6.0, _CPScrollerWidths[CPSmallControlSize]), _CGSizeMake(1.0, _CPScrollerWidths[CPSmallControlSize]), _CGSizeMake(6.0, _CPScrollerWidths[CPSmallControlSize])];
00122 _CPScrollerPartSizes[prefix + miniIdentifier] = [_CGSizeMake(6.0, _CPScrollerWidths[CPMiniControlSize]), _CGSizeMake(1.0, _CPScrollerWidths[CPMiniControlSize]), _CGSizeMake(6.0, _CPScrollerWidths[CPMiniControlSize])];
00123
00124
00125 var prefix = _CPScrollerClassName + _CPScrollerKnobIdentifier + _CPScrollerVerticalIdentifier;
00126
00127 _CPScrollerPartSizes[prefix + regularIdentifier] = [_CGSizeMake(_CPScrollerWidths[CPRegularControlSize], 9.0), _CGSizeMake(_CPScrollerWidths[CPRegularControlSize], 1.0), _CGSizeMake(_CPScrollerWidths[CPRegularControlSize], 9.0)];
00128 _CPScrollerPartSizes[prefix + smallIdentifier] = [_CGSizeMake(_CPScrollerWidths[CPSmallControlSize], 6.0), _CGSizeMake(_CPScrollerWidths[CPSmallControlSize], 1.0), _CGSizeMake(_CPScrollerWidths[CPSmallControlSize], 6.0)];
00129 _CPScrollerPartSizes[prefix + miniIdentifier] = [_CGSizeMake(_CPScrollerWidths[CPMiniControlSize], 6.0), _CGSizeMake(_CPScrollerWidths[CPMiniControlSize], 1.0), _CGSizeMake(_CPScrollerWidths[CPMiniControlSize], 6.0)];
00130
00131
00132 var prefix = _CPScrollerClassName + _CPScrollerKnobSlotIdentifier + _CPScrollerHorizontalIdentifier;
00133
00134 _CPScrollerPartSizes[prefix + regularIdentifier] = _CGSizeMake(1.0, _CPScrollerWidths[CPRegularControlSize]);
00135 _CPScrollerPartSizes[prefix + smallIdentifier] = _CGSizeMake(1.0, _CPScrollerWidths[CPSmallControlSize]);
00136 _CPScrollerPartSizes[prefix + miniIdentifier] = _CGSizeMake(1.0, _CPScrollerWidths[CPMiniControlSize]);
00137
00138
00139 var prefix = _CPScrollerClassName + _CPScrollerKnobSlotIdentifier + _CPScrollerVerticalIdentifier;
00140
00141 _CPScrollerPartSizes[prefix + regularIdentifier] = _CGSizeMake(_CPScrollerWidths[CPRegularControlSize], 1.0);
00142 _CPScrollerPartSizes[prefix + smallIdentifier] = _CGSizeMake(_CPScrollerWidths[CPSmallControlSize], 1.0);
00143 _CPScrollerPartSizes[prefix + miniIdentifier] = _CGSizeMake(_CPScrollerWidths[CPMiniControlSize], 1.0);
00144
00145
00146 var prefix = _CPScrollerClassName + _CPScrollerDecrementArrowIdentifier + _CPScrollerHorizontalIdentifier;
00147
00148 _CPScrollerPartSizes[prefix + regularIdentifier] = _CGSizeMake(_CPScrollerArrowHeights[CPRegularControlSize], _CPScrollerWidths[CPRegularControlSize]);
00149 _CPScrollerPartSizes[prefix + regularIdentifier + _CPScrollerHighlightedIdentifier] = _CGSizeMake(_CPScrollerArrowHeights[CPRegularControlSize], _CPScrollerWidths[CPRegularControlSize]);
00150 _CPScrollerPartSizes[prefix + smallIdentifier] = _CGSizeMake(_CPScrollerArrowHeights[CPSmallControlSize] , _CPScrollerWidths[CPSmallControlSize]);
00151 _CPScrollerPartSizes[prefix + smallIdentifier + _CPScrollerHighlightedIdentifier] = _CGSizeMake(_CPScrollerArrowHeights[CPSmallControlSize] , _CPScrollerWidths[CPSmallControlSize]);
00152 _CPScrollerPartSizes[prefix + miniIdentifier] = _CGSizeMake(_CPScrollerArrowHeights[CPMiniControlSize], _CPScrollerWidths[CPMiniControlSize]);
00153 _CPScrollerPartSizes[prefix + miniIdentifier + _CPScrollerHighlightedIdentifier] = _CGSizeMake(_CPScrollerArrowHeights[CPMiniControlSize], _CPScrollerWidths[CPMiniControlSize]);
00154
00155
00156 var prefix = _CPScrollerClassName + _CPScrollerDecrementArrowIdentifier + _CPScrollerVerticalIdentifier;
00157
00158 _CPScrollerPartSizes[prefix + regularIdentifier] = _CGSizeMake(_CPScrollerWidths[CPRegularControlSize], _CPScrollerArrowHeights[CPRegularControlSize]);
00159 _CPScrollerPartSizes[prefix + regularIdentifier + _CPScrollerHighlightedIdentifier] = _CGSizeMake(_CPScrollerWidths[CPRegularControlSize], _CPScrollerArrowHeights[CPRegularControlSize]);
00160 _CPScrollerPartSizes[prefix + smallIdentifier] = _CGSizeMake(_CPScrollerWidths[CPSmallControlSize], _CPScrollerArrowHeights[CPSmallControlSize]);
00161 _CPScrollerPartSizes[prefix + smallIdentifier + _CPScrollerHighlightedIdentifier] = _CGSizeMake(_CPScrollerWidths[CPSmallControlSize], _CPScrollerArrowHeights[CPSmallControlSize]);
00162 _CPScrollerPartSizes[prefix + miniIdentifier] = _CGSizeMake(_CPScrollerWidths[CPMiniControlSize], _CPScrollerArrowHeights[CPMiniControlSize]);
00163 _CPScrollerPartSizes[prefix + miniIdentifier + _CPScrollerHighlightedIdentifier] = _CGSizeMake(_CPScrollerWidths[CPMiniControlSize], _CPScrollerArrowHeights[CPMiniControlSize]);
00164
00165
00166 var prefix = _CPScrollerClassName + _CPScrollerIncrementArrowIdentifier + _CPScrollerHorizontalIdentifier;
00167
00168 _CPScrollerPartSizes[prefix + regularIdentifier] = _CGSizeMake(_CPScrollerArrowHeights[CPRegularControlSize], _CPScrollerWidths[CPRegularControlSize]);
00169 _CPScrollerPartSizes[prefix + regularIdentifier + _CPScrollerHighlightedIdentifier] = _CGSizeMake(_CPScrollerArrowHeights[CPRegularControlSize], _CPScrollerWidths[CPRegularControlSize]);
00170 _CPScrollerPartSizes[prefix + smallIdentifier] = _CGSizeMake(_CPScrollerArrowHeights[CPSmallControlSize], _CPScrollerWidths[CPSmallControlSize]);
00171 _CPScrollerPartSizes[prefix + smallIdentifier + _CPScrollerHighlightedIdentifier] = _CGSizeMake(_CPScrollerArrowHeights[CPSmallControlSize], _CPScrollerWidths[CPSmallControlSize]);
00172 _CPScrollerPartSizes[prefix + miniIdentifier] = _CGSizeMake(_CPScrollerArrowHeights[CPMiniControlSize], _CPScrollerWidths[CPMiniControlSize]);
00173 _CPScrollerPartSizes[prefix + miniIdentifier + _CPScrollerHighlightedIdentifier] = _CGSizeMake(_CPScrollerArrowHeights[CPMiniControlSize], _CPScrollerWidths[CPMiniControlSize]);
00174
00175
00176 var prefix = _CPScrollerClassName + _CPScrollerIncrementArrowIdentifier + _CPScrollerVerticalIdentifier;
00177
00178 _CPScrollerPartSizes[prefix + regularIdentifier] = _CGSizeMake(_CPScrollerWidths[CPRegularControlSize], _CPScrollerArrowHeights[CPRegularControlSize]);
00179 _CPScrollerPartSizes[prefix + regularIdentifier + _CPScrollerHighlightedIdentifier] = _CGSizeMake(_CPScrollerWidths[CPRegularControlSize], _CPScrollerArrowHeights[CPRegularControlSize]);
00180 _CPScrollerPartSizes[prefix + smallIdentifier] = _CGSizeMake(_CPScrollerWidths[CPSmallControlSize], _CPScrollerArrowHeights[CPSmallControlSize]);
00181 _CPScrollerPartSizes[prefix + smallIdentifier + _CPScrollerHighlightedIdentifier] = _CGSizeMake(_CPScrollerWidths[CPSmallControlSize], _CPScrollerArrowHeights[CPSmallControlSize]);
00182 _CPScrollerPartSizes[prefix + miniIdentifier] = _CGSizeMake(_CPScrollerWidths[CPMiniControlSize], _CPScrollerArrowHeights[CPMiniControlSize]);
00183 _CPScrollerPartSizes[prefix + miniIdentifier + _CPScrollerHighlightedIdentifier] = _CGSizeMake(_CPScrollerWidths[CPMiniControlSize], _CPScrollerArrowHeights[CPMiniControlSize]);
00184 }
00185
00186
00187
00188 - (id)initWithFrame:(CGRect)aFrame
00189 {
00190 self = [super initWithFrame:aFrame];
00191
00192 if (self)
00193 {
00194 _controlSize = CPRegularControlSize;
00195 _partRects = [];
00196
00197 [self setFloatValue:0.0 knobProportion:1.0];
00198
00199 _isHorizontal = CPRectGetWidth(aFrame) > CPRectGetHeight(aFrame);
00200
00201 _hitPart = CPScrollerNoPart;
00202
00203 [self checkSpaceForParts];
00204 [self drawParts];
00205
00206 [self layoutSubviews];
00207 }
00208
00209 return self;
00210 }
00211
00212
00216 + (float)scrollerWidth
00217 {
00218 return [self scrollerWidthForControlSize:CPRegularControlSize];
00219 }
00220
00225 + (float)scrollerWidthForControlSize:(CPControlSize)aControlSize
00226 {
00227 return _CPScrollerWidths[aControlSize];
00228 }
00229
00234 - (void)setControlSize:(CPControlSize)aControlSize
00235 {
00236 if (_controlSize == aControlSize)
00237 return;
00238
00239 _controlSize = aControlSize;
00240
00241 [self drawKnobSlot];
00242 [self drawKnob];
00243 [self drawArrow:CPScrollerDecrementArrow highlight:NO];
00244 [self drawArrow:CPScrollerIncrementArrow highlight:NO];
00245
00246 [self layoutSubviews];
00247 }
00248
00252 - (CPControlSize)controlSize
00253 {
00254 return _controlSize;
00255 }
00256
00257
00262 - (void)setFloatValue:(float)aValue
00263 {
00264 [super setFloatValue:MIN(1.0, MAX(0.0, aValue))];
00265
00266 [self checkSpaceForParts];
00267 [self layoutSubviews];
00268 }
00269
00275 - (void)setFloatValue:(float)aValue knobProportion:(float)aProportion
00276 {
00277 _knobProportion = MIN(1.0, MAX(0.0001, aProportion));
00278
00279 [self setFloatValue:aValue];
00280 }
00281
00285 - (float)knobProportion
00286 {
00287 return _knobProportion;
00288 }
00289
00290
00291
00292 - (CGRect)rectForPart:(CPScrollerPart)aPart
00293 {
00294 if (aPart == CPScrollerNoPart)
00295 return _CGRectMakeZero();
00296
00297 return _partRects[aPart];
00298 }
00299
00305 - (CPScrollerPart)testPart:(CGPoint)aPoint
00306 {
00307 aPoint = [self convertPoint:aPoint fromView:nil];
00308
00309
00310
00311
00312 if (CGRectContainsPoint([self rectForPart:CPScrollerKnob], aPoint))
00313 return CPScrollerKnob;
00314
00315 if (CGRectContainsPoint([self rectForPart:CPScrollerDecrementPage], aPoint))
00316 return CPScrollerDecrementPage;
00317
00318 if (CGRectContainsPoint([self rectForPart:CPScrollerIncrementPage], aPoint))
00319 return CPScrollerIncrementPage;
00320
00321 if (CGRectContainsPoint([self rectForPart:CPScrollerDecrementLine], aPoint))
00322 return CPScrollerDecrementLine;
00323
00324 if (CGRectContainsPoint([self rectForPart:CPScrollerIncrementLine], aPoint))
00325 return CPScrollerIncrementLine;
00326
00327 if (CGRectContainsPoint([self rectForPart:CPScrollerKnobSlot], aPoint))
00328 return CPScrollerKnobSlot;
00329
00330 return CPScrollerNoPart;
00331 }
00332
00336 - (void)checkSpaceForParts
00337 {
00338 var bounds = [self bounds];
00339
00340
00341 if (_knobProportion == 1.0)
00342 {
00343 _usableParts = CPNoScrollerParts;
00344
00345 _partRects[CPScrollerDecrementPage] = _CGRectMakeZero();
00346 _partRects[CPScrollerKnob] = _CGRectMakeZero();
00347 _partRects[CPScrollerIncrementPage] = _CGRectMakeZero();
00348 _partRects[CPScrollerDecrementLine] = _CGRectMakeZero();
00349 _partRects[CPScrollerIncrementLine] = _CGRectMakeZero();
00350
00351
00352 _partRects[CPScrollerKnobSlot] = _CGRectMakeCopy(bounds);
00353
00354 return;
00355 }
00356
00357 var width = _CGRectGetWidth(bounds),
00358 height = _CGRectGetHeight(bounds),
00359 usableArrowHeight = _CPScrollerArrowUsableHeights[_controlSize],
00360 slotWidth = (_isHorizontal ? width : height) - 2.0 * usableArrowHeight,
00361 knobWidth = MAX(_CPScrollerKnobMinimumHeights[_controlSize], (slotWidth * _knobProportion));
00362
00363 _usableParts = CPAllScrollerParts;
00364
00365 var arrowHeight = _CPScrollerArrowHeights[_controlSize],
00366 knobLocation = usableArrowHeight + (slotWidth - knobWidth) * [self floatValue];
00367
00368
00369 if (_isHorizontal)
00370 {
00371
00372
00373 _partRects[CPScrollerDecrementPage] = _CGRectMake(usableArrowHeight, 0.0, knobLocation - usableArrowHeight, height);
00374 _partRects[CPScrollerKnob] = _CGRectMake(knobLocation, 0.0, knobWidth, _CPScrollerWidths[_controlSize]);
00375 _partRects[CPScrollerIncrementPage] = _CGRectMake(knobLocation + knobWidth, 0.0, width - (knobLocation + knobWidth) - usableArrowHeight, height);
00376 _partRects[CPScrollerKnobSlot] = _CGRectMake(usableArrowHeight, 0.0, slotWidth, height);
00377 _partRects[CPScrollerDecrementLine] = _CGRectMake(0.0, 0.0, arrowHeight, height);
00378 _partRects[CPScrollerIncrementLine] = _CGRectMake(width - _CPScrollerArrowHeights[_controlSize], 0.0, arrowHeight, height);
00379 }
00380 else
00381 {
00382
00383
00384 _partRects[CPScrollerDecrementPage] = _CGRectMake(0.0, usableArrowHeight, width, knobLocation - usableArrowHeight);
00385 _partRects[CPScrollerKnob] = _CGRectMake(0.0, knobLocation, _CPScrollerWidths[_controlSize], knobWidth);
00386 _partRects[CPScrollerIncrementPage] = _CGRectMake(0.0, knobLocation + knobWidth, width, height - (knobLocation + knobWidth) - usableArrowHeight);
00387 _partRects[CPScrollerKnobSlot] = _CGRectMake(0.0, usableArrowHeight, width, slotWidth);
00388 _partRects[CPScrollerDecrementLine] = _CGRectMake(0.0, 0.0, width, arrowHeight);
00389 _partRects[CPScrollerIncrementLine] = _CGRectMake(0.0, height - _CPScrollerArrowHeights[_controlSize], width, arrowHeight);
00390 }
00391 }
00392
00397 - (CPUsableScrollerParts)usableParts
00398 {
00399 return _usableParts;
00400 }
00401
00402
00408 - (void)drawArrow:(CPScrollerArrow)anArrow highlight:(BOOL)shouldHighlight
00409 {
00410 var identifier = (anArrow == CPScrollerDecrementArrow ? _CPScrollerDecrementArrowIdentifier : _CPScrollerIncrementArrowIdentifier),
00411 arrowView = (anArrow == CPScrollerDecrementArrow ? _decrementArrowView : _incrementArrowView);
00412
00413 [arrowView setBackgroundColor:_CPControlColorWithPatternImage(
00414 _CPScrollerPartSizes,
00415 _CPScrollerClassName,
00416 identifier,
00417 _isHorizontal ? _CPScrollerHorizontalIdentifier : _CPScrollerVerticalIdentifier,
00418 _CPControlIdentifierForControlSize(_controlSize),
00419 shouldHighlight ? _CPScrollerHighlightedIdentifier : @"")];
00420 }
00421
00425 - (void)drawKnob
00426 {
00427 [_knobView setBackgroundColor:_CPControlThreePartImagePattern(
00428 !_isHorizontal,
00429 _CPScrollerPartSizes,
00430 _CPScrollerClassName,
00431 _CPScrollerKnobIdentifier,
00432 _isHorizontal ? _CPScrollerHorizontalIdentifier : _CPScrollerVerticalIdentifier,
00433 _CPControlIdentifierForControlSize(_controlSize))];
00434 }
00435
00439 - (void)drawKnobSlot
00440 {
00441 [_knobSlotView setBackgroundColor:_CPControlColorWithPatternImage(
00442 _CPScrollerPartSizes,
00443 _CPScrollerClassName,
00444 _CPScrollerKnobSlotIdentifier,
00445 _isHorizontal ? _CPScrollerHorizontalIdentifier : _CPScrollerVerticalIdentifier,
00446 _CPControlIdentifierForControlSize(_controlSize))];
00447 }
00448
00452 - (void)drawParts
00453 {
00454 _knobSlotView = [[CPView alloc] initWithFrame:_CGRectMakeZero()];
00455
00456 [_knobSlotView setHitTests:NO];
00457
00458 [self addSubview:_knobSlotView];
00459
00460 [self drawKnobSlot];
00461
00462 _knobView = [[CPView alloc] initWithFrame:_CGRectMakeZero()];
00463
00464 [_knobView setHitTests:NO];
00465
00466 [self addSubview:_knobView];
00467
00468 [self drawKnob];
00469
00470 _decrementArrowView = [[CPView alloc] initWithFrame:_CGRectMakeZero()];
00471
00472 [_decrementArrowView setHitTests:NO];
00473
00474 [self addSubview:_decrementArrowView];
00475
00476 [self drawArrow:CPScrollerDecrementArrow highlight:NO];
00477
00478 _incrementArrowView = [[CPView alloc] initWithFrame:_CGRectMakeZero()];
00479
00480 [_incrementArrowView setHitTests:NO];
00481
00482 [self addSubview:_incrementArrowView];
00483
00484 [self drawArrow:CPScrollerIncrementArrow highlight:NO];
00485 }
00486
00493 - (void)highlight:(BOOL)shouldHighlight
00494 {
00495 if (_trackingPart == CPScrollerDecrementLine)
00496 [self drawArrow:CPScrollerDecrementArrow highlight:shouldHighlight];
00497
00498 else if (_trackingPart == CPScrollerIncrementLine)
00499 [self drawArrow:CPScrollerIncrementArrow highlight:shouldHighlight];
00500 }
00501
00502
00506 - (CPScrollerPart)hitPart
00507 {
00508 return _hitPart;
00509 }
00510
00515 - (void)trackKnob:(CPEvent)anEvent
00516 {
00517 var type = [anEvent type];
00518
00519 if (type == CPLeftMouseUp)
00520 {
00521 _hitPart = CPScrollerNoPart;
00522
00523 return;
00524 }
00525
00526 if (type == CPLeftMouseDown)
00527 {
00528 _trackingFloatValue = [self floatValue];
00529 _trackingStartPoint = [self convertPoint:[anEvent locationInWindow] fromView:nil];
00530 }
00531
00532 else if (type == CPLeftMouseDragged)
00533 {
00534 var knobRect = [self rectForPart:CPScrollerKnob],
00535 knobSlotRect = [self rectForPart:CPScrollerKnobSlot],
00536 remainder = _isHorizontal ? (_CGRectGetWidth(knobSlotRect) - _CGRectGetWidth(knobRect)) : (_CGRectGetHeight(knobSlotRect) - _CGRectGetHeight(knobRect));
00537
00538 if (remainder <= 0)
00539 [self setFloatValue:0.0];
00540 else
00541 {
00542 var location = [self convertPoint:[anEvent locationInWindow] fromView:nil];
00543 delta = _isHorizontal ? location.x - _trackingStartPoint.x : location.y - _trackingStartPoint.y;
00544
00545 [self setFloatValue:_trackingFloatValue + delta / remainder];
00546 }
00547 }
00548
00549 [CPApp setTarget:self selector:@selector(trackKnob:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
00550
00551 [self sendAction:[self action] to:[self target]];
00552 }
00553
00558 - (void)trackScrollButtons:(CPEvent)anEvent
00559 {
00560 var type = [anEvent type];
00561
00562 if (type == CPLeftMouseUp)
00563 {
00564 [self highlight:NO];
00565 [CPEvent stopPeriodicEvents];
00566
00567 _hitPart = CPScrollerNoPart;
00568
00569 return;
00570 }
00571
00572 if (type == CPLeftMouseDown)
00573 {
00574 _trackingPart = [self hitPart];
00575
00576 _trackingStartPoint = [self convertPoint:[anEvent locationInWindow] fromView:nil];
00577
00578 if ([anEvent modifierFlags] & CPAlternateKeyMask)
00579 {
00580 if (_trackingPart == CPScrollerDecrementLine)
00581 _hitPart = CPScrollerDecrementPage;
00582 else if (_trackingPart == CPScrollerIncrementLine)
00583 _hitPart = CPScrollerIncrementPage;
00584 else if (_trackingPart == CPScrollerDecrementPage || _trackingPart == CPScrollerIncrementPage)
00585 {
00586 var knobRect = [self rectForPart:CPScrollerKnob],
00587 knobWidth = _isHorizontal ? _CGRectGetWidth(knobRect) : _CGRectGetHeight(knobRect),
00588 knobSlotRect = [self rectForPart:CPScrollerKnobSlot],
00589 remainder = (_isHorizontal ? _CGRectGetWidth(knobSlotRect) : _CGRectGetHeight(knobSlotRect)) - knobWidth;
00590
00591 [self setFloatValue:((_isHorizontal ? _trackingStartPoint.x - _CGRectGetMinX(knobSlotRect) : _trackingStartPoint.y - _CGRectGetMinY(knobSlotRect)) - knobWidth / 2.0) / remainder];
00592
00593 _hitPart = CPScrollerKnob;
00594
00595 [self sendAction:[self action] to:[self target]];
00596
00597
00598 return [self trackKnob:anEvent];
00599 }
00600 }
00601
00602 [self highlight:YES];
00603 [self sendAction:[self action] to:[self target]];
00604
00605 [CPEvent startPeriodicEventsAfterDelay:0.5 withPeriod:0.04];
00606 }
00607
00608 else if (type == CPLeftMouseDragged)
00609 {
00610 _trackingStartPoint = [self convertPoint:[anEvent locationInWindow] fromView:nil];
00611
00612 if (_trackingPart == CPScrollerDecrementPage || _trackingPart == CPScrollerIncrementPage)
00613 {
00614 var hitPart = [self testPart:[anEvent locationInWindow]];
00615
00616 if (hitPart == CPScrollerDecrementPage || hitPart == CPScrollerIncrementPage)
00617 {
00618 _trackingPart = hitPart;
00619 _hitPart = hitPart;
00620 }
00621 }
00622
00623 [self highlight:CGRectContainsPoint([self rectForPart:_trackingPart], _trackingStartPoint)];
00624 }
00625 else if (type == CPPeriodic && CGRectContainsPoint([self rectForPart:_trackingPart], _trackingStartPoint))
00626 [self sendAction:[self action] to:[self target]];
00627
00628 [CPApp setTarget:self selector:@selector(trackScrollButtons:) forNextEventMatchingMask:CPPeriodicMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
00629
00630 }
00631
00632 - (void)setFrameSize:(CGSize)aSize
00633 {
00634 [super setFrameSize:aSize];
00635
00636 [self checkSpaceForParts];
00637
00638 var frame = [self frame],
00639 isHorizontal = CPRectGetWidth(frame) > CPRectGetHeight(frame);
00640
00641 if (_isHorizontal != isHorizontal)
00642 {
00643 _isHorizontal = isHorizontal;
00644
00645 [self drawParts];
00646 }
00647
00648 [self layoutSubviews];
00649 }
00650
00654 - (void)layoutSubviews
00655 {
00656 [_knobSlotView setFrame:[self rectForPart:CPScrollerKnobSlot]];
00657
00658 var usableParts = [self usableParts],
00659 hidden = !(usableParts == CPAllScrollerParts);
00660
00661 if (hidden != [_knobView isHidden])
00662 {
00663 [_knobView setHidden:hidden];
00664 [_decrementArrowView setHidden:hidden];
00665 [_incrementArrowView setHidden:hidden];
00666 }
00667
00668 if (!hidden)
00669 {
00670 [_knobView setFrame:[self rectForPart:CPScrollerKnob]];
00671 [_decrementArrowView setFrame:[self rectForPart:CPScrollerDecrementLine]];
00672 [_incrementArrowView setFrame:[self rectForPart:CPScrollerIncrementLine]];
00673 }
00674 }
00675
00676 - (void)mouseDown:(CPEvent)anEvent
00677 {
00678 _hitPart = [self testPart:[anEvent locationInWindow]];
00679
00680 switch (_hitPart)
00681 {
00682 case CPScrollerKnob: return [self trackKnob:anEvent];
00683
00684 case CPScrollerDecrementLine:
00685 case CPScrollerIncrementLine:
00686 case CPScrollerDecrementPage:
00687 case CPScrollerIncrementPage: return [self trackScrollButtons:anEvent];
00688 }
00689 }
00690
00691
00692 - (void)setEnabled:(BOOL)shouldBeEnabled
00693 {
00694 }
00695
00696 @end