15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/dragdrop/drag_utils.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/dragdrop/os_exchange_data.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/font_list.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/geometry/point.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/geometry/rect.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/geometry/size.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/canvas_image_source.h"
17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace drag_utils {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Maximum width of the link drag image in pixels.
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kLinkDragImageVPadding = 3;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// File dragging pixel measurements
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kFileDragImageMaxWidth = 200;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const SkColor kFileDragImageTextColor = SK_ColorBLACK;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FileDragImageSource : public gfx::CanvasImageSource {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileDragImageSource(const base::FilePath& file_name,
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      const gfx::ImageSkia& icon)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : CanvasImageSource(CalculateSize(icon), false),
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        file_name_(file_name),
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        icon_(icon) {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~FileDragImageSource() {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from gfx::CanvasImageSource.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Draw(gfx::Canvas* canvas) OVERRIDE {
44effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    if (!icon_.isNull()) {
45effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      // Paint the icon.
46effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      canvas->DrawImageInt(icon_, (size().width() - icon_.width()) / 2, 0);
47effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    }
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::string16 name = file_name_.BaseName().LossyDisplayName();
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int flags = gfx::Canvas::TEXT_ALIGN_CENTER;
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const gfx::FontList font_list;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Paint the file name. We inset it one pixel to allow room for the halo.
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const gfx::Rect rect(1, icon_.height() + kLinkDragImageVPadding + 1,
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         size().width() - 2, font_list.GetHeight());
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    canvas->DrawStringRectWithHalo(name, font_list, kFileDragImageTextColor,
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   SK_ColorWHITE, rect, flags);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // NO_SUBPIXEL_RENDERING is required when drawing to a non-opaque canvas.
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const gfx::Rect rect(0, icon_.height() + kLinkDragImageVPadding,
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         size().width(), font_list.GetHeight());
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    canvas->DrawStringRectWithFlags(name, font_list, kFileDragImageTextColor,
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    rect,
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    flags | gfx::Canvas::NO_SUBPIXEL_RENDERING);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size CalculateSize(const gfx::ImageSkia& icon) const {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int width = kFileDragImageMaxWidth;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Add +2 here to allow room for the halo.
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const int height = gfx::FontList().GetHeight() + icon.height() +
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       kLinkDragImageVPadding + 2;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return gfx::Size(width, height);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::FilePath file_name_;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const gfx::ImageSkia icon_;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FileDragImageSource);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CreateDragImageForFile(const base::FilePath& file_name,
86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                            const gfx::ImageSkia& icon,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            ui::OSExchangeData* data_object) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(data_object);
89effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  gfx::CanvasImageSource* source = new FileDragImageSource(file_name, icon);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size size = source->size();
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ImageSkia takes ownership of |source|.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::ImageSkia image = gfx::ImageSkia(source, size);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Vector2d cursor_offset(size.width() / 2, kLinkDragImageVPadding);
95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  SetDragImageOnDataObject(image, cursor_offset, data_object);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetDragImageOnDataObject(const gfx::Canvas& canvas,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const gfx::Vector2d& cursor_offset,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              ui::OSExchangeData* data_object) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::ImageSkia image = gfx::ImageSkia(canvas.ExtractImageRep());
102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  SetDragImageOnDataObject(image, cursor_offset, data_object);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace drag_utils
106