diff options
author | feldstein@chromium.org <feldstein@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-07 03:43:51 +0000 |
---|---|---|
committer | feldstein@chromium.org <feldstein@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-07 03:43:51 +0000 |
commit | eda74d6837b1d8915a15f1a0598d1ce3c99b5cb0 (patch) | |
tree | 22f0a72166f5f9b34e37974489b991319ec16baf /chrome/browser/cocoa | |
parent | c3c91a64cba4f083f0aed48a7c4719303dd89e7d (diff) | |
download | chromium_src-eda74d6837b1d8915a15f1a0598d1ce3c99b5cb0.zip chromium_src-eda74d6837b1d8915a15f1a0598d1ce3c99b5cb0.tar.gz chromium_src-eda74d6837b1d8915a15f1a0598d1ce3c99b5cb0.tar.bz2 |
Initial implementation of Drag and Drop for the extension BMM.
Review URL: http://codereview.chromium.org/660139
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40858 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/cocoa')
-rw-r--r-- | chrome/browser/cocoa/bookmark_drag_source.h | 30 | ||||
-rw-r--r-- | chrome/browser/cocoa/bookmark_drag_source.mm | 43 | ||||
-rw-r--r-- | chrome/browser/cocoa/web_contents_drag_source.h | 65 | ||||
-rw-r--r-- | chrome/browser/cocoa/web_contents_drag_source.mm | 131 | ||||
-rw-r--r-- | chrome/browser/cocoa/web_drop_target.mm | 18 |
5 files changed, 287 insertions, 0 deletions
diff --git a/chrome/browser/cocoa/bookmark_drag_source.h b/chrome/browser/cocoa/bookmark_drag_source.h new file mode 100644 index 0000000..fde2086 --- /dev/null +++ b/chrome/browser/cocoa/bookmark_drag_source.h @@ -0,0 +1,30 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import <Cocoa/Cocoa.h> + +#include "chrome/browser/bookmarks/bookmark_drag_data.h" +#include "chrome/browser/cocoa/web_contents_drag_source.h" + +// A class that handles tracking and event processing for a drag and drop +// originating from the content area. +@interface BookmarkDragSource : WebContentsDragSource { + @private + // Our drop data. Should only be initialized once. + std::vector<BookmarkDragData::Element> dropData_; + + Profile* profile_; +} + +// Initialize a DragDataSource object for a drag (originating on the given +// contentsView and with the given dropData and pboard). Fill the pasteboard +// with data types appropriate for dropData. +- (id)initWithContentsView:(TabContentsViewCocoa*)contentsView + dropData: + (const std::vector<BookmarkDragData::Element>&)dropData + profile:(Profile*)profile + pasteboard:(NSPasteboard*)pboard + dragOperationMask:(NSDragOperation)dragOperationMask; + +@end diff --git a/chrome/browser/cocoa/bookmark_drag_source.mm b/chrome/browser/cocoa/bookmark_drag_source.mm new file mode 100644 index 0000000..81e55e6 --- /dev/null +++ b/chrome/browser/cocoa/bookmark_drag_source.mm @@ -0,0 +1,43 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "chrome/browser/cocoa/bookmark_drag_source.h" + +#include "chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/tab_contents/tab_contents_view_mac.h" + +@implementation BookmarkDragSource + +- (id)initWithContentsView:(TabContentsViewCocoa*)contentsView + dropData: + (const std::vector<BookmarkDragData::Element>&)dropData + profile:(Profile*)profile + pasteboard:(NSPasteboard*)pboard + dragOperationMask:(NSDragOperation)dragOperationMask { + self = [super initWithContentsView:contentsView + pasteboard:pboard + dragOperationMask:dragOperationMask]; + if (self) { + dropData_ = dropData; + profile_ = profile; + } + + return self; +} + +- (void)fillPasteboard { + bookmark_pasteboard_helper_mac::WriteToDragClipboard(dropData_, + profile_->GetPath().value()); +} + +- (NSImage*)dragImage { + // TODO(feldstein): Do something better than this. Should have badging + // and a single drag image. + // http://crbug.com/37264 + return [NSImage imageNamed:NSImageNameMultipleDocuments]; +} + +@end // @implementation BookmarkDragSource + diff --git a/chrome/browser/cocoa/web_contents_drag_source.h b/chrome/browser/cocoa/web_contents_drag_source.h new file mode 100644 index 0000000..8d451ea --- /dev/null +++ b/chrome/browser/cocoa/web_contents_drag_source.h @@ -0,0 +1,65 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_COCOA_WEB_CONTENTS_DRAG_SOURCE_H_ +#define CHROME_BROWSER_COCOA_WEB_CONTENTS_DRAG_SOURCE_H_ + +#import <Cocoa/Cocoa.h> + +#include "app/download_file_interface.h" +#include "base/file_path.h" +#include "base/scoped_nsobject.h" +#include "base/scoped_ptr.h" +#include "chrome/browser/bookmarks/bookmark_drag_data.h" + +@class TabContentsViewCocoa; + +// A class that handles tracking and event processing for a drag and drop +// originating from the content area. Subclasses should implement +// fillClipboard and dragImage. +@interface WebContentsDragSource : NSObject { + @private + // Our tab. Weak reference (owns or co-owns us). + TabContentsViewCocoa* contentsView_; + + // Our pasteboard. + scoped_nsobject<NSPasteboard> pasteboard_; + + // A mask of the allowed drag operations. + NSDragOperation dragOperationMask_; +} + +// Initialize a DragDataSource object for a drag (originating on the given +// contentsView and with the given dropData and pboard). Fill the pasteboard +// with data types appropriate for dropData. +- (id)initWithContentsView:(TabContentsViewCocoa*)contentsView + pasteboard:(NSPasteboard*)pboard + dragOperationMask:(NSDragOperation)dragOperationMask; + +// Creates the drag image. Implemented by the subclass. +- (NSImage*)dragImage; + +// Put the data being dragged onto the pasteboard. Implemented by the +// subclass. +- (void)fillPasteboard; + +// Returns a mask of the allowed drag operations. +- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal; + +// Start the drag (on the originally provided contentsView); can do this right +// after -initWithContentsView:.... +- (void)startDrag; + +// End the drag and clear the pasteboard; hook up to +// -draggedImage:endedAt:operation:. +- (void)endDragAt:(NSPoint)screenPoint + operation:(NSDragOperation)operation; + +// Drag moved; hook up to -draggedImage:movedTo:. +- (void)moveDragTo:(NSPoint)screenPoint; + +@end + +#endif // define CHROME_BROWSER_COCOA_WEB_CONTENTS_DRAG_SOURCE_H_ + diff --git a/chrome/browser/cocoa/web_contents_drag_source.mm b/chrome/browser/cocoa/web_contents_drag_source.mm new file mode 100644 index 0000000..8bc883c --- /dev/null +++ b/chrome/browser/cocoa/web_contents_drag_source.mm @@ -0,0 +1,131 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "chrome/browser/cocoa/web_contents_drag_source.h" + +#include "base/file_path.h" +#include "base/nsimage_cache_mac.h" +#include "base/string_util.h" +#include "base/sys_string_conversions.h" +#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/tab_contents/tab_contents_view_mac.h" + +namespace { + +// Make a drag image from the drop data. +// TODO(feldstein): Make this work +NSImage* MakeDragImage() { + // TODO(feldstein): Just a stub for now. Make it do something (see, e.g., + // WebKit/WebKit/mac/Misc/WebNSViewExtras.m: |-_web_DragImageForElement:...|). + + // Default to returning a generic image. + return nsimage_cache::ImageNamed(@"nav.pdf"); +} + +// Flips screen and point coordinates over the y axis to work with webkit +// coordinate systems. +void FlipPointCoordinates(NSPoint& screenPoint, + NSPoint& localPoint, + NSView* view) { + NSRect viewFrame = [view frame]; + localPoint.y = NSHeight(viewFrame) - localPoint.y; + // Flip |screenPoint|. + NSRect screenFrame = [[[view window] screen] frame]; + screenPoint.y = NSHeight(screenFrame) - screenPoint.y; +} + +} // namespace + + +@implementation WebContentsDragSource + +- (id)initWithContentsView:(TabContentsViewCocoa*)contentsView + pasteboard:(NSPasteboard*)pboard + dragOperationMask:(NSDragOperation)dragOperationMask { + if ((self = [super init])) { + contentsView_ = contentsView; + DCHECK(contentsView_); + + pasteboard_.reset([pboard retain]); + DCHECK(pasteboard_.get()); + + dragOperationMask_ = dragOperationMask; + } + + return self; +} + +- (NSImage*)dragImage { + return MakeDragImage(); +} + +- (void)fillPasteboard { + NOTIMPLEMENTED() << "Subclasses should implement fillPasteboard"; +} + +- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal { + return dragOperationMask_; +} + +- (void)startDrag { + [self fillPasteboard]; + NSEvent* currentEvent = [NSApp currentEvent]; + + // Synthesize an event for dragging, since we can't be sure that + // [NSApp currentEvent] will return a valid dragging event. + NSWindow* window = [contentsView_ window]; + NSPoint position = [window mouseLocationOutsideOfEventStream]; + NSTimeInterval eventTime = [currentEvent timestamp]; + NSEvent* dragEvent = [NSEvent mouseEventWithType:NSLeftMouseDragged + location:position + modifierFlags:NSLeftMouseDraggedMask + timestamp:eventTime + windowNumber:[window windowNumber] + context:nil + eventNumber:0 + clickCount:1 + pressure:1.0]; + [window dragImage:[self dragImage] + at:position + offset:NSZeroSize + event:dragEvent + pasteboard:pasteboard_ + source:self + slideBack:YES]; +} + +- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint + operation:(NSDragOperation)operation { +} + +- (void)endDragAt:(NSPoint)screenPoint + operation:(NSDragOperation)operation { + RenderViewHost* rvh = [contentsView_ tabContents]->render_view_host(); + if (rvh) { + rvh->DragSourceSystemDragEnded(); + + NSPoint localPoint = [contentsView_ convertPoint:screenPoint fromView: nil]; + FlipPointCoordinates(screenPoint, localPoint, contentsView_); + rvh->DragSourceEndedAt(localPoint.x, localPoint.y, + screenPoint.x, screenPoint.y, + static_cast<WebKit::WebDragOperation>(operation)); + } + + // Make sure the pasteboard owner isn't us. + [pasteboard_ declareTypes:[NSArray array] owner:nil]; +} + +- (void)moveDragTo:(NSPoint)screenPoint { + RenderViewHost* rvh = [contentsView_ tabContents]->render_view_host(); + if (rvh) { + NSPoint localPoint = [contentsView_ convertPoint:screenPoint fromView:nil]; + FlipPointCoordinates(screenPoint, localPoint, contentsView_); + rvh->DragSourceMovedTo(localPoint.x, localPoint.y, + screenPoint.x, screenPoint.y); + } +} + +@end // @implementation WebContentsDragSource + diff --git a/chrome/browser/cocoa/web_drop_target.mm b/chrome/browser/cocoa/web_drop_target.mm index fa08c69..06e0a98 100644 --- a/chrome/browser/cocoa/web_drop_target.mm +++ b/chrome/browser/cocoa/web_drop_target.mm @@ -5,6 +5,7 @@ #import "chrome/browser/cocoa/web_drop_target.h" #include "base/sys_string_conversions.h" +#include "chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h" #include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/tab_contents/tab_contents.h" #import "third_party/mozilla/include/NSPasteboard+Utils.h" @@ -78,6 +79,12 @@ using WebKit::WebDragOperationsMask; return NSDragOperationNone; } + // If the tab is showing the boomark manager, send BookmarkDrag events + RenderViewHostDelegate::BookmarkDrag* dragDelegate = + tabContents_->GetBookmarkDragDelegate(); + if(dragDelegate) + dragDelegate->OnDragEnter(NULL); + // Fill out a WebDropData from pasteboard. WebDropData data; [self populateWebDropData:&data fromPasteboard:[info draggingPasteboard]]; @@ -132,6 +139,11 @@ using WebKit::WebDragOperationsMask; gfx::Point(screenPoint.x, screenPoint.y), static_cast<WebDragOperationsMask>(mask)); + // If the tab is showing the boomark manager, send BookmarkDrag events + RenderViewHostDelegate::BookmarkDrag* dragDelegate = + tabContents_->GetBookmarkDragDelegate(); + if(dragDelegate) + dragDelegate->OnDragOver(NULL); return current_operation_; } @@ -153,6 +165,12 @@ using WebKit::WebDragOperationsMask; return NO; } + // If the tab is showing the boomark manager, send BookmarkDrag events + RenderViewHostDelegate::BookmarkDrag* dragDelegate = + tabContents_->GetBookmarkDragDelegate(); + if(dragDelegate) + dragDelegate->OnDrop(NULL); + currentRVH_ = NULL; // Create the appropriate mouse locations for WebCore. The draggingLocation |