| 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/shelf/shelf_view.h" | 5 #include "ash/shelf/shelf_view.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <memory> | 8 #include <memory> |
| 9 | 9 |
| 10 #include "ash/ash_switches.h" | 10 #include "ash/ash_switches.h" |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 namespace ash { | 62 namespace ash { |
| 63 | 63 |
| 64 const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_BOTTOM = 0; | 64 const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_BOTTOM = 0; |
| 65 const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_LEFT = 1; | 65 const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_LEFT = 1; |
| 66 const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_RIGHT = 2; | 66 const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_RIGHT = 2; |
| 67 const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_COUNT = 3; | 67 const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_COUNT = 3; |
| 68 | 68 |
| 69 // Default amount content is inset on the left edge. | 69 // Default amount content is inset on the left edge. |
| 70 const int kDefaultLeadingInset = 8; | 70 const int kDefaultLeadingInset = 8; |
| 71 | 71 |
| 72 // Minimum distance before drag starts. | |
| 73 const int kMinimumDragDistance = 8; | |
| 74 | |
| 75 // Additional spacing for the left and right side of icons. | 72 // Additional spacing for the left and right side of icons. |
| 76 const int kHorizontalIconSpacing = 2; | 73 const int kHorizontalIconSpacing = 2; |
| 77 | 74 |
| 78 // Inset for items which do not have an icon. | 75 // Inset for items which do not have an icon. |
| 79 const int kHorizontalNoIconInsetSpacing = | 76 const int kHorizontalNoIconInsetSpacing = |
| 80 kHorizontalIconSpacing + kDefaultLeadingInset; | 77 kHorizontalIconSpacing + kDefaultLeadingInset; |
| 81 | 78 |
| 82 // The proportion of the shelf space reserved for non-panel icons. Panels | 79 // The proportion of the shelf space reserved for non-panel icons. Panels |
| 83 // may flow into this space but will be put into the overflow bubble if there | 80 // may flow into this space but will be put into the overflow bubble if there |
| 84 // is contention for the space. | 81 // is contention for the space. |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 view_->layer()->SetOpacity(1.0f); | 352 view_->layer()->SetOpacity(1.0f); |
| 356 } | 353 } |
| 357 | 354 |
| 358 private: | 355 private: |
| 359 ShelfView* shelf_view_; | 356 ShelfView* shelf_view_; |
| 360 views::View* view_; | 357 views::View* view_; |
| 361 | 358 |
| 362 DISALLOW_COPY_AND_ASSIGN(StartFadeAnimationDelegate); | 359 DISALLOW_COPY_AND_ASSIGN(StartFadeAnimationDelegate); |
| 363 }; | 360 }; |
| 364 | 361 |
| 362 // static |
| 363 const int ShelfView::kMinimumDragDistance = 8; |
| 364 |
| 365 ShelfView::ShelfView(ShelfModel* model, | 365 ShelfView::ShelfView(ShelfModel* model, |
| 366 ShelfDelegate* delegate, | 366 ShelfDelegate* delegate, |
| 367 WmShelf* wm_shelf, | 367 WmShelf* wm_shelf, |
| 368 Shelf* shelf) | 368 Shelf* shelf) |
| 369 : model_(model), | 369 : model_(model), |
| 370 delegate_(delegate), | 370 delegate_(delegate), |
| 371 wm_shelf_(wm_shelf), | 371 wm_shelf_(wm_shelf), |
| 372 shelf_(shelf), | 372 shelf_(shelf), |
| 373 view_model_(new views::ViewModel), | 373 view_model_(new views::ViewModel), |
| 374 first_visible_index_(0), | 374 first_visible_index_(0), |
| (...skipping 12 matching lines...) Expand all Loading... |
| 387 got_deleted_(nullptr), | 387 got_deleted_(nullptr), |
| 388 drag_and_drop_item_pinned_(false), | 388 drag_and_drop_item_pinned_(false), |
| 389 drag_and_drop_shelf_id_(0), | 389 drag_and_drop_shelf_id_(0), |
| 390 drag_replaced_view_(nullptr), | 390 drag_replaced_view_(nullptr), |
| 391 dragged_off_shelf_(false), | 391 dragged_off_shelf_(false), |
| 392 snap_back_from_rip_off_view_(nullptr), | 392 snap_back_from_rip_off_view_(nullptr), |
| 393 item_manager_(Shell::GetInstance()->shelf_item_delegate_manager()), | 393 item_manager_(Shell::GetInstance()->shelf_item_delegate_manager()), |
| 394 overflow_mode_(false), | 394 overflow_mode_(false), |
| 395 main_shelf_(nullptr), | 395 main_shelf_(nullptr), |
| 396 dragged_off_from_overflow_to_shelf_(false), | 396 dragged_off_from_overflow_to_shelf_(false), |
| 397 is_repost_event_(false), | 397 is_repost_event_on_same_item_(false), |
| 398 last_pressed_index_(-1) { | 398 last_pressed_index_(-1) { |
| 399 DCHECK(model_); | 399 DCHECK(model_); |
| 400 DCHECK(wm_shelf_); | 400 DCHECK(wm_shelf_); |
| 401 bounds_animator_.reset(new views::BoundsAnimator(this)); | 401 bounds_animator_.reset(new views::BoundsAnimator(this)); |
| 402 bounds_animator_->AddObserver(this); | 402 bounds_animator_->AddObserver(this); |
| 403 set_context_menu_controller(this); | 403 set_context_menu_controller(this); |
| 404 focus_search_.reset(new ShelfFocusSearch(view_model_.get())); | 404 focus_search_.reset(new ShelfFocusSearch(view_model_.get())); |
| 405 } | 405 } |
| 406 | 406 |
| 407 ShelfView::~ShelfView() { | 407 ShelfView::~ShelfView() { |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 711 // to animate back to its correct location. | 711 // to animate back to its correct location. |
| 712 AnimateToIdealBounds(); | 712 AnimateToIdealBounds(); |
| 713 } else { | 713 } else { |
| 714 drag_and_drop_view->SetSize(pre_drag_and_drop_size_); | 714 drag_and_drop_view->SetSize(pre_drag_and_drop_size_); |
| 715 } | 715 } |
| 716 } | 716 } |
| 717 | 717 |
| 718 drag_and_drop_shelf_id_ = 0; | 718 drag_and_drop_shelf_id_ = 0; |
| 719 } | 719 } |
| 720 | 720 |
| 721 bool ShelfView::ShouldEventActivateButton(View* view, const ui::Event& event) { |
| 722 if (dragging()) |
| 723 return false; |
| 724 |
| 725 // Ignore if we are already in a pointer event sequence started with a repost |
| 726 // event on the same shelf item. See crbug.com/343005 for more detail. |
| 727 if (is_repost_event_on_same_item_) |
| 728 return false; |
| 729 |
| 730 // Don't activate the item twice on double-click. Otherwise the window starts |
| 731 // animating open due to the first click, then immediately minimizes due to |
| 732 // the second click. The user most likely intended to open or minimize the |
| 733 // item once, not do both. |
| 734 if (event.flags() & ui::EF_IS_DOUBLE_CLICK) |
| 735 return false; |
| 736 |
| 737 // Ignore if this is a repost event on the last pressed shelf item. |
| 738 int index = view_model_->GetIndexOfView(view); |
| 739 if (index == -1) |
| 740 return false; |
| 741 return !IsRepostEvent(event) || last_pressed_index_ != index; |
| 742 } |
| 743 |
| 721 void ShelfView::PointerPressedOnButton(views::View* view, | 744 void ShelfView::PointerPressedOnButton(views::View* view, |
| 722 Pointer pointer, | 745 Pointer pointer, |
| 723 const ui::LocatedEvent& event) { | 746 const ui::LocatedEvent& event) { |
| 724 if (drag_view_) | 747 if (drag_view_) |
| 725 return; | 748 return; |
| 726 | 749 |
| 727 int index = view_model_->GetIndexOfView(view); | 750 int index = view_model_->GetIndexOfView(view); |
| 728 if (index == -1) | 751 if (index == -1 || view_model_->view_size() <= 1) |
| 729 return; | 752 return; // View is being deleted, ignore request. |
| 730 | 753 |
| 731 ShelfItemDelegate* item_delegate = | 754 ShelfItemDelegate* item_delegate = |
| 732 item_manager_->GetShelfItemDelegate(model_->items()[index].id); | 755 item_manager_->GetShelfItemDelegate(model_->items()[index].id); |
| 733 if (view_model_->view_size() <= 1 || !item_delegate->IsDraggable()) | 756 if (!item_delegate->IsDraggable()) |
| 734 return; // View is being deleted or not draggable, ignore request. | 757 return; // View is not draggable, ignore request. |
| 735 | 758 |
| 736 // Only when the repost event occurs on the same shelf item, we should ignore | 759 // Only when the repost event occurs on the same shelf item, we should ignore |
| 737 // the call in ShelfView::ButtonPressed(...). | 760 // the call in ShelfView::ButtonPressed(...). |
| 738 is_repost_event_ = IsRepostEvent(event) && (last_pressed_index_ == index); | 761 is_repost_event_on_same_item_ = |
| 762 IsRepostEvent(event) && (last_pressed_index_ == index); |
| 739 | 763 |
| 740 CHECK_EQ(ShelfButton::kViewClassName, view->GetClassName()); | 764 CHECK_EQ(ShelfButton::kViewClassName, view->GetClassName()); |
| 741 drag_view_ = static_cast<ShelfButton*>(view); | 765 drag_view_ = static_cast<ShelfButton*>(view); |
| 742 drag_origin_ = gfx::Point(event.x(), event.y()); | 766 drag_origin_ = gfx::Point(event.x(), event.y()); |
| 743 UMA_HISTOGRAM_ENUMERATION("Ash.ShelfAlignmentUsage", | 767 UMA_HISTOGRAM_ENUMERATION("Ash.ShelfAlignmentUsage", |
| 744 shelf_->SelectValueForShelfAlignment( | 768 shelf_->SelectValueForShelfAlignment( |
| 745 SHELF_ALIGNMENT_UMA_ENUM_VALUE_BOTTOM, | 769 SHELF_ALIGNMENT_UMA_ENUM_VALUE_BOTTOM, |
| 746 SHELF_ALIGNMENT_UMA_ENUM_VALUE_LEFT, | 770 SHELF_ALIGNMENT_UMA_ENUM_VALUE_LEFT, |
| 747 SHELF_ALIGNMENT_UMA_ENUM_VALUE_RIGHT), | 771 SHELF_ALIGNMENT_UMA_ENUM_VALUE_RIGHT), |
| 748 SHELF_ALIGNMENT_UMA_ENUM_VALUE_COUNT); | 772 SHELF_ALIGNMENT_UMA_ENUM_VALUE_COUNT); |
| 749 } | 773 } |
| 750 | 774 |
| 751 void ShelfView::PointerDraggedOnButton(views::View* view, | 775 void ShelfView::PointerDraggedOnButton(views::View* view, |
| 752 Pointer pointer, | 776 Pointer pointer, |
| 753 const ui::LocatedEvent& event) { | 777 const ui::LocatedEvent& event) { |
| 754 // To prepare all drag types (moving an item in the shelf and dragging off), | 778 // To prepare all drag types (moving an item in the shelf and dragging off), |
| 755 // we should check the x-axis and y-axis offset. | 779 // we should check the x-axis and y-axis offset. |
| 756 if (!dragging() && drag_view_ && | 780 if (!dragging() && drag_view_ && |
| 757 ((std::abs(event.x() - drag_origin_.x()) >= kMinimumDragDistance) || | 781 ((std::abs(event.x() - drag_origin_.x()) >= kMinimumDragDistance) || |
| 758 (std::abs(event.y() - drag_origin_.y()) >= kMinimumDragDistance))) { | 782 (std::abs(event.y() - drag_origin_.y()) >= kMinimumDragDistance))) { |
| 759 PrepareForDrag(pointer, event); | 783 PrepareForDrag(pointer, event); |
| 760 } | 784 } |
| 761 if (drag_pointer_ == pointer) | 785 if (drag_pointer_ == pointer) |
| 762 ContinueDrag(event); | 786 ContinueDrag(event); |
| 763 } | 787 } |
| 764 | 788 |
| 765 void ShelfView::PointerReleasedOnButton(views::View* view, | 789 void ShelfView::PointerReleasedOnButton(views::View* view, |
| 766 Pointer pointer, | 790 Pointer pointer, |
| 767 bool canceled) { | 791 bool canceled) { |
| 768 // Reset |is_repost_event| to false. | 792 is_repost_event_on_same_item_ = false; |
| 769 is_repost_event_ = false; | |
| 770 | 793 |
| 771 if (canceled) { | 794 if (canceled) { |
| 772 CancelDrag(-1); | 795 CancelDrag(-1); |
| 773 } else if (drag_pointer_ == pointer) { | 796 } else if (drag_pointer_ == pointer) { |
| 774 FinalizeRipOffDrag(false); | 797 FinalizeRipOffDrag(false); |
| 775 drag_pointer_ = NONE; | 798 drag_pointer_ = NONE; |
| 776 AnimateToIdealBounds(); | 799 AnimateToIdealBounds(); |
| 777 } | 800 } |
| 778 // If the drag pointer is NONE, no drag operation is going on and the | 801 // If the drag pointer is NONE, no drag operation is going on and the |
| 779 // drag_view can be released. | 802 // drag_view can be released. |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 990 views::View* ShelfView::CreateViewForItem(const ShelfItem& item) { | 1013 views::View* ShelfView::CreateViewForItem(const ShelfItem& item) { |
| 991 views::View* view = nullptr; | 1014 views::View* view = nullptr; |
| 992 switch (item.type) { | 1015 switch (item.type) { |
| 993 case TYPE_BROWSER_SHORTCUT: | 1016 case TYPE_BROWSER_SHORTCUT: |
| 994 case TYPE_APP_SHORTCUT: | 1017 case TYPE_APP_SHORTCUT: |
| 995 case TYPE_WINDOWED_APP: | 1018 case TYPE_WINDOWED_APP: |
| 996 case TYPE_PLATFORM_APP: | 1019 case TYPE_PLATFORM_APP: |
| 997 case TYPE_DIALOG: | 1020 case TYPE_DIALOG: |
| 998 case TYPE_APP_PANEL: | 1021 case TYPE_APP_PANEL: |
| 999 case TYPE_IME_MENU: { | 1022 case TYPE_IME_MENU: { |
| 1000 ShelfButton* button = new ShelfButton(this); | 1023 ShelfButton* button = new ShelfButton(this, this); |
| 1001 button->SetImage(item.image); | 1024 button->SetImage(item.image); |
| 1002 ReflectItemStatus(item, button); | 1025 ReflectItemStatus(item, button); |
| 1003 view = button; | 1026 view = button; |
| 1004 break; | 1027 break; |
| 1005 } | 1028 } |
| 1006 | 1029 |
| 1007 case TYPE_APP_LIST: { | 1030 case TYPE_APP_LIST: { |
| 1008 view = new AppListButton(this); | 1031 view = new AppListButton(this, this); |
| 1009 break; | 1032 break; |
| 1010 } | 1033 } |
| 1011 | 1034 |
| 1012 case TYPE_UNDEFINED: | 1035 case TYPE_UNDEFINED: |
| 1013 return nullptr; | 1036 return nullptr; |
| 1014 } | 1037 } |
| 1015 | 1038 |
| 1016 view->set_context_menu_controller(this); | 1039 view->set_context_menu_controller(this); |
| 1017 ConfigureChildView(view); | 1040 ConfigureChildView(view); |
| 1018 return view; | 1041 return view; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1042 ShelfItemDelegate* item_delegate = item_manager_->GetShelfItemDelegate( | 1065 ShelfItemDelegate* item_delegate = item_manager_->GetShelfItemDelegate( |
| 1043 model_->items()[start_drag_index_].id); | 1066 model_->items()[start_drag_index_].id); |
| 1044 if (!item_delegate->IsDraggable()) { | 1067 if (!item_delegate->IsDraggable()) { |
| 1045 CancelDrag(-1); | 1068 CancelDrag(-1); |
| 1046 return; | 1069 return; |
| 1047 } | 1070 } |
| 1048 | 1071 |
| 1049 // Move the view to the front so that it appears on top of other views. | 1072 // Move the view to the front so that it appears on top of other views. |
| 1050 ReorderChildView(drag_view_, -1); | 1073 ReorderChildView(drag_view_, -1); |
| 1051 bounds_animator_->StopAnimatingView(drag_view_); | 1074 bounds_animator_->StopAnimatingView(drag_view_); |
| 1075 |
| 1076 drag_view_->OnDragStarted(); |
| 1052 } | 1077 } |
| 1053 | 1078 |
| 1054 void ShelfView::ContinueDrag(const ui::LocatedEvent& event) { | 1079 void ShelfView::ContinueDrag(const ui::LocatedEvent& event) { |
| 1055 // Due to a syncing operation the application might have been removed. | 1080 // Due to a syncing operation the application might have been removed. |
| 1056 // Bail if it is gone. | 1081 // Bail if it is gone. |
| 1057 int current_index = view_model_->GetIndexOfView(drag_view_); | 1082 int current_index = view_model_->GetIndexOfView(drag_view_); |
| 1058 DCHECK_NE(-1, current_index); | 1083 DCHECK_NE(-1, current_index); |
| 1059 | 1084 |
| 1060 ShelfItemDelegate* item_delegate = | 1085 ShelfItemDelegate* item_delegate = |
| 1061 item_manager_->GetShelfItemDelegate(model_->items()[current_index].id); | 1086 item_manager_->GetShelfItemDelegate(model_->items()[current_index].id); |
| (...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1667 void ShelfView::ShelfItemMoved(int start_index, int target_index) { | 1692 void ShelfView::ShelfItemMoved(int start_index, int target_index) { |
| 1668 view_model_->Move(start_index, target_index); | 1693 view_model_->Move(start_index, target_index); |
| 1669 // When cancelling a drag due to a shelf item being added, the currently | 1694 // When cancelling a drag due to a shelf item being added, the currently |
| 1670 // dragged item is moved back to its initial position. AnimateToIdealBounds | 1695 // dragged item is moved back to its initial position. AnimateToIdealBounds |
| 1671 // will be called again when the new item is added to the |view_model_| but | 1696 // will be called again when the new item is added to the |view_model_| but |
| 1672 // at this time the |view_model_| is inconsistent with the |model_|. | 1697 // at this time the |view_model_| is inconsistent with the |model_|. |
| 1673 if (!cancelling_drag_model_changed_) | 1698 if (!cancelling_drag_model_changed_) |
| 1674 AnimateToIdealBounds(); | 1699 AnimateToIdealBounds(); |
| 1675 } | 1700 } |
| 1676 | 1701 |
| 1677 void ShelfView::ButtonPressed(views::Button* sender, const ui::Event& event) { | 1702 void ShelfView::ButtonPressed(views::Button* sender, |
| 1678 // Do not handle mouse release during drag. | 1703 const ui::Event& event, |
| 1679 if (dragging()) | 1704 views::InkDrop* ink_drop) { |
| 1680 return; | |
| 1681 | |
| 1682 if (sender == overflow_button_) { | 1705 if (sender == overflow_button_) { |
| 1683 ToggleOverflowBubble(); | 1706 ToggleOverflowBubble(); |
| 1684 shelf_button_pressed_metric_tracker_.ButtonPressed( | 1707 shelf_button_pressed_metric_tracker_.ButtonPressed( |
| 1685 event, sender, ShelfItemDelegate::kNoAction); | 1708 event, sender, ShelfItemDelegate::kNoAction); |
| 1686 return; | 1709 return; |
| 1687 } | 1710 } |
| 1688 | 1711 |
| 1689 int view_index = view_model_->GetIndexOfView(sender); | 1712 // None of the checks in ShouldEventActivateButton() affects overflow button. |
| 1690 // May be -1 while in the process of animating closed. | 1713 // So, it is safe to be checked after handling overflow button. |
| 1691 if (view_index == -1) | 1714 if (!ShouldEventActivateButton(sender, event)) |
| 1692 return; | |
| 1693 | |
| 1694 // If the menu was just closed by the same event as this one, we ignore | |
| 1695 // the call and don't open the menu again. See crbug.com/343005 for more | |
| 1696 // detail. | |
| 1697 if (is_repost_event_) | |
| 1698 return; | 1715 return; |
| 1699 | 1716 |
| 1700 // Record the index for the last pressed shelf item. | 1717 // Record the index for the last pressed shelf item. |
| 1701 last_pressed_index_ = view_index; | 1718 last_pressed_index_ = view_model_->GetIndexOfView(sender); |
| 1702 | 1719 DCHECK_LT(-1, last_pressed_index_); |
| 1703 // Don't activate the item twice on double-click. Otherwise the window starts | |
| 1704 // animating open due to the first click, then immediately minimizes due to | |
| 1705 // the second click. The user most likely intended to open or minimize the | |
| 1706 // item once, not do both. | |
| 1707 if (event.flags() & ui::EF_IS_DOUBLE_CLICK) | |
| 1708 return; | |
| 1709 | 1720 |
| 1710 { | 1721 { |
| 1711 ScopedTargetRootWindow scoped_target( | 1722 ScopedTargetRootWindow scoped_target( |
| 1712 sender->GetWidget()->GetNativeView()->GetRootWindow()); | 1723 sender->GetWidget()->GetNativeView()->GetRootWindow()); |
| 1713 // Slow down activation animations if shift key is pressed. | 1724 // Slow down activation animations if shift key is pressed. |
| 1714 std::unique_ptr<ui::ScopedAnimationDurationScaleMode> slowing_animations; | 1725 std::unique_ptr<ui::ScopedAnimationDurationScaleMode> slowing_animations; |
| 1715 if (event.IsShiftDown()) { | 1726 if (event.IsShiftDown()) { |
| 1716 slowing_animations.reset(new ui::ScopedAnimationDurationScaleMode( | 1727 slowing_animations.reset(new ui::ScopedAnimationDurationScaleMode( |
| 1717 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION)); | 1728 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION)); |
| 1718 } | 1729 } |
| 1719 | 1730 |
| 1720 // Collect usage statistics before we decide what to do with the click. | 1731 // Collect usage statistics before we decide what to do with the click. |
| 1721 switch (model_->items()[view_index].type) { | 1732 switch (model_->items()[last_pressed_index_].type) { |
| 1722 case TYPE_APP_SHORTCUT: | 1733 case TYPE_APP_SHORTCUT: |
| 1723 case TYPE_WINDOWED_APP: | 1734 case TYPE_WINDOWED_APP: |
| 1724 case TYPE_PLATFORM_APP: | 1735 case TYPE_PLATFORM_APP: |
| 1725 case TYPE_BROWSER_SHORTCUT: | 1736 case TYPE_BROWSER_SHORTCUT: |
| 1726 Shell::GetInstance()->metrics()->RecordUserMetricsAction( | 1737 Shell::GetInstance()->metrics()->RecordUserMetricsAction( |
| 1727 UMA_LAUNCHER_CLICK_ON_APP); | 1738 UMA_LAUNCHER_CLICK_ON_APP); |
| 1728 break; | 1739 break; |
| 1729 | 1740 |
| 1730 case TYPE_APP_LIST: | 1741 case TYPE_APP_LIST: |
| 1731 Shell::GetInstance()->metrics()->RecordUserMetricsAction( | 1742 Shell::GetInstance()->metrics()->RecordUserMetricsAction( |
| 1732 UMA_LAUNCHER_CLICK_ON_APPLIST_BUTTON); | 1743 UMA_LAUNCHER_CLICK_ON_APPLIST_BUTTON); |
| 1733 break; | 1744 break; |
| 1734 | 1745 |
| 1735 case TYPE_APP_PANEL: | 1746 case TYPE_APP_PANEL: |
| 1736 case TYPE_DIALOG: | 1747 case TYPE_DIALOG: |
| 1737 case TYPE_IME_MENU: | 1748 case TYPE_IME_MENU: |
| 1738 break; | 1749 break; |
| 1739 | 1750 |
| 1740 case TYPE_UNDEFINED: | 1751 case TYPE_UNDEFINED: |
| 1741 NOTREACHED() << "ShelfItemType must be set."; | 1752 NOTREACHED() << "ShelfItemType must be set."; |
| 1742 break; | 1753 break; |
| 1743 } | 1754 } |
| 1744 | 1755 |
| 1745 ShelfItemDelegate::PerformedAction performed_action = | 1756 ShelfItemDelegate::PerformedAction performed_action = |
| 1746 item_manager_->GetShelfItemDelegate(model_->items()[view_index].id) | 1757 item_manager_ |
| 1758 ->GetShelfItemDelegate(model_->items()[last_pressed_index_].id) |
| 1747 ->ItemSelected(event); | 1759 ->ItemSelected(event); |
| 1748 | 1760 |
| 1749 shelf_button_pressed_metric_tracker_.ButtonPressed(event, sender, | 1761 shelf_button_pressed_metric_tracker_.ButtonPressed(event, sender, |
| 1750 performed_action); | 1762 performed_action); |
| 1751 | 1763 |
| 1752 if (performed_action != ShelfItemDelegate::kNewWindowCreated) | 1764 if (performed_action == ShelfItemDelegate::kNewWindowCreated || |
| 1753 ShowListMenuForView(model_->items()[view_index], sender, event); | 1765 !ShowListMenuForView(model_->items()[last_pressed_index_], sender, |
| 1766 event, ink_drop)) { |
| 1767 ink_drop->AnimateToState(views::InkDropState::ACTION_TRIGGERED); |
| 1768 } |
| 1754 } | 1769 } |
| 1755 } | 1770 } |
| 1756 | 1771 |
| 1757 void ShelfView::ShowListMenuForView(const ShelfItem& item, | 1772 bool ShelfView::ShowListMenuForView(const ShelfItem& item, |
| 1758 views::View* source, | 1773 views::View* source, |
| 1759 const ui::Event& event) { | 1774 const ui::Event& event, |
| 1775 views::InkDrop* ink_drop) { |
| 1760 ShelfItemDelegate* item_delegate = | 1776 ShelfItemDelegate* item_delegate = |
| 1761 item_manager_->GetShelfItemDelegate(item.id); | 1777 item_manager_->GetShelfItemDelegate(item.id); |
| 1762 std::unique_ptr<ui::MenuModel> list_menu_model( | 1778 std::unique_ptr<ui::MenuModel> list_menu_model( |
| 1763 item_delegate->CreateApplicationMenu(event.flags())); | 1779 item_delegate->CreateApplicationMenu(event.flags())); |
| 1764 | 1780 |
| 1765 // Make sure we have a menu and it has at least two items in addition to the | 1781 // Make sure we have a menu and it has at least two items in addition to the |
| 1766 // application title and the 3 spacing separators. | 1782 // application title and the 3 spacing separators. |
| 1767 if (!list_menu_model.get() || list_menu_model->GetItemCount() <= 5) | 1783 if (!list_menu_model.get() || list_menu_model->GetItemCount() <= 5) |
| 1768 return; | 1784 return false; |
| 1769 | 1785 |
| 1786 ink_drop->AnimateToState(views::InkDropState::ACTIVATED); |
| 1770 context_menu_id_ = item.id; | 1787 context_menu_id_ = item.id; |
| 1771 ShowMenu(list_menu_model.get(), source, gfx::Point(), false, | 1788 ShowMenu(list_menu_model.get(), source, gfx::Point(), false, |
| 1772 ui::GetMenuSourceTypeForEvent(event)); | 1789 ui::GetMenuSourceTypeForEvent(event)); |
| 1790 // Menu is run synchronously, the menu is closed now and we need to go to |
| 1791 // the deactivated state. |
| 1792 ink_drop->AnimateToState(views::InkDropState::DEACTIVATED); |
| 1793 return true; |
| 1773 } | 1794 } |
| 1774 | 1795 |
| 1775 void ShelfView::ShowContextMenuForView(views::View* source, | 1796 void ShelfView::ShowContextMenuForView(views::View* source, |
| 1776 const gfx::Point& point, | 1797 const gfx::Point& point, |
| 1777 ui::MenuSourceType source_type) { | 1798 ui::MenuSourceType source_type) { |
| 1799 last_pressed_index_ = -1; |
| 1800 |
| 1778 const ShelfItem* item = ShelfItemForView(source); | 1801 const ShelfItem* item = ShelfItemForView(source); |
| 1779 if (!item) { | 1802 if (!item) { |
| 1780 Shell::GetInstance()->ShowContextMenu(point, source_type); | 1803 Shell::GetInstance()->ShowContextMenu(point, source_type); |
| 1781 return; | 1804 return; |
| 1782 } | 1805 } |
| 1783 | 1806 |
| 1784 std::unique_ptr<ui::MenuModel> context_menu_model( | 1807 std::unique_ptr<ui::MenuModel> context_menu_model( |
| 1785 Shell::GetInstance()->delegate()->CreateContextMenu(wm_shelf_, item)); | 1808 Shell::GetInstance()->delegate()->CreateContextMenu(wm_shelf_, item)); |
| 1786 if (!context_menu_model) | 1809 if (!context_menu_model) |
| 1787 return; | 1810 return; |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1877 } | 1900 } |
| 1878 snap_back_from_rip_off_view_ = nullptr; | 1901 snap_back_from_rip_off_view_ = nullptr; |
| 1879 } | 1902 } |
| 1880 } | 1903 } |
| 1881 } | 1904 } |
| 1882 | 1905 |
| 1883 bool ShelfView::IsRepostEvent(const ui::Event& event) { | 1906 bool ShelfView::IsRepostEvent(const ui::Event& event) { |
| 1884 if (closing_event_time_.is_null()) | 1907 if (closing_event_time_.is_null()) |
| 1885 return false; | 1908 return false; |
| 1886 | 1909 |
| 1887 base::TimeTicks last_closing_event_time = closing_event_time_; | |
| 1888 closing_event_time_ = base::TimeTicks(); | |
| 1889 // If the current (press down) event is a repost event, the time stamp of | 1910 // If the current (press down) event is a repost event, the time stamp of |
| 1890 // these two events should be the same. | 1911 // these two events should be the same. |
| 1891 return last_closing_event_time == event.time_stamp(); | 1912 return closing_event_time_ == event.time_stamp(); |
| 1892 } | 1913 } |
| 1893 | 1914 |
| 1894 const ShelfItem* ShelfView::ShelfItemForView(const views::View* view) const { | 1915 const ShelfItem* ShelfView::ShelfItemForView(const views::View* view) const { |
| 1895 const int view_index = view_model_->GetIndexOfView(view); | 1916 const int view_index = view_model_->GetIndexOfView(view); |
| 1896 return (view_index < 0) ? nullptr : &(model_->items()[view_index]); | 1917 return (view_index < 0) ? nullptr : &(model_->items()[view_index]); |
| 1897 } | 1918 } |
| 1898 | 1919 |
| 1899 int ShelfView::CalculateShelfDistance(const gfx::Point& coordinate) const { | 1920 int ShelfView::CalculateShelfDistance(const gfx::Point& coordinate) const { |
| 1900 const gfx::Rect bounds = GetBoundsInScreen(); | 1921 const gfx::Rect bounds = GetBoundsInScreen(); |
| 1901 int distance = shelf_->SelectValueForShelfAlignment( | 1922 int distance = shelf_->SelectValueForShelfAlignment( |
| 1902 bounds.y() - coordinate.y(), coordinate.x() - bounds.right(), | 1923 bounds.y() - coordinate.y(), coordinate.x() - bounds.right(), |
| 1903 bounds.x() - coordinate.x()); | 1924 bounds.x() - coordinate.x()); |
| 1904 return distance > 0 ? distance : 0; | 1925 return distance > 0 ? distance : 0; |
| 1905 } | 1926 } |
| 1906 | 1927 |
| 1907 } // namespace ash | 1928 } // namespace ash |
| OLD | NEW |