summaryrefslogtreecommitdiffstats
path: root/ui/base/dragdrop
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-05 05:37:26 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-05 05:37:26 +0000
commitf68e5d85edd4fb2e47ff01346d7138429c1ec5c4 (patch)
tree38191ef62fc83ad1a6c32015e29be187b5160e04 /ui/base/dragdrop
parentbd2fb568f441498d0cf542b9c8db9d718f9c6475 (diff)
downloadchromium_src-f68e5d85edd4fb2e47ff01346d7138429c1ec5c4.zip
chromium_src-f68e5d85edd4fb2e47ff01346d7138429c1ec5c4.tar.gz
chromium_src-f68e5d85edd4fb2e47ff01346d7138429c1ec5c4.tar.bz2
Move most of ui/views/drag_utils to ui/base/dragdrop so it can be used outside of views. I tried to move SetURLAndDragImage as well, but that would cause a lot of code duplication from Views' TextButton class that would make us worse off (things like mirroring and limiting size).
BUG=98716 Review URL: https://chromiumcodereview.appspot.com/9582041 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@124923 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/base/dragdrop')
-rw-r--r--ui/base/dragdrop/drag_utils.cc72
-rw-r--r--ui/base/dragdrop/drag_utils.h56
-rw-r--r--ui/base/dragdrop/drag_utils_aura.cc26
-rw-r--r--ui/base/dragdrop/drag_utils_gtk.cc46
-rw-r--r--ui/base/dragdrop/drag_utils_win.cc72
5 files changed, 272 insertions, 0 deletions
diff --git a/ui/base/dragdrop/drag_utils.cc b/ui/base/dragdrop/drag_utils.cc
new file mode 100644
index 0000000..70cfb7a
--- /dev/null
+++ b/ui/base/dragdrop/drag_utils.cc
@@ -0,0 +1,72 @@
+// Copyright (c) 2011 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.
+
+#include "ui/base/dragdrop/drag_utils.h"
+
+#include "base/file_util.h"
+#include "base/logging.h"
+#include "base/utf_string_conversions.h"
+#include "googleurl/src/gurl.h"
+#include "ui/base/dragdrop/os_exchange_data.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/canvas_skia.h"
+#include "ui/gfx/font.h"
+#include "ui/gfx/point.h"
+#include "ui/gfx/size.h"
+
+namespace drag_utils {
+
+// Maximum width of the link drag image in pixels.
+static const int kLinkDragImageVPadding = 3;
+
+// File dragging pixel measurements
+static const int kFileDragImageMaxWidth = 200;
+static const SkColor kFileDragImageTextColor = SK_ColorBLACK;
+
+void CreateDragImageForFile(const FilePath& file_name,
+ const SkBitmap* icon,
+ ui::OSExchangeData* data_object) {
+ DCHECK(icon);
+ DCHECK(data_object);
+
+ // Set up our text portion
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ gfx::Font font = rb.GetFont(ResourceBundle::BaseFont);
+
+ const int width = kFileDragImageMaxWidth;
+ // Add +2 here to allow room for the halo.
+ const int height = font.GetHeight() + icon->height() +
+ kLinkDragImageVPadding + 2;
+ gfx::CanvasSkia canvas(gfx::Size(width, height), false /* translucent */);
+
+ // Paint the icon.
+ canvas.DrawBitmapInt(*icon, (width - icon->width()) / 2, 0);
+
+ string16 name = file_name.BaseName().LossyDisplayName();
+#if defined(OS_WIN)
+ // Paint the file name. We inset it one pixel to allow room for the halo.
+ canvas.DrawStringWithHalo(name, font, kFileDragImageTextColor, SK_ColorWHITE,
+ 1, icon->height() + kLinkDragImageVPadding + 1,
+ width - 2, font.GetHeight(),
+ gfx::Canvas::TEXT_ALIGN_CENTER);
+#else
+ canvas.DrawStringInt(name, font, kFileDragImageTextColor,
+ 0, icon->height() + kLinkDragImageVPadding,
+ width, font.GetHeight(), gfx::Canvas::TEXT_ALIGN_CENTER);
+#endif
+
+ SetDragImageOnDataObject(canvas, gfx::Size(width, height),
+ gfx::Point(width / 2, kLinkDragImageVPadding),
+ data_object);
+}
+
+void SetDragImageOnDataObject(const gfx::Canvas& canvas,
+ const gfx::Size& size,
+ const gfx::Point& cursor_offset,
+ ui::OSExchangeData* data_object) {
+ SetDragImageOnDataObject(
+ canvas.AsCanvasSkia()->ExtractBitmap(), size, cursor_offset, data_object);
+}
+
+} // namespace drag_utils
diff --git a/ui/base/dragdrop/drag_utils.h b/ui/base/dragdrop/drag_utils.h
new file mode 100644
index 0000000..b81511d
--- /dev/null
+++ b/ui/base/dragdrop/drag_utils.h
@@ -0,0 +1,56 @@
+// Copyright (c) 2011 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 UI_BASE_DRAGDROP_DRAG_UTILS_H_
+#define UI_BASE_DRAGDROP_DRAG_UTILS_H_
+#pragma once
+
+#include <string>
+
+#include "base/file_path.h"
+#include "ui/base/ui_export.h"
+
+class GURL;
+class SkBitmap;
+
+namespace gfx {
+class Canvas;
+class Point;
+class Size;
+}
+
+namespace ui {
+class OSExchangeData;
+}
+using ui::OSExchangeData;
+
+namespace drag_utils {
+
+// Creates a dragging image to be displayed when the user drags a file from
+// Chrome (via the download manager, for example). The drag image is set into
+// the supplied data_object. 'file_name' can be a full path, but the directory
+// portion will be truncated in the drag image.
+UI_EXPORT void CreateDragImageForFile(const FilePath& file_name,
+ const SkBitmap* icon,
+ ui::OSExchangeData* data_object);
+
+// Sets the drag image on data_object from the supplied canvas. width/height
+// are the size of the image to use, and the offsets give the location of
+// the hotspot for the drag image.
+UI_EXPORT void SetDragImageOnDataObject(const gfx::Canvas& canvas,
+ const gfx::Size& size,
+ const gfx::Point& cursor_offset,
+ ui::OSExchangeData* data_object);
+
+// Sets the drag image on data_object from the supplied bitmap. width/height
+// are the size of the image to use, and the offsets give the location of
+// the hotspot for the drag image.
+UI_EXPORT void SetDragImageOnDataObject(const SkBitmap& bitmap,
+ const gfx::Size& size,
+ const gfx::Point& cursor_offset,
+ ui::OSExchangeData* data_object);
+
+} // namespace drag_utils
+
+#endif // UI_BASE_DRAGDROP_DRAG_UTILS_H_
diff --git a/ui/base/dragdrop/drag_utils_aura.cc b/ui/base/dragdrop/drag_utils_aura.cc
new file mode 100644
index 0000000..41a9636
--- /dev/null
+++ b/ui/base/dragdrop/drag_utils_aura.cc
@@ -0,0 +1,26 @@
+// Copyright (c) 2011 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.
+
+#include "ui/base/dragdrop/drag_utils.h"
+
+#include "base/logging.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/base/dragdrop/os_exchange_data.h"
+#include "ui/base/dragdrop/os_exchange_data_provider_aura.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/point.h"
+#include "ui/gfx/size.h"
+
+namespace drag_utils {
+
+void SetDragImageOnDataObject(const SkBitmap& bitmap,
+ const gfx::Size& size,
+ const gfx::Point& cursor_offset,
+ ui::OSExchangeData* data_object) {
+ ui::OSExchangeDataProviderAura& provider(
+ static_cast<ui::OSExchangeDataProviderAura&>(data_object->provider()));
+ provider.set_drag_image(bitmap);
+}
+
+} // namespace drag_utils
diff --git a/ui/base/dragdrop/drag_utils_gtk.cc b/ui/base/dragdrop/drag_utils_gtk.cc
new file mode 100644
index 0000000..1cc1773
--- /dev/null
+++ b/ui/base/dragdrop/drag_utils_gtk.cc
@@ -0,0 +1,46 @@
+// Copyright (c) 2011 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.
+
+#include "ui/base/dragdrop/drag_utils.h"
+
+#include <gtk/gtk.h>
+
+#include "base/logging.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/base/dragdrop/os_exchange_data.h"
+#include "ui/base/dragdrop/os_exchange_data_provider_gtk.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/gtk_util.h"
+#include "ui/gfx/point.h"
+#include "ui/gfx/size.h"
+
+namespace drag_utils {
+
+void SetDragImageOnDataObject(const SkBitmap& bitmap,
+ const gfx::Size& size,
+ const gfx::Point& cursor_offset,
+ ui::OSExchangeData* data_object) {
+ ui::OSExchangeDataProviderGtk& provider(
+ static_cast<ui::OSExchangeDataProviderGtk&>(data_object->provider()));
+
+ // Convert the bitmap into a GdkPixbuf.
+ GdkPixbuf* canvas_pixbuf = gfx::GdkPixbufFromSkBitmap(&bitmap);
+
+ // Make a new pixbuf of the requested size and copy it over.
+ GdkPixbuf* pixbuf = gdk_pixbuf_new(
+ gdk_pixbuf_get_colorspace(canvas_pixbuf),
+ gdk_pixbuf_get_has_alpha(canvas_pixbuf),
+ gdk_pixbuf_get_bits_per_sample(canvas_pixbuf),
+ size.width(),
+ size.height());
+ gdk_pixbuf_copy_area(canvas_pixbuf, 0, 0, size.width(), size.height(), pixbuf,
+ 0, 0);
+ g_object_unref(canvas_pixbuf);
+
+ // Set the drag data on to the provider.
+ provider.SetDragImage(pixbuf, cursor_offset);
+ g_object_unref(pixbuf);
+}
+
+} // namespace drag_utils
diff --git a/ui/base/dragdrop/drag_utils_win.cc b/ui/base/dragdrop/drag_utils_win.cc
new file mode 100644
index 0000000..2df2e72
--- /dev/null
+++ b/ui/base/dragdrop/drag_utils_win.cc
@@ -0,0 +1,72 @@
+// Copyright (c) 2011 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.
+
+#include "ui/base/dragdrop/drag_utils.h"
+
+#include <objidl.h>
+#include <shlobj.h>
+#include <shobjidl.h>
+
+#include "base/win/scoped_comptr.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/base/dragdrop/os_exchange_data.h"
+#include "ui/base/dragdrop/os_exchange_data_provider_win.h"
+#include "ui/gfx/canvas_skia.h"
+#include "ui/gfx/gdi_util.h"
+#include "ui/gfx/skbitmap_operations.h"
+
+namespace drag_utils {
+
+static void SetDragImageOnDataObject(HBITMAP hbitmap,
+ const gfx::Size& size,
+ const gfx::Point& cursor_offset,
+ IDataObject* data_object) {
+ base::win::ScopedComPtr<IDragSourceHelper> helper;
+ HRESULT rv = CoCreateInstance(CLSID_DragDropHelper, 0, CLSCTX_INPROC_SERVER,
+ IID_IDragSourceHelper, helper.ReceiveVoid());
+ if (SUCCEEDED(rv)) {
+ SHDRAGIMAGE sdi;
+ sdi.sizeDragImage = size.ToSIZE();
+ sdi.crColorKey = 0xFFFFFFFF;
+ sdi.hbmpDragImage = hbitmap;
+ sdi.ptOffset = cursor_offset.ToPOINT();
+ helper->InitializeFromBitmap(&sdi, data_object);
+ }
+}
+
+// Blit the contents of the canvas to a new HBITMAP. It is the caller's
+// responsibility to release the |bits| buffer.
+static HBITMAP CreateHBITMAPFromSkBitmap(const SkBitmap& sk_bitmap) {
+ HDC screen_dc = GetDC(NULL);
+ BITMAPINFOHEADER header;
+ gfx::CreateBitmapHeader(sk_bitmap.width(), sk_bitmap.height(), &header);
+ void* bits;
+ HBITMAP bitmap =
+ CreateDIBSection(screen_dc, reinterpret_cast<BITMAPINFO*>(&header),
+ DIB_RGB_COLORS, &bits, NULL, 0);
+ DCHECK(sk_bitmap.rowBytes() == sk_bitmap.width() * 4);
+ SkAutoLockPixels lock(sk_bitmap);
+ memcpy(
+ bits, sk_bitmap.getPixels(), sk_bitmap.height() * sk_bitmap.rowBytes());
+ ReleaseDC(NULL, screen_dc);
+ return bitmap;
+}
+
+void SetDragImageOnDataObject(const SkBitmap& sk_bitmap,
+ const gfx::Size& size,
+ const gfx::Point& cursor_offset,
+ ui::OSExchangeData* data_object) {
+ DCHECK(data_object && !size.IsEmpty());
+ // InitializeFromBitmap() doesn't expect an alpha channel and is confused
+ // by premultiplied colors, so unpremultiply the bitmap.
+ // SetDragImageOnDataObject(HBITMAP) takes ownership of the bitmap.
+ HBITMAP bitmap = CreateHBITMAPFromSkBitmap(
+ SkBitmapOperations::UnPreMultiply(sk_bitmap));
+
+ // Attach 'bitmap' to the data_object.
+ SetDragImageOnDataObject(bitmap, size, cursor_offset,
+ ui::OSExchangeDataProviderWin::GetIDataObject(*data_object));
+}
+
+} // namespace drag_utils