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.