OLD | NEW |
(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 #include "ui/views/cocoa/cocoa_drag_drop_manager.h" |
| 6 |
| 7 #include "base/mac/mac_util.h" |
| 8 #include "base/strings/sys_string_conversions.h" |
| 9 #include "ui/base/dragdrop/os_exchange_data.h" |
| 10 #include "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/drop_helper.h" |
| 16 |
| 17 namespace {} // namespace |
| 18 |
| 19 @interface CocoaDragSourceProvider : NSObject<NSPasteboardItemDataProvider> { |
| 20 std::unique_ptr<ui::OSExchangeData> data_; |
| 21 } |
| 22 |
| 23 @end |
| 24 |
| 25 @implementation CocoaDragSourceProvider |
| 26 |
| 27 - (id)initWithData:(const ui::OSExchangeData&)data { |
| 28 if ((self = [super init])) { |
| 29 data_.reset(new OSExchangeData(data.provider().Clone())); |
| 30 } |
| 31 return self; |
| 32 } |
| 33 |
| 34 - (id)initWithPasteboard:(NSPasteboard*)pasteboard { |
| 35 if ((self = [super init])) { |
| 36 data_.reset(new OSExchangeData( |
| 37 ui::OSExchangeDataProviderMac::CreateProviderFromPasteboard( |
| 38 pasteboard))); |
| 39 } |
| 40 return self; |
| 41 } |
| 42 |
| 43 - (ui::OSExchangeData*)data { |
| 44 return data_.get(); |
| 45 } |
| 46 |
| 47 - (void)pasteboard:(NSPasteboard*)sender |
| 48 item:(NSPasteboardItem*)item |
| 49 provideDataForType:(NSString*)type { |
| 50 const ui::OSExchangeDataProviderMac* provider = |
| 51 static_cast<const ui::OSExchangeDataProviderMac*>(&data_->provider()); |
| 52 NSData* ns_data = provider->GetNSDataForType(type); |
| 53 [sender setData:ns_data forType:type]; |
| 54 } |
| 55 |
| 56 @end |
| 57 |
| 58 namespace views { |
| 59 |
| 60 CocoaDragDropManager::CocoaDragDropManager(BridgedNativeWidget* bridge) |
| 61 : bridge_(bridge) { |
| 62 DCHECK(bridge); |
| 63 drop_helper_.reset(new DropHelper([bridge->ns_view() hostedView])); |
| 64 } |
| 65 |
| 66 CocoaDragDropManager::~CocoaDragDropManager() {} |
| 67 |
| 68 void CocoaDragDropManager::BeginDrag( |
| 69 const ui::OSExchangeData& data, |
| 70 const gfx::Point& location, |
| 71 int operation, |
| 72 ui::DragDropTypes::DragEventSource source) { |
| 73 drag_source_.reset([[CocoaDragSourceProvider alloc] initWithData:data]); |
| 74 operation_ = operation; |
| 75 |
| 76 const ui::OSExchangeDataProviderMac* provider = |
| 77 static_cast<const ui::OSExchangeDataProviderMac*>(&data.provider()); |
| 78 const base::NativeEvent event = provider->GetNativeEvent(); |
| 79 |
| 80 NSImage* image = gfx::NSImageFromImageSkiaWithColorSpace( |
| 81 provider->GetDragImage(), base::mac::GetSRGBColorSpace()); |
| 82 |
| 83 base::scoped_nsobject<NSPasteboardItem> item([[NSPasteboardItem alloc] init]); |
| 84 [item setDataProvider:drag_source_.get() |
| 85 forTypes:provider->GetPasteboardTypes()]; |
| 86 |
| 87 base::scoped_nsobject<NSDraggingItem> dragItem( |
| 88 [[NSDraggingItem alloc] initWithPasteboardWriter:item.get()]); |
| 89 |
| 90 [dragItem setDraggingFrame:NSMakeRect([event locationInWindow].x, |
| 91 [event locationInWindow].y - |
| 92 [image size].height, |
| 93 [image size].width, [image size].height) |
| 94 contents:image]; |
| 95 |
| 96 [bridge_->ns_view() beginDraggingSessionWithItems:@[ dragItem.get() ] |
| 97 event:event |
| 98 source:nil]; |
| 99 } |
| 100 |
| 101 NSDragOperation CocoaDragDropManager::DraggingOver(id<NSDraggingInfo> sender) { |
| 102 int drag_operation = ui::DragDropTypes::DRAG_NONE; |
| 103 |
| 104 // Since dragging from web contents does not generate OSExchangeData, we |
| 105 // need to create one based on the pasteboard provided. |
| 106 if (!drag_source_.get()) { |
| 107 drag_source_.reset([[CocoaDragSourceProvider alloc] |
| 108 initWithPasteboard:[sender draggingPasteboard]]); |
| 109 } |
| 110 |
| 111 drag_operation = drop_helper_->OnDragOver( |
| 112 *[drag_source_ data], LocationInView([sender draggingLocation]), |
| 113 operation_); |
| 114 |
| 115 return ui::DragDropTypes::DragOperationToNSDragOperation(drag_operation); |
| 116 } |
| 117 |
| 118 NSDragOperation CocoaDragDropManager::OnDrop(id<NSDraggingInfo> sender) { |
| 119 int drag_operation = drop_helper_->OnDrop( |
| 120 *[drag_source_ data], LocationInView([sender draggingLocation]), |
| 121 operation_); |
| 122 return ui::DragDropTypes::DragOperationToNSDragOperation(drag_operation); |
| 123 } |
| 124 |
| 125 void CocoaDragDropManager::EndDrag() { |
| 126 drag_source_.reset(); |
| 127 } |
| 128 |
| 129 void CocoaDragDropManager::SetRootView(View* view) { |
| 130 drop_helper_.reset(new DropHelper(view)); |
| 131 } |
| 132 |
| 133 gfx::Point CocoaDragDropManager::LocationInView(NSPoint point) const { |
| 134 return gfx::Point(point.x, NSHeight([bridge_->ns_window() frame]) - point.y); |
| 135 } |
| 136 |
| 137 } // namespace views |
OLD | NEW |