diff options
author | koz@chromium.org <koz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-20 22:21:32 +0000 |
---|---|---|
committer | koz@chromium.org <koz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-20 22:21:32 +0000 |
commit | 9f355b3532d7290c42fae45be52691a3cf28ebeb (patch) | |
tree | 8e37fe24c5fe1c7cb1fec6798f02be11df8104fe /ui/app_list | |
parent | 4abf5b4c8ed2e74163475a59296e8ba87c98717a (diff) | |
download | chromium_src-9f355b3532d7290c42fae45be52691a3cf28ebeb.zip chromium_src-9f355b3532d7290c42fae45be52691a3cf28ebeb.tar.gz chromium_src-9f355b3532d7290c42fae45be52691a3cf28ebeb.tar.bz2 |
[Win] App launcher drag/drop.
This allows icons to be dragged from the windows App Launcher to the taskbar.
BUG=153335
Review URL: https://chromiumcodereview.appspot.com/17370003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@207608 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/app_list')
-rw-r--r-- | ui/app_list/app_list_view_delegate.h | 11 | ||||
-rw-r--r-- | ui/app_list/apps_grid_view_delegate.h | 11 | ||||
-rw-r--r-- | ui/app_list/test/app_list_test_view_delegate.cc | 8 | ||||
-rw-r--r-- | ui/app_list/test/app_list_test_view_delegate.h | 4 | ||||
-rw-r--r-- | ui/app_list/views/app_list_item_view.cc | 19 | ||||
-rw-r--r-- | ui/app_list/views/app_list_item_view.h | 2 | ||||
-rw-r--r-- | ui/app_list/views/app_list_main_view.cc | 12 | ||||
-rw-r--r-- | ui/app_list/views/app_list_main_view.h | 3 | ||||
-rw-r--r-- | ui/app_list/views/apps_grid_view.cc | 239 | ||||
-rw-r--r-- | ui/app_list/views/apps_grid_view.h | 51 | ||||
-rw-r--r-- | ui/app_list/views/apps_grid_view_unittest.cc | 2 |
11 files changed, 334 insertions, 28 deletions
diff --git a/ui/app_list/app_list_view_delegate.h b/ui/app_list/app_list_view_delegate.h index 1e1150b..bd7e3d3 100644 --- a/ui/app_list/app_list_view_delegate.h +++ b/ui/app_list/app_list_view_delegate.h @@ -5,9 +5,14 @@ #ifndef UI_APP_LIST_APP_LIST_VIEW_DELEGATE_H_ #define UI_APP_LIST_APP_LIST_VIEW_DELEGATE_H_ +#include "base/callback_forward.h" #include "base/strings/string16.h" #include "ui/app_list/app_list_export.h" +namespace base { +class FilePath; +} + namespace gfx { class ImageSkia; } @@ -31,6 +36,12 @@ class APP_LIST_EXPORT AppListViewDelegate { // Gets the SigninDelegate for the app list. Owned by the AppListViewDelegate. virtual SigninDelegate* GetSigninDelegate() = 0; + // Gets a path to a shortcut for the given app. Returns asynchronously as the + // shortcut may not exist yet. + virtual void GetShortcutPathForApp( + const std::string& app_id, + const base::Callback<void(const base::FilePath&)>& callback) = 0; + // Invoked when an AppListeItemModelView is activated by click or enter key. virtual void ActivateAppListItem(AppListItemModel* item, int event_flags) = 0; diff --git a/ui/app_list/apps_grid_view_delegate.h b/ui/app_list/apps_grid_view_delegate.h index 90a892b..59dc8f6 100644 --- a/ui/app_list/apps_grid_view_delegate.h +++ b/ui/app_list/apps_grid_view_delegate.h @@ -5,8 +5,13 @@ #ifndef UI_APP_LIST_APPS_GRID_VIEW_DELEGATE_H_ #define UI_APP_LIST_APPS_GRID_VIEW_DELEGATE_H_ +#include "base/callback_forward.h" #include "ui/app_list/app_list_export.h" +namespace base { +class FilePath; +} + namespace app_list { class AppListItemModel; @@ -17,6 +22,12 @@ class APP_LIST_EXPORT AppsGridViewDelegate { // the flags of the keyboard/mouse event that triggers the activation request. virtual void ActivateApp(AppListItemModel* item, int event_flags) = 0; + // Gets the path to a shortcut for the app represented by |item|. |callback| + // may be run immediately. + virtual void GetShortcutPathForApp( + const std::string& app_id, + const base::Callback<void(const base::FilePath&)>& callback) = 0; + protected: virtual ~AppsGridViewDelegate() {} }; diff --git a/ui/app_list/test/app_list_test_view_delegate.cc b/ui/app_list/test/app_list_test_view_delegate.cc index 6012933..1b7937f 100644 --- a/ui/app_list/test/app_list_test_view_delegate.cc +++ b/ui/app_list/test/app_list_test_view_delegate.cc @@ -4,6 +4,8 @@ #include "ui/app_list/test/app_list_test_view_delegate.h" +#include "base/callback.h" +#include "base/files/file_path.h" #include "ui/gfx/image/image_skia.h" namespace app_list { @@ -21,6 +23,12 @@ SigninDelegate* AppListTestViewDelegate::GetSigninDelegate() { return NULL; } +void AppListTestViewDelegate::GetShortcutPathForApp( + const std::string& app_id, + const base::Callback<void(const base::FilePath&)>& callback) { + callback.Run(base::FilePath()); +} + void AppListTestViewDelegate::ActivateAppListItem(AppListItemModel* item, int event_flags) { last_activated_ = item; diff --git a/ui/app_list/test/app_list_test_view_delegate.h b/ui/app_list/test/app_list_test_view_delegate.h index f28fb050..f14dcc9 100644 --- a/ui/app_list/test/app_list_test_view_delegate.h +++ b/ui/app_list/test/app_list_test_view_delegate.h @@ -5,6 +5,7 @@ #ifndef UI_APP_LIST_TEST_APP_LIST_TEST_VIEW_DELEGATE_H_ #define UI_APP_LIST_TEST_APP_LIST_TEST_VIEW_DELEGATE_H_ +#include "base/callback_forward.h" #include "base/compiler_specific.h" #include "ui/app_list/app_list_view_delegate.h" @@ -24,6 +25,9 @@ class AppListTestViewDelegate : public AppListViewDelegate { // AppListViewDelegate overrides: virtual void SetModel(AppListModel* model) OVERRIDE {} virtual SigninDelegate* GetSigninDelegate() OVERRIDE; + virtual void GetShortcutPathForApp( + const std::string& app_id, + const base::Callback<void(const base::FilePath&)>& callback) OVERRIDE; virtual void ActivateAppListItem(AppListItemModel* item, int event_flags) OVERRIDE; virtual void StartSearch() OVERRIDE {} diff --git a/ui/app_list/views/app_list_item_view.cc b/ui/app_list/views/app_list_item_view.cc index be422c2..ce483e2 100644 --- a/ui/app_list/views/app_list_item_view.cc +++ b/ui/app_list/views/app_list_item_view.cc @@ -14,6 +14,7 @@ #include "ui/app_list/views/cached_label.h" #include "ui/base/accessibility/accessible_view_state.h" #include "ui/base/animation/throb_animation.h" +#include "ui/base/dragdrop/drag_utils.h" #include "ui/base/resource/resource_bundle.h" #include "ui/compositor/layer.h" #include "ui/compositor/scoped_layer_animation_settings.h" @@ -25,6 +26,7 @@ #include "ui/views/controls/label.h" #include "ui/views/controls/menu/menu_item_view.h" #include "ui/views/controls/menu/menu_runner.h" +#include "ui/views/drag_controller.h" namespace app_list { @@ -170,6 +172,14 @@ void AppListItemView::Prerender() { title_->PaintToBackingImage(); } +gfx::ImageSkia AppListItemView::GetDragImage() { + gfx::Canvas canvas(size(), ui::SCALE_FACTOR_100P, false /* is_opaque */); + gfx::Rect bounds(size()); + canvas.DrawColor(SK_ColorTRANSPARENT); + PaintChildren(&canvas); + return gfx::ImageSkia(canvas.ExtractImageRep()); +} + void AppListItemView::ItemIconChanged() { UpdateIcon(); } @@ -340,15 +350,20 @@ void AppListItemView::OnMouseReleased(const ui::MouseEvent& event) { } void AppListItemView::OnMouseCaptureLost() { + // We don't cancel the dag on mouse capture lost for windows as entering a + // synchronous drag causes mouse capture to be lost and pressing escape + // dismisses the app list anyway. +#if !defined(OS_WIN) CustomButton::OnMouseCaptureLost(); apps_grid_view_->EndDrag(true); mouse_drag_timer_.Stop(); SetUIState(UI_STATE_NORMAL); +#endif } bool AppListItemView::OnMouseDragged(const ui::MouseEvent& event) { CustomButton::OnMouseDragged(event); - apps_grid_view_->UpdateDrag(this, AppsGridView::MOUSE, event); + apps_grid_view_->UpdateDragFromItem(AppsGridView::MOUSE, event); // Shows dragging UI when it's confirmed without waiting for the timer. if (ui_state_ != UI_STATE_DRAGGING && @@ -370,7 +385,7 @@ void AppListItemView::OnGestureEvent(ui::GestureEvent* event) { break; case ui::ET_GESTURE_SCROLL_UPDATE: if (touch_dragging_) { - apps_grid_view_->UpdateDrag(this, AppsGridView::TOUCH, *event); + apps_grid_view_->UpdateDragFromItem(AppsGridView::TOUCH, *event); event->SetHandled(); } break; diff --git a/ui/app_list/views/app_list_item_view.h b/ui/app_list/views/app_list_item_view.h index 2a5b4a7..8ab3aa7 100644 --- a/ui/app_list/views/app_list_item_view.h +++ b/ui/app_list/views/app_list_item_view.h @@ -48,6 +48,8 @@ class APP_LIST_EXPORT AppListItemView : public views::CustomButton, const views::Label* title() const { return title_; } + gfx::ImageSkia GetDragImage(); + private: enum UIState { UI_STATE_NORMAL, // Normal UI (icon + label) diff --git a/ui/app_list/views/app_list_main_view.cc b/ui/app_list/views/app_list_main_view.cc index f7a9159..d3791ad 100644 --- a/ui/app_list/views/app_list_main_view.cc +++ b/ui/app_list/views/app_list_main_view.cc @@ -6,6 +6,8 @@ #include <algorithm> +#include "base/callback.h" +#include "base/files/file_path.h" #include "base/strings/string_util.h" #include "ui/app_list/app_list_constants.h" #include "ui/app_list/app_list_item_model.h" @@ -188,6 +190,16 @@ void AppListMainView::ActivateApp(AppListItemModel* item, int event_flags) { delegate_->ActivateAppListItem(item, event_flags); } +void AppListMainView::GetShortcutPathForApp( + const std::string& app_id, + const base::Callback<void(const base::FilePath&)>& callback) { + if (delegate_) { + delegate_->GetShortcutPathForApp(app_id, callback); + return; + } + callback.Run(base::FilePath()); +} + void AppListMainView::QueryChanged(SearchBoxView* sender) { base::string16 query; TrimWhitespace(model_->search_box()->text(), TRIM_ALL, &query); diff --git a/ui/app_list/views/app_list_main_view.h b/ui/app_list/views/app_list_main_view.h index c962e17..6c7f6c7 100644 --- a/ui/app_list/views/app_list_main_view.h +++ b/ui/app_list/views/app_list_main_view.h @@ -69,6 +69,9 @@ class AppListMainView : public views::View, // Overridden from AppsGridViewDelegate: virtual void ActivateApp(AppListItemModel* item, int event_flags) OVERRIDE; + virtual void GetShortcutPathForApp( + const std::string& app_id, + const base::Callback<void(const base::FilePath&)>& callback) OVERRIDE; // Overridden from SearchBoxViewDelegate: virtual void QueryChanged(SearchBoxView* sender) OVERRIDE; diff --git a/ui/app_list/views/apps_grid_view.cc b/ui/app_list/views/apps_grid_view.cc index c957fc1..c3e0c61 100644 --- a/ui/app_list/views/apps_grid_view.cc +++ b/ui/app_list/views/apps_grid_view.cc @@ -24,6 +24,16 @@ #include "ui/aura/root_window.h" #endif +#if defined(OS_WIN) && !defined(USE_AURA) +#include "base/command_line.h" +#include "base/files/file_path.h" +#include "base/win/shortcut.h" +#include "ui/base/dragdrop/drag_utils.h" +#include "ui/base/dragdrop/drop_target_win.h" +#include "ui/base/dragdrop/os_exchange_data.h" +#include "ui/base/dragdrop/os_exchange_data_provider_win.h" +#endif + namespace { // Padding space in pixels for fixed layout. @@ -106,6 +116,121 @@ class RowMoveAnimationDelegate namespace app_list { +#if defined(OS_WIN) && !defined(USE_AURA) +// Interprets drag events sent from Windows via the drag/drop API and forwards +// them to AppsGridView. +// On Windows, in order to have the OS perform the drag properly we need to +// provide it with a shortcut file which may or may not exist at the time the +// drag is started. Therefore while waiting for that shortcut to be located we +// just do a regular "internal" drag and transition into the synchronous drag +// when the shortcut is found/created. Hence a synchronous drag is an optional +// phase of a regular drag and non-Windows platforms drags are equivalent to a +// Windows drag that never enters the synchronous drag phase. +class SynchronousDrag : public ui::DragSourceWin { + public: + SynchronousDrag(app_list::AppsGridView* grid_view, + app_list::AppListItemView* drag_view, + const gfx::Point& drag_view_offset) + : grid_view_(grid_view), + drag_view_(drag_view), + drag_view_offset_(drag_view_offset), + has_shortcut_path_(false), + running_(false), + canceled_(false) { + } + + void set_shortcut_path(const base::FilePath& shortcut_path) { + has_shortcut_path_ = true; + shortcut_path_ = shortcut_path; + } + + bool CanRun() { + return has_shortcut_path_ && !running_; + } + + void Run() { + DCHECK(CanRun()); + running_ = true; + + ui::OSExchangeData data; + SetupExchangeData(&data); + + // Hide the dragged view because the OS is going to create its own. + const gfx::Size drag_view_size = drag_view_->size(); + drag_view_->SetSize(gfx::Size(0, 0)); + + // Blocks until the drag is finished. Calls into the ui::DragSourceWin + // methods. + DWORD effects; + DoDragDrop(ui::OSExchangeDataProviderWin::GetIDataObject(data), + this, DROPEFFECT_MOVE | DROPEFFECT_LINK, &effects); + + // Restore the dragged view to its original size. + drag_view_->SetSize(drag_view_size); + + grid_view_->EndDrag(canceled_ || !IsCursorWithinGridView()); + } + + private: + // Overridden from ui::DragSourceWin. + virtual void OnDragSourceCancel() OVERRIDE { + canceled_ = true; + } + + virtual void OnDragSourceDrop() OVERRIDE { + } + + virtual void OnDragSourceMove() OVERRIDE { + grid_view_->UpdateDrag(app_list::AppsGridView::MOUSE, + GetCursorInGridViewCoords()); + + // Don't turn pages if the cursor is dragged outside the view. + if (!IsCursorWithinGridView()) + grid_view_->StopPageFlipTimer(); + } + + void SetupExchangeData(ui::OSExchangeData* data) { + data->SetFilename(shortcut_path_); + gfx::ImageSkia image(drag_view_->GetDragImage()); + gfx::Size image_size(image.size()); + drag_utils::SetDragImageOnDataObject( + image, + image.size(), + gfx::Vector2d(drag_view_offset_.x(), drag_view_offset_.y()), + data); + } + + HWND GetGridViewHWND() { + return grid_view_->GetWidget()->GetTopLevelWidget()->GetNativeView(); + } + + bool IsCursorWithinGridView() { + POINT p; + GetCursorPos(&p); + return GetGridViewHWND() == WindowFromPoint(p); + } + + gfx::Point GetCursorInGridViewCoords() { + POINT p; + GetCursorPos(&p); + ScreenToClient(GetGridViewHWND(), &p); + gfx::Point grid_view_pt(p.x, p.y); + views::View::ConvertPointFromWidget(grid_view_, &grid_view_pt); + return grid_view_pt; + } + + app_list::AppsGridView* grid_view_; + app_list::AppListItemView* drag_view_; + gfx::Point drag_view_offset_; + bool has_shortcut_path_; + base::FilePath shortcut_path_; + bool running_; + bool canceled_; + + DISALLOW_COPY_AND_ASSIGN(SynchronousDrag); +}; +#endif // defined(OS_WIN) && !defined(USE_AURA) + AppsGridView::AppsGridView(AppsGridViewDelegate* delegate, PaginationModel* pagination_model) : model_(NULL), @@ -217,33 +342,88 @@ void AppsGridView::InitiateDrag(AppListItemView* view, kDragAndDropProxyScale); HideView(drag_view_, true); } - drag_start_ = event.location(); + drag_view_offset_ = event.location(); + ExtractDragLocation(event, &drag_start_grid_view_); + drag_view_start_ = gfx::Point(drag_view_->x(), drag_view_->y()); +} + +void AppsGridView::OnGotShortcutPath(const base::FilePath& path) { +#if defined(OS_WIN) && !defined(USE_AURA) + // Drag may have ended before we get the shortcut path. + if (!synchronous_drag_) + return; + // Setting the shortcut path here means the next time we hit UpdateDrag() + // we'll enter the synchronous drag. + // NOTE we don't Run() the drag here because that causes animations not to + // update for some reason. + synchronous_drag_->set_shortcut_path(path); + DCHECK(synchronous_drag_->CanRun()); +#endif +} + +void AppsGridView::StartSettingUpSynchronousDrag() { +#if defined(OS_WIN) && !defined(USE_AURA) + delegate_->GetShortcutPathForApp( + drag_view_->model()->app_id(), + base::Bind(&AppsGridView::OnGotShortcutPath, base::Unretained(this))); + synchronous_drag_ = new SynchronousDrag(this, drag_view_, drag_view_offset_); +#endif +} + +bool AppsGridView::RunSynchronousDrag() { +#if defined(OS_WIN) && !defined(USE_AURA) + if (synchronous_drag_ && synchronous_drag_->CanRun()) { + synchronous_drag_->Run(); + synchronous_drag_ = NULL; + return true; + } +#endif + return false; +} + +void AppsGridView::CleanUpSynchronousDrag() { +#if defined(OS_WIN) && !defined(USE_AURA) + synchronous_drag_ = NULL; +#endif +} + +void AppsGridView::UpdateDragFromItem(Pointer pointer, + const ui::LocatedEvent& event) { + gfx::Point drag_point_in_grid_view; + ExtractDragLocation(event, &drag_point_in_grid_view); + UpdateDrag(pointer, drag_point_in_grid_view); + + // If a drag and drop host is provided, see if the drag operation needs to be + // forwarded. + DispatchDragEventToDragAndDropHost(event.root_location()); + if (drag_and_drop_host_) + drag_and_drop_host_->UpdateDragIconProxy(event.root_location()); } -void AppsGridView::UpdateDrag(AppListItemView* view, - Pointer pointer, - const ui::LocatedEvent& event) { +void AppsGridView::UpdateDrag(Pointer pointer, const gfx::Point& point) { // EndDrag was called before if |drag_view_| is NULL. if (!drag_view_) return; - if (!dragging() && ExceededDragThreshold(event.location() - drag_start_)) { + if (RunSynchronousDrag()) + return; + + gfx::Vector2d drag_vector(point - drag_start_grid_view_); + if (!dragging() && ExceededDragThreshold(drag_vector)) { drag_pointer_ = pointer; // Move the view to the front so that it appears on top of other views. ReorderChildView(drag_view_, -1); bounds_animator_.StopAnimatingView(drag_view_); + StartSettingUpSynchronousDrag(); } + if (drag_pointer_ != pointer) return; - ExtractDragLocation(event, &last_drag_point_); + last_drag_point_ = point; const Index last_drop_target = drop_target_; CalculateDropTarget(last_drag_point_, false); - // If a drag and drop host is provided, see if the drag operation needs to be - // forwarded. - DispatchDragEventToDragAndDropHost(event); - MaybeStartPageFlipTimer(last_drag_point_); gfx::Point page_switcher_point(last_drag_point_); @@ -254,11 +434,7 @@ void AppsGridView::UpdateDrag(AppListItemView* view, if (last_drop_target != drop_target_) AnimateToIdealBounds(); - if (drag_and_drop_host_) - drag_and_drop_host_->UpdateDragIconProxy(event.root_location()); - - drag_view_->SetPosition( - gfx::PointAtOffsetFromOrigin(last_drag_point_ - drag_start_)); + drag_view_->SetPosition(drag_view_start_ + drag_vector); } void AppsGridView::EndDrag(bool cancel) { @@ -282,11 +458,19 @@ void AppsGridView::EndDrag(bool cancel) { HideView(drag_view_, false); } + // The drag can be ended after the synchronous drag is created but before it + // is Run(). + CleanUpSynchronousDrag(); + drag_pointer_ = NONE; drop_target_ = Index(); drag_view_ = NULL; AnimateToIdealBounds(); + StopPageFlipTimer(); +} + +void AppsGridView::StopPageFlipTimer() { page_flip_timer_.Stop(); page_flip_target_ = -1; } @@ -323,6 +507,22 @@ gfx::Size AppsGridView::GetPreferredSize() { page_switcher_height + insets.height()); } +bool AppsGridView::GetDropFormats( + int* formats, + std::set<OSExchangeData::CustomFormat>* custom_formats) { + // TODO(koz): Only accept a specific drag type for app shortcuts. + *formats = OSExchangeData::FILE_NAME; + return true; +} + +bool AppsGridView::CanDrop(const OSExchangeData& data) { + return true; +} + +int AppsGridView::OnDragUpdated(const ui::DropTargetEvent& event) { + return ui::DragDropTypes::DRAG_MOVE; +} + void AppsGridView::Layout() { if (bounds_animator_.IsAnimating()) bounds_animator_.Cancel(); @@ -747,7 +947,7 @@ void AppsGridView::CalculateDropTarget(const gfx::Point& drag_point, } void AppsGridView::DispatchDragEventToDragAndDropHost( - const ui::LocatedEvent& event) { + const gfx::Point& point) { if (!drag_view_ || !drag_and_drop_host_) return; if (bounds().Contains(last_drag_point_)) { @@ -762,19 +962,18 @@ void AppsGridView::DispatchDragEventToDragAndDropHost( // The event happened outside our app menu and we might need to dispatch. if (forward_events_to_drag_and_drop_host_) { // Dispatch since we have already started. - if (!drag_and_drop_host_->Drag(event.root_location())) { + if (!drag_and_drop_host_->Drag(point)) { // The host is not active any longer and we cancel the operation. forward_events_to_drag_and_drop_host_ = false; drag_and_drop_host_->EndDrag(true); } } else { if (drag_and_drop_host_->StartDrag(drag_view_->model()->app_id(), - event.root_location())) { + point)) { // From now on we forward the drag events. forward_events_to_drag_and_drop_host_ = true; // Any flip operations are stopped. - page_flip_timer_.Stop(); - page_flip_target_ = -1; + StopPageFlipTimer(); } } } diff --git a/ui/app_list/views/apps_grid_view.h b/ui/app_list/views/apps_grid_view.h index 483f737..d8abac2 100644 --- a/ui/app_list/views/apps_grid_view.h +++ b/ui/app_list/views/apps_grid_view.h @@ -18,6 +18,10 @@ #include "ui/views/view.h" #include "ui/views/view_model.h" +#if defined(OS_WIN) && !defined(USE_AURA) +#include "ui/base/dragdrop/drag_source_win.h" +#endif + namespace views { class ButtonListener; class DragImageView; @@ -25,6 +29,10 @@ class DragImageView; namespace app_list { +#if defined(OS_WIN) && !defined(USE_AURA) +class SynchronousDrag; +#endif + namespace test { class AppsGridViewTestApi; } @@ -70,12 +78,22 @@ class APP_LIST_EXPORT AppsGridView : public views::View, void InitiateDrag(AppListItemView* view, Pointer pointer, const ui::LocatedEvent& event); - void UpdateDrag(AppListItemView* view, - Pointer pointer, - const ui::LocatedEvent& event); + + // Called from AppListItemView when it receives a drag event. + void UpdateDragFromItem(Pointer pointer, + const ui::LocatedEvent& event); + + // Called when the user is dragging an app. |point| is in grid view + // coordinates. + void UpdateDrag(Pointer pointer, const gfx::Point& point); void EndDrag(bool cancel); bool IsDraggedView(const views::View* view) const; + void StartSettingUpSynchronousDrag(); + bool RunSynchronousDrag(); + void CleanUpSynchronousDrag(); + void OnGotShortcutPath(const base::FilePath& path); + // Set the drag and drop host for application links. void SetDragAndDropHostOfCurrentAppList( ApplicationDragAndDropHost* drag_and_drop_host); @@ -93,6 +111,14 @@ class APP_LIST_EXPORT AppsGridView : public views::View, virtual bool OnKeyReleased(const ui::KeyEvent& event) OVERRIDE; virtual void ViewHierarchyChanged( const ViewHierarchyChangedDetails& details) OVERRIDE; + virtual bool GetDropFormats( + int* formats, + std::set<OSExchangeData::CustomFormat>* custom_formats) OVERRIDE; + virtual bool CanDrop(const OSExchangeData& data) OVERRIDE; + virtual int OnDragUpdated(const ui::DropTargetEvent& event) OVERRIDE; + + // Stops the timer that triggers a page flip during a drag. + void StopPageFlipTimer(); // Get the last grid view which was created. static AppsGridView* GetLastGridViewForTest(); @@ -177,7 +203,7 @@ class APP_LIST_EXPORT AppsGridView : public views::View, bool use_page_button_hovering); // Dispatch the drag and drop update event to the dnd host (if needed). - void DispatchDragEventToDragAndDropHost(const ui::LocatedEvent& event); + void DispatchDragEventToDragAndDropHost(const gfx::Point& point); // Starts the page flip timer if |drag_point| is in left/right side page flip // zone or is over page switcher. @@ -229,7 +255,22 @@ class APP_LIST_EXPORT AppsGridView : public views::View, views::View* selected_view_; AppListItemView* drag_view_; - gfx::Point drag_start_; + + // The point where the drag started in AppListItemView coordinates. + gfx::Point drag_view_offset_; + + // The point where the drag started in GridView coordinates. + gfx::Point drag_start_grid_view_; + + // The location of |drag_view_| when the drag started. + gfx::Point drag_view_start_; + +#if defined(OS_WIN) && !defined(USE_AURA) + // Created when a drag is started (ie: drag exceeds the drag threshold), but + // not Run() until supplied with a shortcut path. + scoped_refptr<SynchronousDrag> synchronous_drag_; +#endif + Pointer drag_pointer_; Index drop_target_; diff --git a/ui/app_list/views/apps_grid_view_unittest.cc b/ui/app_list/views/apps_grid_view_unittest.cc index 15eecc9..8934204 100644 --- a/ui/app_list/views/apps_grid_view_unittest.cc +++ b/ui/app_list/views/apps_grid_view_unittest.cc @@ -148,7 +148,7 @@ class AppsGridViewTest : public testing::Test { ui::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, translated_to, to, 0); - apps_grid_view_->UpdateDrag(view, pointer, drag_event); + apps_grid_view_->UpdateDragFromItem(pointer, drag_event); } void SimulateKeyPress(ui::KeyboardCode key_code) { |