home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Nebula
/
nebula.bin
/
SourceCode
/
SliderDualActing
/
SliderCellFine.m
< prev
next >
Wrap
Text File
|
1993-01-19
|
6KB
|
232 lines
/**************************************************************************
*
* Object Name: SliderCellFine
*
*--------------------------------------------------------------------------
* Programmer:andrew stone
* Copyright (c) 1989,1990 Stone Design Corp. All rights reserved.
***************************************************************************/
#import "SliderCellFine.h"
#import "SliderDualActing.h"
#import <appkit/Application.h>
#import <dpsclient/wraps.h>
#import <math.h>
/* Dragging 'resolution' of slider: how much the slider changes by */
#define FINE .5 /* reduce altStep to 50% */
#define SUPERFINE .25 /* reduce altStep to 25% */
#define DEFAULT_VAL 50.
#define DEFAULT_MAX 100.
#define DEFAULT_MIN 0.
#define DEFAULT_ALT 1.
@implementation SliderCellFine
+ new
{
//sane defaults
self = [super new];
[self setAltStep:DEFAULT_ALT whole:YES default:DEFAULT_VAL];
[self setMax:DEFAULT_MAX allowHigher:YES min:DEFAULT_MIN allowLower:YES];
return self;
}
- increment
{
if (value+altStep <= maxValue) value += altStep;
else if (scfFlags.allowHigher)
{ [self setMaxValue:value+altStep]; value += altStep; }
else return nil; // failed to work
[textPal setFloatValue:value];
return self;
}
- decrement
{
if (value-altStep >= minValue) value -= altStep;
else if (scfFlags.allowLower)
{ [self setMinValue:value+altStep]; value -= altStep; }
else return nil; // failed to work
[textPal setFloatValue:value];
return self;
}
- (double)checkValue:(double)val // returns validated number
{
if (val>= minValue && val<= maxValue) {
value = val;
return val;
} else if (val<minValue && scfFlags.allowLower) {
[self setMinValue:val];
value = val;
return val;
} else if (val>maxValue && scfFlags.allowHigher) {
[self setMaxValue:val];
value = val;
return val;
} else return value; // no change allowed
}
-(BOOL)isDecimal
{
return scfFlags.isDecimal;
}
- (BOOL)continueTracking:(const NXPoint *)lastPoint
at:(const NXPoint *)currentPoint
inView:controlView
{
NXEvent *e = [NXApp currentEvent];
if (e->flags & NX_ALTERNATEMASK) {
NXRect r;
double step = altStep;
if (!lastPoint) lastPoint = currentPoint;
if (e->flags & NX_SHIFTMASK) {
if (textPal) {
[textPal setFloatingPointFormat:YES left:2 right:2];
scfFlags.isDecimal =YES;
}
if (e->flags & NX_COMMANDMASK) step*=SUPERFINE;
else step *= FINE;
}
else if (scfFlags.isWhole) value = floor(value);
if (trackRect.size.width>trackRect.size.height) {
[self getKnobRect:&r flipped:NO];
if (r.origin.x+r.size.width<trackRect.size.width)
r.size.width+=1.;
if (currentPoint->x >lastPoint->x) {
value+=step;if (value>maxValue) value=maxValue;
} else if (currentPoint->x < lastPoint->x) {
value -= step;if (value<minValue)value=minValue;
}
} else { // is a vertical slider
[self getKnobRect:&r flipped:YES];
if (r.origin.y+r.size.height<trackRect.size.height)
r.size.height+=1.;
if (currentPoint->y < lastPoint->y) {
value+=step; if (value>maxValue) value=maxValue;
} else if (currentPoint->y > lastPoint->y) {
value -= step; if (value<minValue)value=minValue;
}
}
PSsetgray(.5); // Track gray 1.0
NXRectFill(&r);
[self drawKnob];
[textPal setFloatValue:value];
if (scfFlags.sendContinuously) [controlView _sendIt];
lastPoint = currentPoint;
return YES;
}
else if (e->flags & NX_COMMANDMASK) {
NXRect r;
if (trackRect.size.width>trackRect.size.height)
[self getKnobRect:&r flipped:NO];
else
[self getKnobRect:&r flipped:YES];
value = defaultValue;
if (textPal) {
[textPal setFloatingPointFormat:NO left:4 right:0];
[textPal setFloatValue:value];
scfFlags.isDecimal = NO;
}
if (defaultMax) [self setMaxValue:defaultMax];
if (defaultMin) [self setMinValue:defaultMin];
PSsetgray(.5);
NXRectFill(&r);
[self drawKnob];
return YES;
} else {
BOOL retVal;
[textPal setFloatValue:value];
retVal =[super continueTracking:(const NXPoint *)lastPoint
at:(const NXPoint *)currentPoint
inView:controlView];
[textPal setFloatValue:value]; //YUP, two times is better than 1!
if (scfFlags.sendContinuously) [controlView _sendIt];
return retVal;
}
}
// Client Initialization Routines:
// this method allows slider to setup what fine step will be
// and if we should keep it to a whole integer
- setAltStep:(double)step whole:(BOOL)flag default:(double)val
{
scfFlags.isWhole = flag;
scfFlags.isDecimal = 1-flag; // support for Clients rounding results
if (scfFlags.isWhole) [textPal setFloatingPointFormat:NO left:4 right:0];
altStep = step;
defaultValue = val;
value = val;
return self;
}
// set highest high and yes if you can surpass and lowest lows and surpass flag
- setMax:(double)max allowHigher:(BOOL)hi min:(double)min allowLower:(BOOL)lo
{
defaultMax = max;
[self setMaxValue:max];
defaultMin = min;
[self setMinValue:min];
scfFlags.allowHigher = hi;
scfFlags.allowLower = lo;
return self;
}
// archive methods: // not tested C.E.
- read:(NXTypedStream *)stream
{
[super read:stream];
NXReadTypes(stream,"sffff",&scfFlags,&altStep,
&defaultValue,&defaultMax,&defaultMin);
[self setMinValue:defaultMin];
[self setMaxValue:defaultMax];
return self;
}
- write:(NXTypedStream *)stream
{
[super write:stream];
NXWriteTypes(stream,"sffff",&scfFlags,&altStep,
&defaultValue,&defaultMax,&defaultMin);
return self;
}
// private and historical functions
- _setAlwaysSendUpAction:(BOOL)flag
{
scfFlags.sendContinuously = flag;
return self;
}
- setDefault:(double) def
{
defaultValue = def; // needed for GrayView
return self;
}
- setTextPal:anObject
{
textPal = anObject;
return self;
}
@end