Reputation: 435
I've been banging my head to the wall for about two weeks, I've looked at all the Apple documentation available plus hundreds of websites looking for a hint to solve my problem. I'm implementing:
-(void)tableView:(NSTableView *)tableView draggingSession:(NSDraggingSession *)session willBeginAtPoint:(NSPoint)screenPoint forRowIndexes:(NSIndexSet *)rowIndexes
The problem that I'm having is that the icon for the dragged files shows up in a different coordinate system and I can't seem to find a way to make the icon show on the screenPoint where the drag began. I've looked into all [tableView convert* ] methods in several combinations without success. Below is the code I'm currently using.
-(void)tableView:(NSTableView *)tableView draggingSession:(NSDraggingSession *)session willBeginAtPoint:(NSPoint)screenPoint forRowIndexes:(NSIndexSet *)rowIndexes {
[session enumerateDraggingItemsWithOptions:NSDraggingItemEnumerationConcurrent
forView:tableView
classes:[NSArray arrayWithObjects:[NSPasteboardItem class], nil]
searchOptions:nil
usingBlock:^(NSDraggingItem *draggingItem, NSInteger index, BOOL *stop)
{
NSMutableArray *videos = [NSMutableArray array];
for (Video* video in [_arrayController selectedObjects]) {
[videos addObject:video.url];
}
NSImage *draggedImage = [[NSWorkspace sharedWorkspace]iconForFiles:videos];
NSPoint mouseLocInView = [tableView convertPoint:[tableView.window convertRectFromScreen:NSMakeRect(screenPoint.x,screenPoint.y, 0, 0)].origin fromView:nil];
NSLog(@"Mouse location in view: X: %f, Y: %f",mouseLocInView.x, mouseLocInView.y);
NSLog(@"Screen point: X: %f, Y:%f", screenPoint.x, screenPoint.y);
NSRect rect = NSMakeRect(0, 0, 50, 50);
rect.origin =draggingItem.draggingFrame.origin;
[draggingItem setDraggingFrame:rect contents:draggedImage];
session.draggingFormation = NSDraggingFormationDefault;
}];}
Upvotes: 2
Views: 821
Reputation: 463
I finally got it after thoroughly reading the documentation.
The doc for - enumerateDraggingItemsWithOptions:forView:classes:searchOptions:usingBlock: says that "forView:" argument is the view on which the coordinate system should be based for each NSDraggingItem passed. Pass nil for screen coordinate system.
What is very confusin is I was debugging by logging draggingFrame on draggingItem and couldn't figure out what frame it was. Well, it doesn't matter what is in there, if you pass nil as a view, you can set the dragging frame as screen based coordinates, the same you get when calling session.draggingLocation.
#define DRAG_IMAGE_WIDTH 48
#define DRAG_IMAGE_HEIGHT 48
- (void)tableView:(NSTableView *)tableView
draggingSession:(NSDraggingSession *)session
willBeginAtPoint:(NSPoint)screenPoint
forRowIndexes:(NSIndexSet *)rowIndexes {
NSImage *image = [NSImage imageNamed:@"tunnelfile"];
[session enumerateDraggingItemsWithOptions:NSDraggingItemEnumerationConcurrent
forView:nil
classes:[NSArray arrayWithObject:[NSPasteboardItem class]]
searchOptions:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:NSPasteboardURLReadingFileURLsOnlyKey ]
usingBlock:^(NSDraggingItem *draggingItem, NSInteger idx, BOOL *stop)
{
[draggingItem setDraggingFrame:NSMakeRect(session.draggingLocation.x-20,
session.draggingLocation.y-DRAG_IMAGE_HEIGHT+20,
DRAG_IMAGE_WIDTH,
DRAG_IMAGE_HEIGHT)
contents:image];
}];
}
Upvotes: 5