home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Nebula
/
nebula.bin
/
SourceCode
/
Matrix
/
VarMatrix.m
< prev
Wrap
Text File
|
1992-08-21
|
9KB
|
368 lines
/* A subclass of Matrix that allows variable size columns and rows */
/* Creator : Imran Qureshi */
/* August 3, 1992 */
/* e-mail : cooldude@leland.stanford.edu */
/* Provided as FREEWARE */
#import "VarMatrix.h"
#import <appkit/TextFieldCell.h>
#import <objc/List.h>
#import <stdlib.h>
@implementation VarMatrix
-initFrame:(NXRect *)frameRect mode:(int)aMode prototype:aCell numRows:(int)rowsHigh numCols:(int)colsWide;
{
int i;
column *thisColPtr;
row *thisRowPtr;
[super initFrame:frameRect mode:aMode prototype:aCell
numRows:rowsHigh numCols:colsWide];
columnList = [[List alloc] init];
rowList = [[List alloc] init];
for (i=0; i < colsWide; i++) {
thisColPtr = (column*)calloc(1,sizeof(column));
[columnList addObject:(id)thisColPtr];
thisColPtr->x = i * cellSize.width;
thisColPtr->width = cellSize.width;
}
for (i=0; i < rowsHigh; i++) {
thisRowPtr = (row*)calloc(1,sizeof(row));
[rowList addObject:(id)thisRowPtr];
thisRowPtr->y = i * cellSize.height;
thisRowPtr->height = cellSize.height;
}
{
NXRect rect;
[self getFrame:&rect];
rect.size.width =130.;
NXSetRect(&oldRect,rect.origin.x,rect.origin.y,
rect.size.width, rect.size.height);
[self setFrame:&rect];
}
return self;
}
-erase
{
NXRect rect;
[self lockFocus];
[self getFrame:&rect];
NXEraseRect(&rect);
[self unlockFocus];
return self;
}
-setWidth:(float)width forCol:(int)col
{
float diff;
diff = width - ((column*)[columnList objectAt:col])->width;
((column*)[columnList objectAt:col])->width = width;
[self updateColsFrom:col+1 with:diff];
return self;
}
-setHeight:(float)height forRow:(int)theRow
{
float diff;
diff = height - ((row*)[rowList objectAt:theRow])->height;
((row*)[rowList objectAt:theRow])->height = height;
[self updateRowsFrom:theRow+1 with:diff];
return self;
}
-sizeToCells
{
NXRect rect;
[self getFrame:&rect];
NXSetRect(&oldRect,rect.origin.x,rect.origin.y,
rect.size.width, rect.size.height);
rect.size.width = ((column*)[columnList lastObject])->x +
((column*)[columnList lastObject])->width;
rect.size.height = ((row*)[rowList lastObject])->y +
((row*)[rowList lastObject])->height;
[self setFrame:&rect];
return self;
}
-renewRows:(int)newRows cols:(int)newCols
{
column *rectPtr;
row *rowPtr;
int i;
for (i=numCols; i < newCols; i++) {
rectPtr = (column*)calloc(1,sizeof(column));
[columnList addObject:(id)rectPtr];
rectPtr->x = i * cellSize.width;
rectPtr->width = cellSize.width;
}
for (i=numRows; i < newRows; i++) {
rowPtr = (row*)calloc(1,sizeof(row));
[rowList addObject:(id)rowPtr];
rowPtr->y = i * cellSize.height;
rowPtr->height = cellSize.height;
}
[super renewRows:newRows cols:newCols];
return self;
}
-addCol
{
column *rectPtr;
float place;
rectPtr = (column*)calloc(1,sizeof(column));
place = ((column*)[columnList lastObject])->x +
((column*)[columnList lastObject])->width;
[columnList addObject:(id)rectPtr];
rectPtr->x = place;
rectPtr->width = cellSize.width;
[super addCol];
return self;
}
- insertColAt:(int)col
{
column *rectPtr;
float place,diff;
rectPtr = (column*)calloc(1,sizeof(column));
place = ((column*)[columnList objectAt:col-1])->x +
((column*)[columnList objectAt:col-1])->width;
[columnList insertObject:(id)rectPtr at:col];
rectPtr->x = place;
rectPtr->width = cellSize.width;
diff = cellSize.width;
[self updateColsFrom:col+1 with:diff];
return [super insertColAt:col];
}
- removeColAt:(int)col andFree:(BOOL)flag
{
float diff;
/* is negative 'cause we want to subtract this height from the rest */
diff = -((column*)[columnList objectAt:col])->width;
[columnList removeObjectAt:col];
[self updateColsFrom:col with: diff];
return [super removeColAt:col andFree:flag];
}
-addRow
{
row *rectPtr;
float place;
rectPtr = (row*)calloc(1,sizeof(row));
place = ((row*)[rowList lastObject])->y +
((row*)[rowList lastObject])->height;
[rowList addObject:(id)rectPtr];
rectPtr->y = place;
rectPtr->height = cellSize.height;
return [super addRow];
}
- insertRowAt:(int)theRow
{
row *rectPtr;
float place,diff;
rectPtr = (row*)calloc(1,sizeof(row));
place = ((row*)[rowList objectAt:theRow-1])->y +
((row*)[rowList objectAt:theRow-1])->height;
[rowList insertObject:(id)rectPtr at:theRow];
rectPtr->y = place;
rectPtr->height = cellSize.height;
diff = cellSize.width;
[self updateRowsFrom:theRow+1 with:diff];
return [super insertRowAt:theRow];
}
- removeRowAt:(int)theRow andFree:(BOOL)flag
{
float diff;
/* is negative 'cause we want to subtract this height from the rest */
diff = -((row*)[rowList objectAt:theRow])->height;
[rowList removeObjectAt:theRow];
[self updateRowsFrom:theRow with: diff];
return [super removeRowAt:theRow andFree:flag];
}
-updateRowsFrom:(int)rowNum with:(float)diff
{
int i;
for (i=rowNum; i < [rowList count] ; i++) {
((row*)[rowList objectAt:i])->y += diff;
}
return self;
}
-updateColsFrom:(int)colNum with:(float)diff
{
int i;
for (i=colNum; i < [columnList count] ; i++) {
((column*)[columnList objectAt:i])->x += diff;
}
return self;
}
-update
{
int col,row;
NXRect rect;
//printf("update\n");
if ([self superview] == NULL) return [super update];
[self erase];
for (col = 0; col < [columnList count]; col++) {
for (row = 0; row < [rowList count]; row++) {
[self drawCellAt:row :col];
}
}
[self getFrame:&rect];
NXSetRect(&oldRect,rect.origin.x,rect.origin.y,
rect.size.width, rect.size.height);
return self;
}
-drawCellAt:(int)theRow :(int)col
{
NXRect cellFrame = {0.0,0.0,20.0,20.0};
//printf("drawCellAt: %d :%d\n",theRow,col);
//[super drawCellAt:row :col];
cellFrame.origin.x = ((column*)[columnList objectAt:col])->x;
cellFrame.origin.y = ((row *)[rowList objectAt:theRow])->y;
cellFrame.size.width =((column*)[columnList objectAt:col])->width;
cellFrame.size.height =((row*)[rowList objectAt:theRow])->height;
[self lockFocus];
[[self cellAt:theRow :col] drawSelf:&cellFrame inView:self];
[self unlockFocus];
return self;
}
-drawSelf:(const NXRect *)rects :(int)rectCount
{
NXRect rect;
//printf("drawSelf: %d\n",rectCount);
[self getFrame:&rect];
NXEraseRect(&rect);
[super drawSelf:rects :rectCount];
return self;
}
-getCellFrame:(NXRect *)theRect at:(int)theRow :(int)col
{
//printf("getCellFrame at:%d :%d\n",theRow,col);
//[super getCellFrame:theRect at:row :col];
NXSetRect(theRect,((column*)[columnList objectAt:col])->x,
((row *)[rowList objectAt:theRow])->y,
((column*)[columnList objectAt:col])->width,
((row*)[rowList objectAt:theRow])->height);
return self;
}
-getRow:(int *)theRow andCol:(int*)col forPoint:(const NXPoint *)point
{
int i;
//printf("getRow\n");
*theRow = -1;
*col = -1;
for (i = 0; i < [columnList count]; i++) {
if ((point->x >= (((column*)[columnList objectAt:i])->x)) &&
(point->x <= ((((column*)[columnList objectAt:i])->x) +
((column*)[columnList objectAt:i])->width))) {
*col =i;
}
}
for (i = 0; i < [rowList count]; i++) {
if ((point->y >= (((row*)[rowList objectAt:i])->y)) &&
(point->y <= ((((row*)[rowList objectAt:i])->y) +
((row*)[rowList objectAt:i])->height))) {
*theRow =i;
}
}
return self;
}
-getRow:(int *)row andCol:(int *)col ofCell:aCell
{
//printf("getRow for cell\n");
//[aCell getDrawRect:&rect];
//*row = abs(rect.origin.y/20.0);
//*col = abs(rect.origin.x/20.0);
[super getRow:row andCol:col ofCell:aCell];
return self;
}
- mouseDown:(NXEvent *)theEvent
{
NXPoint mouseDownLocation;
int row, column;
id activeCell;
//printf("mouseDown:\n");
/* find the cell that got clicked on and select it */
mouseDownLocation = theEvent->location;
[self convertPoint:&mouseDownLocation fromView:nil];
[self getRow:&row andCol:&column forPoint:&mouseDownLocation];
activeCell = [self cellAt:row :column];
[self selectCell:activeCell];
//[self getCellFrame:&cellFrame at:row :column];
/* do whatever's required for a single-click */
[self sendAction];
return self;
}
-write:(NXTypedStream*)typedStream
{
[super write:typedStream];
NXWriteObject(typedStream,rowList);
NXWriteObject(typedStream,columnList);
return self;
}
-read:(NXTypedStream*)typedStream
{
[super read:typedStream];
rowList = NXReadObject(typedStream);
columnList = NXReadObject(typedStream);
return self;
}
@end