Better implementation of NSProgressIndicator based on patch by Uli

Kusterer <witness.of.teachtext@gmx.net>.
-- Diese und die folgenden Zeilen werden ignoriert  --

M    Source/NSProgressIndicator.m
M    Headers/AppKit/NSProgressIndicator.h
M    ChangeLog
AM   Images/common_ProgressSpinning_4.tiff
AM   Images/common_ProgressIndeterminate_3.tiff
AM   Images/common_ProgressSpinning_8.tiff
M    Images/GNUmakefile
AM   Images/common_ProgressSpinning_1.tiff
AM   Images/common_ProgressSpinning_5.tiff
AM   Images/common_ProgressIndeterminate_4.tiff
AM   Images/common_ProgressSpinning_2.tiff
AM   Images/common_ProgressIndeterminate_1.tiff
AM   Images/common_ProgressSpinning_6.tiff
AM   Images/common_ProgressIndeterminate_5.tiff
AM   Images/common_ProgressSpinning_3.tiff
AM   Images/common_ProgressIndeterminate_2.tiff
AM   Images/common_ProgressSpinning_7.tiff
AM   Images/common_ProgressIndeterminate_6.tiff


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@28900 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
fredkiefer 2009-10-27 22:21:01 +00:00
parent 1443a6b299
commit 9c7aff20ab
18 changed files with 269 additions and 110 deletions

View file

@ -1,8 +1,19 @@
2009-10-27 Fred Kiefer <FredKiefer@gmx.de>
* Headers/AppKit/NSProgressIndicator.h,
* Source/NSProgressIndicator.m: Add missing OSX 10.5 methods and
use the pattern colour patch by Uli Kusterer
<witness.of.teachtext@gmx.net>.
* Images/common_ProgressSpinning_?.tiff
* Images/common_ProgressIndeterminate_?.tiff
New image files by Uli Kusterer <witness.of.teachtext@gmx.net>.
* Images/GNUmakefile: Add the new images.
2009-10-27 Thomas Gamper <icicle@cg.tuwien.ac.at> 2009-10-27 Thomas Gamper <icicle@cg.tuwien.ac.at>
* Source/GSDisplayServer.m * Source/GSDisplayServer.m
* Headers/Additions/GNUstepGUI/GSDisplayServer.h: * Headers/Additions/GNUstepGUI/GSDisplayServer.h:
Add cursor position setter (setMouseLocation:onScreen:). Add cursor position setter (setMouseLocation:onScreen:).
2009-10-25 Fred Kiefer <FredKiefer@gmx.de> 2009-10-25 Fred Kiefer <FredKiefer@gmx.de>

View file

