This is CellScrollView.m in view mode; [Download] [Up]
/************************************************** * SynthBuilder * Copyright 1993 Nick Porcaro All Rights Reserved **************************************************/ /* * You may freely copy, distribute, and reuse the code in this example. * NeXT disclaims any warranty of any kind, expressed or implied, as to its * fitness for any particular use. */ #import "CellScrollView.h" #import "ViewController.h" #import "GenericCell.h" #import "GenericObject.h" #import "Utilities.h" #import "DragView.h" #import "FakeSynthPatch.h" extern char *getAppName(); @implementation CellScrollView static char TempString[1024]; - init { return [self initFrame:NULL]; } - initFrame:(const NXRect *)frameRect /* This is called automatically when the nib is loaded */ { [super initFrame:frameRect]; theFrameRect = frameRect; return self; } - initCellList:aList /* Call this to setup the initial emtpy list * This makes each cell be a GenericCell, which is usually fine */ { theCellList = aList; [self initCellMatrixWithClass:[GenericCell class]]; [self updateList]; return self; } - setCellList:aList /* Call this if theCellList ever changes for a given CellScrollView */ { theCellList = aList; return self; } - initCellMatrix { [self initCellMatrixWithClass:[GenericCell class]]; return self; } - initCellMatrixWithClass:(Class) aClass /* Rarely called from the outside world */ { NXSize interCellSpacing = {0.0, 0.0}, docSize; cellMatrix = [[Matrix alloc] initFrame:theFrameRect mode:NX_LISTMODE cellClass:aClass numRows:0 numCols:1]; /* * In the following lines, * remember that "cellMatrix" is the matrix that will be installed * in the scrollview, "self" is the scrollview. */ /* we don't want any space between the matrix's cells */ [cellMatrix setIntercell:&interCellSpacing]; /* resize the matrix to contain the cells */ [cellMatrix sizeToCells]; [cellMatrix setAutosizeCells:YES]; /* * when the user clicks in the matrix and then drags the mouse out of * scrollView's contentView, we want the matrix to scroll */ [cellMatrix setAutoscroll:YES]; /* let the matrix stretch horizontally */ [cellMatrix setAutosizing:NX_WIDTHSIZABLE]; /* Install the matrix as the docview of the scrollview */ [[self setDocView:cellMatrix] free]; /* set up the visible attributes of the scrollview */ [self setVertScrollerRequired:YES]; [self setBorderType:NX_BEZEL]; /* tell the subviews to resize along with the scrollview */ [self setAutoresizeSubviews:YES]; /* This is the only way to get the clipview to resize too */ [[cellMatrix superview] setAutoresizeSubviews:YES]; /* Allow the scrollview to stretch both horizontally and vertically */ [self setAutosizing:NX_WIDTHSIZABLE|NX_HEIGHTSIZABLE]; /* Resize the matrix to fill the inside of the scrollview */ [self getContentSize:&docSize]; [cellMatrix sizeTo:docSize.width :docSize.height]; return self; } - reportCurrentSelection { static char buf[1000]; GenericCell *cell = [cellMatrix selectedCell]; sprintf(buf, "The highlighted name: %s\n", [[cell genericObject] getName]); NXRunAlertPanel("CellScrollView", buf,0,0,0); return self; } - currentlySelectedObject { return [[cellMatrix selectedCell] genericObject]; } - free { [cellMatrix free]; return [super free]; } - cellMatrix { return cellMatrix; } - deleteSelections { int i; id cell; id anObj; for (i=[cellMatrix cellCount]-1; i>=0; i--) { cell = [cellMatrix cellAt:i:0]; if ([cell isHighlighted]) { /* * If a cell is highlighted, remove (and free) the corresponding item * from the list of theCellList. */ sprintf(TempString, "Do you really want to delete %s", [[cell genericObject] getName]); if (NXRunAlertPanel(getAppName(), TempString, "OK","Cancel",NULL) != NX_ALERTDEFAULT) { return self; } else { anObj = [cell genericObject]; [anObj closeInspector]; [[theCellList removeObject:anObj] free]; } } } [self updateList]; return self; } - editSelections { int i; id cell; for (i=[cellMatrix cellCount]-1; i>=0; i--) { cell = [cellMatrix cellAt:i:0]; if ([cell isHighlighted]) { [[cell genericObject] edit]; } } return self; } - objectsJustAdded { /* * Assumptions in this next line: * There are as many GenericCells as there are theCellList * We've added the new genericObject at the end of the list. * We want to display the genericObject we just added and highlight it. * In short, this is a hack. */ [cellMatrix scrollCellToVisible:[theCellList count]-1 :0]; [cellMatrix selectCellAt:[theCellList count]-1:0]; return self; } static int defCompare(const void *def1, const void *def2) { return strcmp([*(id *)def1 getName],[*(id *)def2 getName]); } - updateList /* * Fill the matrix with GenericCells, associate each GenericCell with a GenericObject. * * Since we recycle the cells (via renewRows:cols:), we also set the state * of each cell to 0 and unhighlight it. If we don't do that, the recycled * cells will display their previous state. */ { int i, cellCount; id utilities; cellCount = [theCellList count]; utilities = [ [ [theViewController getDragView] getPatch] utilities]; [utilities sortList:theCellList sortFunction:defCompare]; /* tell the matrix there are 0 cells in it (but don't deallocate them) */ [cellMatrix renewRows:0 cols:1]; if ([theViewController getFocusLock]) { [cellMatrix lockFocus]; /* for highlightCellAt::lit: */ } for (i=0;i<cellCount;i++) { GenericCell *cell; /* * add a row to the matrix. (This doesn't necessarily allocate a new * cell, thanks to renewRows:cols:). */ [cellMatrix addRow]; cell = [cellMatrix cellAt:i:0]; /* make sure the cell is neither selected nor highlighted */ [cellMatrix highlightCellAt:i:0 lit:NO]; [cell setState:0]; /* install the genericObject in that cell */ [cell setGenericObject:[theCellList objectAt:i]]; } if ([theViewController getFocusLock]) { [cellMatrix unlockFocus]; } [cellMatrix sizeToCells]; [cellMatrix display]; return self; } - getCurrentImage { id anImage; int i, j; id firstSelected = nil; id cell; /* Just get the first one the was selected */ j = 0; for (i=[cellMatrix cellCount]-1; i>=0; i--) { cell = [cellMatrix cellAt:i:0]; if ([cell isHighlighted]) { firstSelected = cell; j++; } } switch (j) { case (0): { anImage = [NXImage findImageNamed:"NoIcon"]; break; } case (1): { anImage = [self getImageFor:[firstSelected genericObject]]; if (! anImage) { anImage = [NXImage findImageNamed:"NoIcon"]; } break; } default: { anImage = [NXImage findImageNamed:"MultipleSelection"]; } } return anImage; } - (BOOL) haveSelection { int i, j; id cell; /* Just get the first one the was selected */ j = 0; for (i=[cellMatrix cellCount]-1; i>=0; i--) { cell = [cellMatrix cellAt:i:0]; if ([cell isHighlighted]) { j++; } } if (j == 0) { return NO; } else { return YES; } } - getImageFor:anObject { id anImage; char *iconName; if (! anObject) { return nil; } if (! (iconName = [anObject getIconFile]) || ! (anImage = [NXImage findImageNamed:iconName])) { anImage = [NXImage findImageNamed:"NoIcon"]; } return anImage; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.