Rich Catalano
Rich Catalano

Reputation: 1147

NSTableView and NSOutlineView drag-and-drop

I have an NSTableView and an NSOutlineView, both with their content provided by bindings, that I'd like to have some drag-and-drop functionality:

I've read Apple's drag-and-drop documentation and gotten just about nowhere. It doesn't really seem to apply to what I need to do. What am I missing?

Upvotes: 8

Views: 6061

Answers (3)

Stephan
Stephan

Reputation: 4263

In MacOS 10.7 some new protocols were added to implement this.

There is a lack of documentation for tables at the moment but you can find some nice examples:

For NSTableViwew the Protocol NSTableViewDataSource defines the following methods:

  • (BOOL)tableView:writeRowsWithIndexes:toPasteboard:
  • tableView:validateDrop:proposedRow:proposedDropOperation:
  • tableView:acceptDrop:row:dropOperation:

For NSOutlineView the Protocol NSOutlineViewDataSource defines the following methods:

  • (BOOL)outlineView:writeItems:toPasteboard:
  • (NSDragOperation)outlineView:validateDrop:proposedItem:proposedChildIndex:
  • (BOOL)outlineView:acceptDrop:item:childIndex:

These are the minimum requirements to implement for each view type. The use cases are quite similar.

  1. If the toPasteboard: method returns YES, the drag is started.
  2. The validateDrop: method controls which target node is allowed by updating the marker in the view
  3. Return YES for the acceptDrop: method if the drop was successful

This lead to two sub-usecases you have to manage. The first one is a drag & drop within the same view or the same operation between two views. Additionally you may distinguish between move, copy or delete operations. A nice example is how the breakpoints work with drag & drop in Xcode.

The tableView has some additional methods to customize drag & drop, but the ones I mentioned are the key methods to get it working.

Upvotes: 6

Peter Hosey
Peter Hosey

Reputation: 96333

You need a data source—AFAIK, you can't make this happen with Bindings alone.

The unfinished Adium Xtras Creator, which is under the BSD license, includes an array controller that you can set as the data source to get drag-and-drop in a Bindings-powered table view.

This requirement may not apply to NSOutlineView and NSTreeController. I haven't tried that.

Upvotes: 5

Jim Puls
Jim Puls

Reputation: 81082

The page you linked to is pretty clear about what you need to do. In table A's data source, implement registerForDraggedTypes: and tableView:writeRowsWithIndexes:toPasteboard: to put some private TableAPasteboardType data on the pasteboard.

In outline B's data source, implement the same two methods and put some private OutlineBPasteboardType data on the pasteboard.

Finally, implement tableView:validateDrop:proposedRow:proposedDropOperation: and tableView:acceptDrop:row:dropOperation: to check the pasteboard for either TableAPasteboardType or OutlineBPasteboardType and make the appropriate changes to your bound model, depending.

It's pretty straightforward once you just plow in and do it.

Upvotes: 7

Related Questions