This is Plot.m in view mode; [Download] [Up]
/* Plot.m by Jonas Karlsson, July 1990
*
* Copyright (C) 1991 The Board of Trustees of
* The Leland Stanford Junior University. All Rights Reserved.
*/
#import "Draw.subproj/draw.h"
#import "Plot.h"
const char Plot_h_rcsid[] = PLOT_H_ID;
const char Plot_m_rcsid[] = "$Id: Plot.m,v 2.54.2.5 1994/02/08 20:30:15 rensing Exp $";
#import "HGraphicView.h"
#import "HTuple.h"
#import <float.h>
#define INDEX_VERSION 2
#define INVERTCUT_VERSION 3
#define FUNCLIST_VERSION 4
#define CURRENT_VERSION FUNCLIST_VERSION
@implementation Plot
static unsigned int plotNum = 0;
static NXAtom namePlot()
{
char buffer[256];
sprintf( buffer, "HippoPlot.%u", plotNum++);
return NXUniqueString(buffer);
}
static void setMarginRect( NXRect *margins, NXRect *bounds, int grid,
int topFlag, int leftFlag)
{
float xOffset=0.0, yOffset=0.0;
switch (topFlag) {
case 0: /* Top */
yOffset = 0.11 * bounds->size.height;
break;
case 1: /* Middle */
yOffset = 0.07 * bounds->size.height;
break;
case 2: /* Bottom */
yOffset = 0.04 * bounds->size.height;
break;
}
switch (leftFlag) {
case 0: /* Left */
xOffset = 0.18 * bounds->size.width;
break;
case 1: /* Middle */
xOffset = 0.11 * bounds->size.width;
break;
case 2: /* Right */
xOffset = 0.04 * bounds->size.width;
break;
}
NXSetRect (margins, xOffset, yOffset,
bounds->size.width * 0.80, bounds->size.height * 0.82);
if ( margins->size.width/grid > 3.001 ) {
margins->origin.x = bounds->origin.x
+ MAX( grid*floor( margins->origin.x/grid ), grid );
margins->size.width = grid*floor( margins->size.width/grid );
} else {
margins->origin.x += bounds->origin.x;
}
if ( margins->size.height/grid > 3.001) {
margins->origin.y = bounds->origin.y
+ MAX( grid*floor( margins->origin.y/grid ), grid );
margins->size.height = grid*floor( margins->size.height/grid );
} else {
margins->origin.y += bounds->origin.y;
}
}
+ initialize
{
[self setVersion:CURRENT_VERSION];
return self;
}
- init
{
NXColor color = NX_COLORCLEAR;
[super init ];
uniqueName = namePlot();
graphicView = NULL;
hTuple = NULL;
disp = NULL;
[self setFillColor:&color];
cutHistFlag = NO;
return self;
}
- initPlotWithTuple: (HTuple*)ht Type: (graphtype_t)type
{
[self init];
disp = h_newDisp(type);
[self replaceTupleWith: ht];
return self;
}
- (const char *)name
{
return uniqueName;
}
- setDispType:(graphtype_t *) type
{
graphtype_t oldtype;
oldtype = h_getDispType(disp);
if (oldtype == *type)
return self;
h_setDispType(disp, *type);
if ((oldtype == HISTOGRAM) && (*type != HISTOGRAM)) {
int i = h_getBinding(disp, XAXIS);
int dim = h_getNtDim(h_getNtuple(disp));
i = MIN(i+1, dim-1);
if (h_getBinding(disp, YAXIS) < 0) {
h_bind(disp, YAXIS, i);
}
i = MIN(i+1, dim-1);
if (h_getBinding(disp, ZAXIS) < 0) {
h_bind(disp, ZAXIS, i);
}
[self NameAxisY:"%y"];
[self NameAxisZ:"%z"];
}
switch (*type) {
case SCATTERPLOT:
h_setDrawType(disp, POINT);
break;
case LEGOPLOT:
disp->doMesh = 1;
break;
case XYPLOT:
case STRIPCHART:
h_setDrawType(disp, POINT);
break;
case HISTOGRAM:
h_setDrawType(disp, BOX);
[self NameAxisY:"Entries / %dx bin"];
default:
break;
}
return self;
}
- setGraphicView:anObject
{
graphicView = anObject;
return self;
}
- graphicView
{
return graphicView;
}
- setInspector:(id)anInspector
{
inspector = anInspector;
return self;
}
- inspector
{
return inspector;
}
- setHTuple: ht withDisplay:(display) d1
{
NXRect bbox;
disp = d1;
[self replaceTupleWith:ht];
h_getDrawRect(disp, (rectangle *) &bbox);
[self setBounds: &bbox];
return self;
}
- setRefFlag:(BOOL) flag
{
h_setNtByRef( disp, flag, NULL );
return self;
}
- setFitted:(BOOL) flag
{
isFitted = flag;
return self;
}
- (BOOL)isFitted
{
return isFitted;
}
- setFixBinsFlag:(BOOL)flag
{
fixBinsFlag = flag;
h_setFixedBins( disp, fixBinsFlag );
return self;
}
- setRefFilename:(const char *)filename
{
if (!filename) return self; /* if filename is not legal, return */
if ( !reffilename ) {
NX_ZONEMALLOC( [self zone], reffilename, char, strlen(filename)+1 );
} else {
NX_ZONEREALLOC( [self zone], reffilename, char, strlen(filename)+1 );
}
strcpy( reffilename, filename );
return self;
}
- changeRefFileNameIfValid:(const char *)filename
{
if ( !hTuple ) {
return self;
}
if ( [hTuple isFakeFilename] ) {
if ( !reffilename ) {
NX_ZONEMALLOC( [self zone], reffilename, char,
strlen(filename)+1 );
} else {
NX_ZONEREALLOC( [self zone], reffilename, char,
strlen(filename)+1 );
}
strcpy( reffilename, filename );
[hTuple setFilename:filename];
}
return self;
}
- replaceTupleWith: ht
{
ntuple tuple;
hTuple = ht;
tuple = (hTuple != nil) ? [hTuple ntuple] : NULL ;
h_bindNtuple(disp, tuple );
if ( !tuple ) return self;
[self setRefFilename:[hTuple filename]];
[self setRefFlag:[hTuple isRef]];
ntindex = [hTuple index];
isFitted = NO;
return self;
}
- replace:oldTuple with:newTuple
{
if ( oldTuple == hTuple ) {
[self replaceTupleWith:newTuple];
}
return self;
}
- closeTuple
{
ntuple tuple;
refFlag = [hTuple isRef];
fixBinsFlag = h_getFixedBins(disp);
h_setFixedBins(disp, YES);
hTuple = nil;
tuple = NULL;
h_bindNtuple(disp, tuple );
return self;
}
- bindReference
{
if ( reffilename == NULL ) return self;
if ( !hTuple ) {
hTuple = [ graphicView hTupleForFile:reffilename index:ntindex];
}
if ( disp == NULL ) return self;
[self replaceTupleWith:hTuple];
if ( !hTuple ) return self;
h_setFixedBins( disp, fixBinsFlag );
return self;
}
- hTuple
{
return hTuple;
}
- (ntuple) ntuple
{
return [hTuple ntuple];
}
- addHTupleToList:tlist
{
if ( hTuple ) {
[tlist addObjectIfAbsent:hTuple];
}
return self;
}
- addPlotToList:list
{
[list addObjectIfAbsent:self];
return self;
}
- (display) histDisplay
{
return disp;
}
- setTitle:(char *) title
{
h_setTitle(disp, title);
return self;
}
- (const char *) title
{
return h_getTitle( disp );
}
- NameAxisX:(const char *)AxisName
{
h_setAxisLabel(disp, XAXIS, AxisName);
return self;
}
- (const char *) axisLabelX
{
return h_getAxisLabel(disp, XAXIS );
}
- NameAxisY:(const char *)AxisName
{
h_setAxisLabel(disp, YAXIS, AxisName);
return self;
}
- (const char *) axisLabelY
{
return h_getAxisLabel(disp, YAXIS );
}
- NameAxisZ:(const char *)AxisName
{
h_setAxisLabel(disp, ZAXIS, AxisName);
return self;
}
- (const char *) axisLabelZ
{
return h_getAxisLabel(disp, YAXIS );
}
- NameAxisW:(const char *)AxisName
{
h_setAxisLabel(disp, WEIGHT, AxisName);
return self;
}
- NameAxisXE:(const char *)AxisName
{
h_setAxisLabel(disp, XERROR, AxisName);
return self;
}
- NameAxisYE:(const char *)AxisName
{
h_setAxisLabel(disp, YERROR, AxisName);
return self;
}
- bindAxisX:(int *)dataDim
{
if ( [self isCutPlot] ) return self;
h_bind(disp, XAXIS, *dataDim );
isFitted = NO;
return self;
}
- bindAxisY:(int *)dataDim
{
h_bind(disp, YAXIS, *dataDim );
isFitted = NO;
return self;
}
- bindAxisZ:(int *)dataDim
{
h_bind(disp, ZAXIS, *dataDim );
isFitted = NO;
return self;
}
- bindAxisW:(int *)dataDim
{
h_bind(disp, WEIGHT, *dataDim );
isFitted = NO;
return self;
}
- bindAxisXE:(int *)dataDim
{
h_bind(disp, XERROR, *dataDim );
isFitted = NO;
return self;
}
- bindAxisYE:(int *)dataDim
{
h_bind(disp, YERROR, *dataDim );
isFitted = NO;
return self;
}
- setLogScale:(binding_t *)axis to:(int *)yesOrNo
{
h_setLogAxis( disp, *axis, *yesOrNo );
return self;
}
- (BOOL) isLogScaleX
{
BOOL val;
val = h_getLogAxis(disp, XAXIS);
return val;
}
- (BOOL) isLogScaleY
{
BOOL val;
val = h_getLogAxis(disp, YAXIS);
return val;
}
- (BOOL) isLogScaleZ
{
BOOL val;
val = h_getLogAxis(disp, ZAXIS);
return val;
}
- setTitlesFlag:(const int *)yesOrNo
{
h_setDrawTitles( disp, *yesOrNo);
return self;
}
- (int) titlesFlag
{
return h_getDrawTitles(disp);
}
- setAxesFlag:(int *)yesOrNo
{
h_setDrawAxes( disp, *yesOrNo );
return self;
}
- (int) axesFlag
{
return h_getDrawAxes( disp );
}
- setAutoScale:(binding_t *)axis to:(const int *)yesOrNo
{
h_setAutoScale(disp, *axis, *yesOrNo);
return self;
}
- getRangeForAxisX:(NXPoint *)p
{
h_getRange(disp, XAXIS, &p->x, &p->y );
return self;
}
- getRangeForAxisY:(NXPoint *)p
{
h_getRange(disp, YAXIS, &p->x, &p->y );
return self;
}
- setRange:(binding_t *)axis to:(const NXPoint *)p
{
h_setRange(disp, *axis, p->x, p->y );
isFitted = NO;
return self;
}
- setRangeAndNbins:(binding_t *)axis to:(const NXPoint *)p
{
float low, high, width;
int nbins;
width = h_getBinWidth(disp, *axis);
nbins = (p->y - p->x) / width;
low = p->x;
high = low + nbins * width;
h_setRange(disp, *axis, low, high);
h_setBinNum(disp, *axis, nbins);
isFitted = NO;
return self;
}
- getRangeForAxisZ:(NXPoint *)p
{
h_getRange(disp, ZAXIS, &p->x, &p->y );
return self;
}
- getRangeForAxis:(binding_t) axis low:(float *) xl high:(float *) xh
{
h_getRange(disp, axis, xl, xh );
return self;
}
- setRangesFrom:plot
{
display plotdisp;
float low, high;
graphtype_t plot_t;
float plot_w, my_w;
if ( plot == self ) return self;
plotdisp = [plot histDisplay];
h_getRange(plotdisp, XAXIS, &low, &high );
h_setRange(disp, XAXIS, low, high );
h_getRange(plotdisp, YAXIS, &low, &high );
/*
* normalize for histograms only
*/
plot_t = h_getDispType( plotdisp);
if ( h_getDispType(disp) == HISTOGRAM &&
plot_t == HISTOGRAM ) {
plot_w = h_getBinWidth( plotdisp, XAXIS );
my_w = h_getBinWidth(disp, XAXIS);
low *= (my_w/plot_w);
high *= (my_w/plot_w);
}
h_setRange(disp, YAXIS, low, high );
isFitted = NO;
return self;
}
- setRangesAndBinsFrom:plot
{
display plotdisp;
float low, high, width;
int nbins;
graphtype_t plot_t;
float plot_w, my_w;
if ( plot == self ) return self;
plotdisp = [plot histDisplay];
h_getRange(plotdisp, XAXIS, &low, &high );
if ( h_getDispType(disp) == HISTOGRAM) {
width = h_getBinWidth(disp, XAXIS);
nbins = (high - low) / width;
high = low + nbins * width;
h_setBinNum(disp, XAXIS, nbins);
}
h_setRange(disp, XAXIS, low, high);
h_getRange(plotdisp, YAXIS, &low, &high );
/*
* normalize for histograms only
*/
plot_t = h_getDispType( plotdisp);
if ( h_getDispType(disp) == HISTOGRAM &&
plot_t == HISTOGRAM ) {
plot_w = h_getBinWidth( plotdisp, XAXIS );
my_w = h_getBinWidth(disp, XAXIS);
low *= (my_w/plot_w);
high *= (my_w/plot_w);
}
h_setRange(disp, YAXIS, low, high );
isFitted = NO;
return self;
}
- getRangeForAxisY:(NXPoint *)range normalizedTo:plot
{
display plotdisp;
float scale;
h_getRange(disp, YAXIS, &range->x, &range->y );
plotdisp = [plot histDisplay];
if ( h_getDispType(disp) != HISTOGRAM ||
h_getDispType(plotdisp) != HISTOGRAM ) {
return self;
}
scale = h_getBinWidth(plotdisp, XAXIS) / h_getBinWidth(disp, XAXIS);
range->x *= scale;
range->y *= scale;
return self;
}
- (float)widthForAxis:(binding_t) axis
{
return h_getBinWidth(disp, axis);
}
- setNumBins:(binding_t *) axis to:(const int *)n
{
h_setBinNum( disp, *axis, *n );
h_setAutoScale( disp, *axis, 0 );
isFitted = NO;
return self;
}
- (int)numBinsForAxis:(binding_t) axis
{
return h_getBinNum(disp, axis);
}
- setLineStyle:(linestyle_t *) style
{
h_setLineStyle(disp, *style);
return self;
}
- getLineStyle:(linestyle_t *) style
{
*style=h_getLineStyle(disp);
return self;
}
- setPlotSym:(plotsymbol_t *) plotsymbol
{
h_setPlotSym(disp, *plotsymbol);
return self;
}
- getPlotSym:(plotsymbol_t *) plotsymbol
{
*plotsymbol=h_getPlotSym(disp);
return self;
}
- setSymSize:(float *) plotsymsize
{
h_setSymSize(disp, *plotsymsize);
return self;
}
- getSymSize:(float *) plotsymsize
{
*plotsymsize=h_getSymSize(disp);
return self;
}
- setDrawType:(drawtype_t *) type
{
h_setDrawType(disp, *type);
return self;
}
- getDrawType:(drawtype_t *) type
{
*type = h_getDrawType(disp);
return self;
}
- setColorType:(const int *)onOff
{
int i;
if ( *onOff )
h_orDrawType(disp, COLOR);
else
{
i = h_getDrawType(disp);
i = i & (~COLOR);
h_setDrawType(disp, i);
}
return self;
}
- setTickLocation: (binding_t *) axis to:(plotloc_t *) loc
{
h_setTickLocation(disp, *axis, *loc );
return self;
}
- setScaleLocation: (binding_t *) axis to:(plotloc_t *) loc
{
h_setScaleLocation(disp, *axis, *loc );
return self;
}
- setLabelLocation: (binding_t *) axis to:(plotloc_t *) loc
{
h_setLabelLocation(disp, *axis, *loc );
return self;
}
- setScaleFontSize: (binding_t *) axis to:(float *) fontSize
{
h_setScaleFontSize( disp, *axis, *fontSize );
return self;
}
- setTickLength: (binding_t *) axis to:(float *) len
{
h_setTickLength( disp, *axis, *len );
return self;
}
- draw
{
NXRect margins;
int grid, topFlag=0, leftFlag=0;
if (bounds.size.width < 1.0 || bounds.size.height < 1.0)
return self;
if ([self fill]) {
PSgsave();
[self setFillColor];
NXRectFill(&bounds);
PSgrestore();
}
if (!gFlags.nooutline) {
[self setLineColor];
}
if ( (NXDrawingStatus == NX_PRINTING) && (linewidth < 0.15) ) {
PSsetlinewidth(0.15); /* in case going to Linotronic (R) */
}
h_setDrawRect (disp, (rectangle *) &bounds );
if ( graphicView && [graphicView gridIsEnabled] ) {
grid = [graphicView gridSpacing];
} else {
grid = 1;
}
if (disp->xAxis.flags.labelLocation & PLOTTOP) topFlag += 1;
if (disp->xAxis.flags.scaleLocation & PLOTTOP) topFlag += 1;
if (disp->yAxis.flags.labelLocation & PLOTRIGHT) leftFlag += 1;
if (disp->yAxis.flags.scaleLocation & PLOTRIGHT) leftFlag += 1;
setMarginRect(&margins, &bounds, grid, topFlag, leftFlag);
h_setMarginRect (disp, (rectangle *) &margins);
/*
* do shading in case of cut plot. Must do after plotting, since h_plot
* sets up margins, autoscales, etc.
* h_shade will keep shading inside bounds of plot.
*/
if ( cutHistFlag && (disp != NULL) && (cutParms.cutFunc != NULL) )
{
switch (cutParms.cutCode)
{
case 0:
h_shade(disp, -FLT_MAX, cutParms.cutValue1);
break;
case 1:
h_shade(disp, cutParms.cutValue1, FLT_MAX);
break;
case 2:
h_shade(disp, cutParms.cutValue1, cutParms.cutValue2);
break;
case 3:
h_shade(disp, -FLT_MAX, cutParms.cutValue1);
h_shade(disp, cutParms.cutValue2, FLT_MAX);
break;
}
}
/*
* draw plot last, so shading doesn't cover it.
*/
h_plot(disp);
return self;
}
- print
{
h_print(disp);
return self;
}
- setBounds:(const NXRect *)aRect
{
NXRect margins;
int grid, topFlag = 0, leftFlag=0;
bounds = *aRect;
h_setDrawRect(disp, (rectangle *) &bounds);
grid = [graphicView gridSpacing];
if (disp->xAxis.flags.labelLocation & PLOTTOP) topFlag += 1;
if (disp->xAxis.flags.scaleLocation & PLOTTOP) topFlag += 1;
if (disp->yAxis.flags.labelLocation & PLOTRIGHT) leftFlag += 1;
if (disp->yAxis.flags.scaleLocation & PLOTRIGHT) leftFlag += 1;
setMarginRect(&margins, &bounds, grid, topFlag, leftFlag);
h_setMarginRect (disp, (rectangle *) &margins);
return self;
}
- sizeToNaturalAspectRatio
{
NXRect defaultBox;
[graphicView calcDefaultPlotSize:&defaultBox];
bounds.origin.y += ( NX_HEIGHT(&bounds) - NX_HEIGHT(&defaultBox) );
bounds.size.height = NX_HEIGHT(&defaultBox);
bounds.size.width = NX_WIDTH(&defaultBox);
[self setBounds:&bounds];
return self;
}
/* Methods supporting Archiving and de-Archiving */
- write:(NXTypedStream *) ts
{
cutStorElem *cut;
dependStorElem *old;
display dlist[] = {NULL, NULL};
char *data;
int len, lenref;
int i;
[super write:ts];
/* change some flags for storage to stream */
if ( hTuple) {
refFlag = [hTuple isRef];
}
fixBinsFlag = h_getFixedBins(disp);
h_setFixedBins(disp, YES);
h_setNtByRef(disp, YES, reffilename );
lenref = strlen(reffilename);
/* write display to buffer */
len = h_dispSize( disp );
NX_ZONEMALLOC( [self zone], data, char, len );
dlist[0] = disp;
if ( h_writeMem( data, len, dlist, NULL ) ) {
printf( "Could not write buffer\n" );
return self;
}
/* restore display in case we are doing copy */
h_setNtByRef( disp, refFlag, NULL );
h_setFixedBins( disp, fixBinsFlag );
/* Now archive Plot object to typed stream */
NXWriteTypes( ts, "ccii", &refFlag, &fixBinsFlag, &len, &lenref );
NXWriteType( ts, "*", &reffilename );
if ( [Plot version] >= INDEX_VERSION ) {
NXWriteType( ts, "i", &ntindex );
NXWriteObjectReference(ts, hTuple);
}
NXWriteArray( ts, "c", len, data );
NXWriteType( ts, "c", &cutHistFlag);
if ( cutHistFlag ) {
len = strlen( cutParms.cutFunc );
NXWriteType( ts, "i", &len );
NXWriteType( ts, "{*iffi}", &cutParms );
NXWriteType( ts, "i", &cutNumber);
}
i = [cutPlotStor count];
NXWriteType( ts, "i", &i );
while ( i-- ) {
cut = [cutPlotStor elementAt:i];
NXWriteObjectReference(ts, cut->plot );
if ( [Plot version] >= INDEX_VERSION ) {
cut->name = [cut->plot name];
NXWriteType( ts, "%", &cut->name );
if ( [Plot version] >= INVERTCUT_VERSION ) {
NXWriteType( ts, "c", &cut->invertFlag );
}
}
}
if ( dependStor ) {
i = [dependStor count];
} else {
i = 0;
}
NXWriteType( ts, "i", &i);
while ( i-- ) {
old = [dependStor elementAt:i];
NXWriteObjectReference( ts, old->plot);
if ( [Plot version] >= INDEX_VERSION ) {
old->name = [old->plot name];
NXWriteType( ts, "%", &old->name );
}
}
free( data );
if ( [Plot version] >= FUNCLIST_VERSION ) {
NXWriteObject( ts, funcList );
}
return self;
}
- read:(NXTypedStream *) ts
{
cutStorElem cut;
dependStorElem new;
ntuple *ntlist;
display *dlist;
char *data;
int len, lenref;
int i, count;
[super read:ts];
uniqueName = namePlot();
NXReadTypes( ts, "ccii", &refFlag, &fixBinsFlag, &len, &lenref);
NX_ZONEMALLOC( [self zone], data, char, len );
NXReadType( ts, "*", &reffilename);
if ( NXTypedStreamClassVersion(ts, "Plot") >= INDEX_VERSION ) {
NXReadType( ts, "i", &ntindex );
hTuple = NXReadObject( ts );
hTuple = nil; /* will bind by reference later */
} else {
ntindex = 0;
hTuple = nil;
}
NXReadArray( ts, "c", len, data );
h_readMem( data, len, &dlist, &ntlist );
NX_FREE( data );
disp = dlist[0];
if ( !hTuple ) disp->tuple = NULL; /* shouldn't happen */
NXReadType( ts, "c", &cutHistFlag );
if ( cutHistFlag ) {
NXReadType( ts, "i", &len );
NX_ZONEMALLOC( [self zone], cutParms.cutFunc, char, len+1 );
NXReadType( ts, "{*iffi}", &cutParms );
NXReadType( ts, "i", &cutNumber);
}
NXReadType( ts, "i", &count );
if ( count ) {
cutPlotStor = [[Storage allocFromZone:[self zone]] initCount:0
elementSize:sizeof(cutStorElem)
description:"@%*"];
}
for ( i = 0; i < count; i++ ) {
cut.plot = NXReadObject( ts );
if ( NXTypedStreamClassVersion(ts, "Plot") >= INDEX_VERSION ) {
NXReadType( ts, "%", &cut.name );
if ( NXTypedStreamClassVersion(ts, "Plot") >= INVERTCUT_VERSION ) {
NXReadType( ts, "c", &cut.invertFlag );
}
} else {
cut.name = NXUniqueString("HippoPlot.NULL" );
cut.invertFlag = FALSE;
}
if ( cut.plot ) {
cut.name = [cut.plot name];
}
[cutPlotStor addElement:&cut.plot];
}
NXReadType( ts, "i", &count );
if ( count ) {
dependStor = [[Storage allocFromZone:[self zone]] initCount:0
elementSize:sizeof(dependStorElem)
description:"@%"];
}
for ( i = 0; i < count; i++ ) {
new.plot = NXReadObject( ts );
if ( NXTypedStreamClassVersion(ts, "Plot") >= INDEX_VERSION ) {
NXReadType( ts, "%", &new.name );
} else {
new.name = NXUniqueString("HippoPlot.NULL" );
}
if ( new.plot ) {
new.name = [new.plot name];
}
[dependStor addElement:&new];
}
if ( NXTypedStreamClassVersion(ts, "Plot") >= FUNCLIST_VERSION ) {
funcList = NXReadObject( ts );
}
return self;
}
- free
{
[self removeAllCuts];
NX_FREE(reffilename);
[cutPlotStor free];
NX_FREE(cutParms.cutFunc);
/* disp should be attached, but it may not be */
if ( disp != NULL ) h_freeDisp(disp);
return [super free];
}
- wasRemovedFrom: gv
{
if (cutHistFlag && [gv isKindOf:[HGraphicView class]])
{
[[gv cutList] removeObject: self];
}
return [super wasRemovedFrom: gv];
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.