| 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 | 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/drag_drop/drag_image_view.h" | 11 #include "ash/drag_drop/drag_image_view.h" |
| 12 #include "ash/launcher/launcher_delegate.h" | 12 #include "ash/launcher/launcher_delegate.h" |
| 13 #include "ash/launcher/launcher_item_delegate.h" | |
| 14 #include "ash/launcher/launcher_item_delegate_manager.h" | |
| 15 #include "ash/root_window_controller.h" | 13 #include "ash/root_window_controller.h" |
| 16 #include "ash/scoped_target_root_window.h" | 14 #include "ash/scoped_target_root_window.h" |
| 17 #include "ash/shelf/alternate_app_list_button.h" | 15 #include "ash/shelf/alternate_app_list_button.h" |
| 18 #include "ash/shelf/app_list_button.h" | 16 #include "ash/shelf/app_list_button.h" |
| 19 #include "ash/shelf/overflow_bubble.h" | 17 #include "ash/shelf/overflow_bubble.h" |
| 20 #include "ash/shelf/overflow_bubble_view.h" | 18 #include "ash/shelf/overflow_bubble_view.h" |
| 21 #include "ash/shelf/overflow_button.h" | 19 #include "ash/shelf/overflow_button.h" |
| 22 #include "ash/shelf/shelf_button.h" | 20 #include "ash/shelf/shelf_button.h" |
| 23 #include "ash/shelf/shelf_icon_observer.h" | 21 #include "ash/shelf/shelf_icon_observer.h" |
| 22 #include "ash/shelf/shelf_item_delegate.h" |
| 23 #include "ash/shelf/shelf_item_delegate_manager.h" |
| 24 #include "ash/shelf/shelf_layout_manager.h" | 24 #include "ash/shelf/shelf_layout_manager.h" |
| 25 #include "ash/shelf/shelf_model.h" | 25 #include "ash/shelf/shelf_model.h" |
| 26 #include "ash/shelf/shelf_tooltip_manager.h" | 26 #include "ash/shelf/shelf_tooltip_manager.h" |
| 27 #include "ash/shelf/shelf_widget.h" | 27 #include "ash/shelf/shelf_widget.h" |
| 28 #include "ash/shell_delegate.h" | 28 #include "ash/shell_delegate.h" |
| 29 #include "ash/wm/coordinate_conversion.h" | 29 #include "ash/wm/coordinate_conversion.h" |
| 30 #include "base/auto_reset.h" | 30 #include "base/auto_reset.h" |
| 31 #include "base/memory/scoped_ptr.h" | 31 #include "base/memory/scoped_ptr.h" |
| 32 #include "base/metrics/histogram.h" | 32 #include "base/metrics/histogram.h" |
| 33 #include "grit/ash_resources.h" | 33 #include "grit/ash_resources.h" |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 context_menu_id_(0), | 386 context_menu_id_(0), |
| 387 leading_inset_(kDefaultLeadingInset), | 387 leading_inset_(kDefaultLeadingInset), |
| 388 cancelling_drag_model_changed_(false), | 388 cancelling_drag_model_changed_(false), |
| 389 last_hidden_index_(0), | 389 last_hidden_index_(0), |
| 390 closing_event_time_(base::TimeDelta()), | 390 closing_event_time_(base::TimeDelta()), |
| 391 got_deleted_(NULL), | 391 got_deleted_(NULL), |
| 392 drag_and_drop_item_pinned_(false), | 392 drag_and_drop_item_pinned_(false), |
| 393 drag_and_drop_launcher_id_(0), | 393 drag_and_drop_launcher_id_(0), |
| 394 dragged_off_shelf_(false), | 394 dragged_off_shelf_(false), |
| 395 snap_back_from_rip_off_view_(NULL), | 395 snap_back_from_rip_off_view_(NULL), |
| 396 item_manager_(Shell::GetInstance()->launcher_item_delegate_manager()), | 396 item_manager_(Shell::GetInstance()->shelf_item_delegate_manager()), |
| 397 layout_manager_(shelf_layout_manager), | 397 layout_manager_(shelf_layout_manager), |
| 398 overflow_mode_(false) { | 398 overflow_mode_(false) { |
| 399 DCHECK(model_); | 399 DCHECK(model_); |
| 400 bounds_animator_.reset(new views::BoundsAnimator(this)); | 400 bounds_animator_.reset(new views::BoundsAnimator(this)); |
| 401 bounds_animator_->AddObserver(this); | 401 bounds_animator_->AddObserver(this); |
| 402 set_context_menu_controller(this); | 402 set_context_menu_controller(this); |
| 403 focus_search_.reset(new LauncherFocusSearch(view_model_.get())); | 403 focus_search_.reset(new LauncherFocusSearch(view_model_.get())); |
| 404 tooltip_.reset(new ShelfTooltipManager(shelf_layout_manager, this)); | 404 tooltip_.reset(new ShelfTooltipManager(shelf_layout_manager, this)); |
| 405 } | 405 } |
| 406 | 406 |
| (...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 972 DCHECK(drag_view_); | 972 DCHECK(drag_view_); |
| 973 drag_pointer_ = pointer; | 973 drag_pointer_ = pointer; |
| 974 start_drag_index_ = view_model_->GetIndexOfView(drag_view_); | 974 start_drag_index_ = view_model_->GetIndexOfView(drag_view_); |
| 975 | 975 |
| 976 if (start_drag_index_== -1) { | 976 if (start_drag_index_== -1) { |
| 977 CancelDrag(-1); | 977 CancelDrag(-1); |
| 978 return; | 978 return; |
| 979 } | 979 } |
| 980 | 980 |
| 981 // If the item is no longer draggable, bail out. | 981 // If the item is no longer draggable, bail out. |
| 982 LauncherItemDelegate* item_delegate = item_manager_->GetLauncherItemDelegate( | 982 ShelfItemDelegate* item_delegate = item_manager_->GetShelfItemDelegate( |
| 983 model_->items()[start_drag_index_].id); | 983 model_->items()[start_drag_index_].id); |
| 984 if (!item_delegate->IsDraggable()) { | 984 if (!item_delegate->IsDraggable()) { |
| 985 CancelDrag(-1); | 985 CancelDrag(-1); |
| 986 return; | 986 return; |
| 987 } | 987 } |
| 988 | 988 |
| 989 // Move the view to the front so that it appears on top of other views. | 989 // Move the view to the front so that it appears on top of other views. |
| 990 ReorderChildView(drag_view_, -1); | 990 ReorderChildView(drag_view_, -1); |
| 991 bounds_animator_->StopAnimatingView(drag_view_); | 991 bounds_animator_->StopAnimatingView(drag_view_); |
| 992 } | 992 } |
| 993 | 993 |
| 994 void ShelfView::ContinueDrag(const ui::LocatedEvent& event) { | 994 void ShelfView::ContinueDrag(const ui::LocatedEvent& event) { |
| 995 // Due to a syncing operation the application might have been removed. | 995 // Due to a syncing operation the application might have been removed. |
| 996 // Bail if it is gone. | 996 // Bail if it is gone. |
| 997 int current_index = view_model_->GetIndexOfView(drag_view_); | 997 int current_index = view_model_->GetIndexOfView(drag_view_); |
| 998 DCHECK_NE(-1, current_index); | 998 DCHECK_NE(-1, current_index); |
| 999 | 999 |
| 1000 LauncherItemDelegate* item_delegate = item_manager_->GetLauncherItemDelegate( | 1000 ShelfItemDelegate* item_delegate = item_manager_->GetShelfItemDelegate( |
| 1001 model_->items()[current_index].id); | 1001 model_->items()[current_index].id); |
| 1002 if (!item_delegate->IsDraggable()) { | 1002 if (!item_delegate->IsDraggable()) { |
| 1003 CancelDrag(-1); | 1003 CancelDrag(-1); |
| 1004 return; | 1004 return; |
| 1005 } | 1005 } |
| 1006 | 1006 |
| 1007 // If this is not a drag and drop host operation and not the app list item, | 1007 // If this is not a drag and drop host operation and not the app list item, |
| 1008 // check if the item got ripped off the shelf - if it did we are done. | 1008 // check if the item got ripped off the shelf - if it did we are done. |
| 1009 if (!drag_and_drop_launcher_id_ && ash::switches::UseDragOffShelf() && | 1009 if (!drag_and_drop_launcher_id_ && ash::switches::UseDragOffShelf() && |
| 1010 RemovableByRipOff(current_index) != NOT_REMOVABLE) { | 1010 RemovableByRipOff(current_index) != NOT_REMOVABLE) { |
| (...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1607 void ShelfView::PointerPressedOnButton(views::View* view, | 1607 void ShelfView::PointerPressedOnButton(views::View* view, |
| 1608 Pointer pointer, | 1608 Pointer pointer, |
| 1609 const ui::LocatedEvent& event) { | 1609 const ui::LocatedEvent& event) { |
| 1610 if (drag_view_) | 1610 if (drag_view_) |
| 1611 return; | 1611 return; |
| 1612 | 1612 |
| 1613 int index = view_model_->GetIndexOfView(view); | 1613 int index = view_model_->GetIndexOfView(view); |
| 1614 if (index == -1) | 1614 if (index == -1) |
| 1615 return; | 1615 return; |
| 1616 | 1616 |
| 1617 LauncherItemDelegate* item_delegate = item_manager_->GetLauncherItemDelegate( | 1617 ShelfItemDelegate* item_delegate = item_manager_->GetShelfItemDelegate( |
| 1618 model_->items()[index].id); | 1618 model_->items()[index].id); |
| 1619 if (view_model_->view_size() <= 1 || !item_delegate->IsDraggable()) | 1619 if (view_model_->view_size() <= 1 || !item_delegate->IsDraggable()) |
| 1620 return; // View is being deleted or not draggable, ignore request. | 1620 return; // View is being deleted or not draggable, ignore request. |
| 1621 | 1621 |
| 1622 drag_view_ = view; | 1622 drag_view_ = view; |
| 1623 drag_offset_ = layout_manager_->PrimaryAxisValue(event.x(), event.y()); | 1623 drag_offset_ = layout_manager_->PrimaryAxisValue(event.x(), event.y()); |
| 1624 UMA_HISTOGRAM_ENUMERATION("Ash.ShelfAlignmentUsage", | 1624 UMA_HISTOGRAM_ENUMERATION("Ash.ShelfAlignmentUsage", |
| 1625 layout_manager_->SelectValueForShelfAlignment( | 1625 layout_manager_->SelectValueForShelfAlignment( |
| 1626 SHELF_ALIGNMENT_UMA_ENUM_VALUE_BOTTOM, | 1626 SHELF_ALIGNMENT_UMA_ENUM_VALUE_BOTTOM, |
| 1627 SHELF_ALIGNMENT_UMA_ENUM_VALUE_LEFT, | 1627 SHELF_ALIGNMENT_UMA_ENUM_VALUE_LEFT, |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1683 if (!tooltip_->IsVisible()) | 1683 if (!tooltip_->IsVisible()) |
| 1684 tooltip_->StopTimer(); | 1684 tooltip_->StopTimer(); |
| 1685 } | 1685 } |
| 1686 | 1686 |
| 1687 base::string16 ShelfView::GetAccessibleName(const views::View* view) { | 1687 base::string16 ShelfView::GetAccessibleName(const views::View* view) { |
| 1688 int view_index = view_model_->GetIndexOfView(view); | 1688 int view_index = view_model_->GetIndexOfView(view); |
| 1689 // May be -1 while in the process of animating closed. | 1689 // May be -1 while in the process of animating closed. |
| 1690 if (view_index == -1) | 1690 if (view_index == -1) |
| 1691 return base::string16(); | 1691 return base::string16(); |
| 1692 | 1692 |
| 1693 LauncherItemDelegate* item_delegate = item_manager_->GetLauncherItemDelegate( | 1693 ShelfItemDelegate* item_delegate = item_manager_->GetShelfItemDelegate( |
| 1694 model_->items()[view_index].id); | 1694 model_->items()[view_index].id); |
| 1695 return item_delegate->GetTitle(); | 1695 return item_delegate->GetTitle(); |
| 1696 } | 1696 } |
| 1697 | 1697 |
| 1698 void ShelfView::ButtonPressed(views::Button* sender, const ui::Event& event) { | 1698 void ShelfView::ButtonPressed(views::Button* sender, const ui::Event& event) { |
| 1699 // Do not handle mouse release during drag. | 1699 // Do not handle mouse release during drag. |
| 1700 if (dragging()) | 1700 if (dragging()) |
| 1701 return; | 1701 return; |
| 1702 | 1702 |
| 1703 if (sender == overflow_button_) { | 1703 if (sender == overflow_button_) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1741 break; | 1741 break; |
| 1742 | 1742 |
| 1743 case TYPE_APP_PANEL: | 1743 case TYPE_APP_PANEL: |
| 1744 break; | 1744 break; |
| 1745 | 1745 |
| 1746 case TYPE_UNDEFINED: | 1746 case TYPE_UNDEFINED: |
| 1747 NOTREACHED() << "LauncherItemType must be set."; | 1747 NOTREACHED() << "LauncherItemType must be set."; |
| 1748 break; | 1748 break; |
| 1749 } | 1749 } |
| 1750 | 1750 |
| 1751 LauncherItemDelegate* item_delegate = | 1751 ShelfItemDelegate* item_delegate = |
| 1752 item_manager_->GetLauncherItemDelegate( | 1752 item_manager_->GetShelfItemDelegate(model_->items()[view_index].id); |
| 1753 model_->items()[view_index].id); | |
| 1754 if (!item_delegate->ItemSelected(event)) | 1753 if (!item_delegate->ItemSelected(event)) |
| 1755 ShowListMenuForView(model_->items()[view_index], sender, event); | 1754 ShowListMenuForView(model_->items()[view_index], sender, event); |
| 1756 } | 1755 } |
| 1757 } | 1756 } |
| 1758 | 1757 |
| 1759 bool ShelfView::ShowListMenuForView(const LauncherItem& item, | 1758 bool ShelfView::ShowListMenuForView(const LauncherItem& item, |
| 1760 views::View* source, | 1759 views::View* source, |
| 1761 const ui::Event& event) { | 1760 const ui::Event& event) { |
| 1762 scoped_ptr<ash::LauncherMenuModel> menu_model; | 1761 scoped_ptr<LauncherMenuModel> menu_model; |
| 1763 LauncherItemDelegate* item_delegate = | 1762 ShelfItemDelegate* item_delegate = |
| 1764 item_manager_->GetLauncherItemDelegate(item.id); | 1763 item_manager_->GetShelfItemDelegate(item.id); |
| 1765 menu_model.reset(item_delegate->CreateApplicationMenu(event.flags())); | 1764 menu_model.reset(item_delegate->CreateApplicationMenu(event.flags())); |
| 1766 | 1765 |
| 1767 // Make sure we have a menu and it has at least two items in addition to the | 1766 // Make sure we have a menu and it has at least two items in addition to the |
| 1768 // application title and the 3 spacing separators. | 1767 // application title and the 3 spacing separators. |
| 1769 if (!menu_model.get() || menu_model->GetItemCount() <= 5) | 1768 if (!menu_model.get() || menu_model->GetItemCount() <= 5) |
| 1770 return false; | 1769 return false; |
| 1771 | 1770 |
| 1772 ShowMenu(scoped_ptr<views::MenuModelAdapter>( | 1771 ShowMenu(scoped_ptr<views::MenuModelAdapter>( |
| 1773 new LauncherMenuModelAdapter(menu_model.get())), | 1772 new LauncherMenuModelAdapter(menu_model.get())), |
| 1774 source, | 1773 source, |
| 1775 gfx::Point(), | 1774 gfx::Point(), |
| 1776 false, | 1775 false, |
| 1777 ui::GetMenuSourceTypeForEvent(event)); | 1776 ui::GetMenuSourceTypeForEvent(event)); |
| 1778 return true; | 1777 return true; |
| 1779 } | 1778 } |
| 1780 | 1779 |
| 1781 void ShelfView::ShowContextMenuForView(views::View* source, | 1780 void ShelfView::ShowContextMenuForView(views::View* source, |
| 1782 const gfx::Point& point, | 1781 const gfx::Point& point, |
| 1783 ui::MenuSourceType source_type) { | 1782 ui::MenuSourceType source_type) { |
| 1784 int view_index = view_model_->GetIndexOfView(source); | 1783 int view_index = view_model_->GetIndexOfView(source); |
| 1785 // TODO(simon.hong81): Create LauncherContextMenu for applist in its | 1784 // TODO(simon.hong81): Create LauncherContextMenu for applist in its |
| 1786 // LauncherItemDelegate. | 1785 // ShelfItemDelegate. |
| 1787 if (view_index != -1 && | 1786 if (view_index != -1 && model_->items()[view_index].type == TYPE_APP_LIST) { |
| 1788 model_->items()[view_index].type == TYPE_APP_LIST) { | |
| 1789 view_index = -1; | 1787 view_index = -1; |
| 1790 } | 1788 } |
| 1791 | 1789 |
| 1792 if (view_index == -1) { | 1790 if (view_index == -1) { |
| 1793 Shell::GetInstance()->ShowContextMenu(point, source_type); | 1791 Shell::GetInstance()->ShowContextMenu(point, source_type); |
| 1794 return; | 1792 return; |
| 1795 } | 1793 } |
| 1796 scoped_ptr<ui::MenuModel> menu_model; | 1794 scoped_ptr<ui::MenuModel> menu_model; |
| 1797 LauncherItemDelegate* item_delegate = item_manager_->GetLauncherItemDelegate( | 1795 ShelfItemDelegate* item_delegate = item_manager_->GetShelfItemDelegate( |
| 1798 model_->items()[view_index].id); | 1796 model_->items()[view_index].id); |
| 1799 menu_model.reset(item_delegate->CreateContextMenu( | 1797 menu_model.reset(item_delegate->CreateContextMenu( |
| 1800 source->GetWidget()->GetNativeView()->GetRootWindow())); | 1798 source->GetWidget()->GetNativeView()->GetRootWindow())); |
| 1801 if (!menu_model) | 1799 if (!menu_model) |
| 1802 return; | 1800 return; |
| 1803 | 1801 |
| 1804 base::AutoReset<LauncherID> reseter( | 1802 base::AutoReset<LauncherID> reseter( |
| 1805 &context_menu_id_, | 1803 &context_menu_id_, |
| 1806 view_index == -1 ? 0 : model_->items()[view_index].id); | 1804 view_index == -1 ? 0 : model_->items()[view_index].id); |
| 1807 | 1805 |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1948 return &(model_->items()[view_index]); | 1946 return &(model_->items()[view_index]); |
| 1949 } | 1947 } |
| 1950 | 1948 |
| 1951 bool ShelfView::ShouldShowTooltipForView(const views::View* view) const { | 1949 bool ShelfView::ShouldShowTooltipForView(const views::View* view) const { |
| 1952 if (view == GetAppListButtonView() && | 1950 if (view == GetAppListButtonView() && |
| 1953 Shell::GetInstance()->GetAppListWindow()) | 1951 Shell::GetInstance()->GetAppListWindow()) |
| 1954 return false; | 1952 return false; |
| 1955 const LauncherItem* item = LauncherItemForView(view); | 1953 const LauncherItem* item = LauncherItemForView(view); |
| 1956 if (!item) | 1954 if (!item) |
| 1957 return true; | 1955 return true; |
| 1958 LauncherItemDelegate* item_delegate = | 1956 ShelfItemDelegate* item_delegate = |
| 1959 item_manager_->GetLauncherItemDelegate(item->id); | 1957 item_manager_->GetShelfItemDelegate(item->id); |
| 1960 return item_delegate->ShouldShowTooltip(); | 1958 return item_delegate->ShouldShowTooltip(); |
| 1961 } | 1959 } |
| 1962 | 1960 |
| 1963 int ShelfView::CalculateShelfDistance(const gfx::Point& coordinate) const { | 1961 int ShelfView::CalculateShelfDistance(const gfx::Point& coordinate) const { |
| 1964 ShelfWidget* shelf = RootWindowController::ForLauncher( | 1962 ShelfWidget* shelf = RootWindowController::ForLauncher( |
| 1965 GetWidget()->GetNativeView())->shelf(); | 1963 GetWidget()->GetNativeView())->shelf(); |
| 1966 ash::ShelfAlignment align = shelf->GetAlignment(); | 1964 ash::ShelfAlignment align = shelf->GetAlignment(); |
| 1967 const gfx::Rect bounds = GetBoundsInScreen(); | 1965 const gfx::Rect bounds = GetBoundsInScreen(); |
| 1968 int distance = 0; | 1966 int distance = 0; |
| 1969 switch (align) { | 1967 switch (align) { |
| 1970 case ash::SHELF_ALIGNMENT_BOTTOM: | 1968 case ash::SHELF_ALIGNMENT_BOTTOM: |
| 1971 distance = bounds.y() - coordinate.y(); | 1969 distance = bounds.y() - coordinate.y(); |
| 1972 break; | 1970 break; |
| 1973 case ash::SHELF_ALIGNMENT_LEFT: | 1971 case ash::SHELF_ALIGNMENT_LEFT: |
| 1974 distance = coordinate.x() - bounds.right(); | 1972 distance = coordinate.x() - bounds.right(); |
| 1975 break; | 1973 break; |
| 1976 case ash::SHELF_ALIGNMENT_RIGHT: | 1974 case ash::SHELF_ALIGNMENT_RIGHT: |
| 1977 distance = bounds.x() - coordinate.x(); | 1975 distance = bounds.x() - coordinate.x(); |
| 1978 break; | 1976 break; |
| 1979 case ash::SHELF_ALIGNMENT_TOP: | 1977 case ash::SHELF_ALIGNMENT_TOP: |
| 1980 distance = coordinate.y() - bounds.bottom(); | 1978 distance = coordinate.y() - bounds.bottom(); |
| 1981 break; | 1979 break; |
| 1982 } | 1980 } |
| 1983 return distance > 0 ? distance : 0; | 1981 return distance > 0 ? distance : 0; |
| 1984 } | 1982 } |
| 1985 | 1983 |
| 1986 } // namespace internal | 1984 } // namespace internal |
| 1987 } // namespace ash | 1985 } // namespace ash |
| OLD | NEW |