@ -15,7 +15,7 @@
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details. Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
@ -27,46 +27,64 @@
#ifndef _GNUstep_H_NSProgressIndicator #ifndef _GNUstep_H_NSProgressIndicator
#define _GNUstep_H_NSProgressIndicator #define _GNUstep_H_NSProgressIndicator
#import <GNUstepBase/GSVersionMacros.h>
#include <AppKit/NSView.h> #import <AppKit/NSView.h>
/* For NSControlTint */
#import <AppKit/NSColor.h>
/* For NSControlSize */
#import <AppKit/NSCell.h>
@class NSTimer; @class NSTimer;
@class NSThread; @class NSThread;
/* For NSControlTint */ typedef enum _NSProgressIndicatorThickness
#include <AppKit/NSColor.h> {
NSProgressIndicatorPreferredThickness = 14,
NSProgressIndicatorPreferredSmallThickness = 10,
NSProgressIndicatorPreferredLargeThickness = 18,
NSProgressIndicatorPreferredAquaThickness = 12
} NSProgressIndicatorThickness;
/* For NSControlSize */ typedef enum _NSProgressIndicatorStyle
#include <AppKit/NSCell.h> {
NSProgressIndicatorBarStyle = 0,
#define NSProgressIndicatorPreferredThickness 14 NSProgressIndicatorSpinningStyle = 1
#define NSProgressIndicatorPreferredSmallThickness 10 } NSProgressIndicatorStyle;
#define NSProgressIndicatorPreferredLargeThickness 18
#define NSProgressIndicatorPreferredAquaThickness 12
@interface NSProgressIndicator : NSView @interface NSProgressIndicator : NSView
{ {
BOOL _isIndeterminate; double _doubleValue;
BOOL _isBezeled; double _minValue;
BOOL _usesThreadedAnimation; double _maxValue;
NSTimeInterval _animationDelay; NSTimeInterval _animationDelay;
double _doubleValue; NSProgressIndicatorStyle _style;
double _minValue; BOOL _isIndeterminate;
double _maxValue; BOOL _isBezeled;
BOOL _isVertical; BOOL _usesThreadedAnimation;
BOOL _isDisplayedWhenStopped;
NSControlTint _controlTint;
NSControlSize _controlSize;
@private @private
BOOL _isRunning; BOOL _isVertical;
int _count; BOOL _isRunning;
NSTimer *_timer; int _count;
NSThread *_thread; NSTimer *_timer;
NSThread *_thread;
} }
// //
// Animating the progress indicator // Animating the progress indicator
// //
#if OS_API_VERSION(GS_API_LATEST, MAC_OS_X_VERSION_10_5)
- (void)animate:(id)sender; - (void)animate:(id)sender;
- (NSTimeInterval)animationDelay; - (NSTimeInterval)animationDelay;
- (void)setAnimationDelay:(NSTimeInterval)delay; - (void)setAnimationDelay:(NSTimeInterval)delay;
#endif
- (void)startAnimation:(id)sender; - (void)startAnimation:(id)sender;
- (void)stopAnimation:(id)sender; - (void)stopAnimation:(id)sender;
- (BOOL)usesThreadedAnimation; - (BOOL)usesThreadedAnimation;
@ -99,6 +117,14 @@
- (NSControlTint)controlTint; - (NSControlTint)controlTint;
- (void)setControlTint:(NSControlTint)tint; - (void)setControlTint:(NSControlTint)tint;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_2, GS_API_LATEST)
- (BOOL)isDisplayedWhenStopped;
- (void)setDisplayedWhenStopped:(BOOL)flag;
- (void)setStyle:(NSProgressIndicatorStyle)style;
- (NSProgressIndicatorStyle)style;
- (void)sizeToFit;
#endif
@end @end
#if OS_API_VERSION(GS_API_NONE, GS_API_NONE) #if OS_API_VERSION(GS_API_NONE, GS_API_NONE)

View file

