CPTableView drag to reorder rows

11 views
Skip to first unread message

Luke

unread,
Jan 26, 2023, 2:59:09 PM1/26/23
to Cappuccino & Objective-J
I see some discussion in this group on how to configure tables for drag and drop. 
I followed most of the patterns I've found, but still when I try to drag a row on my table, it doesn't start a drag operation and just selects the rows that the mouse ends up traversing as I move it with the mouse down. 

Is there a simple example of how to get this working somewhere?  I'm finding it difficult to find - there is plenty of general test code, but not too many examples.

From what I've been able to glean, the magic incantation ought to involve:
- setting setVerticalMotionCanBeginDrag to yes on the table
- having a data source delegate attached to the table that will implement the methods to:
 - validateDrop
 - acceptDrop
 - draggingSession:willBegin (not sure if this is necessary though)
 - writeRowsWithIndexes

Most of this stuff seems to be to handle the results of a drag operation, but I don't even seem to be able to get one started atm. 
 

Luke

unread,
Jan 26, 2023, 4:27:58 PM1/26/23
to Cappuccino & Objective-J
... and I think I'm almost there.

Found an incarnation in the manual tests sources, per a suggestion in this group.

Drag is now starting visually and I think all that's left is for me to do some interactions with the ArrayController to get the operation to complete as intended (I have a bindings-based data source).

daboe01

unread,
Jan 27, 2023, 1:08:55 AM1/27/23
to Cappuccino & Objective-J
ICDDragAndDropTableViewDataType = @"ICDDragAndDropTableViewDataType";
[ICDTableView registerForDraggedTypes:[CPArray arrayWithObjects:ICDDragAndDropTableViewDataType]];
[ICDTableView setDataSource:self];
[ICDTableView setDelegate:self];

- (BOOL)tableView:(CPTableView)aTableView writeRowsWithIndexes:(CPIndexSet)rowIndexes toPasteboard:(CPPasteboard)pasteboard
{
    if (aTableView == ICDTableView)
    {
        var encodedData = [CPKeyedArchiver archivedDataWithRootObject:rowIndexes];
        [pasteboard declareTypes:[CPArray arrayWithObject:ICDDragAndDropTableViewDataType] owner:self];
        [pasteboard setData:encodedData forType:ICDDragAndDropTableViewDataType];

        return YES;
    }

    return NO;
}


- (CPDragOperation)tableView:(CPTableView)aTableView validateDrop:(id)info proposedRow:(CPInteger)row proposedDropOperation:(CPTableViewDropOperation)operation
{
    if (aTableView == ICDTableView)
    {
        [aTableView setDropRow:row dropOperation:CPTableViewDropAbove];
        return CPDragOperationMove;
    }

    return NO;
}


- (BOOL)tableView:(CPTableView)aTableView acceptDrop:(id)info row:(CPInteger)row dropOperation:(CPTableViewDropOperation)operation
{
    if (aTableView == ICDTableView)
    {
        var pasteboard = [info draggingPasteboard],
        encodedData = [pasteboard dataForType:ICDDragAndDropTableViewDataType],
        sourceIndexes = [CPKeyedUnarchiver unarchiveObjectWithData:encodedData];

        if (operation == CPTableViewDropAbove)
        {
            var a = [ICDPredictorController arrangedObjects];
            var maxCount = [a count]
            var indexArray = [];
            [sourceIndexes getIndexes:indexArray maxCount:maxCount inIndexRange:CPMakeRange(0, maxCount)];
            var index = indexArray[0];
            var o = [a objectAtIndex:index];
            [a removeObjectAtIndex:index];
            [a insertObject:o atIndex:MIN(row, maxCount - 1)];
            [ICDPredictorController setContent:a];
        }
       
        return YES;
    }

    return NO;
}


Luke

unread,
Jan 27, 2023, 10:31:22 AM1/27/23
to Cappuccino & Objective-J
:)  Thanks!

Yes, I have this working beautifully now.  Multi-row dragging to organize sequenced list of items.  As always with Cocoa/Cappuccino, you get huge payback from the richness of the components and the framework abstractions (like binding with proxy objects for handling multiple value selection).  However, boilerplate/patterns can often be tricky to bootstrap and samples are essential.  

Increasing divergence between Cappuccino and Apple's frameworks means that some pieces of the incantation can be different to what you might learn from Apple's guides too.
The "[tableView setVerticalMotionCanBeginDrag:YES];" requirement to get an actual drag started is an example I think.
Reply all
Reply to author
Forward
0 new messages