Greetings,
Are you looking to capture inbound drags from outside your app, or drag from (for example) an NSTableView to an NSOutlineView?
Doing a drag internally just involves your source view's datasource (for a tableView in this case, obviously) implementing:
# Drag source
def tableView(aView, writeRows:rows, toPasteboard:pboard)
dragging = rows.collect {|row| @all_rows[row].identifier}
data = NSArchiver.archivedDataWithRootObject(dragging)
pboard.declareTypes(['NSGeneralPboardType'], owner:nil)
pboard.setData(data, forType:'NSGeneralPboardType')
true
end
Your destination data source needs to call something like this (I do it in awakeFromNib):
outline.registerForDraggedTypes(["NSGeneralPboardType"])
Then implement something like this (there's some semi-complex logic here to prevent dropping on top levels, represented by hashes, in my outline; you could ignore that, but it nicely demonstrates some useful tricks like re-targeting drops):
# Drag and drop stuff
def outlineView(outlineView, validateDrop:info, proposedItem:item, proposedChildIndex:index)
return NSDragOperationNone if (item.nil? || item.is_a?(Hash))
if(index != -1)
nearest_index = (index == 0) ? 0 : index-1
prior = self.outlineView(self, child:nearest_index, ofItem:item)
outlineView.setDropItem(prior, dropChildIndex:NSOutlineViewDropOnItemIndex)
end
return NSDragOperationEvery
end
def outlineView(outlineView, acceptDrop:info, item:item, childIndex:index)
data = info.draggingPasteboard.dataForType('NSGeneralPboardType')
rows = NSUnarchiver.unarchiveObjectWithData(data)
NSLog("%@", rows)
rows.each do |row|
# Stuff
end
return true
end
That's how to drag from table to outline. The table-side validateDrop and acceptDrop methods are subtly different; I can paste up code from them if you'd like. My table is only accepting drops from outside the application, though, so it behaves a little differently than intra-application drag/drop.
Actually, that's pretty easy, although the 'devil' is in the details of how to process 'info' in the acceptDrop method...
In awakeFromNib, since I'm interested in browser-drag-sources, I do this (yes, this can just be [...] as in the previous code, instead of NSA.aWO'ing it):
view.registerForDraggedTypes(
NSArray.arrayWithObjects("BookmarkDictionaryListPboardType", "MozURLType",
NSFilenamesPboardType, NSURLPboardType, NSStringPboardType, nil))
then...
def tableView(aView, validateDrop:info, proposedRow:row, proposedDropOperation:op)
NSDragOperationEvery
end
def tableView(aView, acceptDrop:info, row:row, dropOperation:op)
# Accept the drop
return true
end
I hope the formatting is preserved at least somewhat, if not this is likely to get ugly... :)
-- Morgan