Popular sites on the NTP: check that experiment group StartsWith (rather than IS...
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / bookmarks / bookmark_drag_drop_cocoa.mm
blob7fc523ef09b4962cddb595b0fca073137e820c20
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/bookmarks/bookmark_drag_drop.h"
7 #import <Cocoa/Cocoa.h>
9 #include <cmath>
11 #include "base/logging.h"
12 #include "base/mac/scoped_nsobject.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/strings/string16.h"
15 #include "base/strings/sys_string_conversions.h"
16 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/ui/bookmarks/bookmark_drag_drop.h"
19 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h"
20 #import "chrome/browser/ui/cocoa/drag_util.h"
21 #include "components/bookmarks/browser/bookmark_model.h"
22 #include "components/bookmarks/browser/bookmark_node_data.h"
23 #include "ui/base/dragdrop/drag_drop_types.h"
25 using bookmarks::BookmarkModel;
26 using bookmarks::BookmarkNode;
28 namespace {
30 // Make a drag image from the drop data.
31 NSImage* MakeDragImage(BookmarkModel* model,
32                        const std::vector<const BookmarkNode*>& nodes) {
33   if (nodes.size() == 1) {
34     const BookmarkNode* node = nodes[0];
35     const gfx::Image& favicon = model->GetFavicon(node);
36     return drag_util::DragImageForBookmark(
37         favicon.IsEmpty() ? nil : favicon.ToNSImage(),
38         node->GetTitle(),
39         bookmarks::kDefaultBookmarkWidth);
40   } else {
41     // TODO(feldstein): Do something better than this. Should have badging
42     // and a single drag image.
43     // http://crbug.com/37264
44     return [NSImage imageNamed:NSImageNameMultipleDocuments];
45   }
48 }  // namespace
50 namespace chrome {
52 void DragBookmarks(Profile* profile,
53                    const std::vector<const BookmarkNode*>& nodes,
54                    gfx::NativeView view,
55                    ui::DragDropTypes::DragEventSource source) {
56   DCHECK(!nodes.empty());
58   // Allow nested message loop so we get DnD events as we drag this around.
59   base::MessageLoop::ScopedNestableTaskAllower nestable_task_allower(
60       base::MessageLoop::current());
62   bookmarks::BookmarkNodeData drag_data(nodes);
63   drag_data.SetOriginatingProfilePath(profile->GetPath());
64   drag_data.WriteToClipboard(ui::CLIPBOARD_TYPE_DRAG);
66   // Synthesize an event for dragging, since we can't be sure that
67   // [NSApp currentEvent] will return a valid dragging event.
68   NSWindow* window = [view window];
69   NSPoint position = [window mouseLocationOutsideOfEventStream];
70   NSTimeInterval event_time = [[NSApp currentEvent] timestamp];
71   NSEvent* drag_event = [NSEvent mouseEventWithType:NSLeftMouseDragged
72                                            location:position
73                                       modifierFlags:NSLeftMouseDraggedMask
74                                           timestamp:event_time
75                                        windowNumber:[window windowNumber]
76                                             context:nil
77                                         eventNumber:0
78                                          clickCount:1
79                                            pressure:1.0];
81   // TODO(avi): Do better than this offset.
82   NSImage* drag_image = MakeDragImage(
83       BookmarkModelFactory::GetForProfile(profile), nodes);
84   NSSize image_size = [drag_image size];
85   position.x -= std::floor(image_size.width / 2);
86   position.y -= std::floor(image_size.height / 5);
87   [window dragImage:drag_image
88                  at:position
89              offset:NSZeroSize
90               event:drag_event
91          pasteboard:[NSPasteboard pasteboardWithName:NSDragPboard]
92              source:nil
93           slideBack:YES];
96 }  // namespace chrome