• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Varying Row Heights
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Varying Row Heights


  • Subject: Re: Varying Row Heights
  • From: Drew McCormack <email@hidden>
  • Date: Thu, 25 Apr 2002 08:06:49 +0200

On Thursday, April 25, 2002, at 12:36 AM, Paul A. Seligman wrote:

I am looking to implement a TableView in which different rows have different heights depending on the data corresponding to each row. If it helps, I only need two different row heights. There seems to be absolutely nothing in the docs about this, and I
fear it may be impossible. Does anyone have any knowledge about this?

I spent some time trying to do this about 6 months ago. You might check out the archives for what was said then. I think a search for "varying row heights" would find it.

My conclusion was that it was probably possible, but not trivial. I got to the stage that I could have rows with different heights, but when I edited a cell, I couldn't get the field editor to resize properly (the rows themselves do resize properly).

The code I made is slow (I just wanted to see if it worked first), and not that long, so I will include it here. Maybe someone can see what is wrong with it. I have played with it a lot to try to get the correct behavior, so I don't know if it will work straight out of the box. At least it will show you which methods you need to override.



First, here is the header and implementation file for a subclass of NSCell which can be used to set attributes of the cells:


#import <AppKit/AppKit.h>


@interface TextCell : NSTextFieldCell {
NSText *currentFieldEditor;
}

- (void)dealloc;

- (NSText *)setUpFieldEditorAttributes:(NSText *)textObj;

- (NSText *)currentFieldEditor;
- (void)setCurrentFieldEditor:(NSText *)editor;

@end


@implementation TextCell



- (NSText *)setUpFieldEditorAttributes:(NSText *)textObj {
NSTextContainer *container = [textObj textContainer];
//[self setCurrentFieldEditor:textObj];
//textObj = [super setUpFieldEditorAttributes:textObj];
[textObj setFieldEditor:NO];
//[textObj setHorizontallyResizable:NO];
[textObj setVerticallyResizable:YES];
[container setHeightTracksTextView:YES];
//[container setWidthTracksTextView:NO];
//[container setContainerSize:NSMakeSize([container containerSize].width, 10000000.0)];
//[textObj setBackgroundColor: [NSColor redColor]];
//[textObj setDrawsBackground:YES];
//[textObj setAutoresizingMask: NSViewHeightSizable];
return textObj;
}



- (void)editWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject event:(NSEvent *)theEvent {
// aRect.size.height = aRect.size.height + 50.0;
[super editWithFrame:aRect inView:controlView editor:textObj delegate:anObject event:theEvent];
}



@end







Here is the ".h" file of my table view:


#import <Cocoa/Cocoa.h>

@class TextCell;

@interface RowIrregTableView : NSTableView
{
BOOL textHasChanged;
}

- (void)editColumn:(int)columnIndex row:(int)rowIndex withEvent:(NSEvent *)theEvent select:(BOOL)flag;

- (TextCell *)textCellForRow:(int)row column:(int)col;

- (NSRect)rectOfRow:(int)row;
- (NSRect)rectOfColumn:(int)col;
- (NSRect)frameOfCellAtColumn:(int)column row:(int)row;

-(NSRect)frame;


@end





Here is the ".m" file:

#import "RowIrregTableView.h"
#import "TextCell.h"


@interface RowIrregTableView(PrivateMethods)

-(NSRange)rangeOfRow:(int)row;
- (int)maxHeightInRow:(int)row;

@end



@implementation RowIrregTableView



-(id)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
if ( self ) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(TextDidChange:)
name:@"NSControlTextDidChangeNotification"
object:self];
}
return self;
}



- (void)awakeFromNib {
NSArray *cols = [self tableColumns];
NSTableColumn *col;
int i;
NSCell *dataCell;
NSTextView *fe;

for ( i = 0; i < [cols count]; i++ ) {
col = [cols objectAtIndex:i];
dataCell = [[[TextCell alloc] initTextCell:@""] autorelease ];
[dataCell setEditable:YES];
[col setDataCell:dataCell];
}

}



-(void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}



-(void)textDidChange:(NSNotification *)notif {
TextCell *cell;
NSRect frame;

cell = [self textCellForRow:[self editedRow] column:[self editedColumn]];

textHasChanged = YES;

frame = [self frameOfCellAtColumn:[self editedColumn] row:[self editedRow]];
[self setRowHeight:frame.size.height];

}



-(NSRange)rangeOfRow:(int)row {
NSRange range;
int rowIndex;
float spacing = [self intercellSpacing].height;

range.location = 0;
for ( rowIndex = 0; rowIndex < row; rowIndex++ ) {
range.location += [self maxHeightInRow:rowIndex] + spacing;
}
range.length = [self maxHeightInRow:row];

return range;
}



- (TextCell *)textCellForRow:(int)row column:(int)col {
NSTableColumn *tabCol;
NSArray *tableCols = [self tableColumns];
tabCol = [tableCols objectAtIndex:col];
return [tabCol dataCellForRow:row];
}



// Determine maximum height of any cell in 'row'
- (int)maxHeightInRow:(int)row {
float maxHeight;
int colIndex;
id obj;
id <NSCopying> initObjVal;
BOOL releaseObj;
NSTableColumn *tabCol;
TextCell *dataCell;
NSArray *tableCols = [self tableColumns];

maxHeight = [self rowHeight];
for ( colIndex = 0; colIndex < [self numberOfColumns]; colIndex++ ) {

tabCol = [tableCols objectAtIndex:colIndex];
dataCell = [self textCellForRow:row column:colIndex];

initObjVal = [dataCell objectValue];
if ( nil == initObjVal ) continue;

releaseObj = NO;
[initObjVal retain];
obj = [[self dataSource] tableView:self objectValueForTableColumn:tabCol row:row];

if ( textHasChanged && ( row == [self editedRow] ) && ( colIndex == [self editedColumn] ) ) {
obj = [[[self window] fieldEditor:YES forObject:dataCell] string];
releaseObj = NO;
}

[dataCell setObjectValue:obj];
maxHeight = MAX(maxHeight, [dataCell cellSize].height);

if ( releaseObj ) [obj release];
[dataCell setObjectValue:initObjVal];
[initObjVal release];

}

return maxHeight;
}



- (NSRect)rectOfRow:(int)row {
NSRect rect = [super rectOfRow:row];
NSRange rowRange = [self rangeOfRow:row];

rect.origin.y = rowRange.location;
rect.size.height = rowRange.length;

return rect;
}



- (NSRect)rectOfColumn:(int)col {
NSRect rect = [super rectOfColumn:col];
NSRange rowRange = [self rangeOfRow:([self numberOfRows]-1) ];

rect.size.height = rowRange.location + rowRange.length - 1;

return rect;
}



- (NSRect)frameOfCellAtColumn:(int)column row:(int)row {
NSRect rect = [super frameOfCellAtColumn:column row:row];
NSRect rowRect = [self rectOfRow:row];
rect.size.height = rowRect.size.height;
rect.origin.y = rowRect.origin.y;
return rect;
}



-(void)calcAndSetFrame {
NSRect frameRect = [super frame];
NSRect tempRect;
if ( [self numberOfColumns] == 0 || [self numberOfRows] == 0 ) return frameRect;
tempRect = [self rectOfColumn:0];
frameRect.size.height = tempRect.size.height;
tempRect = [self rectOfRow:0];
frameRect.size.width = tempRect.size.width;
[self setFrame: frameRect];
}



-(void)calcAndSetBounds {
NSRect boundsRect = [super bounds];
NSRect tempRect;
if ( [self numberOfColumns] == 0 || [self numberOfRows] == 0 ) return boundsRect;
tempRect = [self rectOfColumn:0];
boundsRect.size.height = tempRect.size.height;
tempRect = [self rectOfRow:0];
boundsRect.size.width = tempRect.size.width;
[self setBounds:boundsRect];
}



- (int)rowAtPoint:(NSPoint)point {
int result;
int i;
NSRect rowRect;
BOOL rowNotFound = YES;

i = -1;
result = -1;
while ( ++i < [self numberOfRows] && rowNotFound ) {
rowRect = [self rectOfRow:i];
if ( ( point.y >= rowRect.origin.y ) && ( point.y <= rowRect.origin.y + rowRect.size.height - 1 ) &&
( point.x >= rowRect.origin.x ) && ( point.x <= rowRect.origin.x + rowRect.size.width - 1 ) ) {
rowNotFound = NO;
result = i;
}
}

return result;

}



- (int)columnAtPoint:(NSPoint)point {
int result;
int i;
NSRect colRect;
BOOL colNotFound = YES;

i = -1;
result = -1;
while ( ++i < [self numberOfColumns] && colNotFound ) {
colRect = [self rectOfColumn:i];
if ( ( point.y >= colRect.origin.y ) && ( point.y <= colRect.origin.y + colRect.size.height - 1 ) &&
( point.x >= colRect.origin.x ) && ( point.x <= colRect.origin.x + colRect.size.width - 1 ) ) {
colNotFound = NO;
result = i;
}
}

return result;

}



- (NSRange)columnsInRect:(NSRect)rect {
NSRange result;
NSPoint point;
NSRect lastCol, lastRow, firstCol, firstRow;
float left, right, top, bottom;
int leftCol, rightCol, topRow, bottomRow;

firstCol = [self rectOfColumn:0 ];
firstRow = [self rectOfRow:0 ];
lastCol = [self rectOfColumn:([self numberOfColumns] - 1) ];
lastRow = [self rectOfRow:([self numberOfRows] - 1) ];

left = rect.origin.x;
right = rect.origin.x + rect.size.width;
top = rect.origin.y;
bottom = rect.origin.y + rect.size.height;

// Check non-overlapping case
if ( ( left > lastCol.origin.x + lastCol.size.width ) ||
( right < firstCol.origin.x ) ||
( top > lastRow.origin.y + lastRow.size.height ) ||
( bottom < firstRow.origin.x ) ) {
result.length = 0.0;
return result;
}

point.x = left;
point.y = 0.0;
leftCol = [self columnAtPoint:point];
if ( leftCol == -1 ) leftCol = 0;

point.x = right;
point.y = 0;
rightCol = [self columnAtPoint:point];
if ( rightCol == -1 ) rightCol = [self numberOfColumns] - 1;

result.location = leftCol;
result.length = (rightCol - leftCol + 1);

return result;

}



- (NSRange)rowsInRect:(NSRect)rect {
NSRange result;
NSPoint point;
NSRect lastCol, lastRow, firstCol, firstRow;
float left, right, top, bottom;
int topRow, bottomRow;

firstCol = [self rectOfColumn:0 ];
firstRow = [self rectOfRow:0 ];
lastCol = [self rectOfColumn:([self numberOfColumns] - 1) ];
lastRow = [self rectOfRow:([self numberOfRows] - 1) ];

left = rect.origin.x;
right = rect.origin.x + rect.size.width;
top = rect.origin.y;
bottom = rect.origin.y + rect.size.height;

// Check non-overlapping case
if ( ( left > lastCol.origin.x + lastCol.size.width ) ||
( right < firstCol.origin.x ) ||
( top > lastRow.origin.y + lastRow.size.height ) ||
( bottom < firstRow.origin.x ) ) {
result.length = 0.0;
return result;
}

point.x = 0.0;
point.y = top;
topRow = [self rowAtPoint:point];
if ( topRow == -1 ) topRow = 0;

point.x = 0.0;
point.y = bottom;
bottomRow = [self rowAtPoint:point];
if ( bottomRow == -1 ) bottomRow = [self numberOfRows] - 1;

result.location = topRow;
result.length = (bottomRow - topRow + 1);

return result;

}



@end


... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
Dr. Drew McCormack
Trade Strategist (www.trade-strategist.com)
Trading simulation software for Mac OS X
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.
  • Prev by Date: Re: ioctl
  • Next by Date: Re: ioctl
  • Previous by thread: Re: Varying Row Heights
  • Next by thread: Inches, Centimeters, and NSMeasurementUnit
  • Index(es):
    • Date
    • Thread