@ -128,6 +128,20 @@ Images_RESOURCE_FILES = \
common_outlineUnexpandable.tiff \ common_outlineUnexpandable.tiff \
common_ret.tiff \ common_ret.tiff \
common_retH.tiff \ common_retH.tiff \
common_ProgressIndeterminate_1.tiff \
common_ProgressIndeterminate_2.tiff \
common_ProgressIndeterminate_3.tiff \
common_ProgressIndeterminate_4.tiff \
common_ProgressIndeterminate_5.tiff \
common_ProgressIndeterminate_6.tiff \
common_ProgressSpinning_1.tiff \
common_ProgressSpinning_2.tiff \
common_ProgressSpinning_3.tiff \
common_ProgressSpinning_4.tiff \
common_ProgressSpinning_5.tiff \
common_ProgressSpinning_6.tiff \
common_ProgressSpinning_7.tiff \
common_ProgressSpinning_8.tiff \
nsmapping.strings \ nsmapping.strings \
page_landscape.tiff \ page_landscape.tiff \
page_portrait.tiff page_portrait.tiff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -14,7 +14,7 @@
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details. Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
@ -27,6 +27,7 @@
#include <Foundation/NSTimer.h> #include <Foundation/NSTimer.h>
#include "AppKit/NSProgressIndicator.h" #include "AppKit/NSProgressIndicator.h"
#include "AppKit/NSGraphics.h" #include "AppKit/NSGraphics.h"
#include "AppKit/NSImage.h"
#include "AppKit/NSWindow.h" #include "AppKit/NSWindow.h"
#include "GNUstepGUI/GSTheme.h" #include "GNUstepGUI/GSTheme.h"
#include "GNUstepGUI/GSNibLoading.h" #include "GNUstepGUI/GSNibLoading.h"
@ -34,32 +35,72 @@
@implementation NSProgressIndicator @implementation NSProgressIndicator
static NSColor *fillColour = nil; static NSColor *fillColour = nil;
#define maxCount 1 #define MaxCount 10
//static NSImage *images[maxCount]; static int indeterminateMaxCount = MaxCount;
static int spinningMaxCount = MaxCount;
static NSColor *indeterminateColors[MaxCount];
static NSImage *spinningImages[MaxCount];
+ (void) initialize + (void) initialize
{ {
if (self == [NSProgressIndicator class]) if (self == [NSProgressIndicator class])
{ {
int i;
[self setVersion: 1]; [self setVersion: 1];
// FIXME: Should come from defaults and should be reset when defaults change // FIXME: Should come from defaults and should be reset when defaults change
// FIXME: Should probably get the color from the color extension list (see NSToolbar) // FIXME: Should probably get the color from the color extension list (see NSToolbar)
fillColour = RETAIN([NSColor controlShadowColor]); fillColour = RETAIN([NSColor controlShadowColor]);
// FIXME: Load the images and set maxCount
// Load images for indeterminate style
for (i = 0; i < MaxCount; i++)
{
NSString *imgName = [NSString stringWithFormat: @"common_ProgressIndeterminate_%d", i + 1];
NSImage *image = [NSImage imageNamed: imgName];
if (image == nil)
{
indeterminateMaxCount = i;
break;
}
indeterminateColors[i] = RETAIN([NSColor colorWithPatternImage: image]);
}
// Load images for spinning style
for (i = 0; i < MaxCount; i++)
{
NSString *imgName = [NSString stringWithFormat: @"common_ProgressSpinning_%d", i + 1];
NSImage *image = [NSImage imageNamed: imgName];
if (image == nil)
{
spinningMaxCount = i;
break;
}
spinningImages[i] = RETAIN(image);
}
} }
} }
- (id)initWithFrame:(NSRect)frameRect - (id)initWithFrame:(NSRect)frameRect
{ {
self = [super initWithFrame: frameRect]; self = [super initWithFrame: frameRect];
if (!self)
return nil;
_isIndeterminate = YES; _isIndeterminate = YES;
_isBezeled = YES; _isBezeled = YES;
_isVertical = NO; _isVertical = NO;
_usesThreadedAnimation = NO; _usesThreadedAnimation = NO;
_animationDelay = 5.0 / 60.0; // 1 twelfth a a second _animationDelay = 5.0 / 60.0; // 1 twelfth a a second
_doubleValue = 0.0; _doubleValue = 0.0;
_minValue = 0.0; _minValue = 0.0;
_maxValue = 100.0; _maxValue = 100.0;
_controlTint = NSDefaultControlTint;
_controlSize = NSRegularControlSize;
[self setStyle: NSProgressIndicatorBarStyle];
return self; return self;
} }
@ -80,13 +121,18 @@ static NSColor *fillColour = nil;
return; return;
_count++; _count++;
if (_count == maxCount) if (((_style == NSProgressIndicatorSpinningStyle) && (_count >= spinningMaxCount))
|| ((_style == NSProgressIndicatorBarStyle) && (_count >= indeterminateMaxCount)))
_count = 0; _count = 0;
[self setNeedsDisplay:YES]; [self setNeedsDisplay:YES];
} }
- (NSTimeInterval)animationDelay { return _animationDelay; } - (NSTimeInterval)animationDelay
{
return _animationDelay;
}
- (void)setAnimationDelay:(NSTimeInterval)delay - (void)setAnimationDelay:(NSTimeInterval)delay
{ {
_animationDelay = delay; _animationDelay = delay;
@ -100,14 +146,14 @@ static NSColor *fillColour = nil;
if (!_usesThreadedAnimation) if (!_usesThreadedAnimation)
{ {
ASSIGN(_timer, [NSTimer scheduledTimerWithTimeInterval: _animationDelay ASSIGN(_timer, [NSTimer scheduledTimerWithTimeInterval: _animationDelay
target: self target: self
selector: @selector(animate:) selector: @selector(animate:)
userInfo: nil userInfo: nil
repeats: YES]); repeats: YES]);
} }
else else
{ {
// Not implemented // FIXME: Not implemented
} }
_isRunning = YES; _isRunning = YES;
@ -125,7 +171,7 @@ static NSColor *fillColour = nil;
} }
else else
{ {
// Not implemented // FIXME: Not implemented
} }
_isRunning = NO; _isRunning = NO;
@ -143,62 +189,82 @@ static NSColor *fillColour = nil;
BOOL wasRunning = _isRunning; BOOL wasRunning = _isRunning;
if (wasRunning) if (wasRunning)
[self stopAnimation: self]; [self stopAnimation: self];
_usesThreadedAnimation = flag; _usesThreadedAnimation = flag;
if (wasRunning) if (wasRunning)
[self startAnimation: self]; [self startAnimation: self];
} }
} }
- (void)incrementBy:(double)delta - (void)incrementBy:(double)delta
{ {
_doubleValue += delta; _doubleValue += delta;
[self setNeedsDisplay:YES]; [self setNeedsDisplay: YES];
}
- (double)doubleValue
{
return _doubleValue;
} }
- (double)doubleValue { return _doubleValue; }
- (void)setDoubleValue:(double)aValue - (void)setDoubleValue:(double)aValue
{ {
if (_doubleValue != aValue) if (_doubleValue != aValue)
{ {
_doubleValue = aValue; _doubleValue = aValue;
[self setNeedsDisplay:YES]; [self setNeedsDisplay: YES];
} }
} }
- (double)minValue { return _minValue; } - (double)minValue
{
return _minValue;
}
- (void)setMinValue:(double)newMinimum - (void)setMinValue:(double)newMinimum
{ {
if (_minValue != newMinimum) if (_minValue != newMinimum)
{ {
_minValue = newMinimum; _minValue = newMinimum;
[self setNeedsDisplay:YES]; [self setNeedsDisplay: YES];
} }
} }
- (double)maxValue { return _maxValue; } - (double)maxValue
{
return _maxValue;
}
- (void)setMaxValue:(double)newMaximum - (void)setMaxValue:(double)newMaximum
{ {
if (_maxValue != newMaximum) if (_maxValue != newMaximum)
{ {
_maxValue = newMaximum; _maxValue = newMaximum;
[self setNeedsDisplay:YES]; [self setNeedsDisplay: YES];
} }
} }
- (BOOL)isBezeled { return _isBezeled; } - (BOOL)isBezeled
{
return _isBezeled;
}
- (void)setBezeled:(BOOL)flag - (void)setBezeled:(BOOL)flag
{ {
if (_isBezeled != flag) if (_isBezeled != flag)
{ {
_isBezeled = flag; _isBezeled = flag;
[self setNeedsDisplay:YES]; [self setNeedsDisplay: YES];
} }
} }
- (BOOL)isIndeterminate { return _isIndeterminate; } - (BOOL)isIndeterminate
{
return _isIndeterminate;
}
- (void)setIndeterminate:(BOOL)flag - (void)setIndeterminate:(BOOL)flag
{ {
_isIndeterminate = flag; _isIndeterminate = flag;
@ -207,31 +273,56 @@ static NSColor *fillColour = nil;
[self stopAnimation: self]; [self stopAnimation: self];
} }
- (BOOL)isDisplayedWhenStopped
{
return _isDisplayedWhenStopped;
}
- (void)setDisplayedWhenStopped:(BOOL)flag
{
_style = _isDisplayedWhenStopped;
}
- (NSProgressIndicatorStyle) style
{
return _style;
}
- (void)setStyle:(NSProgressIndicatorStyle)style
{
_style = style;
_count = 0;
[self setDisplayedWhenStopped: (style == NSProgressIndicatorBarStyle)];
}
- (NSControlSize)controlSize - (NSControlSize)controlSize
{ {
// FIXME return _controlSize;
return NSRegularControlSize;
} }
- (void)setControlSize:(NSControlSize)size - (void)setControlSize:(NSControlSize)size
{ {
// FIXME _controlSize = size;
} }
- (NSControlTint)controlTint - (NSControlTint)controlTint
{ {
// FIXME return _controlTint;
return NSDefaultControlTint;
} }
- (void)setControlTint:(NSControlTint)tint - (void)setControlTint:(NSControlTint)tint
{ {
// FIXME _controlTint = tint;
}
- (void) sizeToFit
{
// FIXME
} }
- (void)drawRect:(NSRect)rect - (void)drawRect:(NSRect)rect
{ {
NSRect r; NSRect r;
// Draw the Bezel // Draw the Bezel
if (_isBezeled) if (_isBezeled)
@ -240,34 +331,51 @@ static NSColor *fillColour = nil;
r = [[GSTheme theme] drawGrayBezel: _bounds withClip: rect]; r = [[GSTheme theme] drawGrayBezel: _bounds withClip: rect];
} }
else else
r = _bounds;
if (_isIndeterminate) // Draw indeterminate
{ {
// FIXME: Do nothing at this stage r = _bounds;
} }
else // Draw determinate
{
if (_doubleValue > _minValue)
{
double val;
if (_doubleValue > _maxValue)
val = _maxValue - _minValue;
else
val = _doubleValue - _minValue;
if (_isVertical) if (_style == NSProgressIndicatorSpinningStyle)
r.size.height = NSHeight(r) * (val / (_maxValue - _minValue)); {
else NSRect imgBox = {{0,0}, {0,0}};
r.size.width = NSWidth(r) * (val / (_maxValue - _minValue));
r = NSIntersectionRect(r,rect); imgBox.size = [spinningImages[_count] size];
if (!NSIsEmptyRect(r)) [spinningImages[_count] drawInRect: r
{ fromRect: imgBox
[fillColour set]; operation: NSCompositeSourceOver
NSRectFill(r); fraction: 1.0];
} }
} else
{
if (_isIndeterminate)
{
[indeterminateColors[_count] set];
NSRectFill(r);
}
else
{
// Draw determinate
if (_doubleValue > _minValue)
{
double val;
if (_doubleValue > _maxValue)
val = _maxValue - _minValue;
else
val = _doubleValue - _minValue;
if (_isVertical)
r.size.height = NSHeight(r) * (val / (_maxValue - _minValue));
else
r.size.width = NSWidth(r) * (val / (_maxValue - _minValue));
r = NSIntersectionRect(r,rect);
if (!NSIsEmptyRect(r))
{
[fillColour set];
NSRectFill(r);
}
}
}
} }
} }
@ -277,7 +385,7 @@ static NSColor *fillColour = nil;
// NSCopying // NSCopying
/* - (id)copyWithZone:(NSZone *)zone /* - (id)copyWithZone:(NSZone *)zone
{ {
NSProgressIndicator *newInd; NSProgressIndicator *newInd;
newInd = [super copyWithZone:zone]; newInd = [super copyWithZone:zone];
[newInd setIndeterminate:_isIndeterminate]; [newInd setIndeterminate:_isIndeterminate];
@ -344,45 +452,45 @@ static NSColor *fillColour = nil;
// id matrix = [aDecoder decodeObjectForKey: @"NSDrawMatrix"]; // id matrix = [aDecoder decodeObjectForKey: @"NSDrawMatrix"];
if ([aDecoder containsValueForKey: @"NSMaxValue"]) if ([aDecoder containsValueForKey: @"NSMaxValue"])
{ {
int max = [aDecoder decodeDoubleForKey: @"NSMaxValue"]; int max = [aDecoder decodeDoubleForKey: @"NSMaxValue"];
[self setMaxValue: max]; [self setMaxValue: max];
} }
if ([aDecoder containsValueForKey: @"NSMinValue"]) if ([aDecoder containsValueForKey: @"NSMinValue"])
{ {
int min = [aDecoder decodeDoubleForKey: @"NSMinValue"]; int min = [aDecoder decodeDoubleForKey: @"NSMinValue"];
[self setMinValue: min]; [self setMinValue: min];
} }
if ([aDecoder containsValueForKey: @"NSpiFlags"]) if ([aDecoder containsValueForKey: @"NSpiFlags"])
{ {
int flags = [aDecoder decodeIntForKey: @"NSpiFlags"]; int flags = [aDecoder decodeIntForKey: @"NSpiFlags"];
_isIndeterminate = ((flags & 2) == 2); _isIndeterminate = ((flags & 2) == 2);
// ignore the rest, since they are not pertinent to GNUstep. // ignore the rest, since they are not pertinent to GNUstep.
} }
// things which Gorm encodes, but IB doesn't care about. // things which Gorm encodes, but IB doesn't care about.
if ([aDecoder containsValueForKey: @"GSDoubleValue"]) if ([aDecoder containsValueForKey: @"GSDoubleValue"])
{ {
_doubleValue = [aDecoder decodeDoubleForKey: @"GSDoubleValue"]; _doubleValue = [aDecoder decodeDoubleForKey: @"GSDoubleValue"];
} }
if ([aDecoder containsValueForKey: @"GSIsBezeled"]) if ([aDecoder containsValueForKey: @"GSIsBezeled"])
{ {
_isBezeled = [aDecoder decodeBoolForKey: @"GSIsBezeled"]; _isBezeled = [aDecoder decodeBoolForKey: @"GSIsBezeled"];
} }
if ([aDecoder containsValueForKey: @"GSIsVertical"]) if ([aDecoder containsValueForKey: @"GSIsVertical"])
{ {
_isVertical = [aDecoder decodeBoolForKey: @"GSIsVertical"]; _isVertical = [aDecoder decodeBoolForKey: @"GSIsVertical"];
} }
if ([aDecoder containsValueForKey: @"GSUsesThreadAnimation"]) if ([aDecoder containsValueForKey: @"GSUsesThreadAnimation"])
{ {
_usesThreadedAnimation = [aDecoder decodeBoolForKey: @"GSUsesThreadAnimation"]; _usesThreadedAnimation = [aDecoder decodeBoolForKey: @"GSUsesThreadAnimation"];
} }
if ([aDecoder containsValueForKey: @"GSAnimationDelay"]) if ([aDecoder containsValueForKey: @"GSAnimationDelay"])
{ {
_animationDelay = [aDecoder decodeDoubleForKey: @"GSAnimationDelay"]; _animationDelay = [aDecoder decodeDoubleForKey: @"GSAnimationDelay"];
} }
} }
else else
{ {
@ -390,7 +498,7 @@ static NSColor *fillColour = nil;
[aDecoder decodeValueOfObjCType: @encode(BOOL) at:&_isBezeled]; [aDecoder decodeValueOfObjCType: @encode(BOOL) at:&_isBezeled];
[aDecoder decodeValueOfObjCType: @encode(BOOL) at:&_usesThreadedAnimation]; [aDecoder decodeValueOfObjCType: @encode(BOOL) at:&_usesThreadedAnimation];
[aDecoder decodeValueOfObjCType: @encode(NSTimeInterval) [aDecoder decodeValueOfObjCType: @encode(NSTimeInterval)
at:&_animationDelay]; at:&_animationDelay];
[aDecoder decodeValueOfObjCType: @encode(double) at:&_doubleValue]; [aDecoder decodeValueOfObjCType: @encode(double) at:&_doubleValue];
[aDecoder decodeValueOfObjCType: @encode(double) at:&_minValue]; [aDecoder decodeValueOfObjCType: @encode(double) at:&_minValue];
[aDecoder decodeValueOfObjCType: @encode(double) at:&_maxValue]; [aDecoder decodeValueOfObjCType: @encode(double) at:&_maxValue];