diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-05 05:37:26 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-05 05:37:26 +0000 |
commit | f68e5d85edd4fb2e47ff01346d7138429c1ec5c4 (patch) | |
tree | 38191ef62fc83ad1a6c32015e29be187b5160e04 /ui/base/dragdrop | |
parent | bd2fb568f441498d0cf542b9c8db9d718f9c6475 (diff) | |
download | chromium_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.cc | 72 | ||||
-rw-r--r-- | ui/base/dragdrop/drag_utils.h | 56 | ||||
-rw-r--r-- | ui/base/dragdrop/drag_utils_aura.cc | 26 | ||||
-rw-r--r-- | ui/base/dragdrop/drag_utils_gtk.cc | 46 | ||||
-rw-r--r-- | ui/base/dragdrop/drag_utils_win.cc | 72 |
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 |