mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-06-02 11:10:59 +00:00
Update NSTableView processing to handle grouped row cells
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/branches/gnustep_testplant_branch@37336 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
c216a53d91
commit
cdfe249de8
5 changed files with 489 additions and 352 deletions
|
@ -146,6 +146,13 @@ enum {
|
||||||
};
|
};
|
||||||
typedef NSUInteger NSImageScaling;
|
typedef NSUInteger NSImageScaling;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
NSCellHitNone = 0,
|
||||||
|
NSCellHitContentArea = 1 << 0,
|
||||||
|
NSCellHitEditableTextArea = 1 << 1,
|
||||||
|
NSCellHitTrackableArea = 1 << 2,
|
||||||
|
};
|
||||||
|
|
||||||
@interface NSCell : NSObject <NSCopying, NSCoding>
|
@interface NSCell : NSObject <NSCopying, NSCoding>
|
||||||
{
|
{
|
||||||
// Attributes
|
// Attributes
|
||||||
|
@ -503,6 +510,10 @@ typedef NSUInteger NSImageScaling;
|
||||||
- (void)setAllowsUndo:(BOOL)flag;
|
- (void)setAllowsUndo:(BOOL)flag;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if OS_API_VERSION(MAC_OS_X_VERSION_10_5, GS_API_LATEST)
|
||||||
|
- (NSUInteger)hitTestForEvent:(NSEvent *)event inRect:(NSRect)cellFrame ofView:(NSView *)controlView;
|
||||||
|
#endif
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -391,6 +391,12 @@ writeRowsWithIndexes: (NSIndexSet*)rows
|
||||||
namesOfPromisedFilesDroppedAtDestination: (NSURL *)dropDestination
|
namesOfPromisedFilesDroppedAtDestination: (NSURL *)dropDestination
|
||||||
forDraggedRowsWithIndexes: (NSIndexSet *)indexSet;
|
forDraggedRowsWithIndexes: (NSIndexSet *)indexSet;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if OS_API_VERSION(MAC_OS_X_VERSION_10_5, GS_API_LATEST)
|
||||||
|
- (BOOL)tableView:(NSTableView*)tableView isGroupRow:(NSInteger)row;
|
||||||
|
- (NSCell *)tableView:(NSTableView*)tableView dataCellForTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row;
|
||||||
|
- (NSIndexSet *)tableView:(NSTableView*)tableView selectionIndexesForProposedSelection:(NSIndexSet*)proposedSelectionIndexes;
|
||||||
|
#endif
|
||||||
@end
|
@end
|
||||||
|
|
||||||
APPKIT_EXPORT NSString *NSTableViewColumnDidMoveNotification;
|
APPKIT_EXPORT NSString *NSTableViewColumnDidMoveNotification;
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#import "AppKit/NSColor.h"
|
#import "AppKit/NSColor.h"
|
||||||
#import "AppKit/NSColorList.h"
|
#import "AppKit/NSColorList.h"
|
||||||
#import "AppKit/NSColorWell.h"
|
#import "AppKit/NSColorWell.h"
|
||||||
|
#import "AppKit/NSGradient.h"
|
||||||
#import "AppKit/NSGraphics.h"
|
#import "AppKit/NSGraphics.h"
|
||||||
#import "AppKit/NSImage.h"
|
#import "AppKit/NSImage.h"
|
||||||
#import "AppKit/NSMenuView.h"
|
#import "AppKit/NSMenuView.h"
|
||||||
|
@ -67,9 +68,8 @@
|
||||||
|
|
||||||
@interface NSTableView (Private)
|
@interface NSTableView (Private)
|
||||||
- (float *)_columnOrigins;
|
- (float *)_columnOrigins;
|
||||||
- (void) _willDisplayCell: (NSCell*)cell
|
- (void) _willDisplayCell: (NSCell*)cell forTableColumn: (NSTableColumn *)tb row: (int)index;
|
||||||
forTableColumn: (NSTableColumn *)tb
|
- (NSCell *) _dataCellForTableColumn: (NSTableColumn *)tb row: (int) rowIndex;
|
||||||
row: (int)index;
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface NSCell (Private)
|
@interface NSCell (Private)
|
||||||
|
@ -2640,11 +2640,46 @@ static NSDictionary *titleTextAttributes[3] = {nil, nil, nil};
|
||||||
if (endingColumn == -1)
|
if (endingColumn == -1)
|
||||||
endingColumn = numberOfColumns - 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];
|
||||||
|
if (cell)
|
||||||
|
{
|
||||||
|
id objectValue = [dataSource tableView: tableView objectValueForTableColumn: nil row: rowIndex];
|
||||||
|
[cell _setInEditing: NO];
|
||||||
|
[cell setShowsFirstResponder:NO];
|
||||||
|
[cell setFocusRingType:NSFocusRingTypeNone];
|
||||||
|
|
||||||
|
[tableView _willDisplayCell: cell forTableColumn: nil row: rowIndex];
|
||||||
|
[cell setObjectValue: objectValue];
|
||||||
|
|
||||||
|
// 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...
|
||||||
|
CGFloat startNum = 212.0 / 255.0;
|
||||||
|
CGFloat endNum = 217.0 / 255.0;
|
||||||
|
NSColor *startColor = [NSColor colorWithCalibratedRed:startNum green:startNum blue:startNum alpha:1.0];
|
||||||
|
NSColor *endColor = [NSColor colorWithCalibratedRed:endNum green:endNum blue:endNum alpha:1.0];
|
||||||
|
NSGradient *gradient = AUTORELEASE([[NSGradient alloc] initWithStartingColor:startColor endingColor:endColor]);
|
||||||
|
|
||||||
|
// Draw the group row...
|
||||||
|
[gradient drawInRect:drawingRect angle:90.0f];
|
||||||
|
[cell drawWithFrame: drawingRect inView: tableView];
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Draw the row between startingColumn and endingColumn */
|
/* Draw the row between startingColumn and endingColumn */
|
||||||
for (i = startingColumn; i <= endingColumn; i++)
|
for (i = startingColumn; i <= endingColumn; i++)
|
||||||
{
|
{
|
||||||
tb = [tableColumns objectAtIndex: i];
|
tb = [tableColumns objectAtIndex: i];
|
||||||
cell = [tb dataCellForRow: rowIndex];
|
cell = [tableView _dataCellForTableColumn:tb row:rowIndex];
|
||||||
if (i == editedColumn && rowIndex == editedRow)
|
if (i == editedColumn && rowIndex == editedRow)
|
||||||
{
|
{
|
||||||
[cell _setInEditing: YES];
|
[cell _setInEditing: YES];
|
||||||
|
|
|
@ -1597,6 +1597,43 @@ static NSColor *dtxtCol;
|
||||||
*interval = 0.1;
|
*interval = 0.1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSUInteger)hitTestForEvent:(NSEvent *)event inRect:(NSRect)cellFrame ofView:(NSView *)controlView
|
||||||
|
{
|
||||||
|
NSUInteger hitResult = NSCellHitNone;
|
||||||
|
NSPoint point = [controlView convertPoint:[event locationInWindow] fromView:nil];
|
||||||
|
|
||||||
|
switch (_cell.type)
|
||||||
|
{
|
||||||
|
case NSImageCellType:
|
||||||
|
{
|
||||||
|
NSRect checkFrame = [self imageRectForBounds:cellFrame];
|
||||||
|
if (NSPointInRect(point, checkFrame))
|
||||||
|
hitResult |= NSCellHitContentArea;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NSTextCellType:
|
||||||
|
{
|
||||||
|
NSString *stringValue = [self stringValue];
|
||||||
|
if (stringValue && [stringValue length])
|
||||||
|
{
|
||||||
|
NSRect checkFrame = [self titleRectForBounds:cellFrame];
|
||||||
|
if (NSPointInRect(point, checkFrame))
|
||||||
|
hitResult |= NSCellHitContentArea;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NSNullCellType:
|
||||||
|
default:
|
||||||
|
hitResult = NSCellHitContentArea;
|
||||||
|
// FIXME: If the cell not disabled, and it would track, OR in NSCellHitTrackableArea...
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(hitResult);
|
||||||
|
}
|
||||||
|
|
||||||
/**<p>Returns whether tracking starts. The NSCell implementation
|
/**<p>Returns whether tracking starts. The NSCell implementation
|
||||||
returns YES when the <var>startPoint</var> is into the control view
|
returns YES when the <var>startPoint</var> is into the control view
|
||||||
retangle, NO otherwise. This method is call at the early stage of
|
retangle, NO otherwise. This method is call at the early stage of
|
||||||
|
@ -2353,7 +2390,7 @@ static NSColor *dtxtCol;
|
||||||
_menu = TEST_RETAIN (_menu);
|
_menu = TEST_RETAIN (_menu);
|
||||||
_cell_image = TEST_RETAIN (_cell_image);
|
_cell_image = TEST_RETAIN (_cell_image);
|
||||||
_formatter = TEST_RETAIN (_formatter);
|
_formatter = TEST_RETAIN (_formatter);
|
||||||
_formatter = TEST_RETAIN (_represented_object);
|
_represented_object = TEST_RETAIN (_represented_object);
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3572,6 +3572,20 @@ static inline float computePeriod(NSPoint mouseLocationWin,
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (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];
|
||||||
|
|
||||||
|
// Return the hit result...
|
||||||
|
return([cell hitTestForEvent:event inRect:cellFrame ofView:self]);
|
||||||
|
}
|
||||||
|
|
||||||
- (void) mouseDown: (NSEvent *)theEvent
|
- (void) mouseDown: (NSEvent *)theEvent
|
||||||
{
|
{
|
||||||
NSPoint initialLocation = [theEvent locationInWindow];
|
NSPoint initialLocation = [theEvent locationInWindow];
|
||||||
|
@ -3602,6 +3616,18 @@ static inline float computePeriod(NSPoint mouseLocationWin,
|
||||||
_clickedRow = [self rowAtPoint: location];
|
_clickedRow = [self rowAtPoint: location];
|
||||||
_clickedColumn = [self columnAtPoint: location];
|
_clickedColumn = [self columnAtPoint: location];
|
||||||
|
|
||||||
|
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];
|
||||||
|
|
||||||
|
// 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 ([theEvent type] == NSLeftMouseDown
|
if ([theEvent type] == NSLeftMouseDown
|
||||||
&& clickCount > 1)
|
&& clickCount > 1)
|
||||||
{
|
{
|
||||||
|
@ -4463,14 +4489,23 @@ This method is deprecated, use -columnIndexesInRect:. */
|
||||||
|| (rowIndex > (_numberOfRows - 1)))
|
|| (rowIndex > (_numberOfRows - 1)))
|
||||||
return NSZeroRect;
|
return NSZeroRect;
|
||||||
|
|
||||||
|
// Setup the common frame values...
|
||||||
frameRect.origin.y = _bounds.origin.y + (rowIndex * _rowHeight);
|
frameRect.origin.y = _bounds.origin.y + (rowIndex * _rowHeight);
|
||||||
frameRect.origin.y += _intercellSpacing.height / 2;
|
frameRect.origin.y += _intercellSpacing.height / 2;
|
||||||
frameRect.size.height = _rowHeight - _intercellSpacing.height;
|
frameRect.size.height = _rowHeight - _intercellSpacing.height;
|
||||||
|
|
||||||
frameRect.origin.x = _columnOrigins[columnIndex];
|
frameRect.origin.x = _columnOrigins[columnIndex];
|
||||||
frameRect.origin.x += _intercellSpacing.width / 2;
|
frameRect.origin.x += _intercellSpacing.width / 2;
|
||||||
|
|
||||||
|
// Group rows take up the entire row...
|
||||||
|
if ([[self delegate] tableView:self isGroupRow:rowIndex] == YES)
|
||||||
|
{
|
||||||
|
frameRect.size.width = [self frame].size.width;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
frameRect.size.width = [[_tableColumns objectAtIndex: columnIndex] width];
|
frameRect.size.width = [[_tableColumns objectAtIndex: columnIndex] width];
|
||||||
frameRect.size.width -= _intercellSpacing.width;
|
frameRect.size.width -= _intercellSpacing.width;
|
||||||
|
}
|
||||||
|
|
||||||
// We add some space to separate the cell from the grid
|
// We add some space to separate the cell from the grid
|
||||||
if (_drawsGrid)
|
if (_drawsGrid)
|
||||||
|
@ -6627,16 +6662,29 @@ For a more detailed explanation, -setSortDescriptors:. */
|
||||||
|
|
||||||
- (BOOL) _shouldSelectRow: (int)rowIndex
|
- (BOOL) _shouldSelectRow: (int)rowIndex
|
||||||
{
|
{
|
||||||
if ([_delegate respondsToSelector:
|
BOOL shouldSelectRow = YES;
|
||||||
@selector (tableView:shouldSelectRow:)] == YES)
|
|
||||||
|
// Apple returns this result if delegate implements it, even if the delegate implements both...
|
||||||
|
if ([_delegate respondsToSelector: @selector (tableView:selectionIndexesForProposedSelection:)] == YES)
|
||||||
{
|
{
|
||||||
if ([_delegate tableView: self shouldSelectRow: rowIndex] == NO)
|
NSMutableIndexSet *proposedSelection = [NSMutableIndexSet indexSet];
|
||||||
{
|
|
||||||
return NO;
|
// Setup the proposed selection indexes...
|
||||||
|
[proposedSelection addIndexes:_selectedRows];
|
||||||
|
[proposedSelection addIndex:rowIndex];
|
||||||
|
|
||||||
|
// Get the delegates allowable selection indexes...
|
||||||
|
NSIndexSet *newSelection = [_delegate tableView:self selectionIndexesForProposedSelection:proposedSelection];
|
||||||
|
|
||||||
|
// And return whether we're allowed to select the new row...
|
||||||
|
shouldSelectRow = [newSelection containsIndex:rowIndex];
|
||||||
}
|
}
|
||||||
|
else if ([_delegate respondsToSelector: @selector (tableView:shouldSelectRow:)] == YES)
|
||||||
|
{
|
||||||
|
shouldSelectRow = [_delegate tableView: self shouldSelectRow: rowIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
return YES;
|
return shouldSelectRow;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) _shouldSelectionChange
|
- (BOOL) _shouldSelectionChange
|
||||||
|
@ -6718,7 +6766,7 @@ For a more detailed explanation, -setSortDescriptors:. */
|
||||||
row: (int) index
|
row: (int) index
|
||||||
{
|
{
|
||||||
id result = nil;
|
id result = nil;
|
||||||
GSKeyValueBinding *theBinding;
|
GSKeyValueBinding *theBinding = nil;
|
||||||
|
|
||||||
theBinding = [GSKeyValueBinding getBinding: NSValueBinding
|
theBinding = [GSKeyValueBinding getBinding: NSValueBinding
|
||||||
forObject: tb];
|
forObject: tb];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue