Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(190)

Side by Side Diff: ui/views/cocoa/drag_drop_client_mac.mm

Issue 1964283002: MacViews: Implemented Drag & Drop (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix for dcheng Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/views/cocoa/drag_drop_client_mac.h ('k') | ui/views/cocoa/drag_drop_client_mac_unittest.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 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.
4
5 #import "ui/views/cocoa/drag_drop_client_mac.h"
6
7 #include "base/mac/mac_util.h"
8 #include "base/run_loop.h"
9 #include "base/strings/sys_string_conversions.h"
10 #import "ui/base/dragdrop/os_exchange_data_provider_mac.h"
11 #include "ui/gfx/image/image_skia_util_mac.h"
12 #include "ui/views/drag_utils.h"
13 #import "ui/views/cocoa/bridged_content_view.h"
14 #import "ui/views/cocoa/bridged_native_widget.h"
15 #include "ui/views/widget/native_widget_mac.h"
16
17 @interface CocoaDragDropDataProvider ()
18 - (id)initWithData:(const ui::OSExchangeData&)data;
19 - (id)initWithPasteboard:(NSPasteboard*)pasteboard;
20 @end
21
22 @implementation CocoaDragDropDataProvider
23
24 std::unique_ptr<ui::OSExchangeData> data_;
Scott Hess - ex-Googler 2016/06/05 20:11:51 Dollars to donuts this is responsible for the wate
tapted 2016/06/05 23:37:35 Ah doh - it just needs curlies around it. I'll sub
25
26 - (id)initWithData:(const ui::OSExchangeData&)data {
27 if ((self = [super init])) {
28 data_.reset(new OSExchangeData(data.provider().Clone()));
29 }
30 return self;
31 }
32
33 - (id)initWithPasteboard:(NSPasteboard*)pasteboard {
34 if ((self = [super init])) {
35 data_ = ui::OSExchangeDataProviderMac::CreateDataFromPasteboard(pasteboard);
36 }
37 return self;
38 }
39
40 - (ui::OSExchangeData*)data {
41 return data_.get();
42 }
43
44 // NSPasteboardItemDataProvider protocol implementation.
45
46 - (void)pasteboard:(NSPasteboard*)sender
47 item:(NSPasteboardItem*)item
48 provideDataForType:(NSString*)type {
49 const ui::OSExchangeDataProviderMac& provider =
50 static_cast<const ui::OSExchangeDataProviderMac&>(data_->provider());
51 NSData* ns_data = provider.GetNSDataForType(type);
52 [sender setData:ns_data forType:type];
53 }
54
55 @end
56
57 namespace views {
58
59 DragDropClientMac::DragDropClientMac(BridgedNativeWidget* bridge,
60 View* root_view)
61 : drop_helper_(root_view),
62 operation_(0),
63 bridge_(bridge),
64 quit_closure_(base::Closure()) {
65 DCHECK(bridge);
66 }
67
68 DragDropClientMac::~DragDropClientMac() {}
69
70 void DragDropClientMac::StartDragAndDrop(
71 View* view,
72 const ui::OSExchangeData& data,
73 int operation,
74 ui::DragDropTypes::DragEventSource source) {
75 data_source_.reset([[CocoaDragDropDataProvider alloc] initWithData:data]);
76 operation_ = operation;
77
78 const ui::OSExchangeDataProviderMac& provider =
79 static_cast<const ui::OSExchangeDataProviderMac&>(data.provider());
80
81 // Synthesize an event for dragging, since we can't be sure that
82 // [NSApp currentEvent] will return a valid dragging event.
83 NSWindow* window = bridge_->ns_window();
84 NSPoint position = [window mouseLocationOutsideOfEventStream];
85 NSTimeInterval event_time = [[NSApp currentEvent] timestamp];
86 NSEvent* event = [NSEvent mouseEventWithType:NSLeftMouseDragged
87 location:position
88 modifierFlags:NSLeftMouseDraggedMask
89 timestamp:event_time
90 windowNumber:[window windowNumber]
91 context:nil
92 eventNumber:0
93 clickCount:1
94 pressure:1.0];
95
96 NSImage* image = gfx::NSImageFromImageSkiaWithColorSpace(
97 provider.GetDragImage(), base::mac::GetSRGBColorSpace());
98
99 base::scoped_nsobject<NSPasteboardItem> item([[NSPasteboardItem alloc] init]);
100 [item setDataProvider:data_source_.get()
101 forTypes:ui::OSExchangeDataProviderMac::
102 SupportedPasteboardTypes()];
103
104 base::scoped_nsobject<NSDraggingItem> drag_item(
105 [[NSDraggingItem alloc] initWithPasteboardWriter:item.get()]);
106
107 // Subtract the image's height from the y location so that the mouse will be
108 // at the upper left corner of the image.
109 NSRect dragging_frame =
110 NSMakeRect([event locationInWindow].x,
111 [event locationInWindow].y - [image size].height,
112 [image size].width, [image size].height);
113 [drag_item setDraggingFrame:dragging_frame contents:image];
114
115 [bridge_->ns_view() beginDraggingSessionWithItems:@[ drag_item.get() ]
116 event:event
117 source:bridge_->ns_view()];
118
119 // Since Drag and drop is asynchronous on Mac, we need to spin a nested run
120 // loop for consistency with other platforms.
121 base::RunLoop run_loop;
122 quit_closure_ = run_loop.QuitClosure();
123 run_loop.Run();
124 }
125
126 NSDragOperation DragDropClientMac::DragUpdate(id<NSDraggingInfo> sender) {
127 int drag_operation = ui::DragDropTypes::DRAG_NONE;
128
129 // Since dragging from non MacView sources does not generate OSExchangeData,
130 // we need to generate one based on the provided pasteboard.
131 if (!data_source_.get()) {
132 data_source_.reset([[CocoaDragDropDataProvider alloc]
133 initWithPasteboard:[sender draggingPasteboard]]);
134 }
135
136 drag_operation = drop_helper_.OnDragOver(
137 *[data_source_ data], LocationInView([sender draggingLocation]),
138 operation_);
139 return ui::DragDropTypes::DragOperationToNSDragOperation(drag_operation);
140 }
141
142 NSDragOperation DragDropClientMac::Drop(id<NSDraggingInfo> sender) {
143 int drag_operation = drop_helper_.OnDrop(
144 *[data_source_ data], LocationInView([sender draggingLocation]),
145 operation_);
146 return ui::DragDropTypes::DragOperationToNSDragOperation(drag_operation);
147 }
148
149 void DragDropClientMac::EndDrag() {
150 data_source_.reset();
151
152 // Allow a test to invoke EndDrag() without spinning the nested run loop.
153 if (!quit_closure_.is_null()) {
154 quit_closure_.Run();
155 quit_closure_.Reset();
156 }
157 }
158
159 gfx::Point DragDropClientMac::LocationInView(NSPoint point) const {
160 return gfx::Point(point.x, NSHeight([bridge_->ns_window() frame]) - point.y);
161 }
162
163 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/cocoa/drag_drop_client_mac.h ('k') | ui/views/cocoa/drag_drop_client_mac_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698