OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |