OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/drag_drop/drag_drop_controller.h" | 5 #include "ash/drag_drop/drag_drop_controller.h" |
6 | 6 |
7 #include "ash/drag_drop/drag_drop_tracker.h" | |
7 #include "ash/drag_drop/drag_image_view.h" | 8 #include "ash/drag_drop/drag_image_view.h" |
8 #include "ash/shell.h" | 9 #include "ash/shell.h" |
9 #include "ash/wm/coordinate_conversion.h" | 10 #include "ash/wm/coordinate_conversion.h" |
10 #include "ash/wm/cursor_manager.h" | 11 #include "ash/wm/cursor_manager.h" |
11 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
12 #include "base/run_loop.h" | 13 #include "base/run_loop.h" |
13 #include "ui/aura/client/capture_client.h" | 14 #include "ui/aura/client/capture_client.h" |
14 #include "ui/aura/client/drag_drop_delegate.h" | 15 #include "ui/aura/client/drag_drop_delegate.h" |
15 #include "ui/aura/env.h" | 16 #include "ui/aura/env.h" |
16 #include "ui/aura/root_window.h" | 17 #include "ui/aura/root_window.h" |
(...skipping 20 matching lines...) Expand all Loading... | |
37 } // namespace | 38 } // namespace |
38 | 39 |
39 //////////////////////////////////////////////////////////////////////////////// | 40 //////////////////////////////////////////////////////////////////////////////// |
40 // DragDropController, public: | 41 // DragDropController, public: |
41 | 42 |
42 DragDropController::DragDropController() | 43 DragDropController::DragDropController() |
43 : drag_image_(NULL), | 44 : drag_image_(NULL), |
44 drag_data_(NULL), | 45 drag_data_(NULL), |
45 drag_operation_(0), | 46 drag_operation_(0), |
46 drag_window_(NULL), | 47 drag_window_(NULL), |
47 drag_drop_in_progress_(false), | |
48 should_block_during_drag_drop_(true) { | 48 should_block_during_drag_drop_(true) { |
49 Shell::GetInstance()->AddEnvEventFilter(this); | 49 Shell::GetInstance()->AddEnvEventFilter(this); |
50 } | 50 } |
51 | 51 |
52 DragDropController::~DragDropController() { | 52 DragDropController::~DragDropController() { |
53 Shell::GetInstance()->RemoveEnvEventFilter(this); | 53 Shell::GetInstance()->RemoveEnvEventFilter(this); |
54 Cleanup(); | 54 Cleanup(); |
55 if (drag_image_.get()) | 55 if (drag_image_.get()) |
56 drag_image_.reset(); | 56 drag_image_.reset(); |
57 } | 57 } |
58 | 58 |
59 int DragDropController::StartDragAndDrop(const ui::OSExchangeData& data, | 59 int DragDropController::StartDragAndDrop(const ui::OSExchangeData& data, |
60 aura::RootWindow* root_window, | |
60 const gfx::Point& root_location, | 61 const gfx::Point& root_location, |
61 int operation) { | 62 int operation) { |
62 DCHECK(!drag_drop_in_progress_); | 63 DCHECK(!IsDragDropInProgress()); |
63 // TODO(oshima): Add CaptureClient client API. | 64 |
64 aura::Window* capture_window = | |
65 aura::client::GetCaptureWindow(Shell::GetPrimaryRootWindow()); | |
66 if (capture_window) | |
67 capture_window->ReleaseCapture(); | |
68 drag_drop_in_progress_ = true; | |
69 drag_cursor_ = ui::kCursorPointer; | 65 drag_cursor_ = ui::kCursorPointer; |
66 drag_drop_tracker_.reset(new DragDropTracker(root_window)); | |
70 | 67 |
71 drag_data_ = &data; | 68 drag_data_ = &data; |
72 drag_operation_ = operation; | 69 drag_operation_ = operation; |
73 const ui::OSExchangeDataProviderAura& provider = | 70 const ui::OSExchangeDataProviderAura& provider = |
74 static_cast<const ui::OSExchangeDataProviderAura&>(data.provider()); | 71 static_cast<const ui::OSExchangeDataProviderAura&>(data.provider()); |
75 | 72 |
76 drag_image_.reset(new DragImageView); | 73 drag_image_.reset(new DragImageView); |
77 drag_image_->SetImage(provider.drag_image()); | 74 drag_image_->SetImage(provider.drag_image()); |
78 drag_image_offset_ = provider.drag_image_offset(); | 75 drag_image_offset_ = provider.drag_image_offset(); |
79 drag_image_->SetBoundsInScreen(gfx::Rect( | 76 drag_image_->SetBoundsInScreen(gfx::Rect( |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
190 delegate->OnDragExited(); | 187 delegate->OnDragExited(); |
191 | 188 |
192 Cleanup(); | 189 Cleanup(); |
193 drag_operation_ = 0; | 190 drag_operation_ = 0; |
194 StartCanceledAnimation(); | 191 StartCanceledAnimation(); |
195 if (should_block_during_drag_drop_) | 192 if (should_block_during_drag_drop_) |
196 quit_closure_.Run(); | 193 quit_closure_.Run(); |
197 } | 194 } |
198 | 195 |
199 bool DragDropController::IsDragDropInProgress() { | 196 bool DragDropController::IsDragDropInProgress() { |
200 return drag_drop_in_progress_; | 197 return !!drag_drop_tracker_.get(); |
201 } | 198 } |
202 | 199 |
203 gfx::NativeCursor DragDropController::GetDragCursor() { | 200 gfx::NativeCursor DragDropController::GetDragCursor() { |
204 return drag_cursor_; | 201 return drag_cursor_; |
205 } | 202 } |
206 | 203 |
207 bool DragDropController::PreHandleKeyEvent(aura::Window* target, | 204 bool DragDropController::PreHandleKeyEvent(aura::Window* target, |
208 ui::KeyEvent* event) { | 205 ui::KeyEvent* event) { |
209 if (drag_drop_in_progress_ && event->key_code() == ui::VKEY_ESCAPE) { | 206 if (IsDragDropInProgress() && event->key_code() == ui::VKEY_ESCAPE) { |
210 DragCancel(); | 207 DragCancel(); |
211 return true; | 208 return true; |
212 } | 209 } |
213 return false; | 210 return false; |
214 } | 211 } |
215 | 212 |
216 bool DragDropController::PreHandleMouseEvent(aura::Window* target, | 213 bool DragDropController::PreHandleMouseEvent(aura::Window* target, |
217 ui::MouseEvent* event) { | 214 ui::MouseEvent* event) { |
218 if (!drag_drop_in_progress_) | 215 if (!IsDragDropInProgress()) |
219 return false; | 216 return false; |
220 switch (event->type()) { | 217 aura::Window* translated_target = drag_drop_tracker_->GetTarget(*event); |
218 if (!translated_target) { | |
219 DragCancel(); | |
220 return true; | |
221 } | |
222 scoped_ptr<ui::MouseEvent> translated_event( | |
223 drag_drop_tracker_->ConvertMouseEvent(translated_target, *event)); | |
224 switch (translated_event->type()) { | |
221 case ui::ET_MOUSE_DRAGGED: | 225 case ui::ET_MOUSE_DRAGGED: |
222 DragUpdate(target, *event); | 226 DragUpdate(translated_target, *translated_event.get()); |
223 break; | 227 break; |
224 case ui::ET_MOUSE_RELEASED: | 228 case ui::ET_MOUSE_RELEASED: |
225 Drop(target, *event); | 229 Drop(translated_target, *translated_event.get()); |
226 break; | 230 break; |
227 default: | 231 default: |
228 // We could reach here if the user drops outside the root window. | |
229 // We could also reach here because RootWindow may sometimes generate a | 232 // We could also reach here because RootWindow may sometimes generate a |
230 // bunch of fake mouse events | 233 // bunch of fake mouse events |
231 // (aura::RootWindow::PostMouseMoveEventAfterWindowChange). | 234 // (aura::RootWindow::PostMouseMoveEventAfterWindowChange). |
232 break; | 235 break; |
233 } | 236 } |
234 return true; | 237 return true; |
235 } | 238 } |
236 | 239 |
237 ui::TouchStatus DragDropController::PreHandleTouchEvent( | 240 ui::TouchStatus DragDropController::PreHandleTouchEvent( |
238 aura::Window* target, | 241 aura::Window* target, |
239 ui::TouchEvent* event) { | 242 ui::TouchEvent* event) { |
240 // TODO(sad): Also check for the touch-id. | 243 // TODO(sad): Also check for the touch-id. |
241 if (!drag_drop_in_progress_) | 244 // TODO(varunjain): Add code for supporting drag-and-drop across displays |
245 // (http://crbug.com/114755). | |
246 if (!IsDragDropInProgress()) | |
242 return ui::TOUCH_STATUS_UNKNOWN; | 247 return ui::TOUCH_STATUS_UNKNOWN; |
243 switch (event->type()) { | 248 switch (event->type()) { |
244 case ui::ET_TOUCH_MOVED: | 249 case ui::ET_TOUCH_MOVED: |
245 DragUpdate(target, *event); | 250 DragUpdate(target, *event); |
246 break; | 251 break; |
247 case ui::ET_TOUCH_RELEASED: | 252 case ui::ET_TOUCH_RELEASED: |
248 Drop(target, *event); | 253 Drop(target, *event); |
249 break; | 254 break; |
250 case ui::ET_TOUCH_CANCELLED: | 255 case ui::ET_TOUCH_CANCELLED: |
251 DragCancel(); | 256 DragCancel(); |
(...skipping 18 matching lines...) Expand all Loading... | |
270 } | 275 } |
271 | 276 |
272 //////////////////////////////////////////////////////////////////////////////// | 277 //////////////////////////////////////////////////////////////////////////////// |
273 // DragDropController, private: | 278 // DragDropController, private: |
274 | 279 |
275 void DragDropController::OnImplicitAnimationsCompleted() { | 280 void DragDropController::OnImplicitAnimationsCompleted() { |
276 DCHECK(drag_image_.get()); | 281 DCHECK(drag_image_.get()); |
277 | 282 |
278 // By the time we finish animation, another drag/drop session may have | 283 // By the time we finish animation, another drag/drop session may have |
279 // started. We do not want to destroy the drag image in that case. | 284 // started. We do not want to destroy the drag image in that case. |
280 if (!drag_drop_in_progress_) | 285 if (!IsDragDropInProgress()) |
281 drag_image_.reset(); | 286 drag_image_.reset(); |
282 } | 287 } |
283 | 288 |
284 void DragDropController::StartCanceledAnimation() { | 289 void DragDropController::StartCanceledAnimation() { |
285 aura::Window* window = drag_image_->GetWidget()->GetNativeView(); | 290 aura::Window* window = drag_image_->GetWidget()->GetNativeView(); |
286 ui::LayerAnimator* animator = window->layer()->GetAnimator(); | 291 ui::LayerAnimator* animator = window->layer()->GetAnimator(); |
287 animator->set_preemption_strategy( | 292 animator->set_preemption_strategy( |
288 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 293 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
289 | 294 |
290 // Stop waiting for any as yet unfinished implicit animations. | 295 // Stop waiting for any as yet unfinished implicit animations. |
291 StopObservingImplicitAnimations(); | 296 StopObservingImplicitAnimations(); |
292 | 297 |
293 ui::ScopedLayerAnimationSettings animation_setter(animator); | 298 ui::ScopedLayerAnimationSettings animation_setter(animator); |
294 animation_setter.SetTransitionDuration(kDragDropAnimationDuration); | 299 animation_setter.SetTransitionDuration(kDragDropAnimationDuration); |
295 animation_setter.AddObserver(this); | 300 animation_setter.AddObserver(this); |
296 window->SetBounds(gfx::Rect(drag_start_location_, window->bounds().size())); | 301 window->SetBounds(gfx::Rect(drag_start_location_, window->bounds().size())); |
297 } | 302 } |
298 | 303 |
299 void DragDropController::Cleanup() { | 304 void DragDropController::Cleanup() { |
300 if (drag_window_) | 305 if (drag_window_) |
301 drag_window_->RemoveObserver(this); | 306 drag_window_->RemoveObserver(this); |
302 drag_window_ = NULL; | 307 drag_window_ = NULL; |
303 drag_data_ = NULL; | 308 drag_data_ = NULL; |
304 drag_drop_in_progress_ = false; | 309 // Cleanup can be called again while deleting DragDropTracker, so use Pass |
310 // instead of reset to avoid double free. | |
311 drag_drop_tracker_.Pass(); | |
danakj
2014/09/27 01:15:04
This is not going to work with unique_ptr, we shou
| |
305 } | 312 } |
306 | 313 |
307 } // namespace internal | 314 } // namespace internal |
308 } // namespace ash | 315 } // namespace ash |
OLD | NEW |