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

Side by Side 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, 7 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ash/launcher/launcher_view.h" 5 #include "ash/launcher/launcher_view.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "ash/ash_constants.h" 9 #include "ash/ash_constants.h"
10 #include "ash/ash_switches.h" 10 #include "ash/ash_switches.h"
11 #include "ash/launcher/app_list_button.h" 11 #include "ash/launcher/app_list_button.h"
12 #include "ash/launcher/launcher_button.h" 12 #include "ash/launcher/launcher_button.h"
13 #include "ash/launcher/launcher_delegate.h" 13 #include "ash/launcher/launcher_delegate.h"
14 #include "ash/launcher/launcher_icon_observer.h" 14 #include "ash/launcher/launcher_icon_observer.h"
15 #include "ash/launcher/launcher_model.h" 15 #include "ash/launcher/launcher_model.h"
16 #include "ash/launcher/launcher_tooltip_manager.h" 16 #include "ash/launcher/launcher_tooltip_manager.h"
17 #include "ash/launcher/overflow_bubble.h" 17 #include "ash/launcher/overflow_bubble.h"
18 #include "ash/launcher/overflow_button.h" 18 #include "ash/launcher/overflow_button.h"
19 #include "ash/launcher/tabbed_launcher_button.h" 19 #include "ash/launcher/tabbed_launcher_button.h"
20 #include "ash/root_window_controller.h" 20 #include "ash/root_window_controller.h"
21 #include "ash/shelf/shelf_layout_manager.h" 21 #include "ash/shelf/shelf_layout_manager.h"
22 #include "ash/shelf/shelf_widget.h" 22 #include "ash/shelf/shelf_widget.h"
23 #include "ash/shell_delegate.h" 23 #include "ash/shell_delegate.h"
24 #include "base/auto_reset.h" 24 #include "base/auto_reset.h"
25 #include "base/command_line.h"
25 #include "base/memory/scoped_ptr.h" 26 #include "base/memory/scoped_ptr.h"
26 #include "grit/ash_resources.h" 27 #include "grit/ash_resources.h"
27 #include "grit/ash_strings.h" 28 #include "grit/ash_strings.h"
28 #include "ui/aura/window.h" 29 #include "ui/aura/window.h"
29 #include "ui/base/l10n/l10n_util.h" 30 #include "ui/base/l10n/l10n_util.h"
30 #include "ui/base/models/simple_menu_model.h" 31 #include "ui/base/models/simple_menu_model.h"
31 #include "ui/base/resource/resource_bundle.h" 32 #include "ui/base/resource/resource_bundle.h"
32 #include "ui/compositor/layer.h" 33 #include "ui/compositor/layer.h"
33 #include "ui/compositor/layer_animator.h" 34 #include "ui/compositor/layer_animator.h"
34 #include "ui/compositor/scoped_animation_duration_scale_mode.h" 35 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 overflow_button_(NULL), 371 overflow_button_(NULL),
371 drag_pointer_(NONE), 372 drag_pointer_(NONE),
372 drag_view_(NULL), 373 drag_view_(NULL),
373 drag_offset_(0), 374 drag_offset_(0),
374 start_drag_index_(-1), 375 start_drag_index_(-1),
375 context_menu_id_(0), 376 context_menu_id_(0),
376 leading_inset_(kDefaultLeadingInset), 377 leading_inset_(kDefaultLeadingInset),
377 cancelling_drag_model_changed_(false), 378 cancelling_drag_model_changed_(false),
378 last_hidden_index_(0), 379 last_hidden_index_(0),
379 closing_event_time_(base::TimeDelta()), 380 closing_event_time_(base::TimeDelta()),
380 got_deleted_(NULL) { 381 got_deleted_(NULL),
382 drag_and_drop_item_created_(false),
383 drag_and_drop_launcher_id_(0) {
381 DCHECK(model_); 384 DCHECK(model_);
382 bounds_animator_.reset(new views::BoundsAnimator(this)); 385 bounds_animator_.reset(new views::BoundsAnimator(this));
383 bounds_animator_->AddObserver(this); 386 bounds_animator_->AddObserver(this);
384 set_context_menu_controller(this); 387 set_context_menu_controller(this);
385 focus_search_.reset(new LauncherFocusSearch(view_model_.get())); 388 focus_search_.reset(new LauncherFocusSearch(view_model_.get()));
386 tooltip_.reset(new LauncherTooltipManager( 389 tooltip_.reset(new LauncherTooltipManager(
387 shelf_layout_manager, this)); 390 shelf_layout_manager, this));
388 } 391 }
389 392
390 LauncherView::~LauncherView() { 393 LauncherView::~LauncherView() {
(...skipping 23 matching lines...) Expand all
414 UpdateFirstButtonPadding(); 417 UpdateFirstButtonPadding();
415 418
416 // We'll layout when our bounds change. 419 // We'll layout when our bounds change.
417 } 420 }
418 421
419 void LauncherView::OnShelfAlignmentChanged() { 422 void LauncherView::OnShelfAlignmentChanged() {
420 UpdateFirstButtonPadding(); 423 UpdateFirstButtonPadding();
421 overflow_button_->OnShelfAlignmentChanged(); 424 overflow_button_->OnShelfAlignmentChanged();
422 LayoutToIdealBounds(); 425 LayoutToIdealBounds();
423 for (int i = 0; i < view_model_->view_size(); ++i) { 426 for (int i = 0; i < view_model_->view_size(); ++i) {
427 // TODO: remove when AppIcon is a Launcher Button.
428 if (TYPE_APP_LIST == model_->items()[i].type) {
429 ShelfLayoutManager* shelf = tooltip_->shelf_layout_manager();
430 static_cast<AppListButton*>(view_model_->view_at(i))->SetImageAlignment(
431 shelf->SelectValueForShelfAlignment(
432 views::ImageButton::ALIGN_CENTER,
433 views::ImageButton::ALIGN_LEFT,
434 views::ImageButton::ALIGN_RIGHT,
435 views::ImageButton::ALIGN_CENTER),
436 shelf->SelectValueForShelfAlignment(
437 views::ImageButton::ALIGN_TOP,
438 views::ImageButton::ALIGN_MIDDLE,
439 views::ImageButton::ALIGN_MIDDLE,
440 views::ImageButton::ALIGN_BOTTOM));
441 }
424 if (i >= first_visible_index_ && i <= last_visible_index_) 442 if (i >= first_visible_index_ && i <= last_visible_index_)
425 view_model_->view_at(i)->Layout(); 443 view_model_->view_at(i)->Layout();
426 } 444 }
427 tooltip_->UpdateArrow(); 445 tooltip_->UpdateArrow();
428 if (overflow_bubble_) 446 if (overflow_bubble_)
429 overflow_bubble_->Hide(); 447 overflow_bubble_->Hide();
430 } 448 }
431 449
432 gfx::Rect LauncherView::GetIdealBoundsOfItemIcon(LauncherID id) { 450 gfx::Rect LauncherView::GetIdealBoundsOfItemIcon(LauncherID id) {
433 int index = model_->ItemIndexByID(id); 451 int index = model_->ItemIndexByID(id);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
501 } 519 }
502 520
503 views::FocusTraversable* LauncherView::GetFocusTraversableParent() { 521 views::FocusTraversable* LauncherView::GetFocusTraversableParent() {
504 return parent()->GetFocusTraversable(); 522 return parent()->GetFocusTraversable();
505 } 523 }
506 524
507 View* LauncherView::GetFocusTraversableParentView() { 525 View* LauncherView::GetFocusTraversableParentView() {
508 return this; 526 return this;
509 } 527 }
510 528
529 bool LauncherView::StartDrag(const std::string& app_id,
530 const gfx::Point& location_in_screen_coordinates) {
531 // Bail if an operation is already going on - or the cursor is not inside.
532 if (drag_and_drop_launcher_id_ ||
533 !GetBoundsInScreen().Contains(location_in_screen_coordinates))
534 return false;
535
536 // If the AppsGridView (which was dispatching this event) was opened by our
537 // button, LauncherView dragging operations are locked and we have to unlock.
538 CancelDrag(-1);
539 drag_and_drop_item_created_ = false;
540 drag_and_drop_app_id_ = app_id;
541 drag_and_drop_launcher_id_ =
542 delegate_->GetLauncherIDForAppID(drag_and_drop_app_id_);
543
544 if (!drag_and_drop_launcher_id_) {
545 delegate_->PinAppWithID(app_id);
546 drag_and_drop_launcher_id_ =
547 delegate_->GetLauncherIDForAppID(drag_and_drop_app_id_);
548 if (!drag_and_drop_launcher_id_)
549 return false;
550 drag_and_drop_item_created_ = true;
551 }
552 views::View* drag_and_drop_view = view_model_->view_at(
553 model_->ItemIndexByID(drag_and_drop_launcher_id_));
554
555 // It is possible that the item gets deleted by a sync operation. We abort the
556 // operation in that case.
557 if (!drag_and_drop_view)
558 return false;
559
560 // Since there is already an icon presented, we hide this one for now.
561 // TODO(skuhne): Once the second CL for this issue lands, uncomment the
562 // following line.
563 // drag_and_drop_view->SetVisible(false);
564 // To accomodate the the drag and drop logic of the launcher, we have to
565 // set the initial position of the drag operation on top of the actual item.
566 // All following calls to the drag and drop logic will then be interpreted
567 // relative to that point.
568 gfx::Point pt = drag_and_drop_view->GetBoundsInScreen().CenterPoint();
569 views::View::ConvertPointFromScreen(drag_and_drop_view, &pt);
570 ui::MouseEvent event(ui::ET_MOUSE_PRESSED,
571 pt, location_in_screen_coordinates, 0);
572 PointerPressedOnButton(
573 drag_and_drop_view, LauncherButtonHost::DRAG_AND_DROP, event);
574
575 // Drag the item where it really belongs.
576 Drag(location_in_screen_coordinates);
577 return true;
578 }
579
580 bool LauncherView::Drag(const gfx::Point& location_in_screen_coordinates) {
581 if (!drag_and_drop_launcher_id_ ||
582 !GetBoundsInScreen().Contains(location_in_screen_coordinates))
583 return false;
584
585 gfx::Point pt = location_in_screen_coordinates;
586 views::View* drag_and_drop_view = view_model_->view_at(
587 model_->ItemIndexByID(drag_and_drop_launcher_id_));
588
589 // It is possible that the item gets deleted by a sync operation. We abort the
590 // operation in that case.
591 if (!drag_and_drop_view)
592 return false;
593
594 views::View::ConvertPointFromScreen(drag_and_drop_view, &pt);
595
596 ui::MouseEvent event(ui::ET_MOUSE_DRAGGED, pt, gfx::Point(), 0);
597 PointerDraggedOnButton(
598 drag_and_drop_view, LauncherButtonHost::DRAG_AND_DROP, event);
599 return true;
600 }
601
602 void LauncherView::EndDrag(bool cancel) {
603 if (!drag_and_drop_launcher_id_)
604 return;
605
606 views::View* drag_and_drop_view = view_model_->view_at(
607 model_->ItemIndexByID(drag_and_drop_launcher_id_));
608 // Note: The returned |drag_and_drop_view| can be NULL.
609 PointerReleasedOnButton(
610 drag_and_drop_view, LauncherButtonHost::DRAG_AND_DROP, cancel);
611
612 if (drag_and_drop_item_created_ && cancel)
613 delegate_->UnpinAppsWithID(drag_and_drop_app_id_);
614
615 if (drag_and_drop_view)
616 drag_and_drop_view->SetVisible(true);
617
618 drag_and_drop_launcher_id_ = 0;
619 }
620
511 void LauncherView::LayoutToIdealBounds() { 621 void LauncherView::LayoutToIdealBounds() {
512 IdealBounds ideal_bounds; 622 IdealBounds ideal_bounds;
513 CalculateIdealBounds(&ideal_bounds); 623 CalculateIdealBounds(&ideal_bounds);
514 624
515 if (bounds_animator_->IsAnimating()) 625 if (bounds_animator_->IsAnimating())
516 AnimateToIdealBounds(); 626 AnimateToIdealBounds();
517 else 627 else
518 views::ViewModelUtils::SetViewBoundsToIdealBounds(*view_model_); 628 views::ViewModelUtils::SetViewBoundsToIdealBounds(*view_model_);
519 629
520 overflow_button_->SetBoundsRect(ideal_bounds.overflow_bounds); 630 overflow_button_->SetBoundsRect(ideal_bounds.overflow_bounds);
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 this, this, tooltip_->shelf_layout_manager()); 851 this, this, tooltip_->shelf_layout_manager());
742 button->SetImage(item.image); 852 button->SetImage(item.image);
743 ReflectItemStatus(item, button); 853 ReflectItemStatus(item, button);
744 view = button; 854 view = button;
745 break; 855 break;
746 } 856 }
747 857
748 case TYPE_APP_LIST: { 858 case TYPE_APP_LIST: {
749 // TODO(dave): turn this into a LauncherButton too. 859 // TODO(dave): turn this into a LauncherButton too.
750 AppListButton* button = new AppListButton(this, this); 860 AppListButton* button = new AppListButton(this, this);
861 ShelfLayoutManager* shelf = tooltip_->shelf_layout_manager();
862 button->SetImageAlignment(
863 shelf->SelectValueForShelfAlignment(
864 views::ImageButton::ALIGN_CENTER,
865 views::ImageButton::ALIGN_LEFT,
866 views::ImageButton::ALIGN_RIGHT,
867 views::ImageButton::ALIGN_CENTER),
868 shelf->SelectValueForShelfAlignment(
869 views::ImageButton::ALIGN_TOP,
870 views::ImageButton::ALIGN_MIDDLE,
871 views::ImageButton::ALIGN_MIDDLE,
872 views::ImageButton::ALIGN_BOTTOM));
751 view = button; 873 view = button;
752 break; 874 break;
753 } 875 }
754 876
755 case TYPE_BROWSER_SHORTCUT: { 877 case TYPE_BROWSER_SHORTCUT: {
756 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 878 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
757 LauncherButton* button = LauncherButton::Create( 879 LauncherButton* button = LauncherButton::Create(
758 this, this, tooltip_->shelf_layout_manager()); 880 this, this, tooltip_->shelf_layout_manager());
759 int image_id = delegate_ ? 881 int image_id = delegate_ ?
760 delegate_->GetBrowserShortcutResourceId() : 882 delegate_->GetBrowserShortcutResourceId() :
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after
1306 return; 1428 return;
1307 1429
1308 { 1430 {
1309 // Slow down activation animations if shift key is pressed. 1431 // Slow down activation animations if shift key is pressed.
1310 scoped_ptr<ui::ScopedAnimationDurationScaleMode> slowing_animations; 1432 scoped_ptr<ui::ScopedAnimationDurationScaleMode> slowing_animations;
1311 if (event.IsShiftDown()) { 1433 if (event.IsShiftDown()) {
1312 slowing_animations.reset(new ui::ScopedAnimationDurationScaleMode( 1434 slowing_animations.reset(new ui::ScopedAnimationDurationScaleMode(
1313 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION)); 1435 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION));
1314 } 1436 }
1315 1437
1316 // Collect usage statistics before we decide what to do with the click. 1438 // Collect usage statistics before we decide what to do with the click.
1317 switch (model_->items()[view_index].type) { 1439 switch (model_->items()[view_index].type) {
1318 case TYPE_APP_SHORTCUT: 1440 case TYPE_APP_SHORTCUT:
1319 case TYPE_WINDOWED_APP: 1441 case TYPE_WINDOWED_APP:
1320 case TYPE_PLATFORM_APP: 1442 case TYPE_PLATFORM_APP:
1321 Shell::GetInstance()->delegate()->RecordUserMetricsAction( 1443 Shell::GetInstance()->delegate()->RecordUserMetricsAction(
1322 UMA_LAUNCHER_CLICK_ON_APP); 1444 UMA_LAUNCHER_CLICK_ON_APP);
1323 // Fallthrough 1445 // Fallthrough
1324 case TYPE_TABBED: 1446 case TYPE_TABBED:
1325 case TYPE_APP_PANEL: 1447 case TYPE_APP_PANEL:
1326 delegate_->ItemSelected(model_->items()[view_index], event); 1448 delegate_->ItemSelected(model_->items()[view_index], event);
1327 break; 1449 break;
1328 1450
1329 case TYPE_APP_LIST: 1451 case TYPE_APP_LIST:
1330 Shell::GetInstance()->delegate()->RecordUserMetricsAction( 1452 Shell::GetInstance()->delegate()->RecordUserMetricsAction(
1331 UMA_LAUNCHER_CLICK_ON_APPLIST_BUTTON); 1453 UMA_LAUNCHER_CLICK_ON_APPLIST_BUTTON);
1332 Shell::GetInstance()->ToggleAppList(GetWidget()->GetNativeView()); 1454 Shell::GetInstance()->ToggleAppList(GetWidget()->GetNativeView());
1333 break; 1455 // Let the current application list know that the launcher can handle
1456 // drag and drop of applications. Note furthermore that the application
1457 // list can only drop items onto the launcher on the same screen.
1458 if (CommandLine::ForCurrentProcess()->HasSwitch(
1459 ash::switches::kAshDragAndDropAppListToLauncher))
1460 Shell::GetInstance()->SetDragAndDropHostOfCurrentAppList(this);
1461 break;
1334 1462
1335 case TYPE_BROWSER_SHORTCUT: 1463 case TYPE_BROWSER_SHORTCUT:
1336 // Click on browser icon is counted in app clicks. 1464 // Click on browser icon is counted in app clicks.
1337 Shell::GetInstance()->delegate()->RecordUserMetricsAction( 1465 Shell::GetInstance()->delegate()->RecordUserMetricsAction(
1338 UMA_LAUNCHER_CLICK_ON_APP); 1466 UMA_LAUNCHER_CLICK_ON_APP);
1339 delegate_->OnBrowserShortcutClicked(event.flags()); 1467 delegate_->OnBrowserShortcutClicked(event.flags());
1340 break; 1468 break;
1341 } 1469 }
1342 } 1470 }
1343 1471
1344 if (model_->items()[view_index].type != TYPE_APP_LIST) 1472 if (model_->items()[view_index].type != TYPE_APP_LIST)
1345 ShowListMenuForView(model_->items()[view_index], sender, event.flags()); 1473 ShowListMenuForView(model_->items()[view_index], sender, event.flags());
1346 } 1474 }
1347 1475
1348 bool LauncherView::ShowListMenuForView(const LauncherItem& item, 1476 bool LauncherView::ShowListMenuForView(const LauncherItem& item,
1349 views::View* source, 1477 views::View* source,
1350 int event_flags) { 1478 int event_flags) {
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1495 bool LauncherView::ShouldShowTooltipForView(const views::View* view) const { 1623 bool LauncherView::ShouldShowTooltipForView(const views::View* view) const {
1496 if (view == GetAppListButtonView() && 1624 if (view == GetAppListButtonView() &&
1497 Shell::GetInstance()->GetAppListWindow()) 1625 Shell::GetInstance()->GetAppListWindow())
1498 return false; 1626 return false;
1499 const LauncherItem* item = LauncherItemForView(view); 1627 const LauncherItem* item = LauncherItemForView(view);
1500 return (!item || delegate_->ShouldShowTooltip(*item)); 1628 return (!item || delegate_->ShouldShowTooltip(*item));
1501 } 1629 }
1502 1630
1503 } // namespace internal 1631 } // namespace internal
1504 } // namespace ash 1632 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698