diff --git a/AppKit/CPTableColumn.j b/AppKit/CPTableColumn.j index 044c1d141..557212519 100644 --- a/AppKit/CPTableColumn.j +++ b/AppKit/CPTableColumn.j @@ -30,8 +30,8 @@ #include "CoreGraphics/CGGeometry.h" CPTableColumnNoResizing = 0; -CPTableColumnAutoresizingMask = 1; -CPTableColumnUserResizingMask = 2; +CPTableColumnAutoresizingMask = 1 << 0; +CPTableColumnUserResizingMask = 1 << 1; @implementation CPTableColumn : CPObject { @@ -50,6 +50,8 @@ CPTableColumnUserResizingMask = 2; CPSortDescriptor _sortDescriptorPrototype; BOOL _isHidden; CPString _headerToolTip; + + BOOL _disableResizingPosting @accessors(property=disableResizingPosting); } - (id)init @@ -68,7 +70,9 @@ CPTableColumnUserResizingMask = 2; _width = 100.0; _minWidth = 10.0; _maxWidth = 1000000.0; - + _resizingMask = CPTableColumnAutoresizingMask | CPTableColumnUserResizingMask; + _disableResizingPosting = NO; + [self setIdentifier:anIdentifier]; var header = [[_CPTableColumnHeaderView alloc] initWithFrame:CGRectMakeZero()]; @@ -79,6 +83,7 @@ CPTableColumnUserResizingMask = 2; [textDataView setValue:[CPColor whiteColor] forThemeAttribute:@"text-color" inState:CPThemeStateHighlighted]; [textDataView setValue:[CPFont boldSystemFontOfSize:12] forThemeAttribute:@"font" inState:CPThemeStateHighlighted]; [textDataView setValue:CPCenterVerticalTextAlignment forThemeAttribute:@"vertical-alignment"]; + [textDataView setValue:CGInsetMake(4.0, 8.0, 0.0, 8.0) forThemeAttribute:@"content-inset"]; [self setDataView:textDataView]; } @@ -116,18 +121,23 @@ CPTableColumnUserResizingMask = 2; if (tableView) { - var index = [[tableView tableColumns] indexOfObjectIdenticalTo:self]; - - // FIXME: THIS IS HORRIBLE. Don't just reload everything when a table column changes, just relayout the changed widths. - tableView._reloadAllRows = YES; - tableView._dirtyTableColumnRangeIndex = tableView._dirtyTableColumnRangeIndex < 0 ? index : MIN(index, tableView._dirtyTableColumnRangeIndex); - + var index = [[tableView tableColumns] indexOfObjectIdenticalTo:self], + dirtyTableColumnRangeIndex = tableView._dirtyTableColumnRangeIndex; + + if (dirtyTableColumnRangeIndex < 0) + tableView._dirtyTableColumnRangeIndex = index; + else + tableView._dirtyTableColumnRangeIndex = MIN(index, tableView._dirtyTableColumnRangeIndex); + + var rows = tableView._exposedRows, + columns = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(index, [tableView._exposedColumns lastIndex] - index + 1)]; + + // FIXME: Would be faster with some sort of -setNeedsDisplayInColumns: that updates a dirtyTableColumnForDisplay cache; then marked columns would relayout their data views at display time. + [tableView _layoutDataViewsInRows:rows columns:columns]; [tableView tile]; - - [[CPNotificationCenter defaultCenter] - postNotificationName:CPTableViewColumnDidResizeNotification - object:tableView - userInfo:[CPDictionary dictionaryWithObjects:[self, oldWidth] forKeys:[@"CPTableColumn", "CPOldWidth"]]]; + + if (!_disableResizingPosting) + [self _postDidResizeNotificationWithOldWidth:oldWidth]; } } @@ -183,7 +193,7 @@ CPTableColumnUserResizingMask = 2; _resizingMask = aResizingMask; } -- (float)resizingMask +- (unsigned)resizingMask { return _resizingMask; } @@ -255,9 +265,9 @@ CPTableColumnUserResizingMask = 2; var dataView = [self dataViewForRow:aRowIndex], dataViewUID = [dataView UID]; -var x = [self tableView]._cachedDataViews[dataViewUID]; -if (x && x.length) -return x.pop(); + var x = [self tableView]._cachedDataViews[dataViewUID]; + if (x && x.length) + return x.pop(); // if we haven't cached an archive of the data view, do it now if (!_dataViewData[dataViewUID]) @@ -265,7 +275,8 @@ return x.pop(); // unarchive the data view cache var newDataView = [CPKeyedUnarchiver unarchiveObjectWithData:_dataViewData[dataViewUID]]; -newDataView.identifier = dataViewUID; + newDataView.identifier = dataViewUID; + return newDataView; } @@ -345,6 +356,14 @@ newDataView.identifier = dataViewUID; return _headerToolTip; } +- (void)_postDidResizeNotificationWithOldWidth:(float)oldWidth +{ + [[CPNotificationCenter defaultCenter] + postNotificationName:CPTableViewColumnDidResizeNotification + object:[self tableView] + userInfo:[CPDictionary dictionaryWithObjects:[self, oldWidth] forKeys:[@"CPTableColumn", "CPOldWidth"]]]; +} + @end var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey", diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j index 79ebf6c49..2feda8741 100644 --- a/AppKit/CPTableHeaderView.j +++ b/AppKit/CPTableHeaderView.j @@ -36,7 +36,7 @@ var CPThemeStatePressed = CPThemeState("pressed"); self = [super initWithFrame:frame]; if (self) { - _textField = [[CPTextField alloc] initWithFrame:[self bounds]]; + _textField = [[CPTextField alloc] initWithFrame:CGRectMake(5, 1, CGRectGetWidth([self bounds]) - 5, CGRectGetHeight([self bounds]) - 1)]; [_textField setAutoresizingMask:CPViewWidthSizable|CPViewHeightSizable]; [_textField setTextColor: [CPColor colorWithHexString: @"333333"]]; [_textField setValue:[CPFont boldSystemFontOfSize:12.0] forThemeAttribute:@"font"]; @@ -99,6 +99,8 @@ var CPThemeStatePressed = CPThemeState("pressed"); int _pressedColumn @accessors(readonly, property=pressedColumn); float _draggedDistance @accessors(readonly, property=draggedDistance); + float _lastLocation; + float _columnOldWidth; CPTableView _tableView @accessors(property=tableView); } @@ -113,6 +115,9 @@ var CPThemeStatePressed = CPThemeState("pressed"); _draggedColumn = CPNotFound; _pressedColumn = CPNotFound; _draggedDistance = 0.0; + _lastLocation = nil; + _columnOldWidth = nil; + [self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview.png", CGSizeMake(1.0, 22.0))]]; } @@ -156,16 +161,22 @@ var CPThemeStatePressed = CPThemeState("pressed"); if (aColumnIndex < 0 || aColumnIndex > [tableColumns count]) [CPException raise:"invalid" reason:"tried to get headerRectOfColumn: on invalid column"]; - bounds.size.width = [tableColumns[aColumnIndex] width] + tableSpacing.width; - - while (--aColumnIndex >= 0) - bounds.origin.x += [tableColumns[aColumnIndex] width] + tableSpacing.width; - + // UPDATE COLUMN RANGES ? + if (_tableView._dirtyTableColumnRangeIndex !== CPNotFound) + [_tableView _recalculateTableColumnRanges]; + + var tableRange = _tableView._tableColumnRanges[aColumnIndex]; + bounds.origin.x = tableRange.location; + bounds.size.width = tableRange.length; + return bounds; } - (CPRect)_resizeRectBeforeColumn:(CPInteger)column { + if (!([_tableView._tableColumns[column] resizingMask] & CPTableColumnUserResizingMask)) + return CGRectMakeZero(); + var rect = [self headerRectOfColumn:column]; rect.origin.x -= 10; @@ -193,52 +204,168 @@ var CPThemeStatePressed = CPThemeState("pressed"); - (void)mouseDown:(CPEvent)theEvent { - var location = [self convertPoint:[theEvent locationInWindow] fromView:nil], - aPoint = CGPointMakeCopy(location), - clickedColumn = [self columnAtPoint:aPoint]; + var mouseLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil], + clickedColumn = [self columnAtPoint:mouseLocation]; if (clickedColumn == -1) return; - - // Error, can't find var CPTableViewDelegate_tableView_mouseDownInHeaderOfTableColumn_ !? - if (_tableView._implementedDelegateMethods & (1 << 6)) - [[_tableView delegate] tableView:_tableView - mouseDownInHeaderOfTableColumn:[[_tableView tableColumns] objectAtIndex:clickedColumn]]; - [self _setPressedColumn:clickedColumn]; + [_tableView _sendDelegateDidMouseDownInHeader:clickedColumn]; + + var resizeLocation = CGPointMake(mouseLocation.x + 10, mouseLocation.y), + resizedColumn = [self columnAtPoint:resizeLocation] - 1; + + // 2 different tracking methods: one for resizing/stop-resizing, another one for selection/reordering + if ([_tableView allowsColumnResizing] + && resizedColumn >= 0 + && CGRectContainsPoint([self _resizeRectBeforeColumn:(resizedColumn + 1)], mouseLocation)) + { + _resizedColumn = resizedColumn; + [_tableView._tableColumns[_resizedColumn] setDisableResizingPosting:YES]; + [self trackResizeWithEvent:theEvent]; + } + else + { + [self _setPressedColumn:clickedColumn]; + [self trackMouseWithEvent:theEvent]; + } } -- (void)mouseUp:(CPEvent)theEvent +- (void)trackMouseWithEvent:(CPEvent)theEvent { - var location = [self convertPoint:[theEvent locationInWindow] fromView:nil], - clickedColumn = [self columnAtPoint:location]; + var type = [theEvent type]; + + if (type == CPLeftMouseUp) + { + var location = [self convertPoint:[theEvent locationInWindow] fromView:nil], + clickedColumn = [self columnAtPoint:location]; - [self _setPressedColumn:CPNotFound]; - - if (clickedColumn == -1) - return; - - if ([_tableView allowsColumnSelection]) - { - if ([theEvent modifierFlags] & CPCommandKeyMask) - { - if ([_tableView isColumnSelected:clickedColumn]) - [_tableView deselectColumn:clickedColumn]; - else if ([_tableView allowsMultipleSelection] == YES) - [_tableView selectColumnIndexes:[CPIndexSet indexSetWithIndex:clickedColumn] byExtendingSelection:YES]; - } - else if ([theEvent modifierFlags] & CPShiftKeyMask) - { - // should be from clickedColumn to lastClickedColum with extending:(direction == previous selection) - var selectedIndexes = [_tableView selectedColumnIndexes], - startColumn = MIN(clickedColumn, [selectedIndexes lastIndex]), - endColumn = MAX(clickedColumn, [selectedIndexes firstIndex]); + [self _setPressedColumn:CPNotFound]; - [_tableView selectColumnIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(startColumn, endColumn - startColumn + 1)] byExtendingSelection:YES]; + if (clickedColumn == -1) + return; + + [_tableView _sendDelegateDidClickColumn:clickedColumn]; + + if ([_tableView allowsColumnSelection]) + { + if ([theEvent modifierFlags] & CPCommandKeyMask) + { + if ([_tableView isColumnSelected:clickedColumn]) + [_tableView deselectColumn:clickedColumn]; + else if ([_tableView allowsMultipleSelection] == YES) + [_tableView selectColumnIndexes:[CPIndexSet indexSetWithIndex:clickedColumn] byExtendingSelection:YES]; + } + else if ([theEvent modifierFlags] & CPShiftKeyMask) + { + // should be from clickedColumn to lastClickedColum with extending:(direction == previous selection) + var selectedIndexes = [_tableView selectedColumnIndexes], + startColumn = MIN(clickedColumn, [selectedIndexes lastIndex]), + endColumn = MAX(clickedColumn, [selectedIndexes firstIndex]); + + [_tableView selectColumnIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(startColumn, endColumn - startColumn + 1)] byExtendingSelection:YES]; + } + else + [_tableView selectColumnIndexes:[CPIndexSet indexSetWithIndex:clickedColumn] byExtendingSelection:NO]; + } + return; + } +/* + else if (type & CPLeftMouseDragged && [_tableView allowsColumnREordering]) + { + // Start dragging here + [[CPCursor closedHandCursor] set]; + return; + } +*/ + [CPApp setTarget:self selector:@selector(trackMouseWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPLeftMouseDownMask untilDate:nil inMode:nil dequeue:YES]; +} + +- (void)trackResizeWithEvent:(CPEvent)anEvent +{ + var location = [self convertPoint:[anEvent locationInWindow] fromView:nil], + tableColumn = [[_tableView tableColumns] objectAtIndex:_resizedColumn], + type = [anEvent type]; + + if (_lastLocation == nil) _lastLocation = location; + if (_columnOldWidth == nil) _columnOldWidth = [tableColumn width]; + + if (type === CPLeftMouseUp) + { + [self _updateResizeCursor:anEvent]; + + [tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth]; + [tableColumn setDisableResizingPosting:NO]; + + _resizedColumn = CPNotFound; + _lastLocation = nil; + _columnOldWidth = nil; + return; + } + else if (type === CPLeftMouseDragged) + { + var newWidth = [tableColumn width] + location.x - _lastLocation.x; + + if (newWidth >= [tableColumn minWidth]) + { + [tableColumn setWidth:newWidth]; + // FIXME: there has to be a better way to do this... + // We should refactor the auto resizing crap. + // We need to figure out the exact cocoa behavior here though. + [_tableView resizeWithOldSuperviewSize:[_tableView bounds]]; + _lastLocation = location; + + [[CPCursor resizeLeftRightCursor] set]; + [self setNeedsLayout]; + [self setNeedsDisplay:YES]; } else - [_tableView selectColumnIndexes:[CPIndexSet indexSetWithIndex:clickedColumn] byExtendingSelection:NO]; + [[CPCursor resizeRightCursor] set]; } + + [CPApp setTarget:self selector:@selector(trackResizeWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES]; +} + +- (void)_updateResizeCursor:(CPEvent)theEvent +{ + var mouseLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + + var mouseOverLocation = CGPointMake(mouseLocation.x + 10, mouseLocation.y), + overColumn = [self columnAtPoint:mouseOverLocation]; + + var isInside = (overColumn > 0 && CGRectContainsPoint([self _resizeRectBeforeColumn:overColumn], mouseLocation)); + if (isInside) + { + var column = [[_tableView tableColumns] objectAtIndex:overColumn - 1]; + if ([column width] == [column minWidth]) + [[CPCursor resizeRightCursor] set]; + else + [[CPCursor resizeLeftRightCursor] set]; + } + else + [[CPCursor arrowCursor] set]; +} + +- (void)viewDidMoveToWindow +{ + if ([_tableView allowsColumnResizing]) + [[self window] setAcceptsMouseMovedEvents:YES]; +} + +- (void)mouseEntered:(CPEvent)theEvent +{ + [self _updateResizeCursor:theEvent]; +} + +- (void)mouseMoved:(CPEvent)theEvent +{ + [self _updateResizeCursor:theEvent]; +} + +- (void)mouseExited:(CPEvent)theEvent +{ + // FIXME: we should use CPCursor push/pop (if previous currentCursor != arrow). + [[CPCursor arrowCursor] set]; } - (void)layoutSubviews diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index 53447782e..702bd313b 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -190,6 +190,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; SEL _doubleAction; unsigned _columnAutoResizingStyle; + CGPoint _originalMouseDownPoint; BOOL _verticalMotionCanDrag; unsigned _destinationDragStyle; BOOL _isSelectingSession; @@ -219,7 +220,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; _selectionHighlightMask = CPTableViewSelectionHighlightStyleRegular; [self setUsesAlternatingRowBackgroundColors:NO]; - [self setAlternatingRowBackgroundColors:[[CPColor whiteColor], [CPColor colorWithHexString:@"e4e7ff"]]]; + [self setAlternatingRowBackgroundColors:[[CPColor whiteColor], /*[CPColor colorWithHexString:@"e4e7ff"]*/ [CPColor colorWithHexString:@"f5f9fc"]]]; _tableColumns = []; _tableColumnRanges = []; @@ -237,7 +238,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; _rowHeight = 23.0; [self setSelectionHightlightColor:[CPColor selectionColor]]; - [self setGridColor:[CPColor grayColor]]; + [self setGridColor:[CPColor colorWithHexString:@"dce0e2"]]; [self setGridStyleMask:CPTableViewGridNone]; _headerView = [[CPTableHeaderView alloc] initWithFrame:CGRectMake(0, 0, [self bounds].size.width, _rowHeight)]; @@ -1179,6 +1180,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; return _CGRectMake(tableColumnRange.location, _CGRectGetMinY(rectOfRow), tableColumnRange.length, _CGRectGetHeight(rectOfRow)); } +//FIX ME: We should refactor this! - (void)resizeWithOldSuperviewSize:(CGSize)aSize { [super resizeWithOldSuperviewSize:aSize]; @@ -1528,6 +1530,24 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; return _delegate; } +- (void)_sendDelegateDidClickColumn:(int)column +{ + if (_implementedDelegateMethods & CPTableViewDelegate_tableView_didClickTableColumn_) + [_delegate tableView:self didClickTableColumn:_tableColumns[column]]; +} + +- (void)_sendDelegateDidDragColumn:(int)column +{ + if (_implementedDelegateMethods & CPTableViewDelegate_tableView_didDragTableColumn_) + [_delegate tableView:self didDragTableColumn:_tableColumns[column]]; +} + +- (void)_sendDelegateDidMouseDownInHeader:(int)column +{ + if (_implementedDelegateMethods & CPTableViewDelegate_tableView_mouseDownInHeaderOfTableColumn_) + [_delegate tableView:self mouseDownInHeaderOfTableColumn:_tableColumns[column]]; +} + //Highlightable Column Headers /* - (CPTableColumn)highlightedTableColumn @@ -1905,6 +1925,45 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; } } +- (void)_layoutDataViewsInRows:(CPIndexSet)rows columns:(CPIndexSet)columns +{ + var rowArray = [], + rowRects = [], + columnArray = []; + + [rows getIndexes:rowArray maxCount:-1 inIndexRange:nil]; + [columns getIndexes:columnArray maxCount:-1 inIndexRange:nil]; + + UPDATE_COLUMN_RANGES_IF_NECESSARY(); + + var columnIndex = 0, + columnsCount = columnArray.length; + + for (; columnIndex < columnsCount; ++columnIndex) + { + var column = columnArray[columnIndex], + tableColumn = _tableColumns[column], + tableColumnUID = [tableColumn UID], + dataViewsForTableColumn = _dataViewsForTableColumns[tableColumnUID], + columnRange = _tableColumnRanges[column]; + + var rowIndex = 0, + rowsCount = rowArray.length; + + for (; rowIndex < rowsCount; ++rowIndex) + { + var row = rowArray[rowIndex], + dataView = dataViewsForTableColumn[row], + frame = [dataView frame]; + + frame.origin.x = columnRange.location; + frame.size.width = columnRange.length; + + [dataView setFrame:frame]; + } + } +} + - (void)_commitDataViewObjectValue:(CPTextView)sender { [_dataSource tableView:self @@ -2196,7 +2255,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; } CGContextClosePath(context); - CGContextSetStrokeColor(context, [CPColor whiteColor]); + CGContextSetStrokeColor(context, [CPColor colorWithHexString:@"e5e5e5"]); CGContextStrokePath(context); } @@ -2289,17 +2348,17 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; else _selectionAnchorRow = row; + + //set ivars for startTrackingPoint and time... + _startTrackingPoint = aPoint; + _startTrackingTimestamp = new Date(); - - if (_implementedDataSourceMethods & CPTableViewDataSource_tableView_setObjectValue_forTableColumn_row_) { - _startTrackingPoint = aPoint; - _startTrackingTimestamp = new Date(); + if (_implementedDataSourceMethods & CPTableViewDataSource_tableView_setObjectValue_forTableColumn_row_) _trackingPointMovedOutOfClickSlop = NO; - } // if the table has drag support then we use mouseUp to select a single row. // otherwise it uses mouse down. - if(!(_implementedDataSourceMethods & CPTableViewDataSource_tableView_writeRowsWithIndexes_toPasteboard_)) + if (!(_implementedDataSourceMethods & CPTableViewDataSource_tableView_writeRowsWithIndexes_toPasteboard_)) [self _updateSelectionWithMouseAtRow:row]; [[self window] makeFirstResponder:self]; @@ -2323,62 +2382,58 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; */ - (BOOL)continueTracking:(CGPoint)lastPoint at:(CGPoint)aPoint { - var row = [self rowAtPoint:aPoint], - canSelect = YES; - - if ((_implementedDelegateMethods & CPTableViewDelegate_tableView_shouldSelectRow_)) - canSelect = [_delegate tableView:self shouldSelectRow:row]; - + var row = [self rowAtPoint:aPoint]; // begin the drag is the datasource lets us, we've move at least +-3px vertical or horizontal, or we're dragging from selected rows and we haven't begun a drag session - if - ( - (!_isSelectingSession && - (_implementedDataSourceMethods & CPTableViewDataSource_tableView_writeRowsWithIndexes_toPasteboard_) && - ( - (lastPoint.x - aPoint.x > 3 || (_verticalMotionCanDrag && ABS(lastPoint.y - aPoint.y) > 3)) - || ([_selectedRowIndexes containsIndex:row]) - )) - ) + if(!_isSelectingSession && _implementedDataSourceMethods & CPTableViewDataSource_tableView_writeRowsWithIndexes_toPasteboard_) { - if ([_selectedRowIndexes containsIndex:row]) - _draggedRowIndexes = [[CPIndexSet alloc] initWithIndexSet:_selectedRowIndexes]; - else - _draggedRowIndexes = [CPIndexSet indexSetWithIndex:row]; - - - //ask the datasource for the data - var pboard = [CPPasteboard pasteboardWithName:CPDragPboard]; - - if ([self canDragRowsWithIndexes:_draggedRowIndexes atPoint:aPoint] && [_dataSource tableView:self writeRowsWithIndexes:_draggedRowIndexes toPasteboard:pboard]) + if ( + (ABS(_startTrackingPoint.x - aPoint.x) > 4 || (_verticalMotionCanDrag && ABS(_startTrackingPoint.y - aPoint.y) > 4)) || + ([_selectedRowIndexes containsIndex:row]) + ) { - var currentEvent = [CPApp currentEvent], - offset = CPPointMakeZero(), - tableColumns = [_tableColumns objectsAtIndexes:_exposedColumns]; - - // We deviate from the default Cocoa implementation here by asking for a view in stead of an image - // We support both, but the view prefered over the image because we can mimic the rows we are dragging - // by re-creating the data views for the dragged rows - var view = [self dragViewForRowsWithIndexes:_draggedRowIndexes - tableColumns:tableColumns - event:currentEvent - offset:offset]; - - if (!view) + if ([_selectedRowIndexes containsIndex:row]) + _draggedRowIndexes = [[CPIndexSet alloc] initWithIndexSet:_selectedRowIndexes]; + else + _draggedRowIndexes = [CPIndexSet indexSetWithIndex:row]; + + + //ask the datasource for the data + var pboard = [CPPasteboard pasteboardWithName:CPDragPboard]; + + if ([self canDragRowsWithIndexes:_draggedRowIndexes atPoint:aPoint] && [_dataSource tableView:self writeRowsWithIndexes:_draggedRowIndexes toPasteboard:pboard]) { - var image = [self dragImageForRowsWithIndexes:_draggedRowIndexes - tableColumns:tableColumns - event:currentEvent - offset:offset]; - view = [[CPImageView alloc] initWithFrame:CPMakeRect(0, 0, [image size].width, [image size].height)]; - [view setImage:image]; + var currentEvent = [CPApp currentEvent], + offset = CPPointMakeZero(), + tableColumns = [_tableColumns objectsAtIndexes:_exposedColumns]; + + // We deviate from the default Cocoa implementation here by asking for a view in stead of an image + // We support both, but the view prefered over the image because we can mimic the rows we are dragging + // by re-creating the data views for the dragged rows + var view = [self dragViewForRowsWithIndexes:_draggedRowIndexes + tableColumns:tableColumns + event:currentEvent + offset:offset]; + + if (!view) + { + var image = [self dragImageForRowsWithIndexes:_draggedRowIndexes + tableColumns:tableColumns + event:currentEvent + offset:offset]; + view = [[CPImageView alloc] initWithFrame:CPMakeRect(0, 0, [image size].width, [image size].height)]; + [view setImage:image]; + } + + var bounds = [view bounds]; + var viewLocation = CPPointMake(aPoint.x - CGRectGetWidth(bounds)/2 + offset.x, aPoint.y - CGRectGetHeight(bounds)/2 + offset.y); + [self dragView:view at:viewLocation offset:CPPointMakeZero() event:[CPApp currentEvent] pasteboard:pboard source:self slideBack:YES]; + _startTrackingPoint = nil; + + return NO; } - - var bounds = [view bounds]; - var viewLocation = CPPointMake(aPoint.x - CGRectGetWidth(bounds)/2 + offset.x, aPoint.y - CGRectGetHeight(bounds)/2 + offset.y); - [self dragView:view at:viewLocation offset:CPPointMakeZero() event:[CPApp currentEvent] pasteboard:pboard source:self slideBack:YES]; - - return NO; } + else if (ABS(_startTrackingPoint.x - aPoint.x) < 5 && ABS(_startTrackingPoint.y - aPoint.y) < 5) + return YES; } _isSelectingSession = YES; @@ -2823,10 +2878,8 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; [self selectRowIndexes:[CPIndexSet indexSetWithIndex:i] byExtendingSelection:extend]; - if(i) - { + if(i >= 0) [self scrollRowToVisible:i]; - } } - (void)moveUp:(id)sender @@ -2872,10 +2925,8 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; [self selectRowIndexes:[CPIndexSet indexSetWithIndex:i] byExtendingSelection:extend]; - if(i) - { + if(i >= 0) [self scrollRowToVisible:i]; - } } - (void)deleteBackward:(id)sender diff --git a/Tests/Manual/TableTest/AppController.j b/Tests/Manual/TableTest/AppController.j index 313b286c7..765c91aa0 100644 --- a/Tests/Manual/TableTest/AppController.j +++ b/Tests/Manual/TableTest/AppController.j @@ -242,7 +242,7 @@ CPLogRegister(CPLogConsole); // if(rowIndex % 2 == 1) // return true; // else - return NO; + return YES; } - (BOOL)selectionShouldChangeInTableView:(CPTableView)aTableView @@ -278,6 +278,11 @@ CPLogRegister(CPLogConsole); return NO; } +- (void)tableView:(CPTableView)aTableView willDisplayView:(CPView)aView forTableColumn:(CPTableColumn)tableColumn row:(int)row +{ + CPLogConsole(_cmd + " column: " + [tableColumn identifier] + " row:" + row) +} + - (void)tableView:(CPTableView)aTableView setObjectValue:(id)aValue forTableColumn:(CPTableColumn)tableColumn row:(int)row {