Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(611)

Unified Diff: ui/aura_shell/drag_drop_controller.cc

Issue 8450018: First shot at implementing drag&drop for Aura (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: added missing test file Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ui/aura_shell/drag_drop_controller.cc
diff --git a/ui/aura_shell/drag_drop_controller.cc b/ui/aura_shell/drag_drop_controller.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c13e6a1ca4f05ba338b4dd96cfdca98a5f5adfe0
--- /dev/null
+++ b/ui/aura_shell/drag_drop_controller.cc
@@ -0,0 +1,154 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/aura_shell/drag_drop_controller.h"
+
+#include "base/message_loop.h"
+#include "ui/aura/desktop.h"
+#include "ui/aura/window.h"
+#include "ui/aura/window_drag_drop_delegate.h"
+#include "ui/base/dragdrop/drag_drop_types.h"
+#include "ui/base/dragdrop/os_exchange_data_provider_aura.h"
+#include "ui/gfx/point.h"
+#include "ui/gfx/rect.h"
+#include "views/controls/image_view.h"
+#include "views/widget/widget.h"
+
+namespace aura_shell {
+namespace internal {
+
+using aura::Desktop;
+
+namespace {
+using views::Widget;
+
+Widget* CreateDragWidget() {
Ben Goodger (Google) 2011/11/11 17:26:53 I'd like it if the whole "view" part of the drag&d
varunjain 2011/11/15 19:39:33 Done.
+ Widget* drag_widget = new Widget;
+ Widget::InitParams params;
+ params.type = Widget::InitParams::TYPE_TOOLTIP;
+ params.keep_on_top = true;
+ params.accept_events = false;
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ params.transparent = true;
+ drag_widget->Init(params);
+ drag_widget->SetOpacity(0xFF);
+ return drag_widget;
+}
+
+} // namespace
+
+DragDropController::DragDropController()
+ : drag_widget_(NULL),
+ drag_data_(NULL),
+ drag_operation_(0),
+ dragged_window_(NULL),
+ drag_drop_in_progress_(false),
+ should_block_during_drag_drop_(true) {
+}
+
+DragDropController::~DragDropController() {
+ Cleanup();
+}
+
+void DragDropController::StartDragAndDrop(const ui::OSExchangeData& data,
+ int operation) {
+ DCHECK(!drag_drop_in_progress_);
+ aura::Window* capture_window = Desktop::GetInstance()->capture_window();
+ if (capture_window)
+ Desktop::GetInstance()->ReleaseCapture(capture_window);
+ drag_drop_in_progress_ = true;
+
+ DCHECK(drag_data_ == NULL && drag_operation_ == 0);
+ DCHECK(drag_widget_.get() == NULL);
+ drag_data_ = &data;
+ drag_widget_.reset(CreateDragWidget());
Ben Goodger (Google) 2011/11/11 17:26:53 This would become something like drag_image_.res
varunjain 2011/11/15 19:39:33 Done.
+ drag_operation_ = operation;
+ gfx::Point location = Desktop::GetInstance()->last_mouse_location();
+ const ui::OSExchangeDataProviderAura& provider =
+ static_cast<const ui::OSExchangeDataProviderAura&>(data.provider());
+
+ views::ImageView* image_view = new views::ImageView();
+ image_view->SetImage(provider.drag_image());
+ drag_widget_->SetContentsView(image_view);
+ drag_widget_->SetBounds(gfx::Rect(location,
+ image_view->GetPreferredSize()));
+ drag_widget_->Show();
+
+ dragged_window_ = Desktop::GetInstance()->GetEventHandlerForPoint(location);
+
+ if (should_block_during_drag_drop_) {
+ MessageLoopForUI::current()->RunWithDispatcher(
+ Desktop::GetInstance()->GetDispatcher());
+ }
+}
+
+void DragDropController::DragUpdate(aura::Window* target,
+ const aura::MouseEvent& event) {
+ if (target != dragged_window_) {
+ if (dragged_window_ && dragged_window_->drag_drop_delegate())
+ dragged_window_->drag_drop_delegate()->OnDragExited();
+
+ dragged_window_ = target;
+ if (dragged_window_ && dragged_window_->drag_drop_delegate()) {
+ aura::DropTargetEvent e(*drag_data_, event.location(), drag_operation_);
+ if (dragged_window_->drag_drop_delegate()->CanDrop(e))
+ dragged_window_->drag_drop_delegate()->OnDragEntered(e);
+ }
+ } else {
+ if (dragged_window_ && dragged_window_->drag_drop_delegate()) {
+ aura::DropTargetEvent e(*drag_data_, event.location(), drag_operation_);
+ dragged_window_->drag_drop_delegate()->OnDragUpdated(e);
+ // TODO(varunjain): uncomment the following lines when cursor issue with
+ // X for tests is fixed.
+ // gfx::NativeCursor cursor = (op == ui::DragDropTypes::DRAG_NONE)?
+ // aura::kCursorMove : aura::kCursorHand;
+ // Desktop::GetInstance()->SetCursor(cursor);
+ }
+ }
+
+ DCHECK(drag_widget_.get());
+ if (drag_widget_->IsVisible()) {
+ gfx::Rect bounds = drag_widget_->GetClientAreaScreenBounds();
+ bounds.set_origin(Desktop::GetInstance()->last_mouse_location());
+ drag_widget_->SetBounds(bounds);
Ben Goodger (Google) 2011/11/11 17:26:53 And this would become drag_image_->SetPosition(Des
varunjain 2011/11/15 19:39:33 Done.
+ }
+}
+
+void DragDropController::Drop(aura::Window* target,
+ const aura::MouseEvent& event) {
+ DCHECK(target == dragged_window_);
+ if (dragged_window_ && dragged_window_->drag_drop_delegate() ) {
+ aura::DropTargetEvent e(*drag_data_, event.location(), drag_operation_);
+ if (dragged_window_->drag_drop_delegate()->CanDrop(e))
+ dragged_window_->drag_drop_delegate()->OnPerformDrop(e);
+ // TODO(varunjain): else Do drag widget flying back animation
+ }
+
+ Cleanup();
+ if (should_block_during_drag_drop_)
+ MessageLoop::current()->Quit();
+}
+
+void DragDropController::DragCancel() {
+ // TODO(varunjain): Do drag widget flying back animation
+ Cleanup();
+ if (should_block_during_drag_drop_)
+ MessageLoop::current()->Quit();
+}
+
+bool DragDropController::IsDragAndDropInProgress() {
+ return drag_drop_in_progress_;
+}
+
+void DragDropController::Cleanup() {
+ if (drag_widget_.get())
+ drag_widget_->Hide();
Ben Goodger (Google) 2011/11/11 17:26:53 This should all be done by drag_image_'s dtor.
varunjain 2011/11/15 19:39:33 Done.
+ drag_widget_.reset();
+ drag_data_ = NULL;
+ drag_operation_ = 0;
+ drag_drop_in_progress_ = false;
+}
+
+} // namespace internal
+} // namespace aura_shell

Powered by Google App Engine
This is Rietveld 408576698