| 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;
|
| }
|
| }
|
|
|
|
|