home *** CD-ROM | disk | FTP | other *** search
-
- /* Generated by Interface Builder */
-
- #import "Gauge.h"
- #import <appkit/graphics.h>
- #import <appkit/Window.h>
-
- #define GAUGEQUANTTICS \
- if (GaugeDat.ticQuanta){ \
- GaugeDat.ticSize = \
- (((int)(GaugeDat.ticSize/GaugeDat.ticQuanta))+1) \
- *GaugeDat.ticQuanta; \
- GaugeDat.startValue = \
- (((int)(GaugeDat.startValue/GaugeDat.ticSize))-1) \
- *GaugeDat.ticSize; \
- }
-
- @implementation Gauge
-
- /**********************************************************************/
- /* Factory Methods
- /**********************************************************************/
-
- + newFrame: (NXRect *) r
- {
- self = [super newFrame:r];
- GaugeDat.backGray = NX_LTGRAY;
- GaugeDat.faceGray = NX_WHITE;
- GaugeDat.ticGray = NX_BLACK;
- GaugeDat.textGray = NX_BLACK;
- GaugeDat.ptGray = NX_DKGRAY;
- [self changeBMSize];
- GaugeDat.startValue = 0.0;
- GaugeDat.ticSize = 0.1;
- GaugeDat.value = 0.5;
- GaugeDat.numMajor = 11;
- GaugeDat.numMinor = 1;
- GaugeDat.ticQuanta = 0.0; /* tic can be any size */
- GaugeDat.aThreshHi = 0.9;
- GaugeDat.aThreshLo =0.1;
- GaugeDat.labelTicPat = "%1.1f"; /* one sig dig on each side */
- GaugeDat.ticFontName = "Helvetica";
- GaugeDat.titleFontName = "Helvetica";
- GaugeFlags.titleOn = NO;
- GaugeFlags.ticsOn = YES;
- GaugeFlags.labelTicsOn = NO;
- GaugeFlags.autoScaleOn = YES;
- GaugeFlags.jumpChange = YES;
- GaugeFlags.overFlow = NO;
- GaugeFlags.autoRenderBit = YES; /*always re render on changes */
- GaugeFlags.borderType = NX_NOBORDER;
- return self;
- }
- /**********************************************************************/
- /* Private Methods
- /**********************************************************************/
- - reScaleGauge:sender
- /* return self if overrun or rescale
- /* else return nil;
- /* This gets called if value is out of thresholds and auto scale is on.
- /*
- /* Autoscaling with no labels will cause the number of tics to change
- /* when blowing up or shrinking tic mark values otherwise ...
- /*
- /* This will rescale the tic marks or start values under thse rules
- /* Underrun:
- /* if .aThreshLo > 0.0
- /* then move low point so we are centered
- /* else if aThreshHi < 1.0
- /* then rescale tic marks to blow up
- /*
- /* Overrun
- /* if .aThreshHi < 1.0
- /* then move the tic marks to shrink
- /* else if .aThreshLo > 0.0
- /* then move up low so this is centered
- /*
- /* Bugs
- /* no way to tell it fixed increment scaling
- /* no wayt to autoscale and cap
- /*
- /* */
- {
- double tStart;
- double tSize;
-
- GaugeFlags.overFlow = NO;
- if ((GaugeDat.value < GAUGEHI) && (GaugeDat.value > GAUGELO))
- return nil;
- /* if not autoscaling or both bounds locked then ... */
- if (!GaugeFlags.autoScaleOn ||
- ((GaugeDat.aThreshLo <= 0.0) && (GaugeDat.aThreshHi >= 1.0))){
- if ((GaugeDat.value < GAUGELO) || (GaugeDat.value > GAUGEHI)){
- GaugeFlags.overFlow = YES;
- if (GaugeDat.value > GAUGEMAX) GaugeDat.value = GAUGEMAX;
- else if (GaugeDat.value < GaugeDat.startValue)
- GaugeDat.value = GaugeDat.startValue;
- [self sendAction:action to:target];
- return self;
- } else return nil;
- }
- /* we know we have at least one valid threshold if we got this far */
- /* and we have an overrun or underrun condition */
- if (GaugeDat.value > GAUGEHI){ /* overrun */
- if (!GaugeFlags.labelTicsOn){
- GaugeDat.numMajor += GaugeDat.numMajor -1 ;
- }else if (GaugeDat.aThreshHi < 1.0){ /* scale tics */
- GaugeDat.ticSize = GAUGESIZE*2 / (GaugeDat.numMajor-1);
- }else{ /* move start */
- GaugeDat.startValue += GAUGESIZE / 2;
- }
- }else{ /* underrun */
- if (!GaugeFlags.labelTicsOn ){
- if (GaugeDat.numMajor > 2)
- GaugeDat.numMajor=((GaugeDat.numMajor-1)/2)+1;
- }else if (GaugeDat.aThreshLo > 0.0){ /*move the start down */
- GaugeDat.startValue -= GAUGESIZE / 2;
- }else{ /* change tic size */
- GaugeDat.ticSize = GAUGESIZE/2 / (GaugeDat.numMajor-1);
- }
- }
- GAUGEQUANTTICS
-
- return self;
- }
-
- /**********************************************************************/
- /* Public Methods
- /**********************************************************************/
- - changeBMSize
- {
- NXRect r;
-
- [self getBounds:&r];
- if (GaugeDat.bm) [GaugeDat.bm free];
- // Create offscreen window for face. Note that the defer: argument
- // has to be NO for windows which will remain offscreen. Deferred
- // windows only get created on a orderFront: (or any other method
- // that causes them to come on screen).
-
- GaugeDat.bm = [Window newContent:&r
- style:NX_PLAINSTYLE
- backing:NX_RETAINED
- buttonMask:0
- defer:NO];
- GaugeDat.bmgState = (int)[GaugeDat.bm gState];
- CONDITIONAL_REFRESH;
- return self;
- }
- - sizeTo:(NXCoord)tW :(NXCoord)tH
- {
- fprintf(stderr,"in sizeTo\n");
- [self changeBMSize];
- return self;
- }
- - refreshBackground:sender;
- /* redraw the bitmap - subclasses should override */
- /* Subclasses should re image the bitmap and then do [self display] */
- {
- [self display];
- return self;
- }
-
- /*____________________________________________________________________*/
-
- - setBackGray:(float)bg Face:(float)fg Tic:(float)tg Text:(float)teg
- Point:(float)pg
- {
- GaugeFlags.autoRenderBit = NO;
- [self setBackgroundGray:bg];
- [self setFaceGray:fg];
- [self setTicGray:tg];
- [self setTextGray:teg];
- GaugeFlags.autoRenderBit = YES;
- CONDITIONAL_REFRESH;
- [self setPointerGray:pg];
- return self;
- }
- - setBackgroundGray:(float)tC
- {
- if ((tC > 1.0) || (tC < 0.0)) return nil;
- GaugeDat.backGray = tC;
- CONDITIONAL_REFRESH;
- return self;
- }
- - setFaceGray:(float)tC
- {
- if ((tC > 1.0) || (tC < 0.0)) return nil;
- GaugeDat.faceGray = tC;
- CONDITIONAL_REFRESH;
- return self;
- }
- - setTicGray:(float)tC
- {
- if ((tC > 1.0) || (tC < 0.0)) return nil;
- GaugeDat.ticGray = tC;
- if (GaugeFlags.ticsOn) CONDITIONAL_REFRESH;
- return self;
- }
- - setTextGray:(float)tC
- {
- if ((tC > 1.0) || (tC < 0.0)) return nil;
- GaugeDat.textGray = tC;
- if (GaugeFlags.labelTicsOn || GaugeFlags.titleOn)
- CONDITIONAL_REFRESH;
- return self;
- }
- - setPointerGray:(float)tC
- {
- if ((tC > 1.0) || (tC < 0.0)) return nil;
- GaugeDat.ptGray = tC;
- [self display];
- return self;
- }
- - (float)backgroundGray
- {
- return GaugeDat.backGray;
- }
- - (float)faceGray
- {
- return GaugeDat.faceGray;
- }
- - (float)ticGray
- {
- return GaugeDat.ticGray;
- }
- - (float)textGray
- {
- return GaugeDat.textGray;
- }
- - (float)pointerGray
- {
- return GaugeDat.ptGray;
- }
-
- /*____________________________________________________________________*/
-
-
- - setLowThresh:(double)lT HighThresh:(double)hT AndQuanta:(double)qT
- {
- if ((lT < 1.0) && (lT >= 0.0)) GaugeDat.aThreshLo = lT;
- if ((hT > 0.0) && (hT <= 1.0)) GaugeDat.aThreshHi = hT;
- GaugeDat.ticQuanta = qT;
- return self;
- }
- - setTic:(double)sTic AndStart:(double)aStart;
- /* this is so we can do auto scale with only one bitmap redraw */
- {
- if (sTic <= 0.0) return nil;
- GaugeDat.ticSize = sTic;
- GaugeDat.startValue = aStart;
- GAUGEQUANTTICS
- if ((GaugeDat.value > GAUGEHI) || (GaugeDat.value < GAUGELO)){
- [self reScaleGauge:self];
- } else GaugeFlags.overFlow = NO;
- CONDITIONAL_REFRESH;
- return self;
- }
- - setTicSize:(double)sTic
- {
- [self setTic:sTic AndStart:GaugeDat.startValue];
- return self;
- }
- - setStartValue:(double)aStart
- {
- [self setTic:GaugeDat.ticSize AndStart:aStart];
- return self;
- }
- - setDoubleValue:(double)aD
- /* if autoscale and out of range then do it ... else load value and display */
- {
- GaugeDat.value = aD;
- if ((aD <= GAUGELO) || (aD >= GAUGEHI)){
- if ([self reScaleGauge:self] != nil)
- CONDITIONAL_REFRESH;
- else [self display];
- }else{
- GaugeFlags.overFlow = NO;
- [self display];
- }
- return self;
- }
- - setFloatValue:(float)aF
- {
- [self setDoubleValue:(double)aF];
- return self;
- }
- - takeDoubleValueFrom:sender;
- {
- [self setDoubleValue:[sender doubleValue]];
- return self;
- }
- - takeFloatValueFrom:sender;
- {
- [self setDoubleValue:(double)[sender floatValue]];
- return self;
- }
- - (double)maxValue
- {
- return GAUGEMAX;
- }
- - (double)ticSize
- {
- return GaugeDat.ticSize;
- }
- - (double)startValue
- {
- return GaugeDat.startValue;
- }
- - (double)doubleValue
- {
- return GaugeDat.value;
- }
- - (float)floatValue
- {
- return (float)GaugeDat.value;
- }
- - (BOOL)overFlowDetected
- {
- return GaugeFlags.overFlow;
- }
-
- /*____________________________________________________________________*/
-
- - setMajorTics:(int)nTic
- {
- if (nTic <= 1) return nil;
- GaugeDat.numMajor = nTic;
- CONDITIONAL_REFRESH;
- return self;
- }
- - setMinorTics:(int)nTic
- {
- if (nTic < 0) return nil;
- GaugeDat.numMinor = nTic;
- CONDITIONAL_REFRESH;
- return self;
- }
- - setTitle:(char *)nTitle
- {
- GaugeDat.title = nTitle;
- CONDITIONAL_REFRESH;
- return self;
- }
- - (int)majorTics
- {
- return GaugeDat.numMajor;
- }
- - (int)minorTics
- {
- return GaugeDat.numMinor;
- }
- - (char *)title
- {
- return GaugeDat.title;
- }
-
- /*____________________________________________________________________*/
-
- - setTitleEnable:(BOOL)aFlag
- {
- if (aFlag == GaugeFlags.titleOn) return nil;
- GaugeFlags.titleOn = aFlag;
- CONDITIONAL_REFRESH;
- return self;
- }
- - setTicsEnable:(BOOL)aFlag
- {
- if (aFlag == GaugeFlags.ticsOn) return nil;
- GaugeFlags.ticsOn = aFlag;
- CONDITIONAL_REFRESH;
- return self;
- }
- - setLabelTicsEnable:(BOOL)aFlag
- {
- if (aFlag == GaugeFlags.labelTicsOn) return nil;
- GaugeFlags.labelTicsOn = aFlag;
- CONDITIONAL_REFRESH;
- return self;
- }
- - setAutoScaleEnable:(BOOL)aFlag
- {
- GaugeFlags.autoScaleOn = aFlag;
- return self;
- }
- - setJumpChangeEnable:(BOOL)aFlag
- {
- GaugeFlags.jumpChange = aFlag;
- return self;
- }
- - setBorderType:(int)aType
- {
- if ( (aType == NX_NOBORDER) || (aType == NX_LINE) ||
- (aType == NX_BEZEL) || (aType == NX_RIDGE)){
- GaugeFlags.borderType = aType;
- CONDITIONAL_REFRESH;
- }
- return self;
- }
- - (BOOL)titleEnabled;
- {
- return GaugeFlags.titleOn;
- }
- - (BOOL)ticsEnabled
- {
- return GaugeFlags.ticsOn;
- }
- - (BOOL)labelTicsEnabled
- {
- return GaugeFlags.labelTicsOn;
- }
- - (BOOL)autoScaleEnabled
- {
- return GaugeFlags.autoScaleOn;
- }
- - (BOOL)jumpChangeEnabled
- {
- return GaugeFlags.jumpChange;
- }
- - (int)borderType
- {
- return GaugeFlags.borderType;
- }
-
-
- /*____________________________________________________________________*/
-
- - awake
- {
- NXRect r;
-
- [self getBounds:&r];
- return [self changeBMSize];
- }
-
- - read:(NXTypedStream*)aStream
- {
- fprintf(stderr,"Gauge.m read:\n");
- [super read:aStream];
- NXReadTypes(aStream,"{ii}",&GaugeFlags);
- NXReadTypes(aStream,"{fffff@idddiiddd****}",&GaugeDat);
- NXReadTypes(aStream,"@:",&target,&action);
- return self;
- }
-
- - write:(NXTypedStream*)aStream
- {
- fprintf(stderr,"Gauge.m: write:\n");
- [super write:aStream];
- NXWriteTypes(aStream,"{ii}",&GaugeFlags);
- NXWriteTypes(aStream,"{fffff@idddiiddd****}",&GaugeDat);
- NXWriteTypes(aStream,"@:",&target,&action);
- return self;
- }
-
-
- /* I wish the control class would do this automaticlly */
- - setTarget:aTarget { target = aTarget; return self; }
- - setAction:(SEL)anAction { action = anAction; return self; }
-
-
- @end
-