This is ColumnMatrix.m in view mode; [Download] [Up]
/* Generated by Interface Builder */
#import "ColumnMatrix.h"
@implementation ColumnMatrix
+ newFrame:(const NXRect *)frameRect
{
id newPrototype;
NXSize newIntercell = {0.0, 0.0},
newCellSize;
char **data = calloc(1, sizeof(char *));
float *tab = calloc(1, sizeof(float));
self = [super newFrame:frameRect
mode:NX_LISTMODE
prototype:[IconColumnCell new]
numRows:0 numCols:1];
[protoCell setBordered:TRUE];
[protoCell setAlignment:NX_LEFTALIGNED];
// this whole section is an ugly kluge because the protoCell
// won't return the correct calcCellSize, since it has no
// data. if we give it data, the clones won't work. so we
// create a new prototype cell, and get its size.
newPrototype = [IconColumnCell new];
[newPrototype setBordered:TRUE];
[newPrototype setNumColumns:1];
[newPrototype setTabs:tab];
data[0] = "data";
[newPrototype setData:data];
[newPrototype calcCellSize:&newCellSize];
[newPrototype free];
newCellSize.height--;
newCellSize.width = frameRect->size.width;
[self setCellSize:&newCellSize];
[self setIntercell:&newIntercell];
[self setBackgroundGray:NX_LTGRAY];
[self setAutoscroll:TRUE];
itemsList = [HashList new];
return self;
}
- (BOOL)acceptsFirstResponder
{
return TRUE;
}
- superviewSizeChanged:(const NXSize*)oldSize
{
NXSize newCellSize;
[super superviewSizeChanged:oldSize];
newCellSize.width = bounds.size.width;
newCellSize.height = cellSize.height;
[self setCellSize:&newCellSize];
[self calcTabs];
return self;
}
- calcTabs
{
int i, cellIndex;
for (i=0; i<numColumns; i++) {
realTabs[i] = tabs[i] * bounds.size.width;
}
[protoCell setTabs:(float *)&realTabs];
for (cellIndex=0; cellIndex<numRows; cellIndex++)
[((List *)cellList)->dataPtr[cellIndex] setTabs:(float *)&realTabs];
return self;
}
#ifdef STUPID
- _mouseDown_listMode:(NXEvent *)event;
{
int cellIndex;
Item *item;
id ret;
BOOL kill = FALSE;
firstCheckRow = numRows+1;
lastCheckRow = 0;
ret = [super _mouseDown_listMode:event];
for (cellIndex = lastCheckRow; cellIndex >= firstCheckRow; cellIndex--) {
item = (((IconColumnCell *)
(((List*)cellList)->dataPtr[cellIndex]))->aux);
#ifdef DEBUG
printf("Checking cell %d, visible %d\n", cellIndex, item->shown);
#endif
if (!item->shown) {
kill = TRUE;
[self removeRowAt:cellIndex andFree:TRUE];
}
}
if (kill) {
[self updateCells];
[[self superview] display];
}
return ret;
}
#endif
- _highlightCellAt:(int)row :(int)col lit:(BOOL)lit andDraw:(BOOL)draw
{
Item *item;
#ifdef STUPID
if (!lit) {
item = (((IconColumnCell *)(((List *)cellList)->dataPtr[row]))->aux);
if (![self itemVisible:item]) {
firstCheckRow = MIN(firstCheckRow, row);
lastCheckRow = MAX(lastCheckRow, row);
}
}
#endif
[super _highlightCellAt:row :col lit:lit andDraw:draw];
return [self drawCellAt:row :col];
}
- updateCells
{
int itemIndex, cellIndex, newCellCount = 0,
itemCount = [itemsList count];
int prevItemIndex, row, col, nextRow;
Item *item, *prevItem;
IconColumnCell *aCell;
BOOL wasShown, add = FALSE, kill = FALSE;
if (!numRows) {
// boy, is this ugly, and boy, is it fast.
for (itemIndex=0; itemIndex<itemCount; itemIndex++) {
item = ((List *)itemsList)->dataPtr[itemIndex];
newCellCount += [self itemVisible:item];
}
[self setCellCount:newCellCount];
for (itemIndex=0, cellIndex=0; itemIndex<itemCount; itemIndex++) {
item = ((List *)itemsList)->dataPtr[itemIndex];
if (item->shown) {
item->cell = ((List *)cellList)->dataPtr[cellIndex];
[((List *)cellList)->dataPtr[cellIndex] setAux:item];
cellIndex++;
} else {
item->cell = nil;
}
}
[self sizeToCells];
[self selectCellAt:-1 :-1];
add = (newCellCount > 0);
} else {
for (itemIndex=0; itemIndex<itemCount; itemIndex++) {
item = ((List *)itemsList)->dataPtr[itemIndex];
wasShown = item->shown;
newCellCount += [self itemVisible:item];
if ((wasShown) && (!item->shown)) {
kill = TRUE;
((IconColumnCell *)(item->cell))->aux = nil;
item->cell = nil;
} else if ((!wasShown) && (item->shown)) {
add = TRUE;
item->cell = nil;
}
}
if (kill) {
for (cellIndex=numRows-1; cellIndex >= 0; cellIndex--) {
aCell = [cellList objectAt:cellIndex];
if (!aCell->aux)
[self removeRowAt:cellIndex andFree:TRUE];
}
for (itemIndex=0, cellIndex=0; itemIndex<itemCount; itemIndex++) {
item = ((List *)itemsList)->dataPtr[itemIndex];
if (item->cell && item->shown) {
if (cellIndex >= numRows)
exit(1);
item->cell = ((List *)cellList)->dataPtr[cellIndex];
[((List *)cellList)->dataPtr[cellIndex] setAux:item];
cellIndex++;
}
}
}
if (add) {
for (itemIndex=itemCount-1; itemIndex >= 0; itemIndex--) {
item = ((List *)itemsList)->dataPtr[itemIndex];
if (item->shown && !item->cell) {
nextRow = 0;
for (prevItemIndex=itemIndex-1; (nextRow == 0)&&(prevItemIndex >= 0);
prevItemIndex--) {
if ((prevItem=((List *)itemsList)->dataPtr[prevItemIndex])->cell) {
if ([self getRow:&row andCol:&col ofCell:prevItem->cell]) {
nextRow = row+1;
}
}
}
[self insertRowAt:nextRow];
item->cell = ((List *)cellList)->dataPtr[nextRow];
[((List *)cellList)->dataPtr[nextRow] setAux:item];
}
}
for (itemIndex=0, cellIndex=0; itemIndex<itemCount; itemIndex++) {
item = ((List *)itemsList)->dataPtr[itemIndex];
if (item->shown) {
item->cell = ((List *)cellList)->dataPtr[cellIndex];
[((List *)cellList)->dataPtr[cellIndex] setAux:item];
cellIndex++;
}
}
}
[self sizeToCells];
}
if (add || kill)
return nil;
else
return self;
}
- setCell:aCell fromItem:item
{
[item setCell:aCell];
[aCell setAux:item];
return self;
}
// Hmm, this is just begging to be subclassed, eh?
- (BOOL)itemVisible:item
{
return TRUE;
}
- setCellCount:(int)newCount
{
int i;
// if (newCount > numRows)
[self renewRows:newCount cols:1];
// else
// while (newCount < numRows)
// [self removeRowAt:numRows-1 andFree:TRUE];
return self;
}
- empty
{
[itemsList freeObjects];
[self setCellCount:0];
[self sizeToCells];
[[self superview] display];
[self selectCellAt:-1 :-1];
[self sendAction];
return self;
}
- selectedCell
{
return realSelectedCell;
}
- selectAll:sender
{
int cellIndex;
for (cellIndex = 0; cellIndex < [cellList count]; cellIndex++) {
// [[cellList objectAt:cellIndex] setIntValue:TRUE];
[self highlightCellAt:cellIndex :0 lit:TRUE];
}
selectedRow = [cellList count];
selectedCell = [cellList objectAt:selectedRow];
[self sendAction];
return [[self superview] display];
}
- sendAction:(SEL)theAction to:theTarget
{
int cellIndex;
id ret;
if (refreshTarget) {
refreshTarget = FALSE;
realSelectedCell = nil;
[super sendAction:theAction to:theTarget];
}
firstSelectedRow = -1;
lastSelectedRow = numRows;
for (cellIndex=0; cellIndex<numRows; cellIndex++) {
if ([(id)(((List *)cellList)->dataPtr[cellIndex]) isHighlighted]) {
lastSelectedRow = cellIndex;
if (firstSelectedRow == -1)
firstSelectedRow = cellIndex;
}
}
if ((firstSelectedRow == lastSelectedRow) && (firstSelectedRow >= 0)) {
realSelectedRow = firstSelectedRow;
realSelectedCell = ((List *)cellList)->dataPtr[realSelectedRow];
[self scrollCellToVisible:realSelectedRow :0];
} else {
realSelectedRow = lastSelectedRow = firstSelectedRow = -1;
realSelectedCell = nil;
}
ret = [super sendAction:theAction to:theTarget];
if (![self updateCells]) {
[[self superview] display];
[self sendAction];
}
return ret;
}
- selectUp:sender
{
if ((firstSelectedRow > 0) && (firstSelectedRow <= numRows-1)) {
[self selectCellAt:--firstSelectedRow :0];
[self sendAction];
} else if (firstSelectedRow == 0) {
[self selectWayUp:sender];
} else {
[self selectCellAt:numRows-1 :0];
[self sendAction];
}
return self;
}
- selectDown:sender
{
if ((lastSelectedRow >= 0) && (lastSelectedRow < numRows-1)) {
[self selectCellAt:++lastSelectedRow :0];
[self sendAction];
} else if (lastSelectedRow == numRows-1) {
[self selectWayDown:sender];
} else {
[self selectCellAt:0 :0];
[self sendAction];
}
return self;
}
// Subclass, perchance to use.
- selectWayUp:sender
{
return self;
}
- selectWayDown:sender
{
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.