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

Unified Diff: ash/launcher/launcher_view.cc

Issue 14533006: Drag and drop between app list and launcher - First patch (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: addressed Created 7 years, 8 months 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: ash/launcher/launcher_view.cc
diff --git a/ash/launcher/launcher_view.cc b/ash/launcher/launcher_view.cc
index bf7b96ba250405f228e486d5661ddf9382fa3d23..4de50bff28d643d8776cec23d0ab1bac2247adf1 100644
--- a/ash/launcher/launcher_view.cc
+++ b/ash/launcher/launcher_view.cc
@@ -22,6 +22,7 @@
#include "ash/shelf/shelf_widget.h"
#include "ash/shell_delegate.h"
#include "base/auto_reset.h"
+#include "base/command_line.h"
#include "base/memory/scoped_ptr.h"
#include "grit/ash_resources.h"
#include "grit/ash_strings.h"
@@ -377,7 +378,9 @@ LauncherView::LauncherView(LauncherModel* model,
cancelling_drag_model_changed_(false),
last_hidden_index_(0),
closing_event_time_(base::TimeDelta()),
- got_deleted_(NULL) {
+ got_deleted_(NULL),
+ drag_and_drop_item_created_(false),
+ drag_and_drop_launcher_id_(0) {
DCHECK(model_);
bounds_animator_.reset(new views::BoundsAnimator(this));
bounds_animator_->AddObserver(this);
@@ -421,6 +424,21 @@ void LauncherView::OnShelfAlignmentChanged() {
overflow_button_->OnShelfAlignmentChanged();
LayoutToIdealBounds();
for (int i = 0; i < view_model_->view_size(); ++i) {
+ // TODO: remove when AppIcon is a Launcher Button.
+ if (TYPE_APP_LIST == model_->items()[i].type) {
+ ShelfLayoutManager* shelf = tooltip_->shelf_layout_manager();
+ static_cast<AppListButton*>(view_model_->view_at(i))->SetImageAlignment(
+ shelf->SelectValueForShelfAlignment(
+ views::ImageButton::ALIGN_CENTER,
+ views::ImageButton::ALIGN_LEFT,
+ views::ImageButton::ALIGN_RIGHT,
+ views::ImageButton::ALIGN_CENTER),
+ shelf->SelectValueForShelfAlignment(
+ views::ImageButton::ALIGN_TOP,
+ views::ImageButton::ALIGN_MIDDLE,
+ views::ImageButton::ALIGN_MIDDLE,
+ views::ImageButton::ALIGN_BOTTOM));
+ }
if (i >= first_visible_index_ && i <= last_visible_index_)
view_model_->view_at(i)->Layout();
}
@@ -508,6 +526,98 @@ View* LauncherView::GetFocusTraversableParentView() {
return this;
}
+bool LauncherView::StartDrag(const std::string& app_id,
+ const gfx::Point& location_in_screen_coordinates) {
+ // Bail if an operation is already going on - or the cursor is not inside.
+ if (drag_and_drop_launcher_id_ ||
+ !GetBoundsInScreen().Contains(location_in_screen_coordinates))
+ return false;
+
+ // If the AppsGridView (which was dispatching this event) was opened by our
+ // button, LauncherView dragging operations are locked and we have to unlock.
+ CancelDrag(-1);
+ drag_and_drop_item_created_ = false;
+ drag_and_drop_app_id_ = app_id;
+ drag_and_drop_launcher_id_ =
+ delegate_->GetLauncherIDForAppID(drag_and_drop_app_id_);
+
+ if (!drag_and_drop_launcher_id_) {
+ delegate_->PinAppWithID(app_id);
+ drag_and_drop_launcher_id_ =
+ delegate_->GetLauncherIDForAppID(drag_and_drop_app_id_);
+ if (!drag_and_drop_launcher_id_)
+ return false;
+ drag_and_drop_item_created_ = true;
+ }
+ views::View* drag_and_drop_view = view_model_->view_at(
+ model_->ItemIndexByID(drag_and_drop_launcher_id_));
+
+ // It is possible that the item gets deleted by a sync operation. We abort the
+ // operation in that case.
+ if (!drag_and_drop_view)
+ return false;
+
+ // Since there is already an icon presented, we hide this one for now.
+ // TODO(skuhne): Once the second CL for this issue lands, uncomment the
+ // following line.
+ // drag_and_drop_view->SetVisible(false);
+ // To accomodate the the drag and drop logic of the launcher, we have to
+ // set the initial position of the drag operation on top of the actual item.
+ // All following calls to the drag and drop logic will then be interpreted
+ // relative to that point.
+ gfx::Point pt = drag_and_drop_view->GetBoundsInScreen().CenterPoint();
+ views::View::ConvertPointFromScreen(drag_and_drop_view, &pt);
+ ui::MouseEvent event(ui::ET_MOUSE_PRESSED,
+ pt, location_in_screen_coordinates, 0);
+ PointerPressedOnButton(
+ drag_and_drop_view, LauncherButtonHost::DRAG_AND_DROP, event);
+
+ // Drag the item where it really belongs.
+ Drag(location_in_screen_coordinates);
+ return true;
+}
+
+bool LauncherView::Drag(const gfx::Point& location_in_screen_coordinates) {
+ if (!drag_and_drop_launcher_id_ ||
+ !GetBoundsInScreen().Contains(location_in_screen_coordinates))
+ return false;
+
+ gfx::Point pt = location_in_screen_coordinates;
+ views::View* drag_and_drop_view = view_model_->view_at(
+ model_->ItemIndexByID(drag_and_drop_launcher_id_));
+
+ // It is possible that the item gets deleted by a sync operation. We abort the
+ // operation in that case.
+ if (!drag_and_drop_view)
+ return false;
+
+ views::View::ConvertPointFromScreen(drag_and_drop_view, &pt);
+
+ ui::MouseEvent event(ui::ET_MOUSE_DRAGGED, pt, gfx::Point(), 0);
+ PointerDraggedOnButton(
+ drag_and_drop_view, LauncherButtonHost::DRAG_AND_DROP, event);
+ return true;
+}
+
+void LauncherView::EndDrag(bool cancel) {
+ if (!drag_and_drop_launcher_id_)
+ return;
+
+ views::View* drag_and_drop_view = view_model_->view_at(
+ model_->ItemIndexByID(drag_and_drop_launcher_id_));
+ // Note: The returned |drag_and_drop_view| can be NULL.
+ PointerReleasedOnButton(
+ drag_and_drop_view, LauncherButtonHost::DRAG_AND_DROP, cancel);
+
+ if (drag_and_drop_item_created_ && cancel)
+ delegate_->UnpinAppsWithID(drag_and_drop_app_id_);
+
+ if (drag_and_drop_view)
+ drag_and_drop_view->SetVisible(true);
+
+ drag_and_drop_launcher_id_ = 0;
+}
+
void LauncherView::LayoutToIdealBounds() {
IdealBounds ideal_bounds;
CalculateIdealBounds(&ideal_bounds);
@@ -748,6 +858,18 @@ views::View* LauncherView::CreateViewForItem(const LauncherItem& item) {
case TYPE_APP_LIST: {
// TODO(dave): turn this into a LauncherButton too.
AppListButton* button = new AppListButton(this, this);
+ ShelfLayoutManager* shelf = tooltip_->shelf_layout_manager();
+ button->SetImageAlignment(
+ shelf->SelectValueForShelfAlignment(
+ views::ImageButton::ALIGN_CENTER,
+ views::ImageButton::ALIGN_LEFT,
+ views::ImageButton::ALIGN_RIGHT,
+ views::ImageButton::ALIGN_CENTER),
+ shelf->SelectValueForShelfAlignment(
+ views::ImageButton::ALIGN_TOP,
+ views::ImageButton::ALIGN_MIDDLE,
+ views::ImageButton::ALIGN_MIDDLE,
+ views::ImageButton::ALIGN_BOTTOM));
view = button;
break;
}
@@ -1313,31 +1435,37 @@ void LauncherView::ButtonPressed(views::Button* sender,
ui::ScopedAnimationDurationScaleMode::SLOW_DURATION));
}
- // Collect usage statistics before we decide what to do with the click.
- switch (model_->items()[view_index].type) {
- case TYPE_APP_SHORTCUT:
- case TYPE_WINDOWED_APP:
- case TYPE_PLATFORM_APP:
- Shell::GetInstance()->delegate()->RecordUserMetricsAction(
- UMA_LAUNCHER_CLICK_ON_APP);
- // Fallthrough
- case TYPE_TABBED:
- case TYPE_APP_PANEL:
- delegate_->ItemSelected(model_->items()[view_index], event);
- break;
+ // Collect usage statistics before we decide what to do with the click.
+ switch (model_->items()[view_index].type) {
+ case TYPE_APP_SHORTCUT:
+ case TYPE_WINDOWED_APP:
+ case TYPE_PLATFORM_APP:
+ Shell::GetInstance()->delegate()->RecordUserMetricsAction(
+ UMA_LAUNCHER_CLICK_ON_APP);
+ // Fallthrough
+ case TYPE_TABBED:
+ case TYPE_APP_PANEL:
+ delegate_->ItemSelected(model_->items()[view_index], event);
+ break;
- case TYPE_APP_LIST:
- Shell::GetInstance()->delegate()->RecordUserMetricsAction(
- UMA_LAUNCHER_CLICK_ON_APPLIST_BUTTON);
- Shell::GetInstance()->ToggleAppList(GetWidget()->GetNativeView());
- break;
+ case TYPE_APP_LIST:
+ Shell::GetInstance()->delegate()->RecordUserMetricsAction(
+ UMA_LAUNCHER_CLICK_ON_APPLIST_BUTTON);
+ Shell::GetInstance()->ToggleAppList(GetWidget()->GetNativeView());
+ // Let the current application list know that the launcher can handle
+ // drag and drop of applications. Note furthermore that the application
+ // list can only drop items onto the launcher on the same screen.
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ ash::switches::kAshDragAndDropAppListToLauncher))
+ Shell::GetInstance()->SetDragAndDropHostOfCurrentAppList(this);
+ break;
- case TYPE_BROWSER_SHORTCUT:
- // Click on browser icon is counted in app clicks.
- Shell::GetInstance()->delegate()->RecordUserMetricsAction(
- UMA_LAUNCHER_CLICK_ON_APP);
- delegate_->OnBrowserShortcutClicked(event.flags());
- break;
+ case TYPE_BROWSER_SHORTCUT:
+ // Click on browser icon is counted in app clicks.
+ Shell::GetInstance()->delegate()->RecordUserMetricsAction(
+ UMA_LAUNCHER_CLICK_ON_APP);
+ delegate_->OnBrowserShortcutClicked(event.flags());
+ break;
}
}

Powered by Google App Engine
This is Rietveld 408576698