This is ErrorBarHandler.m in view mode; [Download] [Up]
/* Generated by Interface Builder */ #import "ErrorBarHandler.h" #import "Plot.h" #import "defs.h" #import <appkit/Font.h> #import <appkit/Panel.h> #import <appkit/Window.h> #import <appkit/Matrix.h> #import <appkit/View.h> #import <appkit/ButtonCell.h> #import <dpsclient/wraps.h> #import <appkit/color.h> /* only for "blanking out" parts of a matrix */ #import <appkit/graphics.h> /* ditto */ /* * The job of this object is to keep the appearance of the Error Bar panel in * accord with the state of the program. This is only needed if the Error Bar * panel is visible. A lot of the code is the same as in ColumnSelectionHandler.m. */ @implementation ErrorBarHandler - init { /* * This global variable keeps track of whether the error bar window * has ever been displayed. We can avoid updating after the selective * file removal if we have never been displayed. */ everVisible = NO; return self; } - eraseDisabledCells:sender { int n, j, numrows, numcols, ncurves; NXRect r; BOOL exbars, eybars; [errorBarMatrix getNumRows:&numrows numCols:&numcols]; [errorBarMatrix lockFocus]; NXSetColor([errorBarMatrix backgroundColor]); /* cf. comment in ColumnSelectionHandler.m */ for (n=0; n<[plotParam nFiles]; n++) { exbars = [plotParam has_exbars:n]; eybars = [plotParam has_eybars:n]; if (!exbars && !eybars) { /* if this file has no error bars, blank out everything */ for (j=-1; j<numcols; j++) { [errorBarMatrix getCellFrame:&r at:n :j+1]; /* note the j+1 here and below */ NXRectFill(&r); } } else if (exbars && !eybars) { /* x error bars, no y error bars, blank out some columns */ for (j=0; j<numcols; j++) { [errorBarMatrix getCellFrame:&r at:n :j+1]; NXRectFill(&r); } } else if (!exbars && eybars) { /* no x error bars, has y error bars; blank out 1st and some more columns */ [errorBarMatrix getCellFrame:&r at:n :0]; NXRectFill(&r); ncurves = [plotParam nCurves:n]; if (ncurves < numcols) { for (j=ncurves; j<numcols; j++) { [errorBarMatrix getCellFrame:&r at:n :j+1]; NXRectFill(&r); } } } else { /* both x and y error bars; maybe blank out some columns */ ncurves = [plotParam nCurves:n]; if (ncurves < numcols) { for (j=ncurves; j<numcols; j++) { [errorBarMatrix getCellFrame:&r at:n :j+1]; NXRectFill(&r); } } } } [errorBarMatrix unlockFocus]; NXPing(); return self; } - removeAll:sender /* This method is called by the "remove all files" method of the Plot object. */ { int n, j; int numrows, numcols; NXSize cellsize, intercell; NXCoord dy; /* Do something only if the window has ever been displayed */ if (everVisible) { [errorBarMatrix getNumRows:&numrows numCols:&numcols]; [errorBarMatrix getCellSize:&cellsize]; [errorBarMatrix getIntercell:&intercell]; /* * Wipe out everything. */ dy = (NXCoord)(numrows - 1) * (cellsize.height + intercell.height); [errorBarMatrix moveBy:0.0 :dy]; /* * Before doing renewRows, set the state of all the cells to 1; this is * because the renewRows method just recycles the cells, and later on * we may find ourselves using a cell which has state=0 when we don't * want such a beast. Also disable all cells (paranoia strikes). */ for (n=0; n<numrows; n++) { for (j=0; j<numcols; j++) { [[errorBarMatrix cellAt:n :j] setState:1]; [[errorBarMatrix cellAt:n :j] setEnabled:YES]; } } [errorBarMatrix renewRows:1 cols:1]; [errorBarMatrix sizeToCells]; [[errorBarMatrix cellAt:0 :0] setType:NX_TOGGLE]; [filenameMatrix moveBy:0.0 :dy]; [filenameMatrix renewRows:1 cols:1]; [[filenameMatrix cellAt:0 :0] setStringValue:"filename"]; [filenameMatrix sizeToCells]; [errorBarText renewRows:1 cols:1]; [errorBarText sizeToCells]; /* Do some drawing now. Display the view. */ [[errorBarMatrix window] display]; NXPing(); /* needed??? */ } return self; } - updatePanel:sender /* * The update button activates this method; it is also called from * windowDidResize and from Plot.m in postludeToReading. We have to * fix up the error bar panel so that it's correct. */ { int n, j; int nfilestotal = [plotParam nFiles], maxcols = 0, ncurves; char title[80]; int numrows, numcols; NXSize cellsize, intercell; NXCoord dy; int ** turned_on; BOOL exbars, eybars; if (everVisible == NO) everVisible = YES; [errorBarMatrix getNumRows:&numrows numCols:&numcols]; [errorBarMatrix getCellSize:&cellsize]; [errorBarMatrix getIntercell:&intercell]; /* * We have to create some additional rows and perhaps some additional columns. */ // First figure out how many columns the matrix should have for (n=0; n<nfilestotal; n++) { maxcols = MAX(maxcols, [plotParam nCurves:n]); } maxcols++; /* add one column for the "x" (zero) column */ if (numrows != nfilestotal || numcols != maxcols) { /* The renewRows:cols: message might have the side effect of setting * the state of all the cells of the matrix back to 0; this is undesired, * so before changing the number of rows and/or columns in the matrix, * make sure we remember which cells in each row were turned on. */ turned_on = (int **)malloc(nfilestotal * sizeof(int)); /* should do error check */ for (n=0; n<nfilestotal; n++) { *(turned_on + n) = (int *)malloc(maxcols * sizeof(int)); } for (n=0; n<nfilestotal; n++) { for (j=0; j<maxcols; j++) { *(*(turned_on+n)+j) = 1; } } for (n=0; n<numrows; n++) { for (j=0; j<numcols; j++) { *(*(turned_on+n)+j) = [[errorBarMatrix cellAt:n :j] state]; } } [errorBarMatrix renewRows:nfilestotal cols:maxcols]; for (n=0; n<nfilestotal; n++) { for (j=0; j<maxcols; j++) { [[errorBarMatrix cellAt:n :j] setState:1]; /* everything turned on */ } } /* Turn cells off if needed. */ for (n=0; n<numrows; n++) { for (j=0; j<numcols; j++) { [[errorBarMatrix cellAt:n :j] setState:*(*(turned_on+n)+j)]; } } for (n=0; n<nfilestotal; n++) { free((void *)*(turned_on + n)); } free((void *)turned_on); } [errorBarMatrix sizeToCells]; dy = (float)(nfilestotal - numrows) * (cellsize.height + intercell.height); [errorBarMatrix moveBy:0.0 :-dy]; // Some of the cells may come in with type NULLCELL; fix them here for (n=0; n<nfilestotal; n++) { for (j=0; j<maxcols; j++) { [[errorBarMatrix cellAt:n :j] setEnabled:YES]; [[errorBarMatrix cellAt:n :j] setType:NX_TOGGLE]; } } // We surround the [errorBarMatrix display] and [self eraseDisabledCells] // calls with the disableFlushWindow, reenableFlushWindow, and flushWindow // calls to prevent the disabled matrix cells from being visible for a long // time while they're drawn and then erased. [errorBarPanel disableFlushWindow]; [errorBarMatrix display]; // Disable cells that shouldn't appear. for (n=0; n<nfilestotal; n++) { exbars = [plotParam has_exbars:n]; eybars = [plotParam has_eybars:n]; if (!exbars && !eybars) { /* if this file has no error bars, disable everything */ for (j=-1; j<maxcols; j++) { [[errorBarMatrix cellAt:n :j+1] setType:NX_NULLCELL]; [[errorBarMatrix cellAt:n :j+1] setEnabled:NO]; } } else if (exbars && !eybars) { /* x error bars, no y error bars, blank out some columns */ for (j=0; j<numcols; j++) { [[errorBarMatrix cellAt:n :j+1] setType:NX_NULLCELL]; [[errorBarMatrix cellAt:n :j+1] setEnabled:NO]; } } else if (!exbars && eybars) { /* no x error bars, has y error bars; blank out 1st and some more columns */ [[errorBarMatrix cellAt:n :0] setType:NX_NULLCELL]; [[errorBarMatrix cellAt:n :0] setEnabled:NO]; ncurves = [plotParam nCurves:n]; if (ncurves < numcols) { for (j=ncurves; j<maxcols; j++) { [[errorBarMatrix cellAt:n :j+1] setType:NX_NULLCELL]; [[errorBarMatrix cellAt:n :j+1] setEnabled:NO]; } } } else { /* both x and y error bars; maybe blank out some columns */ ncurves = [plotParam nCurves:n]; if (ncurves < numcols) { for (j=ncurves; j<numcols; j++) { [[errorBarMatrix cellAt:n :j+1] setType:NX_NULLCELL]; [[errorBarMatrix cellAt:n :j+1] setEnabled:NO]; } } } } // We have to put the makeKeyAndOrderFront before the eraseDisabledCells // method, because eraseDisabledCells does a lockFocus and lockFocus needs // a real window to draw into. We put the makeKeyAndOrderFront here rather // than at the beginning of this method because this way the disabled cells // of the matrix are visible for a shorter period of time. [errorBarPanel makeKeyAndOrderFront:self]; // Now erase those disabled cells. [self eraseDisabledCells:self]; [errorBarPanel reenableFlushWindow]; [errorBarPanel flushWindowIfNeeded]; NXPing(); /* needed? */ // That finishes with the errorBarMatrix; now for the filename Matrix. [filenameMatrix renewRows:nfilestotal cols:1]; for (n=0; n<nfilestotal; n++) { if (!strncmp([plotParam filename:(unsigned)n], "pasteboard", 10)) sprintf(title, "pasteboard"); else sprintf(title, strrchr([plotParam filename:(unsigned)n], '/') + 1); [[filenameMatrix cellAt:n :0] setStringValue:title]; } [filenameMatrix sizeToCells]; [filenameMatrix moveBy:0.0 :-dy]; [filenameMatrix display]; // And now for the errorBarText matrix. [errorBarText renewRows:1 cols:maxcols]; for (j=0; j<maxcols; j++) { sprintf(title, "%d", j); [[errorBarText cellAt:0 :j] setStringValue:title]; } [errorBarText sizeToCells]; [errorBarText display]; return self; } /* * Apropos this, see the remarks in ColumnSelectionHandler.m */ - windowDidResize:sender { [self perform:@selector(updatePanel:) with:self afterDelay:1 /* wait 0.001 second */ cancelPrevious:YES]; return self; } /* * This is called by the selective file removal code in Plot.m. */ - update:sender { int n, nfilestotal = [plotParam nFiles], num_removed = 0; NXSize cellsize, intercell; NXCoord dy; /* Do something only if the window has ever been displayed */ if (everVisible) { [errorBarMatrix getCellSize:&cellsize]; [errorBarMatrix getIntercell:&intercell]; /* * Count down the file removal panel, removing rows as needed. */ for (n = nfilestotal-1; n>=0; n--) { if ([[fileRemovalButtons cellAt:n :0] state] == 1) { /* This file is to be removed. */ num_removed++; [errorBarMatrix removeRowAt:n andFree:YES]; [filenameMatrix removeRowAt:n andFree:YES]; } } [errorBarMatrix sizeToCells]; [filenameMatrix sizeToCells]; if (num_removed > 0) { dy = (NXCoord)(num_removed) * (cellsize.height + intercell.height); [errorBarMatrix moveBy:0.0 :dy]; [filenameMatrix moveBy:0.0 :dy]; } /* Do some drawing now. Display the view. */ [[errorBarMatrix window] display]; NXPing(); /* needed??? */ } return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.