OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "views/widget/drop_helper.h" | |
6 | |
7 #include "ui/base/dragdrop/drag_drop_types.h" | |
8 #include "views/view.h" | |
9 #include "views/widget/widget.h" | |
10 | |
11 namespace views { | |
12 | |
13 DropHelper::DropHelper(View* root_view) | |
14 : root_view_(root_view), | |
15 target_view_(NULL), | |
16 deepest_view_(NULL) { | |
17 } | |
18 | |
19 DropHelper::~DropHelper() { | |
20 } | |
21 | |
22 void DropHelper::ResetTargetViewIfEquals(View* view) { | |
23 if (target_view_ == view) | |
24 target_view_ = NULL; | |
25 if (deepest_view_ == view) | |
26 deepest_view_ = NULL; | |
27 } | |
28 | |
29 int DropHelper::OnDragOver(const OSExchangeData& data, | |
30 const gfx::Point& root_view_location, | |
31 int drag_operation) { | |
32 View* view = CalculateTargetViewImpl(root_view_location, data, true, | |
33 &deepest_view_); | |
34 | |
35 if (view != target_view_) { | |
36 // Target changed notify old drag exited, then new drag entered. | |
37 NotifyDragExit(); | |
38 target_view_ = view; | |
39 NotifyDragEntered(data, root_view_location, drag_operation); | |
40 } | |
41 | |
42 return NotifyDragOver(data, root_view_location, drag_operation); | |
43 } | |
44 | |
45 void DropHelper::OnDragExit() { | |
46 NotifyDragExit(); | |
47 deepest_view_ = target_view_ = NULL; | |
48 } | |
49 | |
50 int DropHelper::OnDrop(const OSExchangeData& data, | |
51 const gfx::Point& root_view_location, | |
52 int drag_operation) { | |
53 View* drop_view = target_view_; | |
54 deepest_view_ = target_view_ = NULL; | |
55 if (!drop_view) | |
56 return ui::DragDropTypes::DRAG_NONE; | |
57 | |
58 if (drag_operation == ui::DragDropTypes::DRAG_NONE) { | |
59 drop_view->OnDragExited(); | |
60 return ui::DragDropTypes::DRAG_NONE; | |
61 } | |
62 | |
63 gfx::Point view_location(root_view_location); | |
64 View* root_view = drop_view->GetWidget()->GetRootView(); | |
65 View::ConvertPointToView(root_view, drop_view, &view_location); | |
66 DropTargetEvent drop_event(data, view_location.x(), view_location.y(), | |
67 drag_operation); | |
68 return drop_view->OnPerformDrop(drop_event); | |
69 } | |
70 | |
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, | |
76 NULL); | |
77 } | |
78 | |
79 View* DropHelper::CalculateTargetViewImpl( | |
80 const gfx::Point& root_view_location, | |
81 const OSExchangeData& data, | |
82 bool check_can_drop, | |
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. | |
87 return target_view_; | |
88 } | |
89 if (deepest_view) | |
90 *deepest_view = view; | |
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 | |
93 // implementation. | |
94 #if defined(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 | |
97 // drop. | |
98 while (view && view != target_view_ && | |
99 (!view->IsEnabled() || !view->CanDrop(data))) { | |
100 view = view->parent(); | |
101 } | |
102 #else | |
103 int formats = 0; | |
104 std::set<OSExchangeData::CustomFormat> custom_formats; | |
105 while (view && view != target_view_) { | |
106 if (view->IsEnabled() && | |
107 view->GetDropFormats(&formats, &custom_formats) && | |
108 data.HasAnyFormat(formats, custom_formats) && | |
109 (!check_can_drop || view->CanDrop(data))) { | |
110 // Found the view. | |
111 return view; | |
112 } | |
113 formats = 0; | |
114 custom_formats.clear(); | |
115 view = view->parent(); | |
116 } | |
117 #endif | |
118 return view; | |
119 } | |
120 | |
121 void DropHelper::NotifyDragEntered(const OSExchangeData& data, | |
122 const gfx::Point& root_view_location, | |
123 int drag_operation) { | |
124 if (!target_view_) | |
125 return; | |
126 | |
127 gfx::Point target_view_location(root_view_location); | |
128 View::ConvertPointToView(root_view_, target_view_, &target_view_location); | |
129 DropTargetEvent enter_event(data, | |
130 target_view_location.x(), | |
131 target_view_location.y(), | |
132 drag_operation); | |
133 target_view_->OnDragEntered(enter_event); | |
134 } | |
135 | |
136 int DropHelper::NotifyDragOver(const OSExchangeData& data, | |
137 const gfx::Point& root_view_location, | |
138 int drag_operation) { | |
139 if (!target_view_) | |
140 return ui::DragDropTypes::DRAG_NONE; | |
141 | |
142 gfx::Point target_view_location(root_view_location); | |
143 View::ConvertPointToView(root_view_, target_view_, &target_view_location); | |
144 DropTargetEvent enter_event(data, | |
145 target_view_location.x(), | |
146 target_view_location.y(), | |
147 drag_operation); | |
148 return target_view_->OnDragUpdated(enter_event); | |
149 } | |
150 | |
151 void DropHelper::NotifyDragExit() { | |
152 if (target_view_) | |
153 target_view_->OnDragExited(); | |
154 } | |
155 | |
156 } // namespace views | |
OLD | NEW |