mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-25 17:31:18 +00:00
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:
parent
731714853b
commit
0122926822
4 changed files with 160 additions and 103 deletions
|
@ -153,6 +153,14 @@ enum {
|
||||||
NSCellHitTrackableArea = 1 << 2,
|
NSCellHitTrackableArea = 1 << 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
NSBackgroundStyleLight = 0,
|
||||||
|
NSBackgroundStyleDark = 1,
|
||||||
|
NSBackgroundStyleRaised = 2,
|
||||||
|
NSBackgroundStyleLowered = 3
|
||||||
|
};
|
||||||
|
typedef NSInteger NSBackgroundStyle;
|
||||||
|
|
||||||
@interface NSCell : NSObject <NSCopying, NSCoding>
|
@interface NSCell : NSObject <NSCopying, NSCoding>
|
||||||
{
|
{
|
||||||
// Attributes
|
// Attributes
|
||||||
|
@ -199,6 +207,7 @@ enum {
|
||||||
unsigned subclass_bool_four: 1;
|
unsigned subclass_bool_four: 1;
|
||||||
// Set while the cell is edited/selected
|
// Set while the cell is edited/selected
|
||||||
unsigned in_editing: 1;
|
unsigned in_editing: 1;
|
||||||
|
unsigned background_style: 2;
|
||||||
} _cell;
|
} _cell;
|
||||||
NSUInteger _mouse_down_flags;
|
NSUInteger _mouse_down_flags;
|
||||||
NSUInteger _action_mask;
|
NSUInteger _action_mask;
|
||||||
|
@ -511,6 +520,8 @@ enum {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if OS_API_VERSION(MAC_OS_X_VERSION_10_5, GS_API_LATEST)
|
#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;
|
- (NSUInteger)hitTestForEvent:(NSEvent *)event inRect:(NSRect)cellFrame ofView:(NSView *)controlView;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -2599,10 +2599,8 @@ static NSDictionary *titleTextAttributes[3] = {nil, nil, nil};
|
||||||
float *columnOrigins = [tableView _columnOrigins];
|
float *columnOrigins = [tableView _columnOrigins];
|
||||||
int editedRow = [tableView editedRow];
|
int editedRow = [tableView editedRow];
|
||||||
int editedColumn = [tableView editedColumn];
|
int editedColumn = [tableView editedColumn];
|
||||||
NSArray *tableColumns = [tableView tableColumns];
|
int startingColumn;
|
||||||
int startingColumn;
|
|
||||||
int endingColumn;
|
int endingColumn;
|
||||||
NSTableColumn *tb;
|
|
||||||
NSRect drawingRect;
|
NSRect drawingRect;
|
||||||
NSCell *cell;
|
NSCell *cell;
|
||||||
int i;
|
int i;
|
||||||
|
@ -2613,96 +2611,88 @@ static NSDictionary *titleTextAttributes[3] = {nil, nil, nil};
|
||||||
return;
|
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:)];
|
BOOL respondsToIsGroupRow = [[tableView delegate] respondsToSelector:@selector(tableView:isGroupRow:)];
|
||||||
|
|
||||||
// First, determine whether the table view delegate wants this row
|
// First, determine whether the table view delegate wants this row
|
||||||
// to be a grouped cell row...
|
// to be a grouped cell row...
|
||||||
if (respondsToIsGroupRow && [[tableView delegate] tableView:tableView isGroupRow:rowIndex])
|
if (respondsToIsGroupRow && [[tableView delegate] tableView:tableView isGroupRow:rowIndex])
|
||||||
{
|
{
|
||||||
cell = [tableView _dataCellForTableColumn:nil row:rowIndex];
|
cell = [tableView preparedCellAtColumn: -1 row:rowIndex];
|
||||||
if (cell)
|
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 _setInEditing: NO];
|
||||||
[cell setShowsFirstResponder:NO];
|
[cell setShowsFirstResponder:NO];
|
||||||
[cell setFocusRingType:NSFocusRingTypeNone];
|
[cell setFocusRingType:NSFocusRingTypeNone];
|
||||||
|
[cell setBackgroundStyle:NSBackgroundStyleDark];
|
||||||
[tableView _willDisplayCell: cell forTableColumn: nil row: rowIndex];
|
|
||||||
[cell setObjectValue: objectValue];
|
|
||||||
|
|
||||||
// Get the drawing rectangle...
|
// Get the drawing rectangle...
|
||||||
drawingRect = [tableView frameOfCellAtColumn: 0 row: rowIndex];
|
drawingRect = [tableView frameOfCellAtColumn: 0 row: rowIndex];
|
||||||
|
|
||||||
// Need to draw in the background gradient - this seems to be done outside the cell drawing
|
// Need to draw in the background gradient - this seems to be done outside the cell drawing
|
||||||
// on Cocoa...
|
// 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];
|
[GroupCellGradient drawInRect:drawingRect angle:90.0f];
|
||||||
|
|
||||||
|
// Draw the group row...
|
||||||
[cell drawWithFrame: drawingRect inView: tableView];
|
[cell drawWithFrame: drawingRect inView: tableView];
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* Draw the row between startingColumn and endingColumn */
|
|
||||||
for (i = startingColumn; i <= endingColumn; i++)
|
|
||||||
{
|
{
|
||||||
tb = [tableColumns objectAtIndex: i];
|
/* Using columnAtPoint: here would make it called twice per row per drawn
|
||||||
cell = [tableView _dataCellForTableColumn:tb row:rowIndex];
|
rect - so we avoid it and do it natively */
|
||||||
if (i == editedColumn && rowIndex == editedRow)
|
|
||||||
{
|
|
||||||
[cell _setInEditing: YES];
|
|
||||||
[cell setShowsFirstResponder:YES];
|
|
||||||
[cell setFocusRingType:NSFocusRingTypeDefault];
|
|
||||||
}
|
|
||||||
|
|
||||||
[tableView _willDisplayCell: cell
|
/* Determine starting column as fast as possible */
|
||||||
forTableColumn: tb
|
x_pos = NSMinX (clipRect);
|
||||||
row: rowIndex];
|
i = 0;
|
||||||
[cell setObjectValue: [dataSource tableView: tableView
|
while ((i < numberOfColumns) && (x_pos > columnOrigins[i]))
|
||||||
objectValueForTableColumn: tb
|
{
|
||||||
row: rowIndex]];
|
i++;
|
||||||
drawingRect = [tableView frameOfCellAtColumn: i
|
}
|
||||||
row: rowIndex];
|
startingColumn = (i - 1);
|
||||||
[cell drawWithFrame: drawingRect inView: tableView];
|
|
||||||
if (i == editedColumn && rowIndex == editedRow)
|
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 = [tableView preparedCellAtColumn: i row:rowIndex];
|
||||||
[cell setShowsFirstResponder:NO];
|
if (i == editedColumn && rowIndex == editedRow)
|
||||||
[cell setFocusRingType:NSFocusRingTypeNone];
|
{
|
||||||
|
[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];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1597,6 +1597,16 @@ static NSColor *dtxtCol;
|
||||||
*interval = 0.1;
|
*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)hitTestForEvent:(NSEvent *)event inRect:(NSRect)cellFrame ofView:(NSView *)controlView
|
||||||
{
|
{
|
||||||
NSUInteger hitResult = NSCellHitNone;
|
NSUInteger hitResult = NSCellHitNone;
|
||||||
|
@ -1617,6 +1627,7 @@ static NSColor *dtxtCol;
|
||||||
NSString *stringValue = [self stringValue];
|
NSString *stringValue = [self stringValue];
|
||||||
if (stringValue && [stringValue length])
|
if (stringValue && [stringValue length])
|
||||||
{
|
{
|
||||||
|
// TODO: Needs to be the string rect NOT the title rect area...
|
||||||
NSRect checkFrame = [self titleRectForBounds:cellFrame];
|
NSRect checkFrame = [self titleRectForBounds:cellFrame];
|
||||||
if (NSPointInRect(point, checkFrame))
|
if (NSPointInRect(point, checkFrame))
|
||||||
hitResult |= NSCellHitContentArea;
|
hitResult |= NSCellHitContentArea;
|
||||||
|
@ -2855,24 +2866,55 @@ static NSColor *dtxtCol;
|
||||||
are deallocated at the end of the run loop. */
|
are deallocated at the end of the run loop. */
|
||||||
- (NSDictionary*) _nonAutoreleasedTypingAttributes
|
- (NSDictionary*) _nonAutoreleasedTypingAttributes
|
||||||
{
|
{
|
||||||
NSDictionary *attr;
|
NSDictionary *attr = nil;
|
||||||
NSColor *color;
|
|
||||||
NSMutableParagraphStyle *paragraphStyle;
|
|
||||||
|
|
||||||
color = [self textColor];
|
switch (_cell.background_style)
|
||||||
/* Note: There are only a few possible paragraph styles for cells.
|
{
|
||||||
TODO: Cache them and reuse them for the whole app lifetime. */
|
case NSBackgroundStyleDark:
|
||||||
paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
|
{
|
||||||
[paragraphStyle setLineBreakMode: [self lineBreakMode]];
|
NSFont *font = [NSFont fontWithName:@"LucidaGrande-Bold" size:12.0];
|
||||||
[paragraphStyle setBaseWritingDirection: [self baseWritingDirection]];
|
NSColor *color = [NSColor colorWithCalibratedWhite:0.458824 alpha:1.0];
|
||||||
[paragraphStyle setAlignment: [self alignment]];
|
|
||||||
|
/* 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:
|
attr = [[NSDictionary alloc] initWithObjectsAndKeys:
|
||||||
_font, NSFontAttributeName,
|
_font, NSFontAttributeName,
|
||||||
color, NSForegroundColorAttributeName,
|
color, NSForegroundColorAttributeName,
|
||||||
paragraphStyle, NSParagraphStyleAttributeName,
|
paragraphStyle, NSParagraphStyleAttributeName,
|
||||||
nil];
|
nil];
|
||||||
RELEASE (paragraphStyle);
|
RELEASE (paragraphStyle);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
return attr;
|
return attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3190,19 +3190,34 @@ byExtendingSelection: (BOOL)flag
|
||||||
|
|
||||||
- (NSCell *) preparedCellAtColumn: (NSInteger)columnIndex row: (NSInteger)rowIndex
|
- (NSCell *) preparedCellAtColumn: (NSInteger)columnIndex row: (NSInteger)rowIndex
|
||||||
{
|
{
|
||||||
NSCell *cell = nil;
|
NSCell *cell = nil;
|
||||||
NSTableColumn *tb = [_tableColumns objectAtIndex: columnIndex];
|
NSTableColumn *tb = nil;
|
||||||
|
|
||||||
|
// -1 on Cocoa means nil table column for group row cell...
|
||||||
|
if (columnIndex >= 0)
|
||||||
|
tb = [_tableColumns objectAtIndex: columnIndex];
|
||||||
|
|
||||||
if ([_delegate respondsToSelector:
|
if ([_delegate respondsToSelector: @selector(tableView:dataCellForTableColumn:row:)])
|
||||||
@selector(tableView:dataCellForTableColumn:row:)])
|
|
||||||
{
|
{
|
||||||
cell = [_delegate tableView: self dataCellForTableColumn: tb
|
cell = [_delegate tableView: self dataCellForTableColumn: tb row: rowIndex];
|
||||||
row: rowIndex];
|
|
||||||
}
|
}
|
||||||
if (cell == nil)
|
|
||||||
|
// If no cell and we're requesting a non-group cell...
|
||||||
|
if ((cell == nil) && tb)
|
||||||
{
|
{
|
||||||
cell = [tb dataCellForRow: rowIndex];
|
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;
|
return cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3574,13 +3589,8 @@ static inline float computePeriod(NSPoint mouseLocationWin,
|
||||||
|
|
||||||
- (NSUInteger)_hitTestForEvent:(NSEvent*)event atColumn:(NSInteger)column row:(NSInteger)row
|
- (NSUInteger)_hitTestForEvent:(NSEvent*)event atColumn:(NSInteger)column row:(NSInteger)row
|
||||||
{
|
{
|
||||||
NSTableColumn *tableColumn = ((column == -1) ? nil : [[self tableColumns] objectAtIndex:column]);
|
NSCell *cell = [self preparedCellAtColumn: column row: row];
|
||||||
NSCell *cell = [self _dataCellForTableColumn:tableColumn row:row];
|
NSRect cellFrame = [self frameOfCellAtColumn:(column == -1) ? 0 : column 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];
|
|
||||||
|
|
||||||
// Return the hit result...
|
// Return the hit result...
|
||||||
return([cell hitTestForEvent:event inRect:cellFrame ofView:self]);
|
return([cell hitTestForEvent:event inRect:cellFrame ofView:self]);
|
||||||
|
@ -3619,13 +3629,17 @@ static inline float computePeriod(NSPoint mouseLocationWin,
|
||||||
if ([theEvent type] == NSLeftMouseDown)
|
if ([theEvent type] == NSLeftMouseDown)
|
||||||
{
|
{
|
||||||
// If the cell processed the mouse hit...
|
// If the cell processed the mouse hit...
|
||||||
BOOL isGrouped = [[self delegate] tableView:self isGroupRow:_clickedRow];
|
NSInteger theColumn = _clickedColumn;
|
||||||
NSInteger theColumn = (isGrouped ? -1 : _clickedColumn);
|
BOOL responds = [[self delegate] respondsToSelector: @selector(tableView:isGroupRow:)];
|
||||||
NSUInteger hitResult = [self _hitTestForEvent:theEvent atColumn:theColumn row:_clickedRow];
|
|
||||||
|
// 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
|
// 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...
|
// 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
|
if ([theEvent type] == NSLeftMouseDown
|
||||||
|
|
Loading…
Reference in a new issue