1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #import "chrome/browser/ui/cocoa/tab_contents/web_contents_drag_source.h" 6 7 #include "app/mac/nsimage_cache.h" 8 #include "base/string_util.h" 9 #include "base/sys_string_conversions.h" 10 #include "chrome/browser/tab_contents/tab_contents_view_mac.h" 11 #include "content/browser/renderer_host/render_view_host.h" 12 #include "content/browser/tab_contents/tab_contents.h" 13 14 namespace { 15 16 // Make a drag image from the drop data. 17 // TODO(feldstein): Make this work 18 NSImage* MakeDragImage() { 19 // TODO(feldstein): Just a stub for now. Make it do something (see, e.g., 20 // WebKit/WebKit/mac/Misc/WebNSViewExtras.m: |-_web_DragImageForElement:...|). 21 22 // Default to returning a generic image. 23 return app::mac::GetCachedImageWithName(@"nav.pdf"); 24 } 25 26 // Flips screen and point coordinates over the y axis to work with webkit 27 // coordinate systems. 28 void FlipPointCoordinates(NSPoint& screenPoint, 29 NSPoint& localPoint, 30 NSView* view) { 31 NSRect viewFrame = [view frame]; 32 localPoint.y = NSHeight(viewFrame) - localPoint.y; 33 // Flip |screenPoint|. 34 NSRect screenFrame = [[[view window] screen] frame]; 35 screenPoint.y = NSHeight(screenFrame) - screenPoint.y; 36 } 37 38 } // namespace 39 40 41 @implementation WebContentsDragSource 42 43 - (id)initWithContentsView:(TabContentsViewCocoa*)contentsView 44 pasteboard:(NSPasteboard*)pboard 45 dragOperationMask:(NSDragOperation)dragOperationMask { 46 if ((self = [super init])) { 47 contentsView_ = contentsView; 48 DCHECK(contentsView_); 49 50 pasteboard_.reset([pboard retain]); 51 DCHECK(pasteboard_.get()); 52 53 dragOperationMask_ = dragOperationMask; 54 } 55 56 return self; 57 } 58 59 - (NSImage*)dragImage { 60 return MakeDragImage(); 61 } 62 63 - (void)fillPasteboard { 64 NOTIMPLEMENTED() << "Subclasses should implement fillPasteboard"; 65 } 66 67 - (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal { 68 return dragOperationMask_; 69 } 70 71 - (void)startDrag { 72 [self fillPasteboard]; 73 NSEvent* currentEvent = [NSApp currentEvent]; 74 75 // Synthesize an event for dragging, since we can't be sure that 76 // [NSApp currentEvent] will return a valid dragging event. 77 NSWindow* window = [contentsView_ window]; 78 NSPoint position = [window mouseLocationOutsideOfEventStream]; 79 NSTimeInterval eventTime = [currentEvent timestamp]; 80 NSEvent* dragEvent = [NSEvent mouseEventWithType:NSLeftMouseDragged 81 location:position 82 modifierFlags:NSLeftMouseDraggedMask 83 timestamp:eventTime 84 windowNumber:[window windowNumber] 85 context:nil 86 eventNumber:0 87 clickCount:1 88 pressure:1.0]; 89 [window dragImage:[self dragImage] 90 at:position 91 offset:NSZeroSize 92 event:dragEvent 93 pasteboard:pasteboard_ 94 source:self 95 slideBack:YES]; 96 } 97 98 - (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint 99 operation:(NSDragOperation)operation { 100 } 101 102 - (void)endDragAt:(NSPoint)screenPoint 103 operation:(NSDragOperation)operation { 104 [contentsView_ tabContents]->SystemDragEnded(); 105 106 RenderViewHost* rvh = [contentsView_ tabContents]->render_view_host(); 107 if (rvh) { 108 NSPoint localPoint = [contentsView_ convertPoint:screenPoint fromView: nil]; 109 FlipPointCoordinates(screenPoint, localPoint, contentsView_); 110 rvh->DragSourceEndedAt(localPoint.x, localPoint.y, 111 screenPoint.x, screenPoint.y, 112 static_cast<WebKit::WebDragOperation>(operation)); 113 } 114 115 // Make sure the pasteboard owner isn't us. 116 [pasteboard_ declareTypes:[NSArray array] owner:nil]; 117 } 118 119 - (void)moveDragTo:(NSPoint)screenPoint { 120 RenderViewHost* rvh = [contentsView_ tabContents]->render_view_host(); 121 if (rvh) { 122 NSPoint localPoint = [contentsView_ convertPoint:screenPoint fromView:nil]; 123 FlipPointCoordinates(screenPoint, localPoint, contentsView_); 124 rvh->DragSourceMovedTo(localPoint.x, localPoint.y, 125 screenPoint.x, screenPoint.y); 126 } 127 } 128 129 @end // @implementation WebContentsDragSource 130 131