libs-gui/Source/GSTable.m
Nicola Pero 2858daf87c First public version.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@5265 72102866-910b-0410-8b05-ffd578937521
1999-11-23 23:35:02 +00:00

1021 lines
26 KiB
Objective-C

/*
GSTable.m
The GSTable class (a GNU extension)
Copyright (C) 1999 Free Software Foundation, Inc.
Author: Nicola Pero <n.pero@mi.flashnet.it>
Date: 1999
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 <AppKit/GSTable.h>
// This is meant to make drawing invisible views a little faster
@interface GSTransparentView : NSView
@end
@implementation GSTransparentView
-(void) lockFocusInRect: (NSRect)rect
{
}
-(void) unlockFocusNeedsFlush: (BOOL)flush
{
}
@end
@interface GSTable (Private)
-(void) _updateRowSize: (int)row;
-(void) _updateColumnSize: (int)column;
-(void) _updateRowOrigin: (int)row;
-(void) _updateColumnOrigin: (int)column;
-(void) _updateWholeTable;
@end
@implementation GSTable: NSView
{
}
//
// Class Methods
//
+(void) initialize
{
if (self == [GSTable class])
[self setVersion: 1];
}
//
// Instance Methods
//
// Designated initializer
-(id) initWithNumberOfRows: (int)rows
numberOfColumns: (int)columns
{
int i;
[super init];
[super setAutoresizesSubviews: NO];
if (!(rows > 0))
{
NSLog (@"Warning: Argument rows <= 0");
rows = 2;
}
if (!(columns > 0))
{
NSLog (@"Warning: Argument columns <= 0");
columns = 2;
}
_numberOfRows = rows;
_numberOfColumns = columns;
_minXBorder = 0;
_maxXBorder = 0;
_minYBorder = 0;
_maxYBorder = 0;
_jails = NSZoneMalloc (NSDefaultMallocZone (),
sizeof (GSTransparentView *) * (rows * columns));
_expandRow = NSZoneMalloc (NSDefaultMallocZone (),
sizeof (BOOL) * rows);
_expandColumn = NSZoneMalloc (NSDefaultMallocZone (),
sizeof (BOOL) * columns);
_columnDimension = NSZoneMalloc (NSDefaultMallocZone (),
sizeof (float) * columns);
_rowDimension = NSZoneMalloc (NSDefaultMallocZone (),
sizeof (float) * rows);
_columnXOrigin = NSZoneMalloc (NSDefaultMallocZone (),
sizeof (float) * columns);
_rowYOrigin = NSZoneMalloc (NSDefaultMallocZone (),
sizeof (float) * rows);
_minColumnDimension = NSZoneMalloc (NSDefaultMallocZone (),
sizeof (float) * columns);
_minRowDimension = NSZoneMalloc (NSDefaultMallocZone (),
sizeof (float) * rows);
_havePrisoner = NSZoneMalloc (NSDefaultMallocZone (),
sizeof (BOOL) * (rows * columns));
for (i = 0; i < (rows * columns); i++)
{
_jails[i] = NULL;
_havePrisoner[i] = NO;
}
for (i = 0; i < rows; i++)
{
_expandRow[i] = YES;
_rowDimension[i] = 0;
_rowYOrigin[i] = 0;
_minRowDimension[i] = 0;
}
_expandingRowNumber = rows;
for (i = 0; i < columns; i++)
{
_expandColumn[i] = YES;
_columnDimension[i] = 0;
_columnXOrigin[i] = 0;
_minColumnDimension[i] = 0;
}
_expandingColumnNumber = columns;
_minimumSize = NSZeroSize;
return self;
}
-(id) init
{
return [self initWithNumberOfRows: 2
numberOfColumns: 2];
}
-(void) dealloc
{
NSZoneFree (NSDefaultMallocZone (), _jails);
NSZoneFree (NSDefaultMallocZone (), _expandColumn);
NSZoneFree (NSDefaultMallocZone (), _expandRow);
NSZoneFree (NSDefaultMallocZone (), _columnDimension);
NSZoneFree (NSDefaultMallocZone (), _rowDimension);
NSZoneFree (NSDefaultMallocZone (), _columnXOrigin);
NSZoneFree (NSDefaultMallocZone (), _rowYOrigin);
NSZoneFree (NSDefaultMallocZone (), _minColumnDimension);
NSZoneFree (NSDefaultMallocZone (), _minRowDimension);
NSZoneFree (NSDefaultMallocZone (), _havePrisoner);
[super dealloc];
}
- (void) setAutoresizesSubviews: (BOOL)flag
{
NSLog (@"Warning: attempt to setAutoresizesSubviews for a GSTable!\n");
return;
}
//
// Setting Border.
//
-(void) setBorder: (float)aBorder
{
[self setMinXBorder: aBorder];
[self setMaxXBorder: aBorder];
[self setMinYBorder: aBorder];
[self setMaxYBorder: aBorder];
}
-(void) setXBorder: (float)aBorder
{
[self setMinXBorder: aBorder];
[self setMaxXBorder: aBorder];
}
-(void) setYBorder: (float)aBorder
{
[self setMinYBorder: aBorder];
[self setMaxYBorder: aBorder];
}
-(void) setMinXBorder: (float)aBorder
{
float borderChange;
NSSize tableSize = [self frame].size;
int i;
if (aBorder < 0)
aBorder = 0;
borderChange = aBorder - _minXBorder;
for(i = 0; i < _numberOfColumns; i++)
{
_columnXOrigin[i] += borderChange;
[self _updateColumnOrigin: i];
}
_minimumSize.width += borderChange;
tableSize.width += borderChange;
[self setFrameSize: tableSize];
_minXBorder = aBorder;
}
-(void) setMaxXBorder: (float)aBorder
{
float borderChange;
NSSize tableSize = [self frame].size;
if (aBorder < 0)
aBorder = 0;
borderChange = aBorder - _maxXBorder;
_minimumSize.width += borderChange;
tableSize.width += borderChange;
[self setFrameSize: tableSize];
_maxXBorder = aBorder;
}
-(void) setMinYBorder: (float)aBorder
{
float borderChange;
NSSize tableSize = [self frame].size;
int i;
if (aBorder < 0)
aBorder = 0;
borderChange = aBorder - _minYBorder;
for(i = 0; i < _numberOfRows; i++)
{
_rowYOrigin[i] += borderChange;
[self _updateRowOrigin: i];
}
_minimumSize.height += borderChange;
tableSize.height += borderChange;
[self setFrameSize: tableSize];
_minYBorder = aBorder;
}
-(void) setMaxYBorder: (float)aBorder
{
float borderChange;
NSSize tableSize = [self frame].size;
if (aBorder < 0)
aBorder = 0;
borderChange = aBorder - _maxYBorder;
_minimumSize.height += borderChange;
tableSize.height += borderChange;
[self setFrameSize: tableSize];
_maxYBorder = aBorder;
}
//
// Adding Views
//
-(void) putView: (NSView *)aView
atRow: (int)row
column: (int)column
{
[self putView: aView
atRow: row
column: column
withMinXMargin: 0
maxXMargin: 0
minYMargin: 0
maxYMargin: 0];
}
-(void) putView: (NSView *)aView
atRow: (int)row
column: (int)column
withMargins: (float)margins
{
[self putView: aView
atRow: row
column: column
withMinXMargin: margins
maxXMargin: margins
minYMargin: margins
maxYMargin: margins];
}
-(void) putView: (NSView *)aView
atRow: (int)row
column: (int)column
withXMargins: (float)xMargins
yMargins: (float)yMargins
{
[self putView: aView
atRow: row
column: column
withMinXMargin: xMargins
maxXMargin: xMargins
minYMargin: yMargins
maxYMargin: yMargins];
}
// The other methods are only wrappers for this one.
-(void) putView: (NSView *)aView
atRow: (int)row
column: (int)column
withMinXMargin: (float)minXMargin
maxXMargin: (float)maxXMargin
minYMargin: (float)minYMargin
maxYMargin: (float)maxYMargin;
{
int jailNumber;
NSRect oldFrame;
NSRect theFrame;
NSRect tableFrame = [self frame];
int i;
// YES if the GSTable needs to be resized
BOOL tableNeedResize = NO;
// YES if the {prisoner + margins} needs to be resized to fill the jail.
// This is accomplished by creating the jail with the old size (of
// {prisoner + margins}), putting the prisoner inside and the resizing
// the jail to the new size.
BOOL prisonerNeedResize = NO;
if (row > (_numberOfRows - 1))
{
NSLog (@"Warning: argument row is > (numberOfRows - 1)\n");
return;
}
if (row < 0)
{
NSLog (@"Warning: argument row is < 0\n");
return;
}
if (column > (_numberOfColumns - 1))
{
NSLog (@"Warning: argument column is > (numberOfColumns - 1)\n");
return;
}
if (column < 0)
{
NSLog (@"Warning: argument column is < 0\n");
return;
}
oldFrame = [aView frame];
oldFrame.size.width += (minXMargin + maxXMargin);
oldFrame.size.height += (minYMargin + maxYMargin);
theFrame = oldFrame;
jailNumber = row * (_numberOfColumns) + column;
//
//
// Manage Column/Row and aView Sizes
//
//
//
// Column
//
if (theFrame.size.width > _columnDimension[column])
{
float xShift = theFrame.size.width - _columnDimension[column];
// Compute new size tableFrame.size
tableFrame.size.width += xShift;
tableNeedResize = YES;
// Resize the column
_columnDimension[column] = theFrame.size.width;
[self _updateColumnSize: column];
// Shift the columns on the right
for (i = column + 1; i < _numberOfColumns; i++)
{
_columnXOrigin[i] += xShift;
[self _updateColumnOrigin: i];
}
}
else // theFrame.size.width <= _columnDimension[column]
{
theFrame.size.width = _columnDimension[column];
prisonerNeedResize = YES;
}
//
// Row
//
if (theFrame.size.height > _rowDimension[row])
{
float yShift = theFrame.size.height - _rowDimension[row];
// Compute new size
tableFrame.size.height += yShift;
tableNeedResize = YES;
// Resize the row
_rowDimension[row] = theFrame.size.height;
[self _updateRowSize: row];
// Shift the rows on the top
for (i = row + 1; i < _numberOfRows; i++)
{
_rowYOrigin[i] += yShift;
[self _updateRowOrigin: i];
}
}
else // theFrame.size.height <= _rowDimension[row]
{
theFrame.size.height = _rowDimension[row];
prisonerNeedResize = YES;
}
if (tableNeedResize)
[self setFrameSize: tableFrame.size];
if (_minColumnDimension[column] < theFrame.size.width)
{
_minimumSize.width += (theFrame.size.width - _minColumnDimension[column]);
_minColumnDimension[column] = theFrame.size.width;
}
if (_minRowDimension[row] < theFrame.size.height)
{
_minimumSize.height += (theFrame.size.height - _minRowDimension[row]);
_minRowDimension[row] = theFrame.size.height;
}
//
//
// Put the jail in the GSTable
//
//
theFrame.origin = NSMakePoint (tableFrame.origin.x + _columnXOrigin[column],
tableFrame.origin.y + _rowYOrigin[row]);
if (_havePrisoner[jailNumber])
{
if (prisonerNeedResize)
[_jails[jailNumber] setFrame: oldFrame];
else // !prisonerNeedResize
[_jails[jailNumber] setFrame: theFrame];
}
else // !_havePrisoner
{
if (prisonerNeedResize)
_jails[jailNumber] = [[GSTransparentView alloc]
initWithFrame: oldFrame];
else // !prisonerNeedResize
_jails[jailNumber] = [[GSTransparentView alloc]
initWithFrame: theFrame];
[_jails[jailNumber] setAutoresizingMask: NSViewNotSizable];
[_jails[jailNumber] setAutoresizesSubviews: YES];
[self addSubview: _jails[jailNumber]];
[_jails[jailNumber] release];
}
//
//
// Put the prisoner in the jail
//
//
if (!_havePrisoner[jailNumber])
{
[_jails[jailNumber] addSubview: aView];
}
else // _havePrisoner[jailNumber]
{
[_jails[jailNumber]
replaceSubview: [[_jails[jailNumber] subviews] objectAtIndex: 0]
with: aView];
}
[aView setFrameOrigin: NSMakePoint (minXMargin, minYMargin)];
if (prisonerNeedResize)
[_jails[jailNumber] setFrame: theFrame];
_havePrisoner[jailNumber] = YES;
}
-(void) resizeWithOldSuperviewSize: (NSSize)oldSize
{
float originShift;
float dimensionIncrement;
unsigned int i;
// YES if the whole GSTable needs an update
BOOL tableNeedUpdate = NO;
NSSize oldFrameSize = frame.size;
NSSize newFrameSize;
[super resizeWithOldSuperviewSize: oldSize];
newFrameSize = frame.size;
//
// Width
//
if (newFrameSize.width <= _minimumSize.width)
{
if (oldFrameSize.width > _minimumSize.width)
{
originShift = _minXBorder;
for (i = 0; i < _numberOfColumns; i++)
{
_columnDimension[i] = _minColumnDimension[i];
_columnXOrigin[i] = originShift;
originShift += _minColumnDimension[i];
}
tableNeedUpdate = YES;
}
}
else // newFrameSize.width > _minimumSize.width
{
if (oldFrameSize.width < _minimumSize.width)
oldFrameSize.width = _minimumSize.width;
if ((newFrameSize.width != oldFrameSize.width) && _expandingColumnNumber)
{
originShift = 0;
dimensionIncrement = newFrameSize.width - oldFrameSize.width;
dimensionIncrement = dimensionIncrement / _expandingColumnNumber;
for (i = 0; i < _numberOfColumns; i++)
{
_columnXOrigin[i] += originShift;
if (_expandColumn[i])
{
_columnDimension[i] += dimensionIncrement;
originShift += dimensionIncrement;
}
}
tableNeedUpdate = YES;
}
}
//
// Height
//
if (newFrameSize.height <= _minimumSize.height)
{
if (oldFrameSize.height > _minimumSize.height)
{
originShift = _minYBorder;
for (i = 0; i < _numberOfRows; i++)
{
_rowDimension[i] = _minRowDimension[i];
_rowYOrigin[i] = originShift;
originShift += _minRowDimension[i];
}
tableNeedUpdate = YES;
}
}
else // newFrameSize.height > _minimumSize.height
{
if (oldFrameSize.height < _minimumSize.height)
oldFrameSize.height = _minimumSize.height;
if ((newFrameSize.height != oldFrameSize.height) && _expandingRowNumber)
{
originShift = 0;
dimensionIncrement = newFrameSize.height - oldFrameSize.height;
dimensionIncrement = dimensionIncrement / _expandingRowNumber;
for (i = 0; i < _numberOfRows; i++)
{
_rowYOrigin[i] += originShift;
if (_expandRow[i])
{
_rowDimension[i] += dimensionIncrement;
originShift += dimensionIncrement;
}
}
tableNeedUpdate = YES;
}
}
if (tableNeedUpdate)
[self _updateWholeTable];
}
//
// Minimum Size
//
-(NSSize) minimumSize
{
return _minimumSize;
}
//
// Resizing
//
-(void) sizeToFit
{
int i;
// This should never happen but anyway.
if ((_numberOfColumns == 0) || (_numberOfRows == 0))
{
[self setFrameSize: NSZeroSize];
return;
}
_columnXOrigin[0] = _minXBorder;
_columnDimension[0] = _minColumnDimension[0];
_rowYOrigin[0] = _minYBorder;
_rowDimension[0] = _minRowDimension[0];
for (i = 1; i < _numberOfColumns; i++)
{
_columnXOrigin[i] = _columnXOrigin[i - 1] + _columnDimension[i - 1];
_columnDimension[i] = _minColumnDimension[i];
}
for (i = 1; i < _numberOfRows; i++)
{
_rowYOrigin[i] = _rowYOrigin[i - 1] + _rowDimension[i - 1];
_rowDimension[i] = _minRowDimension[i];
}
[self _updateWholeTable];
[self setFrameSize: _minimumSize];
}
//
// Adding Rows and Columns
// These should be used to add more rows and columns to the GSTable.
// Of course it is faster to create a GSTable with the right number of rows
// and columns from the beginning.
//
-(void) addRow
{
int j;
_numberOfRows++;
_havePrisoner = NSZoneRealloc (NSDefaultMallocZone (), _havePrisoner,
(_numberOfRows * _numberOfColumns)
* (sizeof (BOOL)));
_jails = NSZoneRealloc (NSDefaultMallocZone (), _jails,
(_numberOfRows * _numberOfColumns)
* sizeof (GSTransparentView *));
for (j = (_numberOfRows - 1) * _numberOfColumns;
j < (_numberOfRows * _numberOfColumns); j++)
{
_jails[j] = NULL;
_havePrisoner[j] = NO;
}
_expandRow = NSZoneRealloc (NSDefaultMallocZone (), _expandRow,
(_numberOfRows) * (sizeof (BOOL)));
_expandRow[_numberOfRows - 1] = YES;
_expandingRowNumber++;
_rowDimension = NSZoneRealloc (NSDefaultMallocZone (), _rowDimension,
(_numberOfRows) * (sizeof (float)));
_rowDimension[_numberOfRows - 1] = 0;
_rowYOrigin = NSZoneRealloc (NSDefaultMallocZone (), _rowYOrigin,
(_numberOfRows) * (sizeof (float)));
_rowYOrigin[_numberOfRows - 1] = (_rowYOrigin[_numberOfRows - 2]
+ _rowDimension[_numberOfRows - 2]);
_minRowDimension = NSZoneRealloc (NSDefaultMallocZone (), _minRowDimension,
(_numberOfRows) * (sizeof (float)));
_minRowDimension[_numberOfRows - 1] = 0;
}
// TODO: -(void) insertRow: (int)row;
// TODO: -(void) removeRow: (int)row;
-(void) addColumn
{
int i, j;
_numberOfColumns++;
_havePrisoner = NSZoneRealloc (NSDefaultMallocZone (), _havePrisoner,
(_numberOfRows * _numberOfColumns)
* (sizeof (BOOL)));
_jails = NSZoneRealloc (NSDefaultMallocZone (), _jails,
(_numberOfRows * _numberOfColumns)
* sizeof (GSTransparentView *));
// Reorder the jails
for (j = (_numberOfRows - 1); j >= 0; j--)
{
_jails[(_numberOfColumns * (j + 1)) - 1] = NULL;
_havePrisoner[(_numberOfColumns * (j + 1)) - 1] = NO;
for (i = (_numberOfColumns - 2); i >= 0; i--)
{
_jails[(_numberOfColumns * j) + i]
= _jails[((_numberOfColumns - 1) * j) + i];
_havePrisoner[(_numberOfColumns * j) + i]
= _havePrisoner[((_numberOfColumns - 1) * j) + i];
}
}
_expandColumn = NSZoneRealloc (NSDefaultMallocZone (), _expandColumn,
(_numberOfColumns) * (sizeof (BOOL)));
_expandColumn[_numberOfColumns - 1] = YES;
_expandingColumnNumber++;
_columnDimension = NSZoneRealloc (NSDefaultMallocZone (), _columnDimension,
(_numberOfColumns) * (sizeof (float)));
_columnDimension[_numberOfColumns - 1] = 0;
_columnXOrigin = NSZoneRealloc (NSDefaultMallocZone (), _columnXOrigin,
(_numberOfColumns) * (sizeof (float)));
_columnXOrigin[_numberOfColumns - 1] = (_columnXOrigin[_numberOfColumns - 2]
+ _columnDimension[_numberOfColumns - 2]);
_minColumnDimension = NSZoneRealloc (NSDefaultMallocZone (),
_minColumnDimension,
(_numberOfColumns) * (sizeof (float)));
_minColumnDimension[_numberOfColumns - 1] = 0;
}
// TODO: -(void) insertColumn: (int)column;
// TODO: -(void) removeColumn: (int)column;
//
// Setting Row and Column Expand Flag
//
-(void) setXResizingEnabled: (BOOL)aFlag
forColumn: (int)column
{
if (column > (_numberOfColumns - 1))
{
NSLog (@"Warning: argument column is > (numberOfColumns - 1)\n");
return;
}
if (column < 0)
{
NSLog (@"Warning: argument column is < 0\n");
return;
}
if ((_expandColumn[column] == YES) && (aFlag == NO))
{
_expandingColumnNumber--;
_expandColumn[column] = aFlag;
}
else if ((_expandColumn[column] == NO) && (aFlag == YES))
{
_expandingColumnNumber++;
_expandColumn[column] = aFlag;
}
}
-(BOOL) isXResizingEnabledForColumn: (int)column
{
if (column > (_numberOfColumns - 1))
{
NSLog (@"Warning: argument column is > (numberOfColumns - 1)\n");
return NO;
}
if (column < 0)
{
NSLog (@"Warning: argument column is < 0\n");
return NO;
}
return _expandColumn[column];
}
-(void) setYResizingEnabled: (BOOL)aFlag
forRow: (int)row
{
if (row > (_numberOfRows - 1))
{
NSLog (@"Warning: argument row is > (numberOfRows - 1)\n");
return;
}
if (row < 0)
{
NSLog (@"Warning: argument row is < 0\n");
return;
}
if ((_expandRow[row] == YES) && (aFlag == NO))
{
_expandingRowNumber--;
_expandRow[row] = aFlag;
}
else if ((_expandRow[row] == NO) && (aFlag == YES))
{
_expandingRowNumber++;
_expandRow[row] = aFlag;
}
}
-(BOOL) isYResizingEnabledForRow: (int)row
{
if (row > (_numberOfRows - 1))
{
NSLog (@"Warning: argument row is > (numberOfRows - 1)\n");
return NO;
}
if (row < 0)
{
NSLog (@"Warning: argument row is < 0\n");
return NO;
}
return _expandRow[row];
}
//
// Getting Row and Column Number
//
-(int) numberOfRows
{
return _numberOfRows;
}
-(int) numberOfColumns
{
return _numberOfColumns;
}
//
// NSCoding protocol
//
-(void) encodeWithCoder: (NSCoder*)aCoder
{
int i;
[super encodeWithCoder: aCoder];
[aCoder encodeValueOfObjCType: @encode(int) at: &_numberOfRows];
[aCoder encodeValueOfObjCType: @encode(int) at: &_numberOfColumns];
for (i = 0; i < _numberOfRows * _numberOfColumns; i++)
{
[aCoder encodeObject: _jails[i]];
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &_havePrisoner[i]];
}
[aCoder encodeValueOfObjCType: @encode(float) at: &_minXBorder];
[aCoder encodeValueOfObjCType: @encode(float) at: &_maxXBorder];
[aCoder encodeValueOfObjCType: @encode(float) at: &_minYBorder];
[aCoder encodeValueOfObjCType: @encode(float) at: &_maxYBorder];
for (i = 0; i < _numberOfColumns; i++)
{
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &_expandColumn[i]];
[aCoder encodeValueOfObjCType: @encode(float) at: &_columnDimension[i]];
[aCoder encodeValueOfObjCType: @encode(float)
at: &_minColumnDimension[i]];
}
for (i = 0; i < _numberOfRows; i++)
{
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &_expandRow[i]];
[aCoder encodeValueOfObjCType: @encode(float) at: &_rowDimension[i]];
[aCoder encodeValueOfObjCType: @encode(float) at: &_minRowDimension[i]];
}
}
-(id) initWithCoder: (NSCoder*)aDecoder
{
int i;
[super initWithCoder: aDecoder];
[super setAutoresizesSubviews: NO];
[aDecoder decodeValueOfObjCType: @encode(int) at: &_numberOfRows];
[aDecoder decodeValueOfObjCType: @encode(int) at: &_numberOfColumns];
//
_jails = NSZoneMalloc (NSDefaultMallocZone (),
sizeof (GSTransparentView *)
* (_numberOfRows * _numberOfColumns));
_havePrisoner = NSZoneMalloc (NSDefaultMallocZone (),
sizeof (BOOL)
* (_numberOfRows * _numberOfColumns));
for (i = 0; i < _numberOfRows * _numberOfColumns; i++)
{
_jails[i] = [aDecoder decodeObject];
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &_havePrisoner[i]];
}
[aDecoder decodeValueOfObjCType: @encode(float) at: &_minXBorder];
[aDecoder decodeValueOfObjCType: @encode(float) at: &_maxXBorder];
[aDecoder decodeValueOfObjCType: @encode(float) at: &_minYBorder];
[aDecoder decodeValueOfObjCType: @encode(float) at: &_maxYBorder];
// We compute _minimumSize, _expandingRowNumber
// and _expandingColumnNumber during deconding.
_minimumSize = NSZeroSize;
_expandingRowNumber = 0;
_expandingColumnNumber = 0;
// Columns
_expandColumn = NSZoneMalloc (NSDefaultMallocZone (),
sizeof (BOOL) * _numberOfColumns);
_columnDimension = NSZoneMalloc (NSDefaultMallocZone (),
sizeof (float) * _numberOfColumns);
_minColumnDimension = NSZoneMalloc (NSDefaultMallocZone (),
sizeof (float) * _numberOfColumns);
_minimumSize.width += _minXBorder;
for (i = 0; i < _numberOfColumns; i++)
{
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &_expandColumn[i]];
if (_expandColumn[i])
_expandingColumnNumber++;
[aDecoder decodeValueOfObjCType: @encode(float) at: &_columnDimension[i]];
[aDecoder decodeValueOfObjCType: @encode(float)
at: &_minColumnDimension[i]];
_minimumSize.width += _minColumnDimension[i];
}
_minimumSize.width += _maxXBorder;
// Calculate column origins
_columnXOrigin = NSZoneMalloc (NSDefaultMallocZone (),
sizeof (float) * _numberOfColumns);
_columnXOrigin[0] = _minXBorder;
for (i = 1; i < _numberOfColumns; i++)
_columnXOrigin[i] = _columnXOrigin[i - 1] + _columnDimension[i - 1];
// Rows
_expandRow = NSZoneMalloc (NSDefaultMallocZone (),
sizeof (BOOL) * _numberOfRows);
_rowDimension = NSZoneMalloc (NSDefaultMallocZone (),
sizeof (float) * _numberOfRows);
_minRowDimension = NSZoneMalloc (NSDefaultMallocZone (),
sizeof (float) * _numberOfRows);
_minimumSize.height += _minYBorder;
for (i = 0; i < _numberOfRows; i++)
{
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &_expandRow[i]];
if (_expandRow[i])
_expandingRowNumber++;
[aDecoder decodeValueOfObjCType: @encode(float) at: &_rowDimension[i]];
[aDecoder decodeValueOfObjCType: @encode(float) at: &_minRowDimension[i]];
_minimumSize.height += _minRowDimension[i];
}
_minimumSize.height += _maxYBorder;
// Calculate row origins
_rowYOrigin = NSZoneMalloc (NSDefaultMallocZone (),
sizeof (float) * _numberOfRows);
_rowYOrigin[0] = _minYBorder;
for (i = 1; i < _numberOfRows; i++)
_rowYOrigin[i] = _rowYOrigin[i - 1] + _rowDimension[i - 1];
return self;
}
// These are meant to speed things up, since the table is invisible.
-(void) lockFocusInRect: (NSRect)rect
{
}
-(void) unlockFocusNeedsFlush: (BOOL)flush
{
}
@end
@implementation GSTable (Private)
//
// After computing new theoretical sizes/positions,
// use the following methods to update the real table view
// to the new sizes/positions.
//
-(void) _updateRowSize: (int)row
{
// NB: This (and the following) is for private use,
// so we do not check that row exists.
int i;
int startIndex = row * _numberOfColumns;
for (i = 0; i < _numberOfColumns; i++)
{
if (_havePrisoner[startIndex + i])
{
[_jails[startIndex + i]
setFrameSize: NSMakeSize (_columnDimension[i],
_rowDimension[row])];
}
}
}
-(void) _updateColumnSize: (int)column
{
int i;
for (i = 0; i < _numberOfRows; i++)
{
if (_havePrisoner[(i * _numberOfColumns) + column])
{
[_jails[(i * _numberOfColumns) + column]
setFrameSize: NSMakeSize (_columnDimension[column],
_rowDimension[i])];
}
}
}
-(void) _updateRowOrigin: (int)row
{
int i;
int startIndex = row * _numberOfColumns;
for (i = 0; i < _numberOfColumns; i++)
{
if (_havePrisoner[startIndex + i])
{
[_jails[startIndex + i]
setFrameOrigin: NSMakePoint (_columnXOrigin[i],
_rowYOrigin[row])];
}
}
}
-(void) _updateColumnOrigin: (int)column
{
int i;
for (i = 0; i < _numberOfRows; i++)
{
if (_havePrisoner[(i * _numberOfColumns) + column])
{
[_jails[(i * _numberOfColumns) + column]
setFrameOrigin: NSMakePoint (_columnXOrigin[column],
_rowYOrigin[i])];
}
}
}
-(void) _updateWholeTable
{
int i,j;
for (j = 0; j < _numberOfColumns; j++)
for (i = 0; i < _numberOfRows; i++)
{
if (_havePrisoner[(i * _numberOfColumns) + j])
{
[_jails[(i * _numberOfColumns) + j]
setFrameOrigin: NSMakePoint (_columnXOrigin[j],
_rowYOrigin[i])];
[_jails[(i * _numberOfColumns) + j]
setFrameSize: NSMakeSize (_columnDimension[j],
_rowDimension[i])];
}
}
}
@end