| 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 |