First shot at implementing drag&drop for Aura

BUG=97845
TEST=none


Review URL: http://codereview.chromium.org/8450018

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110437 0039d316-1c4b-4281-b951-d872f2087c98
parent 211921f6
...@@ -27,7 +27,9 @@ ...@@ -27,7 +27,9 @@
'aura_switches.h', 'aura_switches.h',
'client/aura_constants.cc', 'client/aura_constants.cc',
'client/aura_constants.h', 'client/aura_constants.h',
'client/drag_drop_client.h',
'client/stacking_client.h', 'client/stacking_client.h',
'client/window_drag_drop_delegate.h',
'cursor.h', 'cursor.h',
'desktop_host.h', 'desktop_host.h',
'desktop_host_linux.cc', 'desktop_host_linux.cc',
......
...@@ -11,5 +11,7 @@ const char kRestoreBoundsKey[] = "RestoreBoundsKey"; ...@@ -11,5 +11,7 @@ const char kRestoreBoundsKey[] = "RestoreBoundsKey";
const char kShowStateKey[] = "ShowStateKey"; const char kShowStateKey[] = "ShowStateKey";
const char kTooltipTextKey[] = "TooltipTextKey"; const char kTooltipTextKey[] = "TooltipTextKey";
const char kModalKey[] = "ModalKey"; const char kModalKey[] = "ModalKey";
const char kDesktopDragDropClientKey[] = "DesktopDragDropClientKey";
const char kDragDropDelegateKey[] = "DragDropDelegateKey";
} // namespace aura } // namespace aura
...@@ -29,6 +29,13 @@ AURA_EXPORT extern const char kTooltipTextKey[]; ...@@ -29,6 +29,13 @@ AURA_EXPORT extern const char kTooltipTextKey[];
// A property key to store the boolean property of window modality. // A property key to store the boolean property of window modality.
AURA_EXPORT extern const char kModalKey[]; AURA_EXPORT extern const char kModalKey[];
// A property key to store the drag and drop client for the desktop. The type of
// the value is |aura::DragDropClient*|.
AURA_EXPORT extern const char kDesktopDragDropClientKey[];
// A property key to store the drag and drop delegate for a window. The type of
// the value is |aura::WindowDragDropDelegate*|.
AURA_EXPORT extern const char kDragDropDelegateKey[];
} // namespace aura } // namespace aura
#endif // UI_AURA_CLIENT_AURA_CONSTANTS_H_ #endif // UI_AURA_CLIENT_AURA_CONSTANTS_H_
// 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.
#ifndef UI_AURA_CLIENT_DRAG_DROP_CLIENT_H_
#define UI_AURA_CLIENT_DRAG_DROP_CLIENT_H_
#pragma once
#include "ui/aura/aura_export.h"
#include "ui/aura/event.h"
namespace ui {
class OSExchangeData;
}
namespace aura {
class Window;
// An interface implemented by an object that controls a drag and drop session.
class AURA_EXPORT DragDropClient {
public:
virtual ~DragDropClient() {}
// Initiates a drag and drop session
virtual void StartDragAndDrop(const ui::OSExchangeData& data,
int operation) = 0;
// Called when mouse is dragged during a drag and drop.
virtual void DragUpdate(aura::Window* target, const MouseEvent& event) = 0;
// Called when mouse is released during a drag and drop.
virtual void Drop(aura::Window* target, const MouseEvent& event) = 0;
// Called when a drag and drop session is cancelled.
virtual void DragCancel() = 0;
};
} // namespace aura
#endif // UI_AURA_CLIENT_DRAG_DROP_CLIENT_H_
// 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.
#ifndef UI_AURA_CLIENT_WINDOW_DRAG_DROP_DELEGATE_H_
#define UI_AURA_CLIENT_WINDOW_DRAG_DROP_DELEGATE_H_
#pragma once
#include "ui/aura/aura_export.h"
namespace aura {
class DropTargetEvent;
// Delegate interface for drag and drop actions on aura::Window.
class AURA_EXPORT WindowDragDropDelegate {
public:
// A window that supports drag and drop must override this and return true if
// data contains a type that may be dropped on this window.
virtual bool CanDrop(const DropTargetEvent& event) = 0;
// OnDragEntered is invoked when the mouse enters this window during a drag &
// drop session and CanDrop returns true. This is immediately
// followed by an invocation of OnDragUpdated, and eventually one of
// OnDragExited or OnPerformDrop.
virtual void OnDragEntered(const DropTargetEvent& event) = 0;
// Invoked during a drag and drop session while the mouse is over the window.
// This should return a bitmask of the DragDropTypes::DragOperation supported
// based on the location of the event. Return 0 to indicate the drop should
// not be accepted.
virtual int OnDragUpdated(const DropTargetEvent& event) = 0;
// Invoked during a drag and drop session when the mouse exits the window, or
// when the drag session was canceled and the mouse was over the window.
virtual void OnDragExited() = 0;
// Invoked during a drag and drop session when OnDragUpdated returns a valid
// operation and the user release the mouse.
virtual int OnPerformDrop(const DropTargetEvent& event) = 0;
protected:
virtual ~WindowDragDropDelegate() {}
};
} // namespace aura
#endif // UI_AURA_CLIENT_WINDOW_DRAG_DROP_DELEGATE_H_
...@@ -429,6 +429,10 @@ void Desktop::SetCapture(Window* window) { ...@@ -429,6 +429,10 @@ void Desktop::SetCapture(Window* window) {
mouse_pressed_handler_ = capture_window_; mouse_pressed_handler_ = capture_window_;
if (touch_event_handler_) if (touch_event_handler_)
touch_event_handler_ = capture_window_; touch_event_handler_ = capture_window_;
} else {
// When capture is lost, we must reset the event handlers.
mouse_pressed_handler_ = NULL;
touch_event_handler_ = NULL;
} }
} }
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/event_types.h" #include "base/event_types.h"
#include "base/time.h" #include "base/time.h"
#include "ui/aura/aura_export.h" #include "ui/aura/aura_export.h"
#include "ui/base/dragdrop/os_exchange_data.h"
#include "ui/base/events.h" #include "ui/base/events.h"
#include "ui/base/keycodes/keyboard_codes.h" #include "ui/base/keycodes/keyboard_codes.h"
#include "ui/gfx/point.h" #include "ui/gfx/point.h"
...@@ -180,6 +181,29 @@ class AURA_EXPORT KeyEvent : public Event { ...@@ -180,6 +181,29 @@ class AURA_EXPORT KeyEvent : public Event {
uint16 unmodified_character_; uint16 unmodified_character_;
}; };
class AURA_EXPORT DropTargetEvent : public LocatedEvent {
public:
DropTargetEvent(const ui::OSExchangeData& data,
const gfx::Point& location,
int source_operations)
: LocatedEvent(ui::ET_DROP_TARGET_EVENT, location, 0),
data_(data),
source_operations_(source_operations) {
}
const ui::OSExchangeData& data() const { return data_; }
int source_operations() const { return source_operations_; }
private:
// Data associated with the drag/drop session.
const ui::OSExchangeData& data_;
// Bitmask of supported ui::DragDropTypes::DragOperation by the source.
int source_operations_;
DISALLOW_COPY_AND_ASSIGN(DropTargetEvent);
};
} // namespace aura } // namespace aura
#endif // UI_AURA_EVENT_H_ #endif // UI_AURA_EVENT_H_
...@@ -45,6 +45,10 @@ ...@@ -45,6 +45,10 @@
'desktop_event_filter.h', 'desktop_event_filter.h',
'desktop_layout_manager.cc', 'desktop_layout_manager.cc',
'desktop_layout_manager.h', 'desktop_layout_manager.h',
'drag_drop_controller.cc',
'drag_drop_controller.h',
'drag_image_view.cc',
'drag_image_view.h',
'launcher/app_launcher_button.cc', 'launcher/app_launcher_button.cc',
'launcher/app_launcher_button.h', 'launcher/app_launcher_button.h',
'launcher/launcher.cc', 'launcher/launcher.cc',
...@@ -124,6 +128,7 @@ ...@@ -124,6 +128,7 @@
'sources': [ 'sources': [
'default_container_layout_manager_unittest.cc', 'default_container_layout_manager_unittest.cc',
'desktop_event_filter_unittest.cc', 'desktop_event_filter_unittest.cc',
'drag_drop_controller_unittest.cc',
'launcher/launcher_model_unittest.cc', 'launcher/launcher_model_unittest.cc',
'launcher/view_model_unittest.cc', 'launcher/view_model_unittest.cc',
'launcher/view_model_utils_unittest.cc', 'launcher/view_model_utils_unittest.cc',
......
// 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/client/aura_constants.h"
#include "ui/aura/client/window_drag_drop_delegate.h"
#include "ui/aura/desktop.h"
#include "ui/aura/window.h"
#include "ui/aura_shell/drag_image_view.h"
#include "ui/aura_shell/shell.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/widget/native_widget_aura.h"
namespace aura_shell {
namespace internal {
using aura::Desktop;
namespace {
aura::WindowDragDropDelegate* GetDragDropDelegate(aura::Window* window) {
if (!window)
return NULL;
void* prop = window->GetProperty(aura::kDragDropDelegateKey);
if (!prop)
return NULL;
return static_cast<aura::WindowDragDropDelegate*>(prop);
}
const gfx::Point kDragDropWidgetOffset(0, 0);
}
////////////////////////////////////////////////////////////////////////////////
// DragDropController, public:
DragDropController::DragDropController()
: aura::EventFilter(Desktop::GetInstance()),
drag_image_(NULL),
drag_data_(NULL),
drag_operation_(0),
dragged_window_(NULL),
drag_drop_in_progress_(false),
should_block_during_drag_drop_(true) {
Shell::GetInstance()->AddDesktopEventFilter(this);
}
DragDropController::~DragDropController() {
Shell::GetInstance()->RemoveDesktopEventFilter(this);
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;
drag_data_ = &data;
drag_operation_ = operation;
gfx::Point location = Desktop::GetInstance()->last_mouse_location();
const ui::OSExchangeDataProviderAura& provider =
static_cast<const ui::OSExchangeDataProviderAura&>(data.provider());
drag_image_.reset(new DragImageView);
drag_image_->SetImage(provider.drag_image());
drag_image_->SetScreenBounds(gfx::Rect(location.Add(kDragDropWidgetOffset),
drag_image_->GetPreferredSize()));
drag_image_->SetWidgetVisible(true);
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) {
aura::WindowDragDropDelegate* delegate = NULL;
if (target != dragged_window_) {
if ((delegate = GetDragDropDelegate(dragged_window_)))
delegate->OnDragExited();
dragged_window_ = target;
if ((delegate = GetDragDropDelegate(dragged_window_))) {
aura::DropTargetEvent e(*drag_data_, event.location(), drag_operation_);
if (delegate->CanDrop(e))
delegate->OnDragEntered(e);
}
} else {
if ((delegate = GetDragDropDelegate(dragged_window_))) {
aura::DropTargetEvent e(*drag_data_, event.location(), drag_operation_);
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_image_.get());
if (drag_image_->IsVisible()) {
drag_image_->SetScreenPosition(Desktop::GetInstance()->
last_mouse_location().Add(kDragDropWidgetOffset));
}
}
void DragDropController::Drop(aura::Window* target,
const aura::MouseEvent& event) {
aura::WindowDragDropDelegate* delegate = NULL;
DCHECK(target == dragged_window_);
if ((delegate = GetDragDropDelegate(dragged_window_))) {
aura::DropTargetEvent e(*drag_data_, event.location(), drag_operation_);
if (delegate->CanDrop(e))
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::PreHandleKeyEvent(aura::Window* target,
aura::KeyEvent* event) {
return false;
}
bool DragDropController::PreHandleMouseEvent(aura::Window* target,
aura::MouseEvent* event) {
if (!drag_drop_in_progress_)
return false;
switch (event->type()) {
case ui::ET_MOUSE_DRAGGED:
DragUpdate(target, *event);
break;
case ui::ET_MOUSE_RELEASED:
Drop(target, *event);
break;
case ui::ET_MOUSE_EXITED:
DragCancel();
break;
default:
NOTREACHED();
break;
}
return true;
}
ui::TouchStatus DragDropController::PreHandleTouchEvent(
aura::Window* target,
aura::TouchEvent* event) {
return ui::TOUCH_STATUS_UNKNOWN;
}
////////////////////////////////////////////////////////////////////////////////
// DragDropController, private:
void DragDropController::Cleanup() {
drag_image_.reset();
drag_data_ = NULL;
drag_operation_ = 0;
drag_drop_in_progress_ = false;
}
} // namespace internal
} // namespace aura_shell
// 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.
#ifndef UI_AURA_SHELL_DRAG_DROP_CONTROLLER_H_
#define UI_AURA_SHELL_DRAG_DROP_CONTROLLER_H_
#pragma once
#include "ui/aura_shell/aura_shell_export.h"
#include "ui/aura/client/drag_drop_client.h"
#include "ui/aura/event.h"
#include "ui/aura/event_filter.h"
#include "ui/base/dragdrop/os_exchange_data.h"
#include "ui/base/events.h"
#include "ui/gfx/point.h"
namespace aura {
class Window;
}
namespace aura_shell {
namespace test {
class DragDropControllerTest;
}
namespace internal {
class DragImageView;
class AURA_SHELL_EXPORT DragDropController : public aura::DragDropClient,
public aura::EventFilter {
public:
DragDropController();
virtual ~DragDropController();
void set_should_block_during_drag_drop(bool should_block_during_drag_drop) {
should_block_during_drag_drop_ = should_block_during_drag_drop;
}
// Overridden from aura::DragDropClient:
virtual void StartDragAndDrop(const ui::OSExchangeData& data,
int operation) OVERRIDE;
virtual void DragUpdate(aura::Window* target,
const aura::MouseEvent& event) OVERRIDE;
virtual void Drop(aura::Window* target,
const aura::MouseEvent& event) OVERRIDE;
virtual void DragCancel() OVERRIDE;
// Overridden from aura::EventFilter:
virtual bool PreHandleKeyEvent(aura::Window* target,
aura::KeyEvent* event) OVERRIDE;
virtual bool PreHandleMouseEvent(aura::Window* target,
aura::MouseEvent* event) OVERRIDE;
virtual ui::TouchStatus PreHandleTouchEvent(aura::Window* target,
aura::TouchEvent* event) OVERRIDE;
private:
friend class aura_shell::test::DragDropControllerTest;
// Helper method to reset everything.
void Cleanup();
scoped_ptr<DragImageView> drag_image_;
const ui::OSExchangeData* drag_data_;
int drag_operation_;
aura::Window* dragged_window_;
bool drag_drop_in_progress_;
// Indicates whether the caller should be blocked on a drag/drop session.
// Only be used for tests.
bool should_block_during_drag_drop_;
DISALLOW_COPY_AND_ASSIGN(DragDropController);
};
} // namespace internal
} // namespace aura_shell
#endif // UI_AURA_SHELL_DRAG_DROP_CONTROLLER_H_
This diff is collapsed.
// 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_image_view.h"
#include "views/widget/widget.h"
namespace aura_shell {
namespace internal {
namespace {
using views::Widget;
Widget* CreateDragWidget() {
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;
}
}
DragImageView::DragImageView() : views::ImageView() {
widget_.reset(CreateDragWidget());
widget_->SetContentsView(this);
widget_->SetAlwaysOnTop(true);
// We are owned by the DragDropController.
set_parent_owned(false);
}
DragImageView::~DragImageView() {
widget_->Hide();
}
void DragImageView::SetScreenBounds(const gfx::Rect& bounds) {
widget_->SetBounds(bounds);
}
void DragImageView::SetScreenPosition(const gfx::Point& position) {
widget_->SetBounds(gfx::Rect(position, GetPreferredSize()));
}
void DragImageView::SetWidgetVisible(bool visible) {
if (visible != widget_->IsVisible()) {
if (visible)
widget_->Show();
else
widget_->Hide();
}
}
} // namespace internal
} // namespace aura_shell
// 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.
#ifndef UI_AURA_SHELL_DRAG_IMAGE_VIEW_H_
#define UI_AURA_SHELL_DRAG_IMAGE_VIEW_H_
#pragma once
#include "views/controls/image_view.h"
namespace views {
class Widget;
}
namespace aura_shell {
namespace internal {
class DragImageView : public views::ImageView {
public:
DragImageView();
virtual ~DragImageView();
// Sets the bounds of the native widget.
void SetScreenBounds(const gfx::Rect& bounds);
// Sets the position of the native widget.
void SetScreenPosition(const gfx::Point& position);
// Sets the visibility of the native widget.
void SetWidgetVisible(bool visible);
private:
scoped_ptr<views::Widget> widget_;
DISALLOW_COPY_AND_ASSIGN(DragImageView);
};
} // namespace internal
} // namespace aura_shell
#endif // UI_AURA_SHELL_DRAG_IMAGE_VIEW_H_
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "ui/aura/aura_switches.h" #include "ui/aura/aura_switches.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/drag_drop_client.h"
#include "ui/aura/desktop.h" #include "ui/aura/desktop.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/aura/window_types.h" #include "ui/aura/window_types.h"
...@@ -14,6 +16,7 @@ ...@@ -14,6 +16,7 @@
#include "ui/aura_shell/default_container_layout_manager.h" #include "ui/aura_shell/default_container_layout_manager.h"
#include "ui/aura_shell/desktop_event_filter.h" #include "ui/aura_shell/desktop_event_filter.h"
#include "ui/aura_shell/desktop_layout_manager.h" #include "ui/aura_shell/desktop_layout_manager.h"
#include "ui/aura_shell/drag_drop_controller.h"
#include "ui/aura_shell/launcher/launcher.h" #include "ui/aura_shell/launcher/launcher.h"
#include "ui/aura_shell/modal_container_layout_manager.h" #include "ui/aura_shell/modal_container_layout_manager.h"
#include "ui/aura_shell/shelf_layout_controller.h" #include "ui/aura_shell/shelf_layout_controller.h"
...@@ -103,6 +106,9 @@ Shell::Shell(ShellDelegate* delegate) ...@@ -103,6 +106,9 @@ Shell::Shell(ShellDelegate* delegate)
} }
Shell::~Shell() { Shell::~Shell() {
// Drag drop controller needs a valid shell instance. We destroy it first.
drag_drop_controller_.reset();
DCHECK(instance_ == this); DCHECK(instance_ == this);
instance_ = NULL; instance_ = NULL;
...@@ -180,6 +186,11 @@ void Shell::Init() { ...@@ -180,6 +186,11 @@ void Shell::Init() {
// Force a layout. // Force a layout.
desktop_layout->OnWindowResized(); desktop_layout->OnWindowResized();
// Initialize drag drop controller.
drag_drop_controller_.reset(new internal::DragDropController);
aura::Desktop::GetInstance()->SetProperty(aura::kDesktopDragDropClientKey,
static_cast<aura::DragDropClient*>(drag_drop_controller_.get()));
} }
aura::Window* Shell::GetContainer(int container_id) { aura::Window* Shell::GetContainer(int container_id) {
......
...@@ -30,6 +30,7 @@ class Launcher; ...@@ -30,6 +30,7 @@ class Launcher;
class ShellDelegate; class ShellDelegate;
namespace internal { namespace internal {
class DragDropController;
class ShelfLayoutController; class ShelfLayoutController;
class WorkspaceController; class WorkspaceController;
} }
...@@ -84,6 +85,7 @@ class AURA_SHELL_EXPORT Shell { ...@@ -84,6 +85,7 @@ class AURA_SHELL_EXPORT Shell {
scoped_ptr<Launcher> launcher_; scoped_ptr<Launcher> launcher_;
scoped_ptr<internal::DragDropController> drag_drop_controller_;
scoped_ptr<internal::WorkspaceController> workspace_controller_; scoped_ptr<internal::WorkspaceController> workspace_controller_;
scoped_ptr<internal::ShelfLayoutController> shelf_layout_controller_; scoped_ptr<internal::ShelfLayoutController> shelf_layout_controller_;
......
...@@ -2,63 +2,154 @@ ...@@ -2,63 +2,154 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "ui/base/dragdrop/os_exchange_data.h" #include "ui/base/dragdrop/os_exchange_data_provider_aura.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/utf_string_conversions.h"
#include "net/base/net_util.h"
namespace ui { namespace ui {
// OSExchangeData::Provider implementation for aura on linux. OSExchangeDataProviderAura::OSExchangeDataProviderAura() : formats_(0) {}
class OSExchangeDataProviderAura : public OSExchangeData::Provider {
public:
OSExchangeDataProviderAura() {
NOTIMPLEMENTED();
}
virtual ~OSExchangeDataProviderAura() { void OSExchangeDataProviderAura::SetString(const string16& data) {
} string_ = data;
formats_ |= OSExchangeData::STRING;
}
virtual void SetString(const string16& data) OVERRIDE { void OSExchangeDataProviderAura::SetURL(const GURL& url,
} const string16& title) {
virtual void SetURL(const GURL& url, const string16& title) OVERRIDE { url_ = url;
title_ = title;
formats_ |= OSExchangeData::URL;
}
void OSExchangeDataProviderAura::SetFilename(const FilePath& path) {
filename_ = path;
formats_ |= OSExchangeData::FILE_NAME;
}
void OSExchangeDataProviderAura::SetPickledData(
OSExchangeData::CustomFormat format,
const Pickle& data) {
pickle_data_[format] = data;
formats_ |= OSExchangeData::PICKLED_DATA;
}
bool OSExchangeDataProviderAura::GetString(string16* data) const {
if ((formats_ & OSExchangeData::STRING) == 0)
return false;
*data = string_;
return true;
}
bool OSExchangeDataProviderAura::GetURLAndTitle(GURL* url,
string16* title) const {
if ((formats_ & OSExchangeData::URL) == 0) {
title->clear();
return GetPlainTextURL(url);
} }
virtual void SetFilename(const FilePath& path) OVERRIDE {
if (!url_.is_valid())
return false;
*url = url_;
*title = title_;
return true;
}
bool OSExchangeDataProviderAura::GetFilename(FilePath* path) const {
if ((formats_ & OSExchangeData::FILE_NAME) == 0)
return false;
*path = filename_;
return true;
}
bool OSExchangeDataProviderAura::GetPickledData(
OSExchangeData::CustomFormat format,
Pickle* data) const {
PickleData::const_iterator i = pickle_data_.find(format);
if (i == pickle_data_.end())
return false;
*data = i->second;
return true;
}
bool OSExchangeDataProviderAura::HasString() const {
return (formats_ & OSExchangeData::STRING) != 0;
}
bool OSExchangeDataProviderAura::HasURL() const {
if ((formats_ & OSExchangeData::URL) != 0) {
return true;
} }
virtual void SetPickledData(OSExchangeData::CustomFormat format, // No URL, see if we have plain text that can be parsed as a URL.
const Pickle& data) OVERRIDE { return GetPlainTextURL(NULL);
}
bool OSExchangeDataProviderAura::HasFile() const {
return (formats_ & OSExchangeData::FILE_NAME) != 0;
}
bool OSExchangeDataProviderAura::HasCustomFormat(
OSExchangeData::CustomFormat format) const {
return pickle_data_.find(format) != pickle_data_.end();
}
#if defined(OS_WIN)
void OSExchangeDataProviderAura::SetFileContents(
const FilePath& filename,
const std::string& file_contents) {
NOTIMPLEMENTED();
} }
virtual bool GetString(string16* data) const OVERRIDE { void OSExchangeDataProviderAura::SetHtml(const string16& html,
return false; const GURL& base_url) {
NOTIMPLEMENTED();
} }
virtual bool GetURLAndTitle(GURL* url, string16* title) const OVERRIDE {
bool OSExchangeDataProviderAura::GetFileContents(
FilePath* filename,
std::string* file_contents) const {
NOTIMPLEMENTED();
return false; return false;
} }
virtual bool GetFilename(FilePath* path) const OVERRIDE {
bool OSExchangeDataProviderAura::GetHtml(string16* html,
GURL* base_url) const {
NOTIMPLEMENTED();
return false; return false;
} }
virtual bool GetPickledData(OSExchangeData::CustomFormat format,
Pickle* data) const OVERRIDE { bool OSExchangeDataProviderAura::HasFileContents() const {
NOTIMPLEMENTED();
return false; return false;
} }
virtual bool HasString() const OVERRIDE { bool OSExchangeDataProviderAura::HasHtml() const {
NOTIMPLEMENTED();
return false; return false;
} }
virtual bool HasURL() const OVERRIDE {
return false; void OSExchangeDataProviderAura::SetDownloadFileInfo(
const OSExchangeData::DownloadFileInfo& download) {
NOTIMPLEMENTED();
} }
virtual bool HasFile() const OVERRIDE { #endif
bool OSExchangeDataProviderAura::GetPlainTextURL(GURL* url) const {
if ((formats_ & OSExchangeData::STRING) == 0)
return false; return false;
}
virtual bool HasCustomFormat( GURL test_url(string_);
OSExchangeData::CustomFormat format) const OVERRIDE { if (!test_url.is_valid())
return false; return false;
}
private: if (url)
DISALLOW_COPY_AND_ASSIGN(OSExchangeDataProviderAura); *url = test_url;
}; return true;
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// OSExchangeData, public: // OSExchangeData, public:
......
// 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.
#ifndef UI_BASE_DRAGDROP_OS_EXCHANGE_DATA_PROVIDER_AURA_H_
#define UI_BASE_DRAGDROP_OS_EXCHANGE_DATA_PROVIDER_AURA_H_
#pragma once
#include <map>
#include "ui/base/dragdrop/os_exchange_data.h"
#include "googleurl/src/gurl.h"
#include "base/pickle.h"
#include "base/file_path.h"
#include "third_party/skia/include/core/SkBitmap.h"
namespace ui {
// OSExchangeData::Provider implementation for aura on linux.
class UI_EXPORT OSExchangeDataProviderAura : public OSExchangeData::Provider {
public:
OSExchangeDataProviderAura();
virtual ~OSExchangeDataProviderAura() {}
// Overridden from OSExchangeData::Provider:
virtual void SetString(const string16& data) OVERRIDE;
virtual void SetURL(const GURL& url, const string16& title) OVERRIDE;
virtual void SetFilename(const FilePath& path) OVERRIDE;
virtual void SetPickledData(OSExchangeData::CustomFormat format,
const Pickle& data) OVERRIDE;
virtual bool GetString(string16* data) const OVERRIDE;
virtual bool GetURLAndTitle(GURL* url, string16* title) const OVERRIDE;
virtual bool GetFilename(FilePath* path) const OVERRIDE;
virtual bool GetPickledData(OSExchangeData::CustomFormat format,
Pickle* data) const OVERRIDE;
virtual bool HasString() const OVERRIDE;
virtual bool HasURL() const OVERRIDE;
virtual bool HasFile() const OVERRIDE;
virtual bool HasCustomFormat(
OSExchangeData::CustomFormat format) const OVERRIDE;
#if defined(OS_WIN)
virtual void SetFileContents(const FilePath& filename,
const std::string& file_contents) OVERRIDE;
virtual void SetHtml(const string16& html, const GURL& base_url) OVERRIDE;
virtual bool GetFileContents(FilePath* filename,
std::string* file_contents) const OVERRIDE;
virtual bool GetHtml(string16* html, GURL* base_url) const OVERRIDE;
virtual bool HasFileContents() const OVERRIDE;
virtual bool HasHtml() const OVERRIDE;
virtual void SetDownloadFileInfo(
const OSExchangeData::DownloadFileInfo& download) OVERRIDE;
#endif
void set_drag_image(const SkBitmap& drag_image) { drag_image_ = drag_image; }
const SkBitmap& drag_image() const { return drag_image_; }
private:
typedef std::map<OSExchangeData::CustomFormat, Pickle> PickleData;
// Returns true if |formats_| contains a string format and the string can be
// parsed as a URL.
bool GetPlainTextURL(GURL* url) const;
// Actual formats that have been set. See comment above |known_formats_|
// for details.
int formats_;
// String contents.
string16 string_;
// URL contents.
GURL url_;
string16 title_;
// File name.
FilePath filename_;
// PICKLED_DATA contents.
PickleData pickle_data_;
// Drag image and offset data.
SkBitmap drag_image_;
DISALLOW_COPY_AND_ASSIGN(OSExchangeDataProviderAura);
};
} // namespace ui
#endif // UI_BASE_DRAGDROP_OS_EXCHANGE_DATA_PROVIDER_AURA_H_
...@@ -97,6 +97,7 @@ ...@@ -97,6 +97,7 @@
'base/dragdrop/os_exchange_data.cc', 'base/dragdrop/os_exchange_data.cc',
'base/dragdrop/os_exchange_data.h', 'base/dragdrop/os_exchange_data.h',
'base/dragdrop/os_exchange_data_provider_aura.cc', 'base/dragdrop/os_exchange_data_provider_aura.cc',
'base/dragdrop/os_exchange_data_provider_aura.h',
'base/dragdrop/os_exchange_data_provider_gtk.cc', 'base/dragdrop/os_exchange_data_provider_gtk.cc',
'base/dragdrop/os_exchange_data_provider_gtk.h', 'base/dragdrop/os_exchange_data_provider_gtk.h',
'base/dragdrop/os_exchange_data_provider_win.cc', 'base/dragdrop/os_exchange_data_provider_win.cc',
...@@ -354,7 +355,8 @@ ...@@ -354,7 +355,8 @@
}], }],
['use_aura==1 and OS=="win"', { ['use_aura==1 and OS=="win"', {
'sources/': [ 'sources/': [
['exclude', 'base/dragdrop/os_exchange_data_provider_aura.cc'], ['exclude', 'base/dragdrop/os_exchange_data_provider_win.cc'],
['exclude', 'base/dragdrop/os_exchange_data_provider_win.h'],
['exclude', 'gfx/native_theme_win.cc'], ['exclude', 'gfx/native_theme_win.cc'],
['exclude', 'gfx/native_theme_win.h'], ['exclude', 'gfx/native_theme_win.h'],
['exclude', 'gfx/path_win.cc'], ['exclude', 'gfx/path_win.cc'],
......
// 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 "views/drag_utils.h"
#include "base/logging.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/dragdrop/os_exchange_data.h"
#include "ui/base/dragdrop/os_exchange_data_provider_aura.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/point.h"
#include "ui/gfx/size.h"
using ui::OSExchangeData;
using ui::OSExchangeDataProviderAura;
namespace drag_utils {
void SetDragImageOnDataObject(const SkBitmap& bitmap,
const gfx::Size& size,
const gfx::Point& cursor_offset,
OSExchangeData* data_object) {
OSExchangeDataProviderAura& provider(
static_cast<OSExchangeDataProviderAura&>(data_object->provider()));
provider.set_drag_image(bitmap);
}
} // namespace drag_utils
...@@ -256,6 +256,7 @@ ...@@ -256,6 +256,7 @@
'drag_controller.h', 'drag_controller.h',
'drag_utils.cc', 'drag_utils.cc',
'drag_utils.h', 'drag_utils.h',
'drag_utils_aura.cc',
'drag_utils_gtk.cc', 'drag_utils_gtk.cc',
'drag_utils_linux.cc', 'drag_utils_linux.cc',
'drag_utils_win.cc', 'drag_utils_win.cc',
...@@ -437,6 +438,8 @@ ...@@ -437,6 +438,8 @@
['exclude', 'controls/menu/menu_2.*'], ['exclude', 'controls/menu/menu_2.*'],
], ],
'sources!': [ 'sources!': [
'drag_utils_linux.cc',
'drag_utils_win.cc',
'controls/menu/menu_config_linux.cc', 'controls/menu/menu_config_linux.cc',
'controls/menu/menu_item_view_linux.cc', 'controls/menu/menu_item_view_linux.cc',
'controls/menu/menu_separator_linux.cc', 'controls/menu/menu_separator_linux.cc',
...@@ -462,18 +465,8 @@ ...@@ -462,18 +465,8 @@
'widget/child_window_message_processor.cc', 'widget/child_window_message_processor.cc',
'widget/child_window_message_processor.h', 'widget/child_window_message_processor.h',
], ],
'conditions': [ },
['OS=="win"', { ],
'sources/': [
['include', 'drag_utils_win.cc'],
],
}],
],
}, { # else: use_aura==1
'sources!': [
'drag_utils_linux.cc',
]
}],
['toolkit_uses_gtk == 1', { ['toolkit_uses_gtk == 1', {
'dependencies': [ 'dependencies': [
'../build/linux/system.gyp:gtk', '../build/linux/system.gyp:gtk',
......
...@@ -5,17 +5,21 @@ ...@@ -5,17 +5,21 @@
#include "views/widget/native_widget_aura.h" #include "views/widget/native_widget_aura.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/string_util.h"
#include "ui/aura/client/aura_constants.h" #include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/drag_drop_client.h"
#include "ui/aura/desktop.h" #include "ui/aura/desktop.h"
#include "ui/aura/desktop_observer.h" #include "ui/aura/desktop_observer.h"
#include "ui/aura/event.h" #include "ui/aura/event.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/aura/window_types.h" #include "ui/aura/window_types.h"
#include "ui/base/dragdrop/os_exchange_data.h"
#include "ui/base/ui_base_types.h" #include "ui/base/ui_base_types.h"
#include "ui/gfx/canvas.h" #include "ui/gfx/canvas.h"
#include "ui/gfx/compositor/layer.h" #include "ui/gfx/compositor/layer.h"
#include "ui/gfx/font.h" #include "ui/gfx/font.h"
#include "ui/gfx/screen.h" #include "ui/gfx/screen.h"
#include "views/widget/drop_helper.h"
#include "views/widget/native_widget_delegate.h" #include "views/widget/native_widget_delegate.h"
#include "views/widget/tooltip_manager_views.h" #include "views/widget/tooltip_manager_views.h"
...@@ -151,12 +155,18 @@ void NativeWidgetAura::InitNativeWidget(const Widget::InitParams& params) { ...@@ -151,12 +155,18 @@ void NativeWidgetAura::InitNativeWidget(const Widget::InitParams& params) {
// TODO(beng): do this some other way. // TODO(beng): do this some other way.
delegate_->OnNativeWidgetSizeChanged(params.bounds.size()); delegate_->OnNativeWidgetSizeChanged(params.bounds.size());
can_activate_ = params.can_activate; can_activate_ = params.can_activate;
DCHECK(GetWidget()->GetRootView());
if (params.type != Widget::InitParams::TYPE_TOOLTIP && !params.child) { if (params.type != Widget::InitParams::TYPE_TOOLTIP && !params.child) {
DCHECK(GetWidget()->GetRootView());
views::TooltipManagerViews* manager = new views::TooltipManagerViews( views::TooltipManagerViews* manager = new views::TooltipManagerViews(
GetWidget()->GetRootView()); GetWidget()->GetRootView());
tooltip_manager_.reset(manager); tooltip_manager_.reset(manager);
} }
drop_helper_.reset(new DropHelper(GetWidget()->GetRootView()));
if (params.type != Widget::InitParams::TYPE_TOOLTIP &&
params.type != Widget::InitParams::TYPE_POPUP) {
window_->SetProperty(aura::kDragDropDelegateKey,
static_cast<aura::WindowDragDropDelegate*>(this));
}
} }
NonClientFrameView* NativeWidgetAura::CreateNonClientFrameView() { NonClientFrameView* NativeWidgetAura::CreateNonClientFrameView() {
...@@ -473,8 +483,11 @@ bool NativeWidgetAura::IsAccessibleWidget() const { ...@@ -473,8 +483,11 @@ bool NativeWidgetAura::IsAccessibleWidget() const {
void NativeWidgetAura::RunShellDrag(View* view, void NativeWidgetAura::RunShellDrag(View* view,
const ui::OSExchangeData& data, const ui::OSExchangeData& data,
int operation) { int operation) {
// http://crbug.com/97845 aura::DragDropClient* client = static_cast<aura::DragDropClient*>(
NOTIMPLEMENTED(); aura::Desktop::GetInstance()->GetProperty(
aura::kDesktopDragDropClientKey));
if (client)
client->StartDragAndDrop(data, operation);
} }
void NativeWidgetAura::SchedulePaintInRect(const gfx::Rect& rect) { void NativeWidgetAura::SchedulePaintInRect(const gfx::Rect& rect) {
...@@ -626,6 +639,7 @@ void NativeWidgetAura::OnPaint(gfx::Canvas* canvas) { ...@@ -626,6 +639,7 @@ void NativeWidgetAura::OnPaint(gfx::Canvas* canvas) {
} }
void NativeWidgetAura::OnWindowDestroying() { void NativeWidgetAura::OnWindowDestroying() {
window_->SetProperty(aura::kDragDropDelegateKey, NULL);
delegate_->OnNativeWidgetDestroying(); delegate_->OnNativeWidgetDestroying();
// If the aura::Window is destroyed, we can no longer show tooltips. // If the aura::Window is destroyed, we can no longer show tooltips.
...@@ -644,6 +658,37 @@ void NativeWidgetAura::OnWindowVisibilityChanged(bool visible) { ...@@ -644,6 +658,37 @@ void NativeWidgetAura::OnWindowVisibilityChanged(bool visible) {
delegate_->OnNativeWidgetVisibilityChanged(visible); delegate_->OnNativeWidgetVisibilityChanged(visible);
} }
bool NativeWidgetAura::CanDrop(const aura::DropTargetEvent& event) {
DCHECK(drop_helper_.get() != NULL);
View* view = drop_helper_->target_view();
if (view)
return view->CanDrop(event.data());
return false;
}
void NativeWidgetAura::OnDragEntered(const aura::DropTargetEvent& event) {
DCHECK(drop_helper_.get() != NULL);
drop_helper_->OnDragOver(event.data(), event.location(),
event.source_operations());
}
int NativeWidgetAura::OnDragUpdated(const aura::DropTargetEvent& event) {
DCHECK(drop_helper_.get() != NULL);
return drop_helper_->OnDragOver(event.data(), event.location(),
event.source_operations());
}
void NativeWidgetAura::OnDragExited() {
DCHECK(drop_helper_.get() != NULL);
drop_helper_->OnDragExit();
}
int NativeWidgetAura::OnPerformDrop(const aura::DropTargetEvent& event) {
DCHECK(drop_helper_.get() != NULL);
return drop_helper_->OnDrop(event.data(), event.location(),
event.source_operations());
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Widget, public: // Widget, public:
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/memory/scoped_vector.h" #include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "ui/aura/client/window_drag_drop_delegate.h"
#include "ui/aura/window_delegate.h" #include "ui/aura/window_delegate.h"
#include "ui/base/events.h" #include "ui/base/events.h"
#include "views/views_export.h" #include "views/views_export.h"
...@@ -22,10 +23,12 @@ class Font; ...@@ -22,10 +23,12 @@ class Font;
namespace views { namespace views {
class DropHelper;
class TooltipManagerViews; class TooltipManagerViews;
class VIEWS_EXPORT NativeWidgetAura : public internal::NativeWidgetPrivate, class VIEWS_EXPORT NativeWidgetAura : public internal::NativeWidgetPrivate,
public aura::WindowDelegate { public aura::WindowDelegate,
public aura::WindowDragDropDelegate {
public: public:
explicit NativeWidgetAura(internal::NativeWidgetDelegate* delegate); explicit NativeWidgetAura(internal::NativeWidgetDelegate* delegate);
virtual ~NativeWidgetAura(); virtual ~NativeWidgetAura();
...@@ -139,6 +142,13 @@ class VIEWS_EXPORT NativeWidgetAura : public internal::NativeWidgetPrivate, ...@@ -139,6 +142,13 @@ class VIEWS_EXPORT NativeWidgetAura : public internal::NativeWidgetPrivate,
virtual void OnWindowDestroyed() OVERRIDE; virtual void OnWindowDestroyed() OVERRIDE;
virtual void OnWindowVisibilityChanged(bool visible) OVERRIDE; virtual void OnWindowVisibilityChanged(bool visible) OVERRIDE;
// Overridden from aura::WindowDragDropDelegate:
virtual bool CanDrop(const aura::DropTargetEvent& event) OVERRIDE;
virtual void OnDragEntered(const aura::DropTargetEvent& event) OVERRIDE;
virtual int OnDragUpdated(const aura::DropTargetEvent& event) OVERRIDE;
virtual void OnDragExited() OVERRIDE;
virtual int OnPerformDrop(const aura::DropTargetEvent& event) OVERRIDE;
private: private:
class DesktopObserverImpl; class DesktopObserverImpl;
...@@ -162,6 +172,8 @@ class VIEWS_EXPORT NativeWidgetAura : public internal::NativeWidgetPrivate, ...@@ -162,6 +172,8 @@ class VIEWS_EXPORT NativeWidgetAura : public internal::NativeWidgetPrivate,
scoped_ptr<DesktopObserverImpl> desktop_observer_; scoped_ptr<DesktopObserverImpl> desktop_observer_;
scoped_ptr<DropHelper> drop_helper_;
DISALLOW_COPY_AND_ASSIGN(NativeWidgetAura); DISALLOW_COPY_AND_ASSIGN(NativeWidgetAura);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment