tableView and NSCell processing and drawing updates

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/branches/gnustep_testplant_branch@37347 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Marcian Lytwyn 2013-11-01 15:35:17 +00:00
parent 731714853b
commit 0122926822
4 changed files with 160 additions and 103 deletions

View file

@ -153,6 +153,14 @@ enum {
NSCellHitTrackableArea = 1 << 2,
};
enum {
NSBackgroundStyleLight = 0,
NSBackgroundStyleDark = 1,
NSBackgroundStyleRaised = 2,
NSBackgroundStyleLowered = 3
};
typedef NSInteger NSBackgroundStyle;
@interface NSCell : NSObject <NSCopying, NSCoding>
{
// Attributes
@ -199,6 +207,7 @@ enum {
unsigned subclass_bool_four: 1;
// Set while the cell is edited/selected
unsigned in_editing: 1;
unsigned background_style: 2;
} _cell;
NSUInteger _mouse_down_flags;
NSUInteger _action_mask;
@ -511,6 +520,8 @@ enum {
#endif
#if OS_API_VERSION(MAC_OS_X_VERSION_10_5, GS_API_LATEST)
- (NSBackgroundStyle)backgroundStyle;
- (void)setBackgroundStyle:(NSBackgroundStyle)backgroundStyle;
- (NSUInteger)hitTestForEvent:(NSEvent *)event inRect:(NSRect)cellFrame ofView:(NSView *)controlView;
#endif

View file

@ -2599,10 +2599,8 @@ static NSDictionary *titleTextAttributes[3] = {nil, nil, nil};
float *columnOrigins = [tableView _columnOrigins];
int editedRow = [tableView editedRow];
int editedColumn = [tableView editedColumn];
NSArray *tableColumns = [tableView tableColumns];
int startingColumn;
int startingColumn;
int endingColumn;
NSTableColumn *tb;
NSRect drawingRect;
NSCell *cell;
int i;
@ -2613,96 +2611,88 @@ static NSDictionary *titleTextAttributes[3] = {nil, nil, nil};
return;
}
/* Using columnAtPoint: here would make it called twice per row per drawn
rect - so we avoid it and do it natively */
/* Determine starting column as fast as possible */
x_pos = NSMinX (clipRect);
i = 0;
while ((i < numberOfColumns) && (x_pos > columnOrigins[i]))
{
i++;
}
startingColumn = (i - 1);
if (startingColumn == -1)
startingColumn = 0;
/* Determine ending column as fast as possible */
x_pos = NSMaxX (clipRect);
// Nota Bene: we do *not* reset i
while ((i < numberOfColumns) && (x_pos > columnOrigins[i]))
{
i++;
}
endingColumn = (i - 1);
if (endingColumn == -1)
endingColumn = numberOfColumns - 1;
BOOL respondsToIsGroupRow = [[tableView delegate] respondsToSelector:@selector(tableView:isGroupRow:)];
// First, determine whether the table view delegate wants this row
// to be a grouped cell row...
if (respondsToIsGroupRow && [[tableView delegate] tableView:tableView isGroupRow:rowIndex])
{
cell = [tableView _dataCellForTableColumn:nil row:rowIndex];
cell = [tableView preparedCellAtColumn: -1 row:rowIndex];
if (cell)
{
id objectValue = [dataSource tableView: tableView objectValueForTableColumn: nil row: rowIndex];
static NSGradient *GroupCellGradient = nil;
if (GroupCellGradient == nil)
{
NSColor *startColor = [NSColor colorWithCalibratedWhite:212.0 / 255.0 alpha:1.0f];
NSColor *endColor = [NSColor colorWithCalibratedWhite:217.0 / 255.0 alpha:1.0f];
GroupCellGradient = [[NSGradient alloc] initWithStartingColor:startColor endingColor:endColor];
}
[cell _setInEditing: NO];
[cell setShowsFirstResponder:NO];
[cell setFocusRingType:NSFocusRingTypeNone];
[tableView _willDisplayCell: cell forTableColumn: nil row: rowIndex];
[cell setObjectValue: objectValue];
[cell setBackgroundStyle:NSBackgroundStyleDark];
// Get the drawing rectangle...
drawingRect = [tableView frameOfCellAtColumn: 0 row: rowIndex];
// Need to draw in the background gradient - this seems to be done outside the cell drawing
// on Cocoa...
static NSGradient *GroupCellGradient = nil;
if (GroupCellGradient == nil)
{
NSColor *startColor = [NSColor colorWithCalibratedWhite:212.0 / 255.0 alpha:1.0f];
NSColor *endColor = [NSColor colorWithCalibratedWhite:217.0 / 255.0 alpha:1.0f];
GroupCellGradient = [[NSGradient alloc] initWithStartingColor:startColor endingColor:endColor];
}
// Draw the group row...
[GroupCellGradient drawInRect:drawingRect angle:90.0f];
// Draw the group row...
[cell drawWithFrame: drawingRect inView: tableView];
}
return;
}
/* Draw the row between startingColumn and endingColumn */
for (i = startingColumn; i <= endingColumn; i++)
else
{
tb = [tableColumns objectAtIndex: i];
cell = [tableView _dataCellForTableColumn:tb row:rowIndex];
if (i == editedColumn && rowIndex == editedRow)
{
[cell _setInEditing: YES];
[cell setShowsFirstResponder:YES];
[cell setFocusRingType:NSFocusRingTypeDefault];
}
/* Using columnAtPoint: here would make it called twice per row per drawn
rect - so we avoid it and do it natively */
[tableView _willDisplayCell: cell
forTableColumn: tb
row: rowIndex];
[cell setObjectValue: [dataSource tableView: tableView
objectValueForTableColumn: tb
row: rowIndex]];
drawingRect = [tableView frameOfCellAtColumn: i
row: rowIndex];
[cell drawWithFrame: drawingRect inView: tableView];
if (i == editedColumn && rowIndex == editedRow)
/* Determine starting column as fast as possible */
x_pos = NSMinX (clipRect);
i = 0;
while ((i < numberOfColumns) && (x_pos > columnOrigins[i]))
{
i++;
}
startingColumn = (i - 1);
if (startingColumn == -1)
startingColumn = 0;
/* Determine ending column as fast as possible */
x_pos = NSMaxX (clipRect);
// Nota Bene: we do *not* reset i
while ((i < numberOfColumns) && (x_pos > columnOrigins[i]))
{
i++;
}
endingColumn = (i - 1);
if (endingColumn == -1)
endingColumn = numberOfColumns - 1;
/* Draw the row between startingColumn and endingColumn */
for (i = startingColumn; i <= endingColumn; i++)
{
[cell _setInEditing: NO];
[cell setShowsFirstResponder:NO];
[cell setFocusRingType:NSFocusRingTypeNone];
cell = [tableView preparedCellAtColumn: i row:rowIndex];
if (i == editedColumn && rowIndex == editedRow)
{
[cell _setInEditing: YES];
[cell setShowsFirstResponder:YES];
[cell setFocusRingType:NSFocusRingTypeDefault];
}
drawingRect = [tableView frameOfCellAtColumn: i row: rowIndex];
[cell drawWithFrame: drawingRect inView: tableView];
if (i == editedColumn && rowIndex == editedRow)
{
[cell _setInEditing: NO];
[cell setShowsFirstResponder:NO];
[cell setFocusRingType:NSFocusRingTypeNone];
}
}
}
}

View file

@ -1597,6 +1597,16 @@ static NSColor *dtxtCol;
*interval = 0.1;
}
- (NSBackgroundStyle)backgroundStyle
{
return(_cell.background_style);
}
- (void)setBackgroundStyle:(NSBackgroundStyle)backgroundStyle
{
_cell.background_style = backgroundStyle;
}
- (NSUInteger)hitTestForEvent:(NSEvent *)event inRect:(NSRect)cellFrame ofView:(NSView *)controlView
{
NSUInteger hitResult = NSCellHitNone;
@ -1617,6 +1627,7 @@ static NSColor *dtxtCol;
NSString *stringValue = [self stringValue];
if (stringValue && [stringValue length])
{
// TODO: Needs to be the string rect NOT the title rect area...
NSRect checkFrame = [self titleRectForBounds:cellFrame];
if (NSPointInRect(point, checkFrame))
hitResult |= NSCellHitContentArea;
@ -2855,24 +2866,55 @@ static NSColor *dtxtCol;
are deallocated at the end of the run loop. */
- (NSDictionary*) _nonAutoreleasedTypingAttributes
{
NSDictionary *attr;
NSColor *color;
NSMutableParagraphStyle *paragraphStyle;
NSDictionary *attr = nil;
color = [self textColor];
/* Note: There are only a few possible paragraph styles for cells.
TODO: Cache them and reuse them for the whole app lifetime. */
paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[paragraphStyle setLineBreakMode: [self lineBreakMode]];
[paragraphStyle setBaseWritingDirection: [self baseWritingDirection]];
[paragraphStyle setAlignment: [self alignment]];
switch (_cell.background_style)
{
case NSBackgroundStyleDark:
{
NSFont *font = [NSFont fontWithName:@"LucidaGrande-Bold" size:12.0];
NSColor *color = [NSColor colorWithCalibratedWhite:0.458824 alpha:1.0];
/* Note: There are only a few possible paragraph styles for cells.
TODO: Cache them and reuse them for the whole app lifetime. */
NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[paragraphStyle setLineBreakMode: [self lineBreakMode]];
[paragraphStyle setBaseWritingDirection: [self baseWritingDirection]];
[paragraphStyle setAlignment: [self alignment]];
attr = [[NSDictionary alloc] initWithObjectsAndKeys:
font, NSFontAttributeName,
color, NSForegroundColorAttributeName,
paragraphStyle, NSParagraphStyleAttributeName,
nil];
RELEASE (paragraphStyle);
break;
}
// TODO: Add raised style settings...
case NSBackgroundStyleRaised:
// TODO: Add lowered style settings...
case NSBackgroundStyleLowered:
case NSBackgroundStyleLight:
default:
{
NSColor *color = [self textColor];
/* Note: There are only a few possible paragraph styles for cells.
TODO: Cache them and reuse them for the whole app lifetime. */
NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[paragraphStyle setLineBreakMode: [self lineBreakMode]];
[paragraphStyle setBaseWritingDirection: [self baseWritingDirection]];
[paragraphStyle setAlignment: [self alignment]];
attr = [[NSDictionary alloc] initWithObjectsAndKeys:
_font, NSFontAttributeName,
color, NSForegroundColorAttributeName,
paragraphStyle, NSParagraphStyleAttributeName,
nil];
RELEASE (paragraphStyle);
attr = [[NSDictionary alloc] initWithObjectsAndKeys:
_font, NSFontAttributeName,
color, NSForegroundColorAttributeName,
paragraphStyle, NSParagraphStyleAttributeName,
nil];
RELEASE (paragraphStyle);
break;
}
}
return attr;
}

View file

@ -3190,19 +3190,34 @@ byExtendingSelection: (BOOL)flag
- (NSCell *) preparedCellAtColumn: (NSInteger)columnIndex row: (NSInteger)rowIndex
{
NSCell *cell = nil;
NSTableColumn *tb = [_tableColumns objectAtIndex: columnIndex];
NSCell *cell = nil;
NSTableColumn *tb = nil;
// -1 on Cocoa means nil table column for group row cell...
if (columnIndex >= 0)
tb = [_tableColumns objectAtIndex: columnIndex];
if ([_delegate respondsToSelector:
@selector(tableView:dataCellForTableColumn:row:)])
if ([_delegate respondsToSelector: @selector(tableView:dataCellForTableColumn:row:)])
{
cell = [_delegate tableView: self dataCellForTableColumn: tb
row: rowIndex];
cell = [_delegate tableView: self dataCellForTableColumn: tb row: rowIndex];
}
if (cell == nil)
// If no cell and we're requesting a non-group cell...
if ((cell == nil) && tb)
{
cell = [tb dataCellForRow: rowIndex];
}
// If we got a cell get the object value...this is done here in Cocoa...
if (cell)
{
// Get the object value from the delegate or nil...
[cell setObjectValue:[self _objectValueForTableColumn:tb row:rowIndex]];
// Inform delegate we are getting ready to display
[self _willDisplayCell: cell forTableColumn: tb row: rowIndex];
}
return cell;
}
@ -3574,13 +3589,8 @@ static inline float computePeriod(NSPoint mouseLocationWin,
- (NSUInteger)_hitTestForEvent:(NSEvent*)event atColumn:(NSInteger)column row:(NSInteger)row
{
NSTableColumn *tableColumn = ((column == -1) ? nil : [[self tableColumns] objectAtIndex:column]);
NSCell *cell = [self _dataCellForTableColumn:tableColumn row:row];
NSRect cellFrame = [self frameOfCellAtColumn:(column == -1) ? 0 : column row:row];
id objectValue = [self _objectValueForTableColumn:tableColumn row:row];
// Initialize object value for data cell...
[cell setObjectValue:objectValue];
NSCell *cell = [self preparedCellAtColumn: column row: row];
NSRect cellFrame = [self frameOfCellAtColumn:(column == -1) ? 0 : column row:row];
// Return the hit result...
return([cell hitTestForEvent:event inRect:cellFrame ofView:self]);
@ -3619,13 +3629,17 @@ static inline float computePeriod(NSPoint mouseLocationWin,
if ([theEvent type] == NSLeftMouseDown)
{
// If the cell processed the mouse hit...
BOOL isGrouped = [[self delegate] tableView:self isGroupRow:_clickedRow];
NSInteger theColumn = (isGrouped ? -1 : _clickedColumn);
NSUInteger hitResult = [self _hitTestForEvent:theEvent atColumn:theColumn row:_clickedRow];
NSInteger theColumn = _clickedColumn;
BOOL responds = [[self delegate] respondsToSelector: @selector(tableView:isGroupRow:)];
// Check for grouped row...
if (responds && [[self delegate] tableView:self isGroupRow:_clickedRow])
theColumn = -1;
// Application specific hit test processing is handled within the delegate's should select callbacks
// if they're implemented...however - I'm not sure when this SHOULD be invoked...
[self _shouldSelectRow:_clickedRow];
if ([self _hitTestForEvent:theEvent atColumn:theColumn row:_clickedRow] != NSCellHitNone)
[self _shouldSelectRow:_clickedRow];
}
if ([theEvent type] == NSLeftMouseDown