This is SliderCellFine.m in view mode; [Download] [Up]
/************************************************************************** * * 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
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.