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 <utility> | 7 #include <utility> |
8 | 8 |
9 #include "ash/drag_drop/drag_drop_tracker.h" | 9 #include "ash/drag_drop/drag_drop_tracker.h" |
10 #include "ash/drag_drop/drag_image_view.h" | 10 #include "ash/drag_drop/drag_image_view.h" |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 drag_data_ = &data; | 189 drag_data_ = &data; |
190 drag_operation_ = operation; | 190 drag_operation_ = operation; |
191 | 191 |
192 float drag_image_scale = 1; | 192 float drag_image_scale = 1; |
193 int drag_image_vertical_offset = 0; | 193 int drag_image_vertical_offset = 0; |
194 if (source == ui::DragDropTypes::DRAG_EVENT_SOURCE_TOUCH) { | 194 if (source == ui::DragDropTypes::DRAG_EVENT_SOURCE_TOUCH) { |
195 drag_image_scale = kTouchDragImageScale; | 195 drag_image_scale = kTouchDragImageScale; |
196 drag_image_vertical_offset = kTouchDragImageVerticalOffset; | 196 drag_image_vertical_offset = kTouchDragImageVerticalOffset; |
197 } | 197 } |
198 gfx::Point start_location = screen_location; | 198 gfx::Point start_location = screen_location; |
199 drag_image_final_bounds_for_cancel_animation_ = gfx::Rect( | 199 drag_image_final_bounds_for_cancel_animation_ = |
200 start_location - provider->GetDragImageOffset(), | 200 gfx::Rect(start_location - provider->GetDragImageOffset(), |
201 provider->GetDragImage().size()); | 201 provider->GetDragImage().size()); |
202 drag_image_.reset(new DragImageView(source_window->GetRootWindow(), source)); | 202 drag_image_.reset(new DragImageView(source_window->GetRootWindow(), source)); |
203 drag_image_->SetImage(provider->GetDragImage()); | 203 drag_image_->SetImage(provider->GetDragImage()); |
204 drag_image_offset_ = provider->GetDragImageOffset(); | 204 drag_image_offset_ = provider->GetDragImageOffset(); |
205 gfx::Rect drag_image_bounds(start_location, drag_image_->GetPreferredSize()); | 205 gfx::Rect drag_image_bounds(start_location, drag_image_->GetPreferredSize()); |
206 drag_image_bounds = AdjustDragImageBoundsForScaleAndOffset(drag_image_bounds, | 206 drag_image_bounds = AdjustDragImageBoundsForScaleAndOffset( |
207 drag_image_vertical_offset, drag_image_scale, &drag_image_offset_); | 207 drag_image_bounds, drag_image_vertical_offset, drag_image_scale, |
| 208 &drag_image_offset_); |
208 drag_image_->SetBoundsInScreen(drag_image_bounds); | 209 drag_image_->SetBoundsInScreen(drag_image_bounds); |
209 drag_image_->SetWidgetVisible(true); | 210 drag_image_->SetWidgetVisible(true); |
210 if (source == ui::DragDropTypes::DRAG_EVENT_SOURCE_TOUCH) { | 211 if (source == ui::DragDropTypes::DRAG_EVENT_SOURCE_TOUCH) { |
211 drag_image_->SetTouchDragOperationHintPosition(gfx::Point( | 212 drag_image_->SetTouchDragOperationHintPosition( |
212 drag_image_offset_.x(), | 213 gfx::Point(drag_image_offset_.x(), |
213 drag_image_offset_.y() + drag_image_vertical_offset)); | 214 drag_image_offset_.y() + drag_image_vertical_offset)); |
214 } | 215 } |
215 | 216 |
216 drag_window_ = NULL; | 217 drag_window_ = NULL; |
217 | 218 |
218 // Ends cancel animation if it's in progress. | 219 // Ends cancel animation if it's in progress. |
219 if (cancel_animation_) | 220 if (cancel_animation_) |
220 cancel_animation_->End(); | 221 cancel_animation_->End(); |
221 | 222 |
222 if (should_block_during_drag_drop_) { | 223 if (should_block_during_drag_drop_) { |
223 base::RunLoop run_loop; | 224 base::RunLoop run_loop; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 cursor = ui::kCursorGrabbing; | 293 cursor = ui::kCursorGrabbing; |
293 ash::Shell::GetInstance()->cursor_manager()->SetCursor(cursor); | 294 ash::Shell::GetInstance()->cursor_manager()->SetCursor(cursor); |
294 } | 295 } |
295 } | 296 } |
296 | 297 |
297 DCHECK(drag_image_.get()); | 298 DCHECK(drag_image_.get()); |
298 if (drag_image_->visible()) { | 299 if (drag_image_->visible()) { |
299 gfx::Point root_location_in_screen = event.root_location(); | 300 gfx::Point root_location_in_screen = event.root_location(); |
300 ::wm::ConvertPointToScreen(target->GetRootWindow(), | 301 ::wm::ConvertPointToScreen(target->GetRootWindow(), |
301 &root_location_in_screen); | 302 &root_location_in_screen); |
302 drag_image_->SetScreenPosition( | 303 drag_image_->SetScreenPosition(root_location_in_screen - |
303 root_location_in_screen - drag_image_offset_); | 304 drag_image_offset_); |
304 drag_image_->SetTouchDragOperation(op); | 305 drag_image_->SetTouchDragOperation(op); |
305 } | 306 } |
306 } | 307 } |
307 | 308 |
308 void DragDropController::Drop(aura::Window* target, | 309 void DragDropController::Drop(aura::Window* target, |
309 const ui::LocatedEvent& event) { | 310 const ui::LocatedEvent& event) { |
310 ash::Shell::GetInstance()->cursor_manager()->SetCursor(ui::kCursorPointer); | 311 ash::Shell::GetInstance()->cursor_manager()->SetCursor(ui::kCursorPointer); |
311 | 312 |
312 // We must guarantee that a target gets a OnDragEntered before Drop. WebKit | 313 // We must guarantee that a target gets a OnDragEntered before Drop. WebKit |
313 // depends on not getting a Drop without DragEnter. This behavior is | 314 // depends on not getting a Drop without DragEnter. This behavior is |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 // event will still be dispatched to other handlers and we depend on | 416 // event will still be dispatched to other handlers and we depend on |
416 // individual handlers' kindness to not touch events marked ER_HANDLED (not | 417 // individual handlers' kindness to not touch events marked ER_HANDLED (not |
417 // all handlers are so kind and may cause bugs like crbug.com/236493). | 418 // all handlers are so kind and may cause bugs like crbug.com/236493). |
418 event->StopPropagation(); | 419 event->StopPropagation(); |
419 | 420 |
420 // If current drag session was not started by touch, dont process this event. | 421 // If current drag session was not started by touch, dont process this event. |
421 if (current_drag_event_source_ != ui::DragDropTypes::DRAG_EVENT_SOURCE_TOUCH) | 422 if (current_drag_event_source_ != ui::DragDropTypes::DRAG_EVENT_SOURCE_TOUCH) |
422 return; | 423 return; |
423 | 424 |
424 // Apply kTouchDragImageVerticalOffset to the location. | 425 // Apply kTouchDragImageVerticalOffset to the location. |
425 ui::GestureEvent touch_offset_event(*event, | 426 ui::GestureEvent touch_offset_event(*event, static_cast<aura::Window*>(NULL), |
426 static_cast<aura::Window*>(NULL), | |
427 static_cast<aura::Window*>(NULL)); | 427 static_cast<aura::Window*>(NULL)); |
428 gfx::PointF touch_offset_location = touch_offset_event.location_f(); | 428 gfx::PointF touch_offset_location = touch_offset_event.location_f(); |
429 gfx::PointF touch_offset_root_location = touch_offset_event.root_location_f(); | 429 gfx::PointF touch_offset_root_location = touch_offset_event.root_location_f(); |
430 touch_offset_location.Offset(0, kTouchDragImageVerticalOffset); | 430 touch_offset_location.Offset(0, kTouchDragImageVerticalOffset); |
431 touch_offset_root_location.Offset(0, kTouchDragImageVerticalOffset); | 431 touch_offset_root_location.Offset(0, kTouchDragImageVerticalOffset); |
432 touch_offset_event.set_location_f(touch_offset_location); | 432 touch_offset_event.set_location_f(touch_offset_location); |
433 touch_offset_event.set_root_location_f(touch_offset_root_location); | 433 touch_offset_event.set_root_location_f(touch_offset_root_location); |
434 | 434 |
435 aura::Window* translated_target = | 435 aura::Window* translated_target = |
436 drag_drop_tracker_->GetTarget(touch_offset_event); | 436 drag_drop_tracker_->GetTarget(touch_offset_event); |
(...skipping 12 matching lines...) Expand all Loading... |
449 case ui::ET_GESTURE_SCROLL_END: | 449 case ui::ET_GESTURE_SCROLL_END: |
450 case ui::ET_SCROLL_FLING_START: | 450 case ui::ET_SCROLL_FLING_START: |
451 Drop(translated_target, *translated_event.get()); | 451 Drop(translated_target, *translated_event.get()); |
452 break; | 452 break; |
453 case ui::ET_GESTURE_LONG_TAP: | 453 case ui::ET_GESTURE_LONG_TAP: |
454 // Ideally we would want to just forward this long tap event to the | 454 // Ideally we would want to just forward this long tap event to the |
455 // |drag_source_window_|. However, webkit does not accept events while a | 455 // |drag_source_window_|. However, webkit does not accept events while a |
456 // drag drop is still in progress. The drag drop ends only when the nested | 456 // drag drop is still in progress. The drag drop ends only when the nested |
457 // message loop ends. Due to this stupidity, we have to defer forwarding | 457 // message loop ends. Due to this stupidity, we have to defer forwarding |
458 // the long tap. | 458 // the long tap. |
459 pending_long_tap_.reset( | 459 pending_long_tap_.reset(new ui::GestureEvent( |
460 new ui::GestureEvent(*event, | 460 *event, |
461 static_cast<aura::Window*>(drag_drop_tracker_->capture_window()), | 461 static_cast<aura::Window*>(drag_drop_tracker_->capture_window()), |
462 static_cast<aura::Window*>(drag_source_window_))); | 462 static_cast<aura::Window*>(drag_source_window_))); |
463 DoDragCancel(kTouchCancelAnimationDuration); | 463 DoDragCancel(kTouchCancelAnimationDuration); |
464 break; | 464 break; |
465 default: | 465 default: |
466 break; | 466 break; |
467 } | 467 } |
468 event->SetHandled(); | 468 event->SetHandled(); |
469 } | 469 } |
470 | 470 |
471 void DragDropController::OnWindowDestroyed(aura::Window* window) { | 471 void DragDropController::OnWindowDestroyed(aura::Window* window) { |
472 if (drag_window_ == window) | 472 if (drag_window_ == window) |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
507 } | 507 } |
508 } | 508 } |
509 } | 509 } |
510 | 510 |
511 void DragDropController::DoDragCancel(int drag_cancel_animation_duration_ms) { | 511 void DragDropController::DoDragCancel(int drag_cancel_animation_duration_ms) { |
512 ash::Shell::GetInstance()->cursor_manager()->SetCursor(ui::kCursorPointer); | 512 ash::Shell::GetInstance()->cursor_manager()->SetCursor(ui::kCursorPointer); |
513 | 513 |
514 // |drag_window_| can be NULL if we have just started the drag and have not | 514 // |drag_window_| can be NULL if we have just started the drag and have not |
515 // received any DragUpdates, or, if the |drag_window_| gets destroyed during | 515 // received any DragUpdates, or, if the |drag_window_| gets destroyed during |
516 // a drag/drop. | 516 // a drag/drop. |
517 aura::client::DragDropDelegate* delegate = drag_window_? | 517 aura::client::DragDropDelegate* delegate = |
518 aura::client::GetDragDropDelegate(drag_window_) : NULL; | 518 drag_window_ ? aura::client::GetDragDropDelegate(drag_window_) : NULL; |
519 if (delegate) | 519 if (delegate) |
520 delegate->OnDragExited(); | 520 delegate->OnDragExited(); |
521 | 521 |
522 Cleanup(); | 522 Cleanup(); |
523 drag_operation_ = 0; | 523 drag_operation_ = 0; |
524 StartCanceledAnimation(drag_cancel_animation_duration_ms); | 524 StartCanceledAnimation(drag_cancel_animation_duration_ms); |
525 if (should_block_during_drag_drop_) | 525 if (should_block_during_drag_drop_) |
526 quit_closure_.Run(); | 526 quit_closure_.Run(); |
527 } | 527 } |
528 | 528 |
529 void DragDropController::AnimationProgressed(const gfx::Animation* animation) { | 529 void DragDropController::AnimationProgressed(const gfx::Animation* animation) { |
530 gfx::Rect current_bounds = animation->CurrentValueBetween( | 530 gfx::Rect current_bounds = animation->CurrentValueBetween( |
531 drag_image_initial_bounds_for_cancel_animation_, | 531 drag_image_initial_bounds_for_cancel_animation_, |
532 drag_image_final_bounds_for_cancel_animation_); | 532 drag_image_final_bounds_for_cancel_animation_); |
533 drag_image_->SetBoundsInScreen(current_bounds); | 533 drag_image_->SetBoundsInScreen(current_bounds); |
534 } | 534 } |
535 | 535 |
536 void DragDropController::AnimationCanceled(const gfx::Animation* animation) { | 536 void DragDropController::AnimationCanceled(const gfx::Animation* animation) { |
537 AnimationEnded(animation); | 537 AnimationEnded(animation); |
538 } | 538 } |
539 | 539 |
540 void DragDropController::StartCanceledAnimation(int animation_duration_ms) { | 540 void DragDropController::StartCanceledAnimation(int animation_duration_ms) { |
541 DCHECK(drag_image_.get()); | 541 DCHECK(drag_image_.get()); |
542 drag_image_->SetTouchDragOperationHintOff(); | 542 drag_image_->SetTouchDragOperationHintOff(); |
543 drag_image_initial_bounds_for_cancel_animation_ = | 543 drag_image_initial_bounds_for_cancel_animation_ = |
544 drag_image_->GetBoundsInScreen(); | 544 drag_image_->GetBoundsInScreen(); |
545 cancel_animation_.reset(CreateCancelAnimation(animation_duration_ms, | 545 cancel_animation_.reset(CreateCancelAnimation( |
546 kCancelAnimationFrameRate, | 546 animation_duration_ms, kCancelAnimationFrameRate, this)); |
547 this)); | |
548 cancel_animation_->Start(); | 547 cancel_animation_->Start(); |
549 } | 548 } |
550 | 549 |
551 void DragDropController::ForwardPendingLongTap() { | 550 void DragDropController::ForwardPendingLongTap() { |
552 if (drag_source_window_ && drag_source_window_->delegate()) { | 551 if (drag_source_window_ && drag_source_window_->delegate()) { |
553 drag_source_window_->delegate()->OnGestureEvent(pending_long_tap_.get()); | 552 drag_source_window_->delegate()->OnGestureEvent(pending_long_tap_.get()); |
554 DispatchGestureEndToWindow(drag_source_window_); | 553 DispatchGestureEndToWindow(drag_source_window_); |
555 } | 554 } |
556 pending_long_tap_.reset(); | 555 pending_long_tap_.reset(); |
557 if (drag_source_window_) | 556 if (drag_source_window_) |
558 drag_source_window_->RemoveObserver(this); | 557 drag_source_window_->RemoveObserver(this); |
559 drag_source_window_ = NULL; | 558 drag_source_window_ = NULL; |
560 } | 559 } |
561 | 560 |
562 void DragDropController::Cleanup() { | 561 void DragDropController::Cleanup() { |
563 if (drag_window_) | 562 if (drag_window_) |
564 drag_window_->RemoveObserver(this); | 563 drag_window_->RemoveObserver(this); |
565 drag_window_ = NULL; | 564 drag_window_ = NULL; |
566 drag_data_ = NULL; | 565 drag_data_ = NULL; |
567 // Cleanup can be called again while deleting DragDropTracker, so delete | 566 // Cleanup can be called again while deleting DragDropTracker, so delete |
568 // the pointer with a local variable to avoid double free. | 567 // the pointer with a local variable to avoid double free. |
569 std::unique_ptr<ash::DragDropTracker> holder = std::move(drag_drop_tracker_); | 568 std::unique_ptr<ash::DragDropTracker> holder = std::move(drag_drop_tracker_); |
570 } | 569 } |
571 | 570 |
572 } // namespace ash | 571 } // namespace ash |
OLD | NEW |