mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-25 05:20:54 +00:00
Each header file includes only the header files it needs and it uses @class to forward reference a class. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@2189 72102866-910b-0410-8b05-ffd578937521
1617 lines
31 KiB
Objective-C
1617 lines
31 KiB
Objective-C
/*
|
|
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 <Foundation/NSValue.h>
|
|
#include <Foundation/NSArray.h>
|
|
#include <AppKit/NSMatrix.h>
|
|
#include <AppKit/NSActionCell.h>
|
|
#include <AppKit/NSWindow.h>
|
|
#include <AppKit/NSApplication.h>
|
|
|
|
#define GNU_DEFAULT_CELL_HEIGHT 20
|
|
|
|
//
|
|
// Class variables
|
|
//
|
|
static Class NSMATRIX_DEFAULT_CELL_CLASS = nil;
|
|
|
|
@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
|
|
{
|
|
int i;
|
|
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
|
|
{
|
|
if ([selected_cells count])
|
|
return [selected_cells lastObject];
|
|
|
|
return nil;
|
|
}
|
|
|
|
/*
|
|
* 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;
|
|
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;
|
|
|
|
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
|