1 // Copyright (c) 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 "ui/views/widget/drop_helper.h"
7 #include "ui/base/dragdrop/drag_drop_types.h"
8 #include "ui/views/view.h"
9 #include "ui/views/widget/widget.h"
13 DropHelper::DropHelper(View
* root_view
)
14 : root_view_(root_view
),
19 DropHelper::~DropHelper() {
22 void DropHelper::ResetTargetViewIfEquals(View
* view
) {
23 if (target_view_
== view
)
25 if (deepest_view_
== view
)
29 int DropHelper::OnDragOver(const OSExchangeData
& data
,
30 const gfx::Point
& root_view_location
,
32 View
* view
= CalculateTargetViewImpl(root_view_location
, data
, true,
35 if (view
!= target_view_
) {
36 // Target changed notify old drag exited, then new drag entered.
39 NotifyDragEntered(data
, root_view_location
, drag_operation
);
42 return NotifyDragOver(data
, root_view_location
, drag_operation
);
45 void DropHelper::OnDragExit() {
47 deepest_view_
= target_view_
= NULL
;
50 int DropHelper::OnDrop(const OSExchangeData
& data
,
51 const gfx::Point
& root_view_location
,
53 View
* drop_view
= target_view_
;
54 deepest_view_
= target_view_
= NULL
;
56 return ui::DragDropTypes::DRAG_NONE
;
58 if (drag_operation
== ui::DragDropTypes::DRAG_NONE
) {
59 drop_view
->OnDragExited();
60 return ui::DragDropTypes::DRAG_NONE
;
63 gfx::Point
view_location(root_view_location
);
64 View
* root_view
= drop_view
->GetWidget()->GetRootView();
65 View::ConvertPointToTarget(root_view
, drop_view
, &view_location
);
66 ui::DropTargetEvent
drop_event(data
, view_location
, view_location
,
68 return drop_view
->OnPerformDrop(drop_event
);
71 View
* DropHelper::CalculateTargetView(
72 const gfx::Point
& root_view_location
,
73 const OSExchangeData
& data
,
74 bool check_can_drop
) {
75 return CalculateTargetViewImpl(root_view_location
, data
, check_can_drop
,
79 View
* DropHelper::CalculateTargetViewImpl(
80 const gfx::Point
& root_view_location
,
81 const OSExchangeData
& data
,
83 View
** deepest_view
) {
84 View
* view
= root_view_
->GetEventHandlerForPoint(root_view_location
);
85 if (view
== deepest_view_
) {
86 // The view the mouse is over hasn't changed; reuse the target.
91 // TODO(sky): for the time being these are separate. Once I port chrome menu
92 // I can switch to the #else implementation and nuke the OS_WIN
95 // View under mouse changed, which means a new view may want the drop.
96 // Walk the tree, stopping at target_view_ as we know it'll accept the
98 while (view
&& view
!= target_view_
&&
99 (!view
->enabled() || !view
->CanDrop(data
))) {
100 view
= view
->parent();
104 std::set
<OSExchangeData::CustomFormat
> custom_formats
;
105 while (view
&& view
!= target_view_
) {
106 if (view
->enabled() &&
107 view
->GetDropFormats(&formats
, &custom_formats
) &&
108 data
.HasAnyFormat(formats
, custom_formats
) &&
109 (!check_can_drop
|| view
->CanDrop(data
))) {
114 custom_formats
.clear();
115 view
= view
->parent();
121 void DropHelper::NotifyDragEntered(const OSExchangeData
& data
,
122 const gfx::Point
& root_view_location
,
123 int drag_operation
) {
127 gfx::Point
target_view_location(root_view_location
);
128 View::ConvertPointToTarget(root_view_
, target_view_
, &target_view_location
);
129 ui::DropTargetEvent
enter_event(data
,
130 target_view_location
,
131 target_view_location
,
133 target_view_
->OnDragEntered(enter_event
);
136 int DropHelper::NotifyDragOver(const OSExchangeData
& data
,
137 const gfx::Point
& root_view_location
,
138 int drag_operation
) {
140 return ui::DragDropTypes::DRAG_NONE
;
142 gfx::Point
target_view_location(root_view_location
);
143 View::ConvertPointToTarget(root_view_
, target_view_
, &target_view_location
);
144 ui::DropTargetEvent
enter_event(data
,
145 target_view_location
,
146 target_view_location
,
148 return target_view_
->OnDragUpdated(enter_event
);
151 void DropHelper::NotifyDragExit() {
153 target_view_
->OnDragExited();