0

Mac: Make image dragging 162.4% more awesome.

Also needs a webkit patch to do anything ( https://bugs.webkit.org/show_bug.cgi?id=37069 ), but can be landed independently.

BUG=11457,18992
TEST=(all require the webkit patch, so this won't work yet)
http://html5demos.com/drag and http://ljouanneau.com/lab/html5/demodragdrop.html
  Dragging should show image
http://www.google.com/
  Dragging google image should show image
http://www.travelvivi.com/wp-content/uploads/2009/09/Eiffel_Tower.jpg
  Dragging image should work, drag image should be smaller than image itself
Random website
  Mark some text, drag it. Should show drag cursor and no image

Review URL: http://codereview.chromium.org/1539018

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@43631 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
thakis@chromium.org
2010-04-05 18:45:33 +00:00
parent 0a6d4ce880
commit 78043bddf1
5 changed files with 44 additions and 17 deletions

@ -23,6 +23,12 @@ struct WebDropData;
// Our drop data. Should only be initialized once.
scoped_ptr<WebDropData> dropData_;
// The image to show as drag image. Can be nil.
scoped_nsobject<NSImage> dragImage_;
// The offset to draw |dragImage_| at.
NSPoint imageOffset_;
// Our pasteboard.
scoped_nsobject<NSPasteboard> pasteboard_;
@ -41,6 +47,8 @@ struct WebDropData;
// with data types appropriate for dropData.
- (id)initWithContentsView:(TabContentsViewCocoa*)contentsView
dropData:(const WebDropData*)dropData
image:(NSImage*)image
offset:(NSPoint)offset
pasteboard:(NSPasteboard*)pboard
dragOperationMask:(NSDragOperation)dragOperationMask;

@ -35,16 +35,6 @@ namespace {
// |NSURLPboardType|.
NSString* const kNSURLTitlePboardType = @"public.url-name";
// Make a drag image from the drop data.
// TODO(viettrungluu): Move this somewhere more sensible.
NSImage* MakeDragImage(const WebDropData* drop_data) {
// TODO(viettrungluu): 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");
}
// Returns a filename appropriate for the drop data
// TODO(viettrungluu): Refactor to make it common across platforms,
// and move it somewhere sensible.
@ -122,6 +112,8 @@ void PromiseWriterTask::Run() {
- (id)initWithContentsView:(TabContentsViewCocoa*)contentsView
dropData:(const WebDropData*)dropData
image:(NSImage*)image
offset:(NSPoint)offset
pasteboard:(NSPasteboard*)pboard
dragOperationMask:(NSDragOperation)dragOperationMask {
if ((self = [super init])) {
@ -131,6 +123,9 @@ void PromiseWriterTask::Run() {
dropData_.reset(new WebDropData(*dropData));
DCHECK(dropData_.get());
dragImage_.reset([image retain]);
imageOffset_ = offset;
pasteboard_.reset([pboard retain]);
DCHECK(pasteboard_.get());
@ -225,6 +220,13 @@ void PromiseWriterTask::Run() {
clickCount:1
pressure:1.0];
if (dragImage_) {
position.x -= imageOffset_.x;
// Deal with Cocoa's flipped coordinate system.
position.y -= [dragImage_.get() size].height - imageOffset_.y;
}
// Per kwebster, offset arg is ignored, see -_web_DragImageForElement: in
// third_party/WebKit/WebKit/mac/Misc/WebNSViewExtras.m.
[window dragImage:[self dragImage]
at:position
offset:NSZeroSize
@ -386,7 +388,11 @@ void PromiseWriterTask::Run() {
}
- (NSImage*)dragImage {
return MakeDragImage(dropData_.get());
if (dragImage_)
return dragImage_;
// Default to returning a generic image.
return nsimage_cache::ImageNamed(@"nav.pdf");
}
@end // @implementation WebDragSource (Private)

@ -26,6 +26,7 @@
#include "chrome/common/notification_type.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/render_messages.h"
#include "skia/ext/skia_utils_mac.h"
#import "third_party/mozilla/include/NSPasteboard+Utils.h"
using WebKit::WebDragOperation;
@ -49,7 +50,9 @@ COMPILE_ASSERT_MATCHING_ENUM(DragOperationEvery);
- (void)registerDragTypes;
- (void)setCurrentDragOperation:(NSDragOperation)operation;
- (void)startDragWithDropData:(const WebDropData&)dropData
dragOperationMask:(NSDragOperation)operationMask;
dragOperationMask:(NSDragOperation)operationMask
image:(NSImage*)image
offset:(NSPoint)offset;
- (void)cancelDeferredClose;
- (void)closeTabAfterEvent;
@end
@ -141,10 +144,12 @@ void TabContentsViewMac::StartDragging(
// The drag invokes a nested event loop, arrange to continue
// processing events.
MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
// TODO(estade): make use of |image| and |image_offset|.
NSDragOperation mask = static_cast<NSDragOperation>(allowed_operations);
NSPoint offset = NSPointFromCGPoint(image_offset.ToCGPoint());
[cocoa_view_ startDragWithDropData:drop_data
dragOperationMask:mask];
dragOperationMask:mask
image:gfx::SkBitmapToNSImage(image)
offset:offset];
}
void TabContentsViewMac::RenderViewCreated(RenderViewHost* host) {
@ -376,10 +381,14 @@ void TabContentsViewMac::Observe(NotificationType type,
}
- (void)startDragWithDropData:(const WebDropData&)dropData
dragOperationMask:(NSDragOperation)operationMask {
dragOperationMask:(NSDragOperation)operationMask
image:(NSImage*)image
offset:(NSPoint)offset {
dragSource_.reset([[WebDragSource alloc]
initWithContentsView:self
dropData:&dropData
image:image
offset:offset
pasteboard:[NSPasteboard pasteboardWithName:NSDragPboard]
dragOperationMask:operationMask]);
[dragSource_ startDrag];

@ -128,6 +128,8 @@
#include "gfx/native_theme_win.h"
#elif defined(USE_X11)
#include "third_party/WebKit/WebKit/chromium/public/linux/WebRenderTheme.h"
#elif defined(OS_MACOSX)
#include "skia/ext/skia_utils_mac.h"
#endif
using appcache::WebApplicationCacheHostImpl;
@ -1905,8 +1907,7 @@ void RenderView::startDragging(const WebDragData& data,
#if WEBKIT_USING_SKIA
SkBitmap bitmap(image.getSkBitmap());
#elif WEBKIT_USING_CG
// Needs implementing: http://crbug.com/11457
SkBitmap bitmap;
SkBitmap bitmap = gfx::CGImageToSkBitmap(image.getCGImageRef());
#endif
Send(new ViewHostMsg_StartDragging(routing_id_,

@ -168,6 +168,9 @@ SkBitmap NSImageToSkBitmap(NSImage* image, NSSize size, bool is_opaque) {
}
NSImage* SkBitmapToNSImage(const SkBitmap& skiaBitmap) {
if (skiaBitmap.isNull())
return nil;
// First convert SkBitmap to CGImageRef.
CGImageRef cgimage = SkCreateCGImageRef(skiaBitmap);