API  0.9.6
 All Classes Files Functions Variables Macros Groups Pages
CPProgressIndicator.j
Go to the documentation of this file.
1 /*
2  * CPProgressIndicator.j
3  * AppKit
4  *
5  * Created by Francisco Tolmasky.
6  * Copyright 2008, 280 North, Inc.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 
24 
25 /*
26  @global
27  @group CPProgressIndicatorStyle
28 */
30 /*
31  @global
32  @group CPProgressIndicatorStyle
33 */
35 /*
36  @global
37  @group CPProgressIndicatorStyle
38 */
40 
42 
46 
55 @implementation CPProgressIndicator : CPView
56 {
57  double _minValue;
58  double _maxValue;
59 
60  double _doubleValue;
61 
62  CPControlSize _controlSize;
63 
64  BOOL _isIndeterminate;
65  CPProgressIndicatorStyle _style;
66 
67  BOOL _isAnimating;
68 
69  BOOL _isDisplayedWhenStoppedSet;
70  BOOL _isDisplayedWhenStopped;
71 }
72 
73 /*
74  @ignore
75 */
76 + (void)initialize
77 {
78  if (self !== [CPProgressIndicator class])
79  return;
80 
81  var bundle = [CPBundle bundleForClass:self];
82 
84 
86  [bundle pathForResource:@"CPProgressIndicator/CPProgressIndicatorSpinningStyleMini.gif"] size:CGSizeMake(16.0, 16.0)]];
88  [bundle pathForResource:@"CPProgressIndicator/CPProgressIndicatorSpinningStyleSmall.gif"] size:CGSizeMake(32.0, 32.0)]];
90  [bundle pathForResource:@"CPProgressIndicator/CPProgressIndicatorSpinningStyleRegular.gif"] size:CGSizeMake(64.0, 64.0)]];
91 
92  CPProgressIndicatorBezelBorderViewPool = [];
93 
94  var start = CPProgressIndicatorBarStyle,
96 
97  for (; start <= end; ++start)
98  {
99  CPProgressIndicatorBezelBorderViewPool[start] = [];
100  CPProgressIndicatorBezelBorderViewPool[start][CPMiniControlSize] = [];
101  CPProgressIndicatorBezelBorderViewPool[start][CPSmallControlSize] = [];
102  CPProgressIndicatorBezelBorderViewPool[start][CPRegularControlSize] = [];
103  }
104 
107 
108  CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle] = @"Bar";
109  CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorSpinningStyle] = @"Spinny";
110  CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorHUDBarStyle] = @"HUDBar";
111 
112  var regularIdentifier = _CPControlIdentifierForControlSize(CPRegularControlSize),
113  smallIdentifier = _CPControlIdentifierForControlSize(CPSmallControlSize),
114  miniIdentifier = _CPControlIdentifierForControlSize(CPMiniControlSize);
115 
117 
118  // Bar Style
119  var prefixes = [
120  CPProgressIndicatorClassName + @"BezelBorder" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle],
121  CPProgressIndicatorClassName + @"Bar" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle],
122  CPProgressIndicatorClassName + @"BezelBorder" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorHUDBarStyle],
123  CPProgressIndicatorClassName + @"Bar" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorHUDBarStyle]
124  ];
125 
126  for (var i = 0, count = prefixes.length; i < count; i++)
127  {
128  var prefix = prefixes[i];
129  CPProgressIndicatorStyleSizes[prefix + regularIdentifier] = [_CGSizeMake(3.0, 16.0), _CGSizeMake(1.0, 16.0), _CGSizeMake(3.0, 16.0)];
130  CPProgressIndicatorStyleSizes[prefix + smallIdentifier] = [_CGSizeMake(3.0, 16.0), _CGSizeMake(1.0, 16.0), _CGSizeMake(3.0, 16.0)];
131  CPProgressIndicatorStyleSizes[prefix + miniIdentifier] = [_CGSizeMake(3.0, 16.0), _CGSizeMake(1.0, 16.0), _CGSizeMake(3.0, 16.0)];
132  }
133 }
134 
135 - (id)initWithFrame:(CGRect)aFrame
136 {
137  self = [super initWithFrame:aFrame];
138 
139  if (self)
140  {
141  _minValue = 0.0;
142  _maxValue = 100.0;
143 
144  _doubleValue = 0.0;
145 
147  _isDisplayedWhenStoppedSet = NO;
148 
149  _controlSize = CPRegularControlSize;
150 
151  [self updateBackgroundColor];
152  [self drawBar];
153  }
154 
155  return self;
156 }
157 
158 /*
159  @ignore
160 */
161 - (void)setUsesThreadedAnimation:(BOOL)aFlag
162 {
163 }
164 
169 - (void)startAnimation:(id)aSender
170 {
171  _isAnimating = YES;
172 
173  [self _hideOrDisplay];
174 }
175 
180 - (void)stopAnimation:(id)aSender
181 {
182  _isAnimating = NO;
183 
184  [self _hideOrDisplay];
185 }
186 
190 - (BOOL)usesThreadedAnimation
191 {
192  return NO;
193 }
194 
195 // Advancing the Progress Bar
200 - (void)incrementBy:(double)aValue
201 {
202  [self setDoubleValue:_doubleValue + aValue];
203 }
204 
208 - (void)setDoubleValue:(double)aValue
209 {
210  _doubleValue = MIN(MAX(aValue, _minValue), _maxValue);
211 
212  [self drawBar];
213 }
214 
218 - (double)doubleValue
219 {
220  return _doubleValue;
221 }
222 
227 - (void)setMinValue:(double)aValue
228 {
229  _minValue = aValue;
230 }
231 
235 - (double)minValue
236 {
237  return _minValue;
238 }
239 
244 - (void)setMaxValue:(double)aValue
245 {
246  _maxValue = aValue;
247 }
248 
252 - (double)maxValue
253 {
254  return _maxValue;
255 }
256 
257 // Setting the Appearance
262 - (void)setControlSize:(CPControlSize)aControlSize
263 {
264  if (_controlSize == aControlSize)
265  return;
266 
267  _controlSize = aControlSize;
268 
269  [self updateBackgroundColor];
270 }
271 
275 - (CPControlSize)controlSize
276 {
277  return _controlSize;
278 }
279 
280 /*
281  Not yet implemented
282 */
283 - (void)setControlTint:(CPControlTint)aControlTint
284 {
285 }
286 
287 /*
288  Not yet implemented.
289 */
290 - (CPControlTint)controlTint
291 {
292  return 0;
293 }
294 
295 /*
296  Not yet implemented.
297 */
298 - (void)setBezeled:(BOOL)isBezeled
299 {
300 }
301 
302 /*
303  Not yet implemented.
304 */
305 - (BOOL)isBezeled
306 {
307  return YES;
308 }
309 
314 - (void)setIndeterminate:(BOOL)isIndeterminate
315 {
316  if (_isIndeterminate == isIndeterminate)
317  return;
318 
319  _isIndeterminate = isIndeterminate;
320 
321  [self updateBackgroundColor];
322 }
323 
327 - (BOOL)isIndeterminate
328 {
329  return _isIndeterminate;
330 }
331 
336 - (void)setStyle:(CPProgressIndicatorStyle)aStyle
337 {
338  if (_style == aStyle)
339  return;
340 
341  _style = aStyle;
342 
343  [self updateBackgroundColor];
344 }
345 
349 - (void)sizeToFit
350 {
351  if (_style == CPProgressIndicatorSpinningStyle)
352  [self setFrameSize:[[CPProgressIndicatorSpinningStyleColors[_controlSize] patternImage] size]];
353  else
354  [self setFrameSize:CGSizeMake(CGRectGetWidth([self frame]), CPProgressIndicatorStyleSizes[
355  CPProgressIndicatorClassName + @"BezelBorder" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle] + _CPControlIdentifierForControlSize(_controlSize)][0].height)];
356 }
357 
363 - (void)setDisplayedWhenStopped:(BOOL)isDisplayedWhenStopped
364 {
365  if (_isDisplayedWhenStoppedSet && _isDisplayedWhenStopped == isDisplayedWhenStopped)
366  return;
367 
368  _isDisplayedWhenStoppedSet = YES;
369 
370  _isDisplayedWhenStopped = isDisplayedWhenStopped;
371 
372  [self _hideOrDisplay];
373 }
374 
378 - (BOOL)isDisplayedWhenStopped
379 {
380  if (_isDisplayedWhenStoppedSet)
381  return _isDisplayedWhenStopped;
382 
384  return YES;
385 
386  return NO;
387 }
388 
389 /* @ignore */
390 - (void)_hideOrDisplay
391 {
392  [self setHidden:!_isAnimating && ![self isDisplayedWhenStopped]];
393 }
394 
395 - (void)setFrameSize:(CGSize)aSize
396 {
397  [super setFrameSize:aSize];
398 
399  [self drawBar];
400 }
401 
402 /* @ignore */
403 - (void)drawBar
404 {
405  if (_style == CPProgressIndicatorSpinningStyle)
406  return;
407 
408  var barView = [self layoutEphemeralSubviewNamed:"bar-view"
409  positioned:CPWindowBelow
411 
412  [barView setBackgroundColor:_CPControlThreePartImagePattern(
413  NO,
414  CPProgressIndicatorStyleSizes,
415  CPProgressIndicatorClassName,
416  @"Bar",
417  CPProgressIndicatorStyleIdentifiers[_style],
418  _CPControlIdentifierForControlSize(_controlSize))];
419 }
420 
421 - (CPView)createEphemeralSubviewNamed:(CPString)aName
422 {
423  return [[CPView alloc] initWithFrame:_CGRectMakeZero()];
424 }
425 
426 - (CGRect)rectForEphemeralSubviewNamed:(CPString)aViewName
427 {
428  if (aViewName === @"bar-view" && _style !== CPProgressIndicatorSpinningStyle)
429  {
430  var width = CGRectGetWidth([self bounds]),
431  barWidth = width * ((_doubleValue - _minValue) / (_maxValue - _minValue));
432 
433  if (barWidth > 0.0 && barWidth < 4.0)
434  barWidth = 4.0;
435 
436  return _CGRectMake(0, 0, barWidth, 16.0);
437  }
438 
439  return nil;
440 }
441 
442 /* @ignore */
443 - (void)updateBackgroundColor
444 {
445  if (YES)//_isBezeled)
446  {
447  if (_style == CPProgressIndicatorSpinningStyle)
448  {
449  // This will cause the bar view to go away due to having a nil rect when _style == CPProgressIndicatorSpinningStyle.
450  [self layoutEphemeralSubviewNamed:"bar-view"
451  positioned:CPWindowBelow
453 
454  [self setBackgroundColor:CPProgressIndicatorSpinningStyleColors[_controlSize]];
455  }
456  else
457  {
458  [self setBackgroundColor:_CPControlThreePartImagePattern(
459  NO,
460  CPProgressIndicatorStyleSizes,
461  CPProgressIndicatorClassName,
462  @"BezelBorder",
463  CPProgressIndicatorStyleIdentifiers[_style],
464  _CPControlIdentifierForControlSize(_controlSize))];
465 
466  [self drawBar];
467  }
468  }
469  else
470  [self setBackgroundColor:nil];
471 }
472 
473 @end
474 
475 
477 
478 - (id)initWithCoder:(CPCoder)aCoder
479 {
480  if (self = [super initWithCoder:aCoder])
481  {
482  _minValue = [aCoder decodeObjectForKey:@"_minValue"];
483  _maxValue = [aCoder decodeObjectForKey:@"_maxValue"];
484  _doubleValue = [aCoder decodeObjectForKey:@"_doubleValue"];
485  _controlSize = [aCoder decodeObjectForKey:@"_controlSize"];
486  _isIndeterminate = [aCoder decodeObjectForKey:@"_isIndeterminate"];
487  _style = [aCoder decodeIntForKey:@"_style"];
488  _isAnimating = [aCoder decodeObjectForKey:@"_isAnimating"];
489  _isDisplayedWhenStoppedSet = [aCoder decodeObjectForKey:@"_isDisplayedWhenStoppedSet"];
490  _isDisplayedWhenStopped = [aCoder decodeObjectForKey:@"_isDisplayedWhenStopped"];
491 
492  [self updateBackgroundColor];
493  }
494 
495  return self;
496 }
497 
498 - (void)encodeWithCoder:(CPCoder)aCoder
499 {
500  // Don't encode the background colour. It can be recreated based on the flags and if encoded causes hardcoded
501  // image paths in the cib while just wasting space.
502  var backgroundColor = [self backgroundColor];
503  [self setBackgroundColor:nil];
504  [super encodeWithCoder:aCoder];
505  [self setBackgroundColor:backgroundColor];
506 
507  [aCoder encodeObject:_minValue forKey:@"_minValue"];
508  [aCoder encodeObject:_maxValue forKey:@"_maxValue"];
509  [aCoder encodeObject:_doubleValue forKey:@"_doubleValue"];
510  [aCoder encodeObject:_controlSize forKey:@"_controlSize"];
511  [aCoder encodeObject:_isIndeterminate forKey:@"_isIndeterminate"];
512  [aCoder encodeInt:_style forKey:@"_style"];
513  [aCoder encodeObject:_isAnimating forKey:@"_isAnimating"];
514  [aCoder encodeObject:_isDisplayedWhenStoppedSet forKey:@"_isDisplayedWhenStoppedSet"];
515  [aCoder encodeObject:_isDisplayedWhenStopped forKey:@"_isDisplayedWhenStopped"];
516 }
517 
518 @end