mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-09-17 16:11:28 +00:00
CPTableView: drag & drop improvements
- Default dragView containing dragged rows, works with discrete rows - scroll-as-you-drag feature - draggingEntered returns a drag operation. Rearranged a bit the code. - fixed dragPoint/target row - Modified test app so you can drag in both ways and also move indexes internally
This commit is contained in:
+179
-74
@@ -137,7 +137,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
|
||||
|
||||
BOOL _reloadAllRows;
|
||||
Object _objectValues;
|
||||
CPRange _exposedRows;
|
||||
CPIndexSet _exposedRows;
|
||||
CPIndexSet _exposedColumns;
|
||||
|
||||
Object _dataViewsForTableColumns;
|
||||
@@ -1057,10 +1057,6 @@ window.setTimeout(function(){
|
||||
{
|
||||
var y = aPoint.y;
|
||||
|
||||
if (NO)
|
||||
{
|
||||
}
|
||||
|
||||
var row = FLOOR(y / (_rowHeight + _intercellSpacing.height));
|
||||
|
||||
if (row >= _numberOfRows)
|
||||
@@ -1269,28 +1265,13 @@ window.setTimeout(function(){
|
||||
|
||||
- (void)scrollRowToVisible:(int)rowIndex
|
||||
{
|
||||
var scrollView = [[self superview] superview];
|
||||
|
||||
if ([scrollView isKindOfClass:[CPScrollView class]] && [scrollView documentView] === self)
|
||||
{
|
||||
var rect = CGRectMake([scrollView._contentView bounds].origin.x, rowIndex*[self rowHeight], 1, [self rowHeight]);
|
||||
[[[scrollView contentView] documentView] scrollRectToVisible: rect];
|
||||
}
|
||||
[self scrollRectToVisible:[self rectOfRow:rowIndex]];
|
||||
}
|
||||
|
||||
- (void)scrollColumnToVisible:(int)columnIndex
|
||||
{
|
||||
var rect = [self rectOfColumn:columnIndex];
|
||||
|
||||
var scrollView = [[self superview] superview];
|
||||
|
||||
if ([scrollView isKindOfClass:[CPScrollView class]] && [scrollView documentView] === self)
|
||||
{
|
||||
var rect = CGRectMake(rect.origin.x, [scrollView._contentView bounds].origin.y, rect.size.width, 1);
|
||||
[[[scrollView contentView] documentView] scrollRectToVisible: rect];
|
||||
|
||||
/*FIX ME: tableview header isn't rendered until you click the horizontal scroller (or scroll)*/
|
||||
}
|
||||
[self scrollRectToVisible:[self rectOfColumn:columnIndex]];
|
||||
/*FIX ME: tableview header isn't rendered until you click the horizontal scroller (or scroll)*/
|
||||
}
|
||||
|
||||
//Persistence
|
||||
@@ -1404,7 +1385,7 @@ window.setTimeout(function(){
|
||||
if ([_delegate respondsToSelector:@selector(tableViewColumnDidResize:)])
|
||||
[defaultCenter
|
||||
addObserver:_delegate
|
||||
selector:@selector(tableViewColumnDidMove:)
|
||||
selector:@selector(tableViewColumnDidResize:)
|
||||
name:CPTableViewColumnDidResizeNotification
|
||||
object:self];
|
||||
|
||||
@@ -1461,6 +1442,64 @@ window.setTimeout(function(){
|
||||
return image;
|
||||
}
|
||||
|
||||
- (CPImage)dragViewForRowsWithIndexes:(CPIndexSet)dragRows tableColumns:(CPArray)theTableColumns event:(CPEvent)dragEvent offset:(CPPointPointer)dragImageOffset
|
||||
{
|
||||
var draggedRowsArray = [],
|
||||
colCount = [theTableColumns count],
|
||||
rowsCount = [dragRows count],
|
||||
firstRowIndex = [dragRows firstIndex],
|
||||
rowIndexesLength = [dragRows lastIndex] - firstRowIndex + 1,
|
||||
|
||||
firstRowRect = [self rectOfRow:firstRowIndex],
|
||||
exposedMinX = CGRectGetMinX([self exposedClipRect]),
|
||||
dragViewWidth = CGRectGetWidth([self exposedClipRect]),
|
||||
dragViewHeight = rowIndexesLength * _rowHeight,
|
||||
|
||||
location = [self convertPoint:[dragEvent locationInWindow] fromView:nil];
|
||||
|
||||
dragImageOffset.x = exposedMinX + CGRectGetMinX(firstRowRect) - location.x + dragViewWidth/2;
|
||||
dragImageOffset.y = CGRectGetMinY(firstRowRect) - location.y + dragViewHeight/2;
|
||||
|
||||
var draggedView = [[CPView alloc] initWithFrame:CGRectMake(0, 0, dragViewWidth, dragViewHeight)];
|
||||
|
||||
[dragRows getIndexes:draggedRowsArray maxCount:-1 inIndexRange:CPMakeRange(firstRowIndex, rowIndexesLength)];
|
||||
|
||||
// calculate the dragImageOffset : we want the ghost row to be where the real row is.
|
||||
|
||||
for (var i = 0; i < rowsCount ; i++)
|
||||
{
|
||||
var rowIndex = draggedRowsArray[i];
|
||||
var dataViewOriginY = (rowIndex - firstRowIndex) * [self rowHeight];
|
||||
for (var c = 0; c < colCount; c++)
|
||||
{
|
||||
var column = [theTableColumns objectAtIndex:c],
|
||||
tableColumnUID = [column UID],
|
||||
dataView = _dataViewsForTableColumns[tableColumnUID][rowIndex];
|
||||
|
||||
var frame = [dataView frame];
|
||||
frame.origin.y = dataViewOriginY;
|
||||
frame.origin.x -= exposedMinX;
|
||||
|
||||
// Mega hack: The default CPView impl. doesn't implement -copy so we copy the innerHTML
|
||||
// It ok because it's a temporary view and we won't have to interact with it later ...
|
||||
// ... except we want the text to be normal when it's a selected row (unset the highlighted theme state)
|
||||
// and that does'nt work.
|
||||
// Possible fix: only for default dataviews (CPTextField), we can implement -copy and unset the state
|
||||
var html = dataView._DOMElement.innerHTML;
|
||||
var dataViewCopy = [[CPView alloc] initWithFrame:frame];
|
||||
dataViewCopy._DOMElement.innerHTML = html;
|
||||
|
||||
// This works (don't know how ?!). Until we fix the previous bug, we can stay with a white transparent bg
|
||||
// so at least we have a visible feedback of the dragged row. Maybe less opaque ...
|
||||
[dataViewCopy setBackgroundColor:[CPColor colorWithWhite:1 alpha:0.7]];
|
||||
|
||||
[draggedView addSubview:dataViewCopy];
|
||||
}
|
||||
}
|
||||
|
||||
return draggedView;
|
||||
}
|
||||
|
||||
- (void)setDraggingSourceOperationMask:(CPDragOperation)mask forLocal:(BOOL)isLocal
|
||||
{
|
||||
//ignoral local for the time being since only one capp app can run at a time...
|
||||
@@ -1793,7 +1832,11 @@ window.setTimeout(function(){
|
||||
[self drawBackgroundInClipRect:exposedRect];
|
||||
[self drawGridInClipRect:exposedRect];
|
||||
[self highlightSelectionInClipRect:exposedRect];
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)aRect
|
||||
{
|
||||
[_tableDrawView display];
|
||||
}
|
||||
|
||||
- (void)drawBackgroundInClipRect:(CGRect)aRect
|
||||
@@ -2097,7 +2140,7 @@ window.setTimeout(function(){
|
||||
var row = [self rowAtPoint:aPoint];
|
||||
|
||||
//if the user clicks outside a row then deslect everything
|
||||
if(row < 0 && _allowsEmptySelection)
|
||||
if (row < 0 && _allowsEmptySelection)
|
||||
[self selectRowIndexes:[CPIndexSet indexSet] byExtendingSelection:NO];
|
||||
|
||||
[self _noteSelectionIsChanging];
|
||||
@@ -2158,9 +2201,29 @@ window.setTimeout(function(){
|
||||
if([self canDragRowsWithIndexes:_draggedRowIndexes atPoint:aPoint] && [_dataSource tableView:self writeRowsWithIndexes:_draggedRowIndexes toPasteboard:pboard])
|
||||
{
|
||||
//create drag view/image
|
||||
var theDragImage = [self dragImageForRowsWithIndexes:_draggedRowIndexes tableColumns:_exposedColumns event:[CPApp currentEvent] offset:CGSizeMakeZero()];
|
||||
//we should begin the drag opperation here
|
||||
[self dragImage:theDragImage at:aPoint offset:CGSizeMakeZero() event:[CPApp currentEvent] pasteboard:pboard source:self slideBack:YES];
|
||||
var draggedColumns = [_tableColumns objectsAtIndexes:_exposedColumns];
|
||||
|
||||
var dragViewOffset = CGPointMakeZero();
|
||||
var theDragView = [self dragViewForRowsWithIndexes:_draggedRowIndexes tableColumns:draggedColumns event:[CPApp currentEvent] offset:dragViewOffset];
|
||||
|
||||
//we should begin the drag opperation here
|
||||
if (theDragView != nil) // special behavior: if the subclass returns nil, ask the subclass for an image
|
||||
{
|
||||
var bounds = [theDragView bounds];
|
||||
// Cocoa doc:"A dragImageOffset of NSZeroPoint will cause the image to be centered under the cursor."
|
||||
var dragViewLocation = CGPointMake(aPoint.x + dragViewOffset.x - CGRectGetWidth(bounds)/2, aPoint.y + dragViewOffset.y - CGRectGetHeight(bounds)/2);
|
||||
[self dragView:theDragView at:dragViewLocation offset:CGSizeMakeZero() event:[CPApp currentEvent] pasteboard:pboard source:self slideBack:YES];
|
||||
}
|
||||
else
|
||||
{
|
||||
var dragImageOffset = CGPointMakeZero();
|
||||
var theDragImage = [self dragImageForRowsWithIndexes:_draggedRowIndexes tableColumns:draggedColumns event:[CPApp currentEvent] offset:dragImageOffset];
|
||||
|
||||
var imageSize = [theDragImage size];
|
||||
var dragImageLocation = CGPointMake(aPoint.x + dragImageOffset.x - imageSize.width/2, aPoint.y + dragImageOffset.y - imageSize.height/2);
|
||||
|
||||
[self dragImage:theDragImage at:dragImageLocation offset:CGSizeMakeZero() event:[CPApp currentEvent] pasteboard:pboard source:self slideBack:YES];
|
||||
}
|
||||
//console.log([[CPDragServer sharedDragServer] draggingSource])
|
||||
// FIX ME: figure out what to do with the damn operation mask, does capp not support this yet?
|
||||
// FIX ME: set the operation mask to _dragOperationDefaultMask
|
||||
@@ -2259,7 +2322,28 @@ window.setTimeout(function(){
|
||||
*/
|
||||
- (CPDragOperation)draggingEntered:(id)sender
|
||||
{
|
||||
var dropOperation = [self _proposedDropOperation],
|
||||
draggingLocation = [sender draggingLocation],
|
||||
row;
|
||||
|
||||
var location = [self convertPoint:draggingLocation fromView:nil];
|
||||
|
||||
row = [self _proposedRowAtPoint:location];
|
||||
|
||||
if(_retargetedDropRow !== nil)
|
||||
row = _retargetedDropRow;
|
||||
|
||||
var draggedTypes = [self registeredDraggedTypes],
|
||||
count = [draggedTypes count],
|
||||
i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if ([[[sender draggingPasteboard] types] containsObject:[draggedTypes objectAtIndex: i]])
|
||||
return [self _validateDrop:sender proposedRow:row proposedDropOperation:dropOperation];
|
||||
}
|
||||
|
||||
return CPDragOperationNone;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2275,11 +2359,16 @@ window.setTimeout(function(){
|
||||
*/
|
||||
- (void)draggingEnded:(id)sender
|
||||
{
|
||||
_retargetedDropOperation = nil;
|
||||
_retargetedDropRow = nil;
|
||||
[_dropOperationFeedbackView setHidden:YES];
|
||||
[self _draggingEnded];
|
||||
}
|
||||
|
||||
- (void)_draggingEnded
|
||||
{
|
||||
_retargetedDropOperation = nil;
|
||||
_retargetedDropRow = nil;
|
||||
_draggedRowIndexes = [CPIndexSet indexSet];
|
||||
[_dropOperationFeedbackView setHidden:YES];
|
||||
}
|
||||
/*
|
||||
@ignore
|
||||
*/
|
||||
@@ -2304,58 +2393,75 @@ window.setTimeout(function(){
|
||||
/*
|
||||
@ignore
|
||||
*/
|
||||
- (CPInteger)_proposedRowAtPoint:(CGPoint)dragPoint
|
||||
{
|
||||
var numberOfRows = [self numberOfRows],
|
||||
row;
|
||||
// cocoa seems to jump to the next row when we approach the below row
|
||||
dragPoint.y += FLOOR(_rowHeight/4);
|
||||
|
||||
if (dragPoint.y > numberOfRows * (_rowHeight + _intercellSpacing.height))
|
||||
{
|
||||
if ([self _proposedDropOperation] === CPTableViewDropAbove)
|
||||
row = numberOfRows;
|
||||
else
|
||||
row = numberOfRows - 1;
|
||||
}
|
||||
else
|
||||
row = [self rowAtPoint:dragPoint];
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
- (void)_validateDrop:(id)info proposedRow:(CPInteger)row proposedDropOperation:(CPTableViewDropOperation)dropOperation
|
||||
{
|
||||
if(_implementedDataSourceMethods & CPTableViewDataSource_tableView_validateDrop_proposedRow_proposedDropOperation_)
|
||||
return [_dataSource tableView:self validateDrop:info proposedRow:row proposedDropOperation:dropOperation];
|
||||
|
||||
return CPDragOperationNone;
|
||||
}
|
||||
|
||||
- (CPDragOperation)draggingUpdated:(id)sender
|
||||
{
|
||||
var dropOperation = [self _proposedDropOperation],
|
||||
numberOfRows = [self numberOfRows],
|
||||
draggingLocation = [sender draggingLocation],
|
||||
dragOperation,
|
||||
row;
|
||||
|
||||
var location = [self convertPoint:draggingLocation fromView:nil];
|
||||
|
||||
var location = [sender draggingLocation],
|
||||
scrollview = [[self superview] superview],
|
||||
contentview = [scrollview contentView],
|
||||
dropOperation = [self _proposedDropOperation];
|
||||
|
||||
location = [contentview convertPoint:location fromView:nil];
|
||||
if(_headerView)
|
||||
location.y += CGRectGetHeight([_headerView bounds]);
|
||||
|
||||
var row = [self rowAtPoint:location] - 1;
|
||||
|
||||
//FIX ME: if the operation is CPTableViewDropAbove, we should be able to drop BELOW...
|
||||
if(row < 0 && dropOperation === CPTableViewDropOn)
|
||||
row = [self numberOfRows] - 1;
|
||||
else if(row < 0)
|
||||
row = [self numberOfRows] - 1;
|
||||
|
||||
if(!(_implementedDataSourceMethods & CPTableViewDataSource_tableView_validateDrop_proposedRow_proposedDropOperation_))
|
||||
var operation = CPDragOperationNone;
|
||||
else
|
||||
var operation = [_dataSource tableView:self validateDrop:sender proposedRow:row proposedDropOperation:dropOperation];
|
||||
|
||||
|
||||
|
||||
row = [self _proposedRowAtPoint:location];
|
||||
dragOperation = [self _validateDrop:sender proposedRow:row proposedDropOperation:dropOperation];
|
||||
|
||||
if(_retargetedDropRow !== nil)
|
||||
row = _retargetedDropRow;
|
||||
|
||||
//if the user forces -1 then we should highlight the whole tabelview
|
||||
var rowRect;
|
||||
if(_retargetedDropRow === -1)
|
||||
var rowRect = [self exposedClipRect];
|
||||
rowRect = [self exposedClipRect];
|
||||
else
|
||||
var rowRect = [self rectOfRow:row];
|
||||
rowRect = [self rectOfRow:row];
|
||||
|
||||
var exposedClipRect = [self exposedClipRect];
|
||||
var visibleWidth = _CGRectGetWidth(exposedClipRect);
|
||||
|
||||
if([[[self superview] superview] isKindOfClass:[CPScrollView class]])
|
||||
var visibleWidth = _CGRectGetWidth([[[self superview] superview] bounds]);
|
||||
else
|
||||
var visibleWidth = row.size.width;
|
||||
rowRect = _CGRectMake(_CGRectGetMinX(exposedClipRect), rowRect.origin.y, visibleWidth, rowRect.size.height);
|
||||
|
||||
rowRect = _CGRectMake(_CGRectGetMinX([self _exposedRect]), rowRect.origin.y, visibleWidth, rowRect.size.height);
|
||||
|
||||
[_dropOperationFeedbackView setDropOperation:[self _proposedDropOperation]];
|
||||
[_dropOperationFeedbackView setHidden:NO];
|
||||
[_dropOperationFeedbackView setDropOperation:dropOperation];
|
||||
[_dropOperationFeedbackView setHidden:(dragOperation == CPDragOperationNone)];
|
||||
[_dropOperationFeedbackView setFrame:rowRect];
|
||||
[_dropOperationFeedbackView setCurrentRow:row];
|
||||
[self addSubview:_dropOperationFeedbackView];
|
||||
|
||||
return operation;
|
||||
|
||||
|
||||
// FIXME : Maybe we should do this in a timer outside this method. Problem: we don't know when the scroll ends and neighter when the next -draggingUpdated is called. Which one will come first ?
|
||||
if (row > 0 && location.y - CGRectGetMinY(exposedClipRect) < _rowHeight)
|
||||
[self scrollRowToVisible:row - 1];
|
||||
else if (row < numberOfRows && CGRectGetMaxY(exposedClipRect) - location.y < _rowHeight)
|
||||
[self scrollRowToVisible:row + 1];
|
||||
|
||||
return dragOperation;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2376,11 +2482,9 @@ window.setTimeout(function(){
|
||||
- (BOOL)performDragOperation:(id)sender
|
||||
{
|
||||
var operation = [self _proposedDropOperation],
|
||||
location = [sender draggingLocation],
|
||||
scrollview = [[self superview] superview],
|
||||
contentview = [scrollview contentView];
|
||||
draggingLocation = [sender draggingLocation];
|
||||
|
||||
location = [contentview convertPoint:location fromView:scrollview];
|
||||
var location = [self convertPoint:draggingLocation fromView:nil];
|
||||
|
||||
if(_retargetedDropRow !== nil)
|
||||
var row = _retargetedDropRow;
|
||||
@@ -2412,7 +2516,8 @@ window.setTimeout(function(){
|
||||
we're using this because we drag views instead of images so we can get the rows themselves to actually drag
|
||||
*/
|
||||
- (void)draggedView:(CPImage)aView endedAt:(CGPoint)aLocation operation:(CPDragOperation)anOperation
|
||||
{
|
||||
{
|
||||
[self _draggingEnded];
|
||||
[self draggedImage:aView endedAt:aLocation operation:anOperation];
|
||||
}
|
||||
|
||||
@@ -2838,4 +2943,4 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
|
||||
//CGContextStrokeLineSegments(context, [aRect.origin.x + 8, aRect.origin.y + 8, 300 , aRect.origin.y + 8]);
|
||||
}
|
||||
}
|
||||
@end
|
||||
@end
|
||||
|
||||
@@ -22,13 +22,12 @@ CPLogRegister(CPLogConsole);
|
||||
dataSet1 = [],
|
||||
dataSet2 = [];
|
||||
|
||||
for(var i = 1; i < 11; i++)
|
||||
for(var i = 1; i < 100; i++)
|
||||
{
|
||||
dataSet1[i - 1] = i;
|
||||
dataSet2[i - 1] = i + 10;
|
||||
}
|
||||
|
||||
|
||||
var window1 = [[CPWindow alloc] initWithContentRect:CGRectMake(50, 50, 500, 400) styleMask:CPTitledWindowMask],
|
||||
view = [window1 contentView];
|
||||
|
||||
@@ -57,16 +56,12 @@ CPLogRegister(CPLogConsole);
|
||||
|
||||
iconImage = [[CPImage alloc] initWithContentsOfFile:"http://cappuccino.org/images/favicon.png" size:CGSizeMake(16,16)];
|
||||
|
||||
var textDataView = [CPTextField new];
|
||||
// [textDataView setFrameSize:CGSizeMake(200,32)];
|
||||
// [textDataView setValue:CGInsetMake(9.0, 7.0, 5.0, 8.0) forThemeAttribute:@"content-inset"];
|
||||
//[textDataView setValue:CGInsetMake(9.0, 7.0, 5.0, 8.0) forThemeAttribute:@"content-inset"];
|
||||
//[textDataView setValue:CGInsetMake(4.0, 4.0, 3.0, 4.0) forThemeAttribute:@"bezel-inset"];
|
||||
// [textDataView setValue:CGInsetMake(2, 0, 0, 0) forThemeAttribute:@"focus-inset"];
|
||||
// [textDataView setValue:CGInsetMake(0, 0, 0, 0) forThemeAttribute:@"focus-inset" inState:CPThemeStateBezeled|CPThemeStateEditing];
|
||||
|
||||
[textDataView setValue:[CPColor whiteColor] forThemeAttribute:@"text-color" inState:CPThemeStateHighlighted];
|
||||
[textDataView setValue:[CPFont systemFontOfSize:12] forThemeAttribute:@"font" inState:CPThemeStateHighlighted];
|
||||
|
||||
//[textDataView setValue:CGSizeMake(1,1) forThemeAttribute:@"text-shadow-offset"];
|
||||
//[textDataView setValue:[CPColor blackColor] forThemeAttribute:@"text-shadow-color" inState:CPThemeStateHighlighted];
|
||||
@@ -84,7 +79,6 @@ CPLogRegister(CPLogConsole);
|
||||
[column setWidth:200.0];
|
||||
[column setMinWidth:150.0];
|
||||
|
||||
[column setDataView:textDataView];
|
||||
[column setEditable:YES];
|
||||
[tableView addTableColumn:column];
|
||||
}
|
||||
@@ -94,7 +88,7 @@ CPLogRegister(CPLogConsole);
|
||||
[tableView setColumnAutoresizingStyle:CPTableViewUniformColumnAutoresizingStyle];
|
||||
|
||||
var scrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(100, 100, CGRectGetWidth([view bounds]), CGRectGetHeight([view bounds]))];
|
||||
[tableView setRowHeight:32.0];
|
||||
[tableView setRowHeight:22.0];
|
||||
[scrollView setDocumentView:tableView];
|
||||
[scrollView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
||||
|
||||
@@ -104,7 +98,6 @@ CPLogRegister(CPLogConsole);
|
||||
|
||||
[tableView setDelegate:self];
|
||||
[tableView setDataSource:self];
|
||||
[tableView setRowHeight:22.0];
|
||||
[tableView setVerticalMotionCanBeginDrag:NO];
|
||||
[tableView setDraggingDestinationFeedbackStyle:CPTableViewDropOn];
|
||||
[tableView registerForDraggedTypes:[CPArray arrayWithObject:tableTestDragType]];
|
||||
@@ -259,9 +252,19 @@ CPLogRegister(CPLogConsole);
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)tableViewSelectionDidChange:(id)blah
|
||||
- (void)tableViewSelectionDidChange:(id)notification
|
||||
{
|
||||
|
||||
CPLogConsole(_cmd + [notification description]);
|
||||
}
|
||||
|
||||
- (void)tableViewSelectionIsChanging:(id)notification
|
||||
{
|
||||
CPLogConsole(_cmd + [notification description]);
|
||||
}
|
||||
|
||||
- (void)tableViewColumnDidResize:(id)notification
|
||||
{
|
||||
CPLogConsole(_cmd + [notification description]);
|
||||
}
|
||||
|
||||
//- (CPIndexSet)tableView:(CPTableView)tableView selectionIndexesForProposedSelection:(CPIndexSet)proposedSelectionIndexes
|
||||
@@ -283,14 +286,7 @@ CPLogRegister(CPLogConsole);
|
||||
|
||||
- (BOOL)tableView:(CPTableView)aTableView writeRowsWithIndexes:(CPIndexSet)rowIndexes toPasteboard:(CPPasteboard)pboard
|
||||
{
|
||||
//var selectedRows = [aTableView selectedRowIndexes];
|
||||
[pboard declareTypes:[CPArray arrayWithObject:tableTestDragType] owner:self];
|
||||
|
||||
if(aTableView === tableView)
|
||||
var data = [dataSet1 objectsAtIndexes:rowIndexes];
|
||||
else if(aTableView === tableView2)
|
||||
var data = [dataSet2 objectsAtIndexes:rowIndexes];
|
||||
|
||||
var data = [rowIndexes, [aTableView UID]];
|
||||
|
||||
var encodedData = [CPKeyedArchiver archivedDataWithRootObject:data];
|
||||
[pboard declareTypes:[CPArray arrayWithObject:tableTestDragType] owner:self];
|
||||
@@ -306,42 +302,57 @@ CPLogRegister(CPLogConsole);
|
||||
{
|
||||
// console.log([aTableView rectOfRow:0]);
|
||||
//console.log(row)
|
||||
|
||||
[[aTableView window] orderFront:nil];
|
||||
|
||||
if(aTableView === tableView)
|
||||
[aTableView setDropRow:row dropOperation:CPTableViewDropOn];
|
||||
else
|
||||
[aTableView setDropRow:row dropOperation:CPTableViewDropAbove];
|
||||
|
||||
return CPDragOperationMove;
|
||||
}
|
||||
|
||||
- (BOOL)tableView:(CPTableView)aTableView acceptDrop:(id)info row:(int)row dropOperation:(CPTableViewDropOperation)operation
|
||||
{
|
||||
|
||||
{
|
||||
var pboard = [info draggingPasteboard],
|
||||
rowData = [pboard dataForType:tableTestDragType];
|
||||
rowData = [pboard dataForType:tableTestDragType],
|
||||
tables = [tableView, tableView2],
|
||||
dataSets = [dataSet1, dataSet2];
|
||||
|
||||
rowData = [CPKeyedUnarchiver unarchiveObjectWithData:rowData];
|
||||
|
||||
var sourceIndexes = rowData[0],
|
||||
sourceTableUID = rowData[1];
|
||||
|
||||
var index = (aTableView == tableView) ? 1 : 0;
|
||||
|
||||
var destinationTable = tables[1 - index],
|
||||
sourceTable = tables[index],
|
||||
destinationDataSet = dataSets[1 - index],
|
||||
sourceDataSet = dataSets[index];
|
||||
|
||||
//remember to check the operation/info
|
||||
if(aTableView === tableView)
|
||||
if(operation | CPDragOperationMove)
|
||||
{
|
||||
//[dataSet1 insertObjects:(CPArray)objects atIndexes:(CPIndexSet)indexes];
|
||||
}
|
||||
else if(aTableView === tableView2)
|
||||
{
|
||||
//setup indices
|
||||
|
||||
//console.log("drag source");
|
||||
//console.log([[CPDragServer sharedDragServer] draggingSource]);
|
||||
|
||||
var indices = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(row, [rowData count])];
|
||||
[dataSet2 insertObjects:rowData atIndexes:indices];
|
||||
|
||||
console.log(operation);
|
||||
if(operation | CPDragOperationMove)
|
||||
if (sourceTableUID == [aTableView UID])
|
||||
{
|
||||
[dataSet1 removeObjectsInArray:rowData];
|
||||
[tableView reloadData];
|
||||
[tableView selectRowIndexes:[CPIndexSet indexSet] byExtendingSelection:NO];
|
||||
[destinationDataSet moveIndexes:sourceIndexes toIndex:row];
|
||||
[destinationTable reloadData];
|
||||
var destIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(row, [sourceIndexes count])];
|
||||
[destinationTable selectRowIndexes:destIndexes byExtendingSelection:NO];
|
||||
}
|
||||
else
|
||||
{
|
||||
var destIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(row, [sourceIndexes count])];
|
||||
var sourceObjects = [sourceDataSet objectsAtIndexes:sourceIndexes];
|
||||
|
||||
[destinationDataSet insertObjects:sourceObjects atIndexes:destIndexes];
|
||||
[destinationTable reloadData];
|
||||
[destinationTable selectRowIndexes:destIndexes byExtendingSelection:NO];
|
||||
|
||||
[sourceDataSet removeObjectsAtIndexes:sourceIndexes];
|
||||
[sourceTable reloadData];
|
||||
[sourceTable selectRowIndexes:[CPIndexSet indexSet] byExtendingSelection:NO];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,4 +364,37 @@ CPLogRegister(CPLogConsole);
|
||||
//for convenience
|
||||
}
|
||||
|
||||
@end
|
||||
@end
|
||||
|
||||
@implementation CPArray (MoveIndexes)
|
||||
|
||||
- (void)moveIndexes:(CPIndexSet)indexes toIndex:(int)insertIndex
|
||||
{
|
||||
var aboveCount = 0,
|
||||
object,
|
||||
removeIndex;
|
||||
|
||||
var index = [indexes lastIndex];
|
||||
|
||||
while (index != CPNotFound)
|
||||
{
|
||||
if (index >= insertIndex)
|
||||
{
|
||||
removeIndex = index + aboveCount;
|
||||
aboveCount ++;
|
||||
}
|
||||
else
|
||||
{
|
||||
removeIndex = index;
|
||||
insertIndex --;
|
||||
}
|
||||
|
||||
object = [self objectAtIndex:removeIndex];
|
||||
[self removeObjectAtIndex:removeIndex];
|
||||
[self insertObject:object atIndex:insertIndex];
|
||||
|
||||
index = [indexes indexLessThanIndex:index];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user