diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j index b0b0db4d5..6e33d0483 100644 --- a/AppKit/CPTableHeaderView.j +++ b/AppKit/CPTableHeaderView.j @@ -349,15 +349,18 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal CPLog.debug(@"start drag"); var tableColumn = [[[self tableView] tableColumns] objectAtIndex:aColumnIndex], - columnRect = [self headerRectOfColumn:aColumnIndex], - // offset = CPSizeMake(_mouseDownLocation.x - aPoint.x, _mouseDownLocation.y); + columnRect = [self headerRectOfColumn:aColumnIndex]; - var frame = CPRectMake(0.0, 0.0, [tableColumn width], CPRectGetHeight([[self tableView] bounds])), - view = [[CPView alloc] initWithFrame:frame]; - - [view setBackgroundColor:[CPColor greenColor]]; + var offset = CPPointMakeZero(), + view = [[self tableView] dragViewForTableColumns:[tableColumn] event:[CPApp currentEvent] offset:offset], + viewLocation = CPPointMakeZero(); - [self dragView:view at:aPoint offset:CPSizeMake(0.0, 0.0) event:[CPApp currentEvent] + viewLocation.x = ( CPRectGetMinX(columnRect) + offset.x ) + ( aPoint.x - _mouseDownLocation.x ); + viewLocation.y = CPRectGetMinY(columnRect) + offset.y; + + [view setAlphaValue:0.7]; + + [self dragView:view at:viewLocation offset:CPSizeMakeZero() event:[CPApp currentEvent] pasteboard:[CPPasteboard pasteboardWithName:CPDragPboard] source:self slideBack:YES]; return NO; @@ -366,10 +369,33 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal return YES; } +- (void)_constrainDragView:(CPView)theDragView at:(CPPoint)aPoint +{ + var tableColumns = [[self tableView] tableColumns], + lastColumnRect = [self headerRectOfColumn:[tableColumns indexOfObjectIdenticalTo:[tableColumns lastObject]]], + dragWindow = [theDragView window], + frame = [dragWindow frame]; + + // Because the drag window is as wide as the entire tableview, it's start origin is always 0.0 + // The minimal x coordinate is the minimal dragged table columns negated x value + var minimumX = -(CPRectGetMinX([self headerRectOfColumn:_activeColumn])) + maximumX = CPRectGetMinX(lastColumnRect); + + // This effectively clamps the value between the minimal and maximum + // frame.origin.x = MAX(minimumX, MIN(CPRectGetMinX(frame), maximumX)); + + // Make sure the column cannot move vertically + frame.origin.y = CPRectGetMinY([self convertRect:lastColumnRect toView:nil]); + + [dragWindow setFrame:frame]; +} + - (void)draggedView:(CPView)aView movedTo:(CPPoint)aPoint { + [self _constrainDragView:aView at:aPoint]; + var hoveredColumn = [self columnAtPoint:aPoint], - if (_activeColumn === hoveredColumn) + if (hoveredColumn === -1 || _activeColumn === hoveredColumn) return; var columnRect = [self headerRectOfColumn:hoveredColumn], diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index b3c6add2a..11a6cab8f 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -1803,7 +1803,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; return [[CPImage alloc] initWithContentsOfFile:@"Frameworks/AppKit/Resources/GenericFile.png" size:CGSizeMake(32,32)]; } -- (CPView)dragViewForRowsWithIndexes:(CPIndexSet)theDraggedRows tableColumns:(CPArray)theTableColumns event:(CPEvent)theDragEvent offset:(CPPoint)dragViewOffset +- (CPView)dragViewForRowsWithIndexes:(CPIndexSet)theDraggedRows tableColumns:(CPArray)theTableColumns event:(CPEvent)theDragEvent offset:(CPPointPointer)dragViewOffset { var bounds = [self bounds], view = [[CPView alloc] initWithFrame:bounds]; @@ -1839,6 +1839,57 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; return view; } +- (CPView)dragViewForTableColumns:(CPArray)theTableColumns event:(CPEvent)theDragEvent offset:(CPPointPointer)theDragViewOffset +{ + var bounds = CPRectMake(0.0, 0.0, 0.0, CPRectGetHeight([self bounds]) + 23.0); + index = [theTableColumns count], + dragView = [[CPView alloc] initWithFrame:CPRectMakeZero()]; + + // Fetch all the data views for the columns and visible rows + // After that copy these add them to a transparent drag view and use that drag view + // to make it appear we are dragging images of those rows (as you would do in regular Cocoa) + while (index--) + { + // Get the tablecolumn and create a rect with it's width so we can use CPRectUnion + // to determine the end result + var tableColumn = [theTableColumns objectAtIndex:index], + columnIndex = [[self tableColumns] indexOfObjectIdenticalTo:tableColumn]; + columnRect = [self rectOfColumn:columnIndex], + headerView = [tableColumn headerView]; + + // Add the column header view + columnHeaderView = [[_CPTableColumnHeaderView alloc] initWithFrame:[headerView frame]]; + [columnHeaderView setStringValue:[headerView stringValue]]; + [columnHeaderView setThemeState:[headerView themeState]]; + [dragView addSubview:columnHeaderView]; + + bounds = CPRectUnion(bounds, columnRect); + + row = [_exposedRows firstIndex]; + while (row !== CPNotFound) + { + var dataView = [self _newDataViewForRow:row tableColumn:tableColumn], + dataViewFrame = [self frameOfDataViewAtColumn:columnIndex row:row]; + + // Offset by table header height to make room for the table header + dataViewFrame.origin.y += 23.0; + [dataView setFrame:dataViewFrame]; + + [dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]]; + [dragView addSubview:dataView]; + + row = [_exposedRows indexGreaterThanIndex:row]; + } + } + + // The columns are placed in the drag window at their original locations resulting in the dragged column + // being of when started the drag, we compensate for this by offseting the drag window by the x coordinate of the column + theDragViewOffset.x -= columnRect.origin.x; + [dragView setFrame:bounds]; + + return dragView; +} + - (void)setDraggingSourceOperationMask:(CPDragOperation)mask forLocal:(BOOL)isLocal { //ignoral local for the time being since only one capp app can run at a time...