libs-gui/Source/NSMatrix.m

1618 lines
31 KiB
Mathematica
Raw Normal View History

/*
NSMatrix.m
Matrix class for grouping controls
Copyright (C) 1996 Free Software Foundation, Inc.
Author: Pascal Forget <pascal@wsc.com>
Scott Christley <scottc@net-community.com>
Date: 1996
This file is part of the GNUstep GUI Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; see the file COPYING.LIB.
If not, write to the Free Software Foundation,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <gnustep/gui/NSMatrix.h>
#include <Foundation/NSValue.h>
#include <Foundation/NSArray.h>
#include <gnustep/gui/NSActionCell.h>
#include <gnustep/gui/NSWindow.h>
#include <gnustep/gui/NSApplication.h>
#define GNU_DEFAULT_CELL_HEIGHT 20
//
// Class variables
//
Class NSMATRIX_DEFAULT_CELL_CLASS;
@implementation NSMatrix
+ (void)initialize
{
if (self == [NSMatrix class])
{
NSDebugLog(@"Initialize NSMatrix class\n");
// Set initial version
[self setVersion: 1];
// Set the default cell class
NSMATRIX_DEFAULT_CELL_CLASS = [NSCell class];
}
}
//
// Initializing the NSMatrix Class
//
+ (Class)cellClass
{
return NSMATRIX_DEFAULT_CELL_CLASS;
}
+ (void)setCellClass:(Class)classId
{
NSMATRIX_DEFAULT_CELL_CLASS = classId;
}
//
// Initializing an NSMatrix Object
//
- (void)createInitialMatrix
{
NSSize cs;
int i, j;
id aRow, aFloat;
// Determine cell width and height for uniform cell size
cs.width = (frame.size.width - (inter_cell.width * (num_cols - 1)))
/ num_cols;
cs.height = (frame.size.height - (inter_cell.height * (num_rows - 1)))
/ num_rows;
// Save cell widths and heights in arrays
aFloat = [NSNumber numberWithFloat: cs.height];
for (i = 0;i < num_rows; ++i)
[row_heights addObject:aFloat];
aFloat = [NSNumber numberWithFloat: cs.width];
for (i = 0;i < num_cols; ++i)
[col_widths addObject:aFloat];
for (i = 0;i < num_rows; ++i)
{
aRow = [NSMutableArray arrayWithCapacity: num_cols];
[rows addObject: aRow];
for (j = 0;j < num_cols; ++j)
{
if (cell_prototype != nil)
{
[(NSMutableArray *)aRow addObject:
[cell_prototype copy]];
}
else
{
[(NSMutableArray *)aRow addObject:
[[cell_class alloc] init]];
}
}
}
}
- (id)initWithFrame:(NSRect)frameRect
{
return [self initWithFrame: frameRect
mode: NSTrackModeMatrix
cellClass: NSMATRIX_DEFAULT_CELL_CLASS
numberOfRows: 0
numberOfColumns: 0];
}
- (id)initWithFrame:(NSRect)frameRect
mode:(int)aMode
cellClass:(Class)classId
numberOfRows:(int)rowsHigh
numberOfColumns:(int)colsWide
{
NSDebugLog(@"NSMatrix start -initWithFrame: ..cellClass:\n");
[super initWithFrame:frameRect];
if (rowsHigh < 0)
{
NSLog(@"NSMatrix initWithFrame:mode: rows has to be >= 0.\n");
NSLog(@"Will create matrix with 0 rows.\n");
num_rows = 0;
}
else
{
num_rows = rowsHigh;
}
if (colsWide < 0)
{
NSLog(@"NSMatrix initWithFrame:mode: columns has to be >= 0.\n");
NSLog(@"Will create matrix with 0 columns.\n");
num_cols = 0;
}
else
{
num_cols = colsWide;
}
rows = [[NSMutableArray alloc] init];
row_heights = [[NSMutableArray alloc] init];
col_widths = [[NSMutableArray alloc] init];
selected_cells = [[NSMutableArray alloc] init];
inter_cell.width = inter_cell.height = 2;
allows_empty_selection = YES;
cell_prototype = nil;
cell_class = classId;
mode = aMode;
[self createInitialMatrix];
NSDebugLog(@"NSMatrix end -initWithFrame: ..cellClass:\n");
return self;
}
- (id)initWithFrame:(NSRect)frameRect
mode:(int)aMode
prototype:(NSCell *)aCell
numberOfRows:(int)rowsHigh
numberOfColumns:(int)colsWide
{
[super initWithFrame:frameRect];
if (aCell == nil)
{
NSLog(@"NSMatrix ");
NSLog(@"initWithFrame:mode:prototype:numberOfRows:numberOfColumns: ");
NSLog(@"prototype can't be nil. ");
NSLog(@"Using NSCell as the default class.\n");
cell_prototype = nil;
cell_class = [NSCell class];
}
else
{
cell_prototype = [aCell retain];
}
return self;
}
//
// Setting the Selection Mode
//
- (NSMatrixMode)mode
{
return mode;
}
- (void)setMode:(NSMatrixMode)aMode
{
mode = aMode;
}
//
// Configuring the NSMatrix
//
- (BOOL)allowsEmptySelection
{
return allows_empty_selection;
}
- (BOOL)isSelectionByRect
{
return selection_by_rect;
}
- (void)setAllowsEmptySelection:(BOOL)flag
{
allows_empty_selection = flag;
}
- (void)setSelectionByRect:(BOOL)flag
{
selection_by_rect = flag;
}
//
// Setting the Cell Class
//
- (Class)cellClass
{
return cell_class;
}
- (id)prototype
{
return cell_prototype;
}
- (void)setCellClass:(Class)classId
{
cell_class = classId;
}
- (void)setPrototype:(NSCell *)aCell
{
cell_prototype = [aCell retain];
}
//
// Laying Out the NSMatrix
//
- (void)addColumn
{
int i;
NSNumber *anInt;
NSMutableArray *aRow;
if (num_rows <= 0)
{
[rows addObject:[[NSMutableArray alloc] init]];
num_rows = 1;
[row_heights removeAllObjects];
anInt = [NSNumber numberWithInt: GNU_DEFAULT_CELL_HEIGHT];
[row_heights addObject:anInt];
}
for (i=0; i<num_rows; i++)
{
aRow = (NSMutableArray *)[rows objectAtIndex:i];
if (cell_prototype != nil)
{
[aRow addObject:[cell_prototype copy]];
}
else
{
[aRow addObject:[[cell_class alloc] init]];
}
anInt = [NSNumber numberWithInt:
(frame.size.width / (float)(num_cols+1))];
[col_widths addObject:anInt];
}
num_cols++;
}
- (void)addColumnWithCells:(NSArray *)cellArray
{
NSMutableArray *a;
id e, o;
id re, aRow;
int nrows, new_rows;
NSNumber *aFloat;
NSSize cs;
int i;
NSDebugLog(@"NSMatrix addColumnWithCells:\n");
// No array then forget the add
if (!cellArray)
return;
// Add more rows if need be
nrows = [cellArray count];
if (nrows > num_rows)
{
NSDebugLog(@"NSMatrix add more rows %d %d\n", nrows, num_rows);
new_rows = nrows - num_rows;
for (i = 0; i < new_rows; ++i)
{
a = [[NSMutableArray alloc] init];
[rows addObject: a];
++num_rows;
}
}
++num_cols;
NSDebugLog(@"NSMatrix rows %d cols %d\n", num_rows, num_cols);
// Determine cell width and height for uniform cell size
cs.width = (frame.size.width - (inter_cell.width * (num_cols - 1)))
/ num_cols;
cs.height = (frame.size.height - (inter_cell.height * (num_rows - 1)))
/ num_rows;
// Save cell widths and heights in arrays
aFloat = [NSNumber numberWithFloat: cs.height];
for (i = 0;i < nrows; ++i)
[row_heights addObject:aFloat];
aFloat = [NSNumber numberWithFloat: cs.width];
[col_widths addObject:aFloat];
NSDebugLog(@"NSMatrix cell size %f %f\n", cs.width, cs.height);
e = [cellArray objectEnumerator];
o = [e nextObject];
re = [rows objectEnumerator];
aRow = [re nextObject];
while (o)
{
[aRow addObject: o];
[o retain];
o = [e nextObject];
aRow = [re nextObject];
}
}
- (void)addRow
{
int i;
NSNumber *anInt;
NSMutableArray *newRow = [[NSMutableArray alloc] init];
if (cell_prototype != nil)
{
[newRow addObject:[cell_prototype copy]];
}
else
{
[newRow addObject:[[cell_class alloc] init]];
}
if (num_cols > 0)
{
for (i=1; i<num_cols; i++)
{
if (cell_prototype != nil)
{
[newRow addObject:[cell_prototype copy]];
}
else
{
[newRow addObject:[[cell_class alloc] init]];
}
}
anInt = [NSNumber numberWithInt: GNU_DEFAULT_CELL_HEIGHT];
[row_heights addObject:anInt];
[rows addObject:newRow];
num_rows++;
}
else
{
[self addColumn];
}
}
- (void)addRowWithCells:(NSArray *)cellArray
{
NSMutableArray *a;
id e, o;
float ncols;
NSNumber *aFloat;
NSSize cs;
int i;
NSDebugLog(@"NSMatrix addRowWithCells:\n");
// No array then forget the add
if (!cellArray)
return;
a = [[NSMutableArray alloc] init];
[rows addObject: a];
++num_rows;
ncols = [cellArray count];
// Determine cell width and height for uniform cell size
cs.width = (frame.size.width - (inter_cell.width * (ncols - 1)))
/ ncols;
cs.height = (frame.size.height - (inter_cell.height * (num_rows - 1)))
/ num_rows;
// Save cell widths and heights in arrays
aFloat = [NSNumber numberWithFloat: cs.height];
[row_heights addObject:aFloat];
aFloat = [NSNumber numberWithFloat: cs.width];
for (i = 0;i < ncols; ++i)
[col_widths addObject:aFloat];
e = [cellArray objectEnumerator];
o = [e nextObject];
while (o)
{
[a addObject: o];
[o retain];
o = [e nextObject];
}
}
- (void)addRowWithCells:(NSArray *)cellArray
rowSizes:(NSArray *)rowSizes
columnSizes:(NSArray *)columnSizes
{
NSMutableArray *a;
id e, o;
float ncols;
NSNumber *aFloat;
NSSize cs;
int i;
NSDebugLog(@"NSMatrix addRowWithCells:\n");
// No array then forget the insert
if (!cellArray)
return;
a = [[NSMutableArray alloc] init];
[rows addObject: a];
++num_rows;
ncols = [cellArray count];
// Determine cell width and height for uniform cell size
cs.width = (frame.size.width - (inter_cell.width * (ncols - 1)))
/ ncols;
cs.height = (frame.size.height - (inter_cell.height * (num_rows - 1)))
/ num_rows;
// Save cell widths and heights in arrays
aFloat = [NSNumber numberWithFloat: cs.height];
[row_heights addObject:aFloat];
aFloat = [NSNumber numberWithFloat: cs.width];
for (i = 0;i < ncols; ++i)
[col_widths addObject:aFloat];
e = [cellArray objectEnumerator];
o = [e nextObject];
while (o)
{
[a addObject: o];
[o retain];
o = [e nextObject];
}
}
- (NSRect)cellFrameAtRow:(int)row
column:(int)column
{
NSRect r;
int i;
/* Initialize the size to all zeroes */
r.origin.x = 0;
r.origin.y = 0;
r.size.width = 0;
r.size.height = 0;
#if 0
/* Validate arguments */
if ((row >= num_rows) || (row < 0))
{
return r;
}
if ((column >= num_cols) || (column < 0))
{
return r;
}
#endif
/* Compute the x origin */
for (i=0; i<column; i++)
{
r.origin.x += [(NSNumber *)[col_widths objectAtIndex:i] floatValue];
r.origin.x += inter_cell.width;
}
/* Get the column width */
r.size.width = [(NSNumber *)[col_widths objectAtIndex:i] floatValue];
/* Compute the y origin */
r.origin.y = frame.size.height;
r.origin.y -= [(NSNumber *)[row_heights objectAtIndex:0] floatValue];
for (i = 1;i < (row+1); i++)
{
r.origin.y -= inter_cell.height;
r.origin.y -= [(NSNumber *)[row_heights objectAtIndex:i] floatValue];
}
/* Get the height */
r.size.height = [(NSNumber *)[row_heights objectAtIndex:row] floatValue];
NSDebugLog(@"NSMatrix cellFrameAtRow: %d column:%d is: %f %f %f %f\n",
row, column,
r.origin.x, r.origin.y, r.size.width, r.size.height);
return r;
}
- (NSSize)cellSize
{
/*****************************************
* This method is for the OpenStep mode, *
* where all rows have the same size. *
*****************************************/
NSSize s = {0, 0};
if ((num_cols < 1) || (num_rows < 1))
{
return s;
}
s.width = [[col_widths objectAtIndex:0] floatValue];
s.height= [[row_heights objectAtIndex:0] floatValue];
return s;
}
- (void)getNumberOfRows:(int *)rowCount
columns:(int *)columnCount
{
*rowCount = num_rows;
*columnCount = num_cols;
}
- (void)insertColumn:(int)column
{
NSMutableArray *currentRow;
id newCell;
int i, j;
i = column - num_cols;
while (i--)
{
[self addColumn];
}
if (num_cols > 1)
{
for (i=0; i<num_rows; i++)
{
currentRow = [rows objectAtIndex:i];
newCell = [currentRow lastObject];
for (j=num_cols-1; j>column; j--)
{
[currentRow replaceObjectAtIndex:j withObject:
[currentRow objectAtIndex:i-1]];
}
[currentRow replaceObjectAtIndex:column withObject:newCell];
}
}
}
- (void)insertColumn:(int)column withCells:(NSArray *)cellArray
{
NSCell *newCell;
int i, count;
[self insertColumn:column];
if (cellArray != nil)
{
count = [cellArray count];
}
else
{
count = 0;
}
for (i=0; i<num_rows; i++)
{
if (i < count)
{
newCell = (NSCell *)[cellArray objectAtIndex:i];
[self putCell:newCell atRow:i column:column];
}
else
{
break;
}
}
}
- (void)insertRow:(int)row
{
NSMutableArray *aRow;
int i;
i = row - num_rows;
while (i--)
{
[self addRow];
}
if (num_rows > 1)
{
aRow = [rows lastObject];
for (i=num_rows-1; i> row; i--)
{
[rows replaceObjectAtIndex:i withObject:[rows objectAtIndex:i-1]];
}
[rows replaceObjectAtIndex:row withObject:aRow];
}
}
- (void)insertRow:(int)row withCells:(NSArray *)cellArray
{
NSCell *newCell;
int i, count;
id e, o;
// No array then forget the insert
if (!cellArray)
return;
[self insertRow:row];
e = [cellArray objectEnumerator];
o = [e nextObject];
i = 0;
while (o)
{
[self putCell: o atRow: row column: i];
o = [e nextObject];
++i;
}
}
- (NSSize)intercellSpacing
{
return inter_cell;
}
- (NSCell *)makeCellAtRow:(int)row
column:(int)column
{
id newCell;
if ((row < num_rows)
&& (row > -1)
&& (column < num_cols)
&& (column > -1))
{
newCell = [[cell_class alloc] init];
[[rows objectAtIndex:row] replaceObjectAtIndex:column
withObject:newCell];
return newCell;
}
else
{
return nil;
}
}
- (void)putCell:(NSCell *)newCell
atRow:(int)row
column:(int)column
{
NSMutableArray *aRow;
if ((row > -1)
&& (row < num_rows)
&& (column > -1)
&& (column < num_cols))
{
aRow = (NSMutableArray *)[rows objectAtIndex:row];
[aRow replaceObjectAtIndex:column withObject:newCell];
}
}
- (void)removeColumn:(int)column
{
int i;
NSMutableArray *aRow;
if ((column > -1) && (column < num_cols))
{
for (i=0; i<num_rows; i++)
{
aRow = (NSMutableArray *)[rows objectAtIndex:i];
[aRow removeObjectAtIndex:column];
}
[col_widths removeObjectAtIndex:column];
num_cols--;
}
}
- (void)removeRow:(int)row
{
if ((row > -1) && (row < num_rows))
{
[rows removeObjectAtIndex:row];
[row_heights removeObjectAtIndex:row];
num_rows--;
}
}
- empty
{
[rows removeAllObjects];
[selected_cells removeAllObjects];
num_rows = 0;
num_cols = 0;
return self;
}
- (void)renewRows:(int)newRows
columns:(int)newColumns
{}
- (void)setCellSize:(NSSize)aSize
{
NSNumber *aFloat;
id old;
int i;
for (i=0; i<num_cols; i++)
{
aFloat = [NSNumber numberWithFloat: aSize.width];
old = [col_widths objectAtIndex:i];
[col_widths replaceObjectAtIndex:i withObject: aFloat];
[old release];
}
for (i=0; i<num_rows; i++)
{
aFloat = [NSNumber numberWithFloat: aSize.height];
old = [row_heights objectAtIndex:i];
[row_heights replaceObjectAtIndex:i withObject: aFloat];
[old release];
}
}
- (void)setColumnWidth:(int)width at:(int)column;
{
NSNumber *aFloat;
id old;
if ((column > -1) && (column < num_cols))
{
aFloat = [NSNumber numberWithFloat: width];
old = [col_widths objectAtIndex:column];
[col_widths replaceObjectAtIndex:column withObject: aFloat];
[old release];
}
}
- (void)setIntercellSpacing:(NSSize)aSize
{
inter_cell = aSize;
}
- (void)sortUsingFunction:(int (*)(id element1, id element2,
void *userData))comparator
context:(void *)context
{}
- (void)sortUsingSelector:(SEL)comparator
{}
- (int)numCols;
{
return num_cols;
}
- (int)numRows;
{
return num_rows;
}
//
// Finding Matrix Coordinates
//
/*
* The next function returns NO if the point is located inside
* the matrix but also in an intercell gap, which may or may
* not be the behavior God intended...
*/
- (BOOL)getRow:(int *)row
column:(int *)column
forPoint:(NSPoint)aPoint
{
NSRect myFrame = [self bounds];
NSRect cFrame;
id re, ce;
id aRow, aCol;
int i, j;
/* Trivial rejection if the point is not in the Matrix's frame rect */
if (![self mouse: aPoint inRect: myFrame])
{
NSDebugLog(@"NSMatrix point %f %f not in rect %f %f %f %f\n",
aPoint.x, aPoint.y, myFrame.origin.x, myFrame.origin.y,
myFrame.size.width, myFrame.size.height);
return NO;
}
/* Here an optimized algo could be used at the expense of clarity */
re = [rows objectEnumerator];
aRow = [re nextObject];
i = 0;
while (aRow)
{
ce = [aRow objectEnumerator];
aCol = [ce nextObject];
j = 0;
while (aCol)
{
cFrame = [self cellFrameAtRow:i column:j];
if ([self mouse: aPoint inRect: cFrame])
{
*row = i;
*column = j;
return YES;
}
aCol = [ce nextObject];
++j;
}
aRow = [re nextObject];
++i;
}
return NO;
}
- (BOOL)getRow:(int *)row
column:(int *)column
ofCell:(NSCell *)aCell
{
id re, ce;
id aRow, aCol;
int i, j;
re = [rows objectEnumerator];
aRow = [re nextObject];
i = 0;
while (aRow)
{
ce = [aRow objectEnumerator];
aCol = [ce nextObject];
j = 0;
while (aCol)
{
if ((NSCell *)[self cellAtRow:i column:j] == aCell)
{
*row = i;
*column = j;
return YES;
}
aCol = [ce nextObject];
++j;
}
aRow = [re nextObject];
++i;
}
return NO;
}
//
// Modifying Individual Cells
//
- (void)setState:(int)value
atRow:(int)row
column:(int)column
{
NSMutableArray *aRow;
NSCell *aCell;
if ((row > -1)
&& (row < num_rows)
&& (column > -1)
&& (column < num_cols))
{
aRow = (NSMutableArray *)[rows objectAtIndex:row];
aCell = (NSCell *)[aRow objectAtIndex:column];
[aCell setState:value];
}
}
//
// Selecting Cells
//
- (void)deselectAllCells
{
if (allows_empty_selection)
[selected_cells removeAllObjects];
}
- (void)deselectSelectedCell
{
int cnt = [selected_cells count];
// Is anything even selected?
if (cnt > 0)
// Only empty array if empty selection is allowed
if ((cnt != 1) || (allows_empty_selection))
[selected_cells removeLastObject];
}
- (void)selectAll:(id)sender
{
[selected_cells removeAllObjects];
[selected_cells addObjectsFromArray:[self cells]];
}
- (void)selectCellAtRow:(int)row
column:(int)column
{
int index;
id aCell = [self cellAtRow:row column:column];
NSDebugLog(@"NSMatrix select cell at %d %d\n", row, column);
if (aCell != nil)
{
// Add to selected cell list if not already
index = [selected_cells indexOfObject:aCell];
if ((index < 0) || (index > [selected_cells count]))
{
[selected_cells addObject:aCell];
}
}
}
- (BOOL)selectCellWithTag:(int)anInt
{
id aCell = [self cellWithTag:anInt];
int index;
if (cell != nil)
{
index = [selected_cells indexOfObject:aCell];
if ((index < 0) || (index > [selected_cells count]))
{
[selected_cells addObject:aCell];
}
return YES;
} else {
return NO;
}
}
- (id)selectedCell
{
return [selected_cells lastObject];
}
/*
* returns an array of the selected cells
*/
- (NSArray *)selectedCells
{
return selected_cells;
}
- (int)selectedColumn
{
int row, col;
id aCell;
if ([selected_cells count])
{
aCell = [selected_cells lastObject];
if ([self getRow: &row column: &col ofCell: aCell])
return col;
}
// Not found
return -1;
}
- (int)selectedRow
{
int row, col;
id aCell;
if ([selected_cells count])
{
aCell = [selected_cells lastObject];
if ([self getRow: &row column: &col ofCell: aCell])
return row;
}
// Not found
return -1;
}
- (void)setSelectionFrom:(int)startPos
to:(int)endPos
anchor:(int)anchorPos
highlight:(BOOL)flag
{}
//
// Finding Cells
//
- (id)cellAtRow:(int)row
column:(int)column
{
id aRow;
if ((row >= num_rows) || (row < 0))
{
NSLog(@"NSMatrix cellAt:: invalid row (%d)\n", row);
return nil;
}
aRow = [rows objectAtIndex: row];
if ((column >= [aRow count]) || (column < 0))
{
NSLog(@"NSMatrix cellAt:: invalid column (%d)\n", column);
return nil;
}
return [(NSArray *)aRow objectAtIndex:column];
}
- (id)cellWithTag:(int)anInt
{
id re, ce;
int i, j;
NSMutableArray *aRow;
NSCell *aCell;
// Loop through the rows and columns and find the cell
re = [rows objectEnumerator];
aRow = [re nextObject];
while (aRow)
{
ce = [aRow objectEnumerator];
aCell = (NSCell *)[ce nextObject];
while (aCell)
{
if ([aCell tag] == anInt)
return aCell;
aCell = (NSCell *)[ce nextObject];
}
}
return nil;
}
- (NSArray *)cells
{
NSMutableArray *cells;
int i;
if ((num_cols < 1) || (num_rows < 1))
{
return nil;
}
else
{
cells = [[NSMutableArray alloc]
initWithCapacity:(num_rows * num_cols)];
for (i=0; i<num_rows; i++)
{
[cells addObjectsFromArray:(NSArray *)[rows objectAtIndex:i]];
}
return cells;
}
}
//
// Modifying Graphic Attributes
//
- (NSColor *)backgroundColor
{
return nil;
}
- (NSColor *)cellBackgroundColor
{
return nil;
}
- (BOOL)drawsBackground
{
return draws_background;
}
- (BOOL)drawsCellBackground
{
return draws_cell_background;
}
- (void)setBackgroundColor:(NSColor *)aColor
{}
- (void)setCellBackgroundColor:(NSColor *)aColor
{}
- (void)setDrawsBackground:(BOOL)flag
{
draws_background = flag;
}
- (void)setDrawsCellBackground:(BOOL)flag
{
draws_cell_background = flag;
}
//
// Editing Text in Cells
//
- (void)selectText:(id)sender
{}
- (id)selectTextAtRow:(int)row
column:(int)column
{
return nil;
}
- (void)textDidBeginEditing:(NSNotification *)notification
{}
- (void)textDidChange:(NSNotification *)notification
{}
- (void)textDidEndEditing:(NSNotification *)notification
{}
- (BOOL)textShouldBeginEditing:(NSText *)textObject
{
return NO;
}
- (BOOL)textShouldEndEditing:(NSText *)textObject
{
return NO;
}
//
// Setting Tab Key Behavior
//
- (id)nextText
{
return nil;
}
- (id)previousText
{
return nil;
}
- (void)setNextText:(id)anObject
{}
- (void)setPreviousText:(id)anObject
{}
//
// Assigning a Delegate
//
- (void)setDelegate:(id)anObject
{}
- (id)delegate
{
return nil;
}
//
// Resizing the Matrix and Cells
//
- (BOOL)autosizesCells
{
return autosize;
}
- (void)setAutosizesCells:(BOOL)flag
{
autosize = flag;
}
- (void)setValidateSize:(BOOL)flag
{}
- (void)sizeToCells
{
NSSize newSize;
NSNumber *value;
int row, col;
newSize.width = 0;
newSize.height = 0;
NSDebugLog(@"NSMatrix intercell height: %4.0f\n", inter_cell.height);
for (row=0; row<num_rows; row++)
{
value = [row_heights objectAtIndex:row];
newSize.height += [value intValue];
if ((row > 0) && (row < (num_rows-1) ))
{
newSize.height += inter_cell.height;
}
}
for (col=0; col<num_cols; col++)
{
value = [col_widths objectAtIndex:col];
newSize.width += [value intValue];
if ((col > 0) && (col < (num_cols-1) ))
{
newSize.width += inter_cell.width;
}
}
#if 1
NSDebugLog(@"NSMatrix size: %4.0f %4.0f\n",newSize.width,newSize.height);
#endif
[(NSView *)self setFrameSize:newSize];
}
- (void)resizeWithOldSuperviewSize:(NSSize)oldSize
{
NSDebugLog(@"NSMatrix resize %f %f old %f %f\n", bounds.size.width,
bounds.size.height, oldSize.width, oldSize.height);
}
//
// Scrolling
//
- (BOOL)isAutoscroll
{
return autoscroll;
}
- (void)scrollCellToVisibleAtRow:(int)row
column:(int)column
{}
- (void)setAutoscroll:(BOOL)flag
{
autoscroll = flag;
}
- (void)setScrollable:(BOOL)flag
{
scrollable = flag;
}
//
// Displaying
//
- (void)display;
{
id re, ce;
int row, col;
NSMutableArray *aRow;
id aCol;
NSDebugLog(@"NSMatrix display %f %f %f %f\n", bounds.origin.x,
bounds.origin.y, bounds.size.width, bounds.size.height);
re = [rows objectEnumerator];
aRow = (NSMutableArray *)[re nextObject];
row = 0;
while (aRow)
{
ce = [aRow objectEnumerator];
aCol = [ce nextObject];
col = 0;
while (aCol)
{
[self drawCellAtRow: row column: col];
++col;
aCol = [ce nextObject];
}
++row;
aRow = [re nextObject];
}
NSDebugLog(@"End NSMatrix display\n");
}
- (void)drawCellAtRow:(int)row
column:(int)column
{
NSMutableArray *aRow = [rows objectAtIndex: row];
NSCell *aCell = [aRow objectAtIndex: column];
NSDebugLog(@"NSMatrix draw cell %d %d %d %d\n", row, column, [rows count],
[aRow count]);
[aCell drawWithFrame:
[self cellFrameAtRow:row column:column]
inView:self];
}
- (void)highlightCell:(BOOL)flag
atRow:(int)row
column:(int)column
{
NSCell *aCell = [self cellAtRow:row column:column];
NSRect cellFrame;
BOOL did_lock = NO;
if (aCell != nil)
{
cellFrame = [self cellFrameAtRow:row column:column];
[aCell highlight:flag withFrame:cellFrame inView:self];
}
}
//
// Target and Action
//
- (SEL)doubleAction
{
return double_action;
}
- (void)setDoubleAction:(SEL)aSelector
{
double_action = aSelector;
}
- (SEL)errorAction
{
return error_action;
}
- (BOOL)sendAction
{
NSCell *aCell = [self selectedCell];
NSDebugLog(@"NSMatrix -sendAction\n");
if (!aCell) return NO;
if ([aCell isKindOfClass:[NSActionCell class]])
{
NSDebugLog(@"NSMatrix sending action\n");
[self sendAction: [aCell action] to: [aCell target]];
return YES;
}
NSDebugLog(@"NSMatrix no action\n");
return NO;
}
- (void)sendAction:(SEL)aSelector
to:(id)anObject
forAllCells:(BOOL)flag
{
BOOL (*test)(id, SEL, id);
id row, columns, col;
id aCell;
BOOL result;
// If the object doesn't respond to selector then quit
if (![anObject respondsToSelector: aSelector])
return;
// Obtain function pointer to selector
test = (BOOL (*)(id, SEL, id))[anObject methodForSelector: aSelector];
// Enumerate through all the cells
row = [rows objectEnumerator];
columns = [row nextObject];
while (columns)
{
col = [columns objectEnumerator];
aCell = [col nextObject];
while (aCell)
{
// Call the method
result = test(anObject, aSelector, aCell);
// If the result is NO
// and we shouldn't continue for all cells
// then quit
if ((!result) && (!flag))
return;
aCell = [col nextObject];
}
columns = [row nextObject];
}
}
- (void)sendDoubleAction
{
NSCell *aCell = [self selectedCell];
NSDebugLog(@"NSMatrix -sendDoubleAction\n");
if (!aCell) return;
if (double_action)
{
NSDebugLog(@"NSMatrix sending double action\n");
[self sendAction: double_action to: [aCell target]];
}
else
NSDebugLog(@"NSMatrix no double action\n");
}
- (void)setErrorAction:(SEL)aSelector
{
error_action = aSelector;
}
//
// Handling Event and Action Messages
//
- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
{
if (mode == NSListModeMatrix)
{
return NO;
}
return YES;
}
- (void)highlightTrackingMode:(NSEvent *)theEvent
{
NSPoint location;
NSPoint point;
NSCell *aCell;
int aRow, aCol;
NSRect cellFrame;
NSApplication *theApp = [NSApplication sharedApplication];
BOOL mouseUp, done;
NSEvent *e;
unsigned int event_mask = NSLeftMouseDownMask | NSLeftMouseUpMask
| NSMouseMovedMask;
// Capture mouse
[[self window] captureMouse: self];
mouseUp = NO;
done = NO;
e = theEvent;
while (!done)
{
location = [e locationInWindow];
point = [self convertPoint: location fromView: nil];
// Find out what cell was clicked on
if ([self getRow:&aRow column:&aCol forPoint:point])
{
NSDebugLog(@"NSMatrix found row/column from point\n");
aCell = [self cellAtRow:aRow column:aCol];
if (!aCell)
{
// Yikes problem here
NSLog(@"NSMatrix no cell at %d %d\n", aRow, aCol);
mouseUp = NO;
done = YES;
continue;
}
NSDebugLog(@"NSMatrix found cell\n");
cellFrame = [self cellFrameAtRow: aRow column: aCol];
mouseUp = [aCell trackMouse: e inRect: cellFrame
ofView:self untilMouseUp:YES];
e = [theApp currentEvent];
}
// If mouse went up then we are done
if ((mouseUp) || ([e type] == NSLeftMouseUp))
done = YES;
else
{
NSDebugLog(@"NSMatrix process another event\n");
e = [theApp nextEventMatchingMask:event_mask untilDate:nil
inMode:nil dequeue:YES];
}
}
// Release mouse
[[self window] releaseMouse: self];
// If the mouse went up in the button
if (mouseUp)
{
NSDebugLog(@"NSMatrix the mouse went up in a button\n");
// Unhighlight the cell
[aCell highlight: NO withFrame: cellFrame
inView: self];
// Select the cell
[self selectCellAtRow: aRow column: aCol];
NSDebugLog(@"NSMatrix send action\n");
// Send action
if ([theEvent clickCount] == 1)
[self sendAction];
else
[self sendDoubleAction];
}
}
- (void)mouseDown:(NSEvent *)theEvent
{
NSView *view = [[self window] contentView];
NSPoint location = [theEvent locationInWindow];
NSPoint point = [super_view convertPoint:location fromView:view];
NSDebugLog(@"NSMatrix mouseDown at point %f %f\n", point.x, point.y);
// What mode are we in?
switch(mode)
{
case NSTrackModeMatrix:
break;
case NSHighlightModeMatrix:
NSDebugLog(@"NSMatrix NSHighlightModeMatrix\n");
[self highlightTrackingMode: theEvent];
break;
case NSRadioModeMatrix:
break;
case NSListModeMatrix:
break;
}
}
- (int)mouseDownFlags
{
return 0;
}
- (BOOL)performKeyEquivalent:(NSEvent *)theEvent
{
return NO;
}
//
// Managing the Cursor
//
- (void)resetCursorRects
{}
//
// NSCoding protocol
//
- (void)encodeWithCoder:aCoder
{
[super encodeWithCoder:aCoder];
}
- initWithCoder:aDecoder
{
[super initWithCoder:aDecoder];
return self;
}
@end