1 // Copyright (c) 2011 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 "ui/views/widget/desktop_aura/desktop_drop_target_win.h"
7 #include "base/win/win_util.h"
8 #include "ui/aura/window.h"
9 #include "ui/aura/window_tree_host.h"
10 #include "ui/base/dragdrop/drag_drop_types.h"
11 #include "ui/base/dragdrop/drop_target_event.h"
12 #include "ui/base/dragdrop/os_exchange_data_provider_win.h"
13 #include "ui/events/event_constants.h"
14 #include "ui/wm/public/drag_drop_client.h"
15 #include "ui/wm/public/drag_drop_delegate.h"
17 using aura::client::DragDropDelegate
;
18 using ui::OSExchangeData
;
19 using ui::OSExchangeDataProviderWin
;
23 DesktopDropTargetWin::DesktopDropTargetWin(aura::Window
* root_window
,
25 : ui::DropTargetWin(window
),
26 root_window_(root_window
),
27 target_window_(NULL
) {
30 DesktopDropTargetWin::~DesktopDropTargetWin() {
32 target_window_
->RemoveObserver(this);
35 DWORD
DesktopDropTargetWin::OnDragEnter(IDataObject
* data_object
,
39 scoped_ptr
<OSExchangeData
> data
;
40 scoped_ptr
<ui::DropTargetEvent
> event
;
41 DragDropDelegate
* delegate
;
42 // Translate will call OnDragEntered.
43 Translate(data_object
, key_state
, position
, effect
, &data
, &event
, &delegate
);
44 return ui::DragDropTypes::DragOperationToDropEffect(
45 ui::DragDropTypes::DRAG_NONE
);
48 DWORD
DesktopDropTargetWin::OnDragOver(IDataObject
* data_object
,
52 int drag_operation
= ui::DragDropTypes::DRAG_NONE
;
53 scoped_ptr
<OSExchangeData
> data
;
54 scoped_ptr
<ui::DropTargetEvent
> event
;
55 DragDropDelegate
* delegate
;
56 Translate(data_object
, key_state
, position
, effect
, &data
, &event
, &delegate
);
58 drag_operation
= delegate
->OnDragUpdated(*event
);
59 return ui::DragDropTypes::DragOperationToDropEffect(drag_operation
);
62 void DesktopDropTargetWin::OnDragLeave(IDataObject
* data_object
) {
66 DWORD
DesktopDropTargetWin::OnDrop(IDataObject
* data_object
,
70 int drag_operation
= ui::DragDropTypes::DRAG_NONE
;
71 scoped_ptr
<OSExchangeData
> data
;
72 scoped_ptr
<ui::DropTargetEvent
> event
;
73 DragDropDelegate
* delegate
;
74 Translate(data_object
, key_state
, position
, effect
, &data
, &event
, &delegate
);
76 drag_operation
= delegate
->OnPerformDrop(*event
);
78 target_window_
->RemoveObserver(this);
79 target_window_
= NULL
;
81 return ui::DragDropTypes::DragOperationToDropEffect(drag_operation
);
84 void DesktopDropTargetWin::OnWindowDestroyed(aura::Window
* window
) {
85 DCHECK(window
== target_window_
);
86 target_window_
= NULL
;
89 void DesktopDropTargetWin::Translate(
90 IDataObject
* data_object
,
94 scoped_ptr
<OSExchangeData
>* data
,
95 scoped_ptr
<ui::DropTargetEvent
>* event
,
96 DragDropDelegate
** delegate
) {
97 gfx::Point
location(position
.x
, position
.y
);
98 gfx::Point root_location
= location
;
99 root_window_
->GetHost()->ConvertPointFromNativeScreen(
101 aura::Window
* target_window
=
102 root_window_
->GetEventHandlerForPoint(root_location
);
103 bool target_window_changed
= false;
104 if (target_window
!= target_window_
) {
107 target_window_
= target_window
;
109 target_window_
->AddObserver(this);
110 target_window_changed
= true;
115 *delegate
= aura::client::GetDragDropDelegate(target_window_
);
119 data
->reset(new OSExchangeData(new OSExchangeDataProviderWin(data_object
)));
120 location
= root_location
;
121 aura::Window::ConvertPointToTarget(root_window_
, target_window_
, &location
);
122 event
->reset(new ui::DropTargetEvent(
126 ui::DragDropTypes::DropEffectToDragOperation(effect
)));
128 flags
|= base::win::IsAltPressed() ? ui::EF_ALT_DOWN
: ui::EF_NONE
;
129 flags
|= base::win::IsShiftPressed() ? ui::EF_SHIFT_DOWN
: ui::EF_NONE
;
130 flags
|= base::win::IsCtrlPressed() ? ui::EF_CONTROL_DOWN
: ui::EF_NONE
;
131 (*event
)->set_flags(flags
);
132 if (target_window_changed
)
133 (*delegate
)->OnDragEntered(*event
->get());
136 void DesktopDropTargetWin::NotifyDragLeave() {
139 DragDropDelegate
* delegate
=
140 aura::client::GetDragDropDelegate(target_window_
);
142 delegate
->OnDragExited();
143 target_window_
->RemoveObserver(this);
144 target_window_
= NULL
;