summaryrefslogtreecommitdiffstats
path: root/ui/app_list
diff options
context:
space:
mode:
authorskuhne@chromium.org <skuhne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-08 21:40:08 +0000
committerskuhne@chromium.org <skuhne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-08 21:40:08 +0000
commit00c8469e26c18b47981a92931acbc209efa8c3e4 (patch)
tree17c1576f6737ce4d49500baf3805b92a6e4e0af0 /ui/app_list
parent993951d6500d51ee010103c7f8727eaa900bd563 (diff)
downloadchromium_src-00c8469e26c18b47981a92931acbc209efa8c3e4.zip
chromium_src-00c8469e26c18b47981a92931acbc209efa8c3e4.tar.gz
chromium_src-00c8469e26c18b47981a92931acbc209efa8c3e4.tar.bz2
This is the first of two patches to drag and drop items from the app list to the launcher.
Everything basically works with this patch, but two essential things are still missing: 1. The icon which gets dragged should get its own widget so that it can get visually dragged outside the app list. 2. The unit tests. They will be send as a second patch because of: a. The patch is already pretty big as it is. b. I want to make get this "signed off" before continuing this route. BUG=166429 TEST=visual, tests come with second patch Review URL: https://chromiumcodereview.appspot.com/14533006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@199016 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/app_list')
-rw-r--r--ui/app_list/app_list.gyp1
-rw-r--r--ui/app_list/app_list_item_model.h4
-rw-r--r--ui/app_list/views/app_list_drag_and_drop_host.h41
-rw-r--r--ui/app_list/views/app_list_main_view.cc5
-rw-r--r--ui/app_list/views/app_list_main_view.h6
-rw-r--r--ui/app_list/views/app_list_view.cc6
-rw-r--r--ui/app_list/views/app_list_view.h9
-rw-r--r--ui/app_list/views/apps_grid_view.cc55
-rw-r--r--ui/app_list/views/apps_grid_view.h21
-rw-r--r--ui/app_list/views/contents_view.cc18
-rw-r--r--ui/app_list/views/contents_view.h9
11 files changed, 160 insertions, 15 deletions
diff --git a/ui/app_list/app_list.gyp b/ui/app_list/app_list.gyp
index e42f52a..ba86a6c 100644
--- a/ui/app_list/app_list.gyp
+++ b/ui/app_list/app_list.gyp
@@ -69,6 +69,7 @@
'signin_delegate_observer.h',
'views/app_list_background.cc',
'views/app_list_background.h',
+ 'views/app_list_drag_and_drop_host.h',
'views/app_list_item_view.cc',
'views/app_list_item_view.h',
'views/app_list_main_view.cc',
diff --git a/ui/app_list/app_list_item_model.h b/ui/app_list/app_list_item_model.h
index d0acd76..d437564 100644
--- a/ui/app_list/app_list_item_model.h
+++ b/ui/app_list/app_list_item_model.h
@@ -43,6 +43,9 @@ class APP_LIST_EXPORT AppListItemModel {
void SetPercentDownloaded(int percent_downloaded);
int percent_downloaded() const { return percent_downloaded_; }
+ void set_app_id(const std::string& app_id) { app_id_ = app_id; }
+ const std::string& app_id() { return app_id_; }
+
void AddObserver(AppListItemModelObserver* observer);
void RemoveObserver(AppListItemModelObserver* observer);
@@ -57,6 +60,7 @@ class APP_LIST_EXPORT AppListItemModel {
bool highlighted_;
bool is_installing_;
int percent_downloaded_;
+ std::string app_id_;
ObserverList<AppListItemModelObserver> observers_;
diff --git a/ui/app_list/views/app_list_drag_and_drop_host.h b/ui/app_list/views/app_list_drag_and_drop_host.h
new file mode 100644
index 0000000..3da9cf7
--- /dev/null
+++ b/ui/app_list/views/app_list_drag_and_drop_host.h
@@ -0,0 +1,41 @@
+// Copyright 2013 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_APP_LIST_VIEWS_APP_LIST_DRAG_AND_DROP_HOST_H_
+#define UI_APP_LIST_VIEWS_APP_LIST_DRAG_AND_DROP_HOST_H_
+
+#include <string>
+
+namespace gfx {
+class Point;
+} // namespace gfx
+
+namespace app_list {
+
+// This class will get used by the AppListView to drag and drop Application
+// shortcuts onto another host (the launcher).
+class ApplicationDragAndDropHost {
+ public:
+ // A drag operation could get started. The recipient has to return true if
+ // he wants to take it - e.g. |location_in_screen_poordinates| is over a
+ // target area. The passed |app_id| identifies the application which should
+ // get dropped.
+ virtual bool StartDrag(const std::string& app_id,
+ const gfx::Point& location_in_screen_coordinates) = 0;
+
+ // This gets only called when the |StartDrag| function returned true and it
+ // dispatches the mouse coordinate change accordingly. When the function
+ // returns false it requests that the operation be aborted since the event
+ // location is out of bounds.
+ virtual bool Drag(const gfx::Point& location_in_screen_coordinates) = 0;
+
+ // Once |StartDrag| returned true, this function is guaranteed to be called
+ // when the mouse / touch events stop. If |cancel| is set, the drag operation
+ // was aborted, otherwise the change should be kept.
+ virtual void EndDrag(bool cancel) = 0;
+};
+
+} // namespace app_list
+
+#endif // UI_APP_LIST_VIEWS_APP_LIST_DRAG_AND_DROP_HOST_H_
diff --git a/ui/app_list/views/app_list_main_view.cc b/ui/app_list/views/app_list_main_view.cc
index e966ec9..c7b11d10 100644
--- a/ui/app_list/views/app_list_main_view.cc
+++ b/ui/app_list/views/app_list_main_view.cc
@@ -134,6 +134,11 @@ void AppListMainView::Prerender() {
contents_view_->Prerender();
}
+void AppListMainView::SetDragAndDropHostOfCurrentAppList(
+ app_list::ApplicationDragAndDropHost* drag_and_drop_host) {
+ contents_view_->SetDragAndDropHostOfCurrentAppList(drag_and_drop_host);
+}
+
void AppListMainView::PreloadIcons(PaginationModel* pagination_model,
views::View* anchor) {
ui::ScaleFactor scale_factor = ui::SCALE_FACTOR_100P;
diff --git a/ui/app_list/views/app_list_main_view.h b/ui/app_list/views/app_list_main_view.h
index 6225b31..9206f20 100644
--- a/ui/app_list/views/app_list_main_view.h
+++ b/ui/app_list/views/app_list_main_view.h
@@ -18,6 +18,7 @@ class Widget;
namespace app_list {
+class ApplicationDragAndDropHost;
class AppListModel;
class AppListItemModel;
class AppListViewDelegate;
@@ -47,6 +48,11 @@ class AppListMainView : public views::View,
SearchBoxView* search_box_view() { return search_box_view_; }
+ // If |drag_and_drop_host| is not NULL it will be called upon drag and drop
+ // operations outside the application list.
+ void SetDragAndDropHostOfCurrentAppList(
+ ApplicationDragAndDropHost* drag_and_drop_host);
+
private:
class IconLoader;
diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc
index e81bfdf..5f94919 100644
--- a/ui/app_list/views/app_list_view.cc
+++ b/ui/app_list/views/app_list_view.cc
@@ -128,13 +128,17 @@ void AppListView::SetAnchorPoint(const gfx::Point& anchor_point) {
SizeToContents(); // Repositions view relative to the anchor.
}
+void AppListView::SetDragAndDropHostOfCurrentAppList(
+ app_list::ApplicationDragAndDropHost* drag_and_drop_host) {
+ app_list_main_view_->SetDragAndDropHostOfCurrentAppList(drag_and_drop_host);
+}
+
void AppListView::ShowWhenReady() {
app_list_main_view_->ShowAppListWhenReady();
}
void AppListView::Close() {
app_list_main_view_->Close();
-
if (delegate_)
delegate_->Dismiss();
else
diff --git a/ui/app_list/views/app_list_view.h b/ui/app_list/views/app_list_view.h
index 486dfce..eb21ceb 100644
--- a/ui/app_list/views/app_list_view.h
+++ b/ui/app_list/views/app_list_view.h
@@ -15,7 +15,7 @@ class Widget;
}
namespace app_list {
-
+class ApplicationDragAndDropHost;
class AppListMainView;
class AppListModel;
class AppListViewDelegate;
@@ -44,6 +44,13 @@ class APP_LIST_EXPORT AppListView : public views::BubbleDelegateView,
void SetAnchorPoint(const gfx::Point& anchor_point);
+ // If |drag_and_drop_host| is not NULL it will be called upon drag and drop
+ // operations outside the application list. This has to be called after
+ // InitAsBubble was called since the app list object needs to exist so that
+ // it can set the host.
+ void SetDragAndDropHostOfCurrentAppList(
+ app_list::ApplicationDragAndDropHost* drag_and_drop_host);
+
// Shows the UI when there are no pending icon loads. Otherwise, starts a
// timer to show the UI when a maximum allowed wait time has expired.
void ShowWhenReady();
diff --git a/ui/app_list/views/apps_grid_view.cc b/ui/app_list/views/apps_grid_view.cc
index 9cfe08e..21719da 100644
--- a/ui/app_list/views/apps_grid_view.cc
+++ b/ui/app_list/views/apps_grid_view.cc
@@ -6,8 +6,10 @@
#include <algorithm>
+#include "ui/app_list/app_list_item_model.h"
#include "ui/app_list/apps_grid_view_delegate.h"
#include "ui/app_list/pagination_model.h"
+#include "ui/app_list/views/app_list_drag_and_drop_host.h"
#include "ui/app_list/views/app_list_item_view.h"
#include "ui/app_list/views/page_switcher.h"
#include "ui/app_list/views/pulsing_block_view.h"
@@ -108,6 +110,8 @@ AppsGridView::AppsGridView(AppsGridViewDelegate* delegate,
selected_view_(NULL),
drag_view_(NULL),
drag_pointer_(NONE),
+ drag_and_drop_host_(NULL),
+ forward_events_to_drag_and_drop_host_(false),
page_flip_target_(-1),
page_flip_delay_in_ms_(kPageFlipDelayInMs),
bounds_animator_(this) {
@@ -177,7 +181,7 @@ void AppsGridView::EnsureViewVisible(const views::View* view) {
pagination_model_->SelectPage(index.page, false);
}
-void AppsGridView::InitiateDrag(views::View* view,
+void AppsGridView::InitiateDrag(AppListItemView* view,
Pointer pointer,
const ui::LocatedEvent& event) {
if (drag_view_ || pulsing_blocks_model_.view_size())
@@ -187,7 +191,7 @@ void AppsGridView::InitiateDrag(views::View* view,
drag_start_ = event.location();
}
-void AppsGridView::UpdateDrag(views::View* view,
+void AppsGridView::UpdateDrag(AppListItemView* view,
Pointer pointer,
const ui::LocatedEvent& event) {
if (!dragging() && drag_view_ &&
@@ -200,6 +204,9 @@ void AppsGridView::UpdateDrag(views::View* view,
if (drag_pointer_ != pointer)
return;
+ // If a drag and drop host is provided, see if the drag operation needs to be
+ // forwarded.
+ DispatchDragEventToDragAndDropHost(event);
ExtractDragLocation(event, &last_drag_point_);
const Index last_drop_target = drop_target_;
@@ -218,7 +225,10 @@ void AppsGridView::UpdateDrag(views::View* view,
}
void AppsGridView::EndDrag(bool cancel) {
- if (!cancel && dragging() && drag_view_) {
+ if (forward_events_to_drag_and_drop_host_) {
+ forward_events_to_drag_and_drop_host_ = false;
+ drag_and_drop_host_->EndDrag(cancel);
+ } else if (!cancel && dragging() && drag_view_) {
CalculateDropTarget(last_drag_point_, true);
if (IsValidIndex(drop_target_))
MoveItemInModel(drag_view_, drop_target_);
@@ -239,6 +249,11 @@ bool AppsGridView::IsDraggedView(const views::View* view) const {
return drag_view_ == view;
}
+void AppsGridView::SetDragAndDropHostOfCurrentAppList(
+ ApplicationDragAndDropHost* drag_and_drop_host) {
+ drag_and_drop_host_ = drag_and_drop_host;
+}
+
void AppsGridView::Prerender(int page_index) {
Layout();
int start = std::max(0, (page_index - kPrerenderPages) * tiles_per_page());
@@ -659,6 +674,40 @@ void AppsGridView::CalculateDropTarget(const gfx::Point& drag_point,
}
}
+void AppsGridView::DispatchDragEventToDragAndDropHost(
+ const ui::LocatedEvent& event) {
+ if (!drag_view_ || !drag_and_drop_host_)
+ return;
+ if (bounds().Contains(last_drag_point_)) {
+ // The event was issued inside the app menu and we should get all events.
+ if (forward_events_to_drag_and_drop_host_) {
+ // The DnD host was previously called and needs to be informed that the
+ // session returns to the owner.
+ forward_events_to_drag_and_drop_host_ = false;
+ drag_and_drop_host_->EndDrag(true);
+ }
+ } else {
+ // 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())) {
+ // 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())) {
+ // 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;
+ }
+ }
+ }
+}
+
void AppsGridView::MaybeStartPageFlipTimer(const gfx::Point& drag_point) {
int new_page_flip_target = -1;
diff --git a/ui/app_list/views/apps_grid_view.h b/ui/app_list/views/apps_grid_view.h
index b91ba64..f62e9af 100644
--- a/ui/app_list/views/apps_grid_view.h
+++ b/ui/app_list/views/apps_grid_view.h
@@ -28,6 +28,7 @@ namespace test {
class AppsGridViewTestApi;
}
+class ApplicationDragAndDropHost;
class AppListItemView;
class AppsGridViewDelegate;
class PageSwitcher;
@@ -65,15 +66,19 @@ class APP_LIST_EXPORT AppsGridView : public views::View,
// transition, this does nothing.
void EnsureViewVisible(const views::View* view);
- void InitiateDrag(views::View* view,
+ void InitiateDrag(AppListItemView* view,
Pointer pointer,
const ui::LocatedEvent& event);
- void UpdateDrag(views::View* view,
+ void UpdateDrag(AppListItemView* view,
Pointer pointer,
const ui::LocatedEvent& event);
void EndDrag(bool cancel);
bool IsDraggedView(const views::View* view) const;
+ // Set the drag and drop host for application links.
+ void SetDragAndDropHostOfCurrentAppList(
+ ApplicationDragAndDropHost* drag_and_drop_host);
+
// Prerenders the icons on and around |page_index|.
void Prerender(int page_index);
@@ -157,6 +162,9 @@ class APP_LIST_EXPORT AppsGridView : public views::View,
void CalculateDropTarget(const gfx::Point& drag_point,
bool use_page_button_hovering);
+ // Dispatch the drag and drop update event to the dnd host (if needed).
+ void DispatchDragEventToDragAndDropHost(const ui::LocatedEvent& event);
+
// Starts the page flip timer if |drag_point| is in left/right side page flip
// zone or is over page switcher.
void MaybeStartPageFlipTimer(const gfx::Point& drag_point);
@@ -202,11 +210,18 @@ class APP_LIST_EXPORT AppsGridView : public views::View,
views::View* selected_view_;
- views::View* drag_view_;
+ AppListItemView* drag_view_;
gfx::Point drag_start_;
Pointer drag_pointer_;
Index drop_target_;
+ // An application target drag and drop host which accepts dnd operations.
+ ApplicationDragAndDropHost* drag_and_drop_host_;
+
+ // The drag operation is currently inside the dnd host and events get
+ // forwarded.
+ bool forward_events_to_drag_and_drop_host_;
+
// Last mouse drag location in this view's coordinates.
gfx::Point last_drag_point_;
diff --git a/ui/app_list/views/contents_view.cc b/ui/app_list/views/contents_view.cc
index e256f4b..77c8fb0 100644
--- a/ui/app_list/views/contents_view.cc
+++ b/ui/app_list/views/contents_view.cc
@@ -54,13 +54,12 @@ ContentsView::ContentsView(AppListMainView* app_list_main_view,
kPageTransitionDurationInMs,
kOverscrollPageTransitionDurationMs);
- AppsGridView* apps_grid_view = new AppsGridView(app_list_main_view,
- pagination_model);
- apps_grid_view->SetLayout(kPreferredIconDimension,
- kPreferredCols,
- kPreferredRows);
- AddChildView(apps_grid_view);
- view_model_->Add(apps_grid_view, kIndexAppsGrid);
+ apps_grid_view_ = new AppsGridView(app_list_main_view, pagination_model);
+ apps_grid_view_->SetLayout(kPreferredIconDimension,
+ kPreferredCols,
+ kPreferredRows);
+ AddChildView(apps_grid_view_);
+ view_model_->Add(apps_grid_view_, kIndexAppsGrid);
SearchResultListView* search_results_view = new SearchResultListView(
app_list_main_view);
@@ -81,6 +80,11 @@ void ContentsView::SetModel(AppListModel* model) {
}
}
+void ContentsView::SetDragAndDropHostOfCurrentAppList(
+ app_list::ApplicationDragAndDropHost* drag_and_drop_host) {
+ apps_grid_view_->SetDragAndDropHostOfCurrentAppList(drag_and_drop_host);
+}
+
void ContentsView::SetShowState(ShowState show_state) {
if (show_state_ == show_state)
return;
diff --git a/ui/app_list/views/contents_view.h b/ui/app_list/views/contents_view.h
index 131481c..f9f31ab 100644
--- a/ui/app_list/views/contents_view.h
+++ b/ui/app_list/views/contents_view.h
@@ -17,6 +17,8 @@ class ViewModel;
namespace app_list {
+class AppsGridView;
+class ApplicationDragAndDropHost;
class AppListMainView;
class AppListModel;
class PaginationModel;
@@ -33,6 +35,11 @@ class ContentsView : public views::View {
void SetModel(AppListModel* model);
+ // If |drag_and_drop| is not NULL it will be called upon drag and drop
+ // operations outside the application list.
+ void SetDragAndDropHostOfCurrentAppList(
+ app_list::ApplicationDragAndDropHost* drag_and_drop_host);
+
void ShowSearchResults(bool show);
void Prerender();
@@ -65,6 +72,8 @@ class ContentsView : public views::View {
ShowState show_state_;
PaginationModel* pagination_model_; // Owned by AppListController.
+ AppsGridView* apps_grid_view_; // Owned by the view.
+
scoped_ptr<views::ViewModel> view_model_;
scoped_ptr<views::BoundsAnimator> bounds_animator_;