15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 58bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ash/shelf/shelf_view.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/ash_constants.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/ash_switches.h" 11a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "ash/drag_drop/drag_image_view.h" 12d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)#include "ash/metrics/user_metrics_recorder.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/root_window_controller.h" 14a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "ash/scoped_target_root_window.h" 15424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ash/shelf/alternate_app_list_button.h" 16424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ash/shelf/app_list_button.h" 17424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ash/shelf/overflow_bubble.h" 18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/shelf/overflow_bubble_view.h" 19424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ash/shelf/overflow_button.h" 20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/shelf/shelf_button.h" 21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ash/shelf/shelf_delegate.h" 221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ash/shelf/shelf_icon_observer.h" 23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ash/shelf/shelf_item_delegate.h" 24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ash/shelf/shelf_item_delegate_manager.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shelf/shelf_layout_manager.h" 26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ash/shelf/shelf_menu_model.h" 27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/shelf/shelf_model.h" 284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/shelf/shelf_tooltip_manager.h" 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shelf/shelf_widget.h" 30d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)#include "ash/shell.h" 31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/wm/coordinate_conversion.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/auto_reset.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/metrics/histogram.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_resources.h" 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "grit/ash_strings.h" 37a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "ui/aura/client/screen_position_client.h" 38a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "ui/aura/root_window.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window.h" 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/base/accessibility/accessible_view_state.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/models/simple_menu_model.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer.h" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer_animator.h" 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/scoped_animation_duration_scale_mode.h" 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h" 487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/gfx/point.h" 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/animation/bounds_animator.h" 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/border.h" 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/controls/button/image_button.h" 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/menu/menu_model_adapter.h" 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/menu/menu_runner.h" 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/focus/focus_search.h" 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/view_model.h" 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/view_model_utils.h" 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h" 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using gfx::Animation; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using views::View; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_BOTTOM = 0; 66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_LEFT = 1; 67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_RIGHT = 2; 68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_COUNT = 3; 69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Default amount content is inset on the left edge. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kDefaultLeadingInset = 8; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Minimum distance before drag starts. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMinimumDragDistance = 8; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Size between the buttons. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kButtonSpacing = 4; 78ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochconst int kAlternateButtonSpacing = 10; 79ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 80ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Size allocated to for each button. 81ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochconst int kButtonSize = 44; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Additional spacing for the left and right side of icons. 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kHorizontalIconSpacing = 2; 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Inset for items which do not have an icon. 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kHorizontalNoIconInsetSpacing = 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kHorizontalIconSpacing + kDefaultLeadingInset; 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The proportion of the launcher space reserved for non-panel icons. Panels 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// may flow into this space but will be put into the overflow bubble if there 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// is contention for the space. 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const float kReservedNonPanelIconProportion = 0.67f; 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This is the command id of the menu item which contains the name of the menu. 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kCommandIdOfMenuName = 0; 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The background color of the active item in the list. 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const SkColor kActiveListItemBackgroundColor = SkColorSetRGB(203 , 219, 241); 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The background color of the active & hovered item in the list. 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const SkColor kFocusedActiveListItemBackgroundColor = 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkColorSetRGB(193, 211, 236); 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The text color of the caption item in a list. 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const SkColor kCaptionItemForegroundColor = SK_ColorBLACK; 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The maximum allowable length of a menu line of an application menu in pixels. 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kMaximumAppMenuItemLength = 350; 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 111424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// The distance of the cursor from the outer rim of the shelf before it 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// separates. 113424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)const int kRipOffDistance = 48; 114424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 115424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// The rip off drag and drop proxy image should get scaled by this factor. 116424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)const float kDragAndDropProxyScale = 1.5f; 117424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// The opacity represents that this partially disappeared item will get removed. 119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const float kDraggedImageOpacity = 0.5f; 120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The MenuModelAdapter gets slightly changed to adapt the menu appearance to 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// our requirements. 125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class ShelfMenuModelAdapter : public views::MenuModelAdapter { 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) explicit ShelfMenuModelAdapter(ShelfMenuModel* menu_model); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // views::MenuModelAdapter: 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual const gfx::Font* GetLabelFont(int command_id) const OVERRIDE; 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool IsCommandEnabled(int id) const OVERRIDE; 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void GetHorizontalIconMargins(int id, 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int icon_size, 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int* left_margin, 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int* right_margin) const OVERRIDE; 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool GetForegroundColor(int command_id, 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_hovered, 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkColor* override_color) const OVERRIDE; 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool GetBackgroundColor(int command_id, 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_hovered, 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkColor* override_color) const OVERRIDE; 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual int GetMaxWidthForMenu(views::MenuItemView* menu) OVERRIDE; 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool ShouldReserveSpaceForSubmenuIndicator() const OVERRIDE; 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ShelfMenuModel* menu_model_; 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ShelfMenuModelAdapter); 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)ShelfMenuModelAdapter::ShelfMenuModelAdapter(ShelfMenuModel* menu_model) 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : MenuModelAdapter(menu_model), 153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) menu_model_(menu_model) { 154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const gfx::Font* ShelfMenuModelAdapter::GetLabelFont(int command_id) const { 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (command_id != kCommandIdOfMenuName) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return MenuModelAdapter::GetLabelFont(command_id); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return &rb.GetFont(ui::ResourceBundle::BoldFont); 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool ShelfMenuModelAdapter::IsCommandEnabled(int id) const { 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return id != kCommandIdOfMenuName; 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool ShelfMenuModelAdapter::GetForegroundColor(int command_id, 169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool is_hovered, 170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SkColor* override_color) const { 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (command_id != kCommandIdOfMenuName) 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *override_color = kCaptionItemForegroundColor; 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool ShelfMenuModelAdapter::GetBackgroundColor(int command_id, 179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool is_hovered, 180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SkColor* override_color) const { 181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!menu_model_->IsCommandActive(command_id)) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *override_color = is_hovered ? kFocusedActiveListItemBackgroundColor : 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kActiveListItemBackgroundColor; 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ShelfMenuModelAdapter::GetHorizontalIconMargins(int command_id, 190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int icon_size, 191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int* left_margin, 192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int* right_margin) const { 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *left_margin = kHorizontalIconSpacing; 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *right_margin = (command_id != kCommandIdOfMenuName) ? 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kHorizontalIconSpacing : -(icon_size + kHorizontalNoIconInsetSpacing); 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 198a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)int ShelfMenuModelAdapter::GetMaxWidthForMenu(views::MenuItemView* menu) { 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return kMaximumAppMenuItemLength; 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 202a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool ShelfMenuModelAdapter::ShouldReserveSpaceForSubmenuIndicator() const { 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Custom FocusSearch used to navigate the launcher in the order items are in 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the ViewModel. 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LauncherFocusSearch : public views::FocusSearch { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit LauncherFocusSearch(views::ViewModel* view_model) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : FocusSearch(NULL, true, true), 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_(view_model) {} 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~LauncherFocusSearch() {} 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // views::FocusSearch overrides: 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual View* FindNextFocusableView( 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) View* starting_view, 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool reverse, 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Direction direction, 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool check_starting_view, 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::FocusTraversable** focus_traversable, 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) View** focus_traversable_view) OVERRIDE { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = view_model_->GetIndexOfView(starting_view); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index == -1) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return view_model_->view_at(0); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (reverse) { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) --index; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index < 0) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index = view_model_->view_size() - 1; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++index; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index >= view_model_->view_size()) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index = 0; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return view_model_->view_at(index); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::ViewModel* view_model_; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(LauncherFocusSearch); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AnimationDelegate used when inserting a new item. This steadily increases the 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// opacity of the layer as the animation progress. 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FadeInAnimationDelegate 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public views::BoundsAnimator::OwnedAnimationDelegate { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit FadeInAnimationDelegate(views::View* view) : view_(view) {} 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~FadeInAnimationDelegate() {} 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // AnimationDelegate overrides: 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AnimationProgressed(const Animation* animation) OVERRIDE { 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->layer()->SetOpacity(animation->GetCurrentValue()); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->layer()->ScheduleDraw(); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AnimationEnded(const Animation* animation) OVERRIDE { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->layer()->SetOpacity(1.0f); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->layer()->ScheduleDraw(); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AnimationCanceled(const Animation* animation) OVERRIDE { 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->layer()->SetOpacity(1.0f); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->layer()->ScheduleDraw(); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* view_; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(FadeInAnimationDelegate); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ReflectItemStatus(const ash::LauncherItem& item, ShelfButton* button) { 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (item.status) { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATUS_CLOSED: 276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->ClearState(ShelfButton::STATE_ACTIVE); 277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->ClearState(ShelfButton::STATE_RUNNING); 278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->ClearState(ShelfButton::STATE_ATTENTION); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATUS_RUNNING: 281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->ClearState(ShelfButton::STATE_ACTIVE); 282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->AddState(ShelfButton::STATE_RUNNING); 283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->ClearState(ShelfButton::STATE_ATTENTION); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATUS_ACTIVE: 286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->AddState(ShelfButton::STATE_ACTIVE); 287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->ClearState(ShelfButton::STATE_RUNNING); 288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->ClearState(ShelfButton::STATE_ATTENTION); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATUS_ATTENTION: 291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->ClearState(ShelfButton::STATE_ACTIVE); 292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->ClearState(ShelfButton::STATE_RUNNING); 293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->AddState(ShelfButton::STATE_ATTENTION); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// AnimationDelegate used when deleting an item. This steadily decreased the 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// opacity of the layer as the animation progress. 3028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)class ShelfView::FadeOutAnimationDelegate 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public views::BoundsAnimator::OwnedAnimationDelegate { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) FadeOutAnimationDelegate(ShelfView* host, views::View* view) 3068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) : shelf_view_(host), 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_(view) {} 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~FadeOutAnimationDelegate() {} 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // AnimationDelegate overrides: 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AnimationProgressed(const Animation* animation) OVERRIDE { 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->layer()->SetOpacity(1 - animation->GetCurrentValue()); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->layer()->ScheduleDraw(); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AnimationEnded(const Animation* animation) OVERRIDE { 3168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) shelf_view_->OnFadeOutAnimationEnded(); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AnimationCanceled(const Animation* animation) OVERRIDE { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ShelfView* shelf_view_; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<views::View> view_; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(FadeOutAnimationDelegate); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AnimationDelegate used to trigger fading an element in. When an item is 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// inserted this delegate is attached to the animation that expands the size of 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the item. When done it kicks off another animation to fade the item in. 3318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)class ShelfView::StartFadeAnimationDelegate 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public views::BoundsAnimator::OwnedAnimationDelegate { 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) StartFadeAnimationDelegate(ShelfView* host, 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* view) 3368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) : shelf_view_(host), 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_(view) {} 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~StartFadeAnimationDelegate() {} 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // AnimationDelegate overrides: 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AnimationEnded(const Animation* animation) OVERRIDE { 3428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) shelf_view_->FadeIn(view_); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AnimationCanceled(const Animation* animation) OVERRIDE { 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->layer()->SetOpacity(1.0f); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ShelfView* shelf_view_; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* view_; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(StartFadeAnimationDelegate); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ShelfView::ShelfView(ShelfModel* model, 356a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ShelfDelegate* delegate, 357a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ShelfLayoutManager* manager) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : model_(model), 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_(delegate), 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_(new views::ViewModel), 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_visible_index_(0), 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_visible_index_(-1), 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_button_(NULL), 3644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) owner_overflow_bubble_(NULL), 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_pointer_(NONE), 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_view_(NULL), 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_offset_(0), 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_drag_index_(-1), 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_menu_id_(0), 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) leading_inset_(kDefaultLeadingInset), 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cancelling_drag_model_changed_(false), 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_hidden_index_(0), 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) closing_event_time_(base::TimeDelta()), 374b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) got_deleted_(NULL), 3757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) drag_and_drop_item_pinned_(false), 376424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) drag_and_drop_launcher_id_(0), 377424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) dragged_off_shelf_(false), 378424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) snap_back_from_rip_off_view_(NULL), 379a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) item_manager_(Shell::GetInstance()->shelf_item_delegate_manager()), 380a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) layout_manager_(manager), 381a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) overflow_mode_(false), 382a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) main_shelf_(NULL), 383a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) dragged_off_from_overflow_to_shelf_(false) { 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(model_); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_animator_.reset(new views::BoundsAnimator(this)); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_animator_->AddObserver(this); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_context_menu_controller(this); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) focus_search_.reset(new LauncherFocusSearch(view_model_.get())); 389a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) tooltip_.reset(new ShelfTooltipManager(manager, this)); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)ShelfView::~ShelfView() { 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_animator_->RemoveObserver(this); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->RemoveObserver(this); 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If we are inside the MenuRunner, we need to know if we were getting 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // deleted while it was running. 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (got_deleted_) 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *got_deleted_ = true; 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::Init() { 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->AddObserver(this); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LauncherItems& items(model_->items()); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (LauncherItems::const_iterator i = items.begin(); i != items.end(); ++i) { 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* child = CreateViewForItem(*i); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child->SetPaintToLayer(true); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->Add(child, static_cast<int>(i - items.begin())); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildView(child); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ShelfStatusChanged(); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_button_ = new OverflowButton(this); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_button_->set_context_menu_controller(this); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConfigureChildView(overflow_button_); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildView(overflow_button_); 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateFirstButtonPadding(); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We'll layout when our bounds change. 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::OnShelfAlignmentChanged() { 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateFirstButtonPadding(); 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overflow_button_->OnShelfAlignmentChanged(); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LayoutToIdealBounds(); 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i=0; i < view_model_->view_size(); ++i) { 426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO: remove when AppIcon is a Shelf Button. 427eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (TYPE_APP_LIST == model_->items()[i].type && 428eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch !ash::switches::UseAlternateShelfLayout()) { 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<AppListButton*>(view_model_->view_at(i))->SetImageAlignment( 4301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->SelectValueForShelfAlignment( 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::ImageButton::ALIGN_CENTER, 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::ImageButton::ALIGN_LEFT, 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::ImageButton::ALIGN_RIGHT, 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::ImageButton::ALIGN_CENTER), 4351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->SelectValueForShelfAlignment( 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::ImageButton::ALIGN_TOP, 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::ImageButton::ALIGN_MIDDLE, 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::ImageButton::ALIGN_MIDDLE, 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::ImageButton::ALIGN_BOTTOM)); 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (i >= first_visible_index_ && i <= last_visible_index_) 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view_model_->view_at(i)->Layout(); 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 444d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) tooltip_->Close(); 445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (overflow_bubble_) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_bubble_->Hide(); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::SchedulePaintForAllButtons() { 450ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = 0; i < view_model_->view_size(); ++i) { 451ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (i >= first_visible_index_ && i <= last_visible_index_) 452ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch view_model_->view_at(i)->SchedulePaint(); 453ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 454ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (overflow_button_ && overflow_button_->visible()) 455ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch overflow_button_->SchedulePaint(); 456ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 457ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 4588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)gfx::Rect ShelfView::GetIdealBoundsOfItemIcon(LauncherID id) { 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = model_->ItemIndexByID(id); 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (index == -1 || (index > last_visible_index_ && 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) index < model_->FirstPanelIndex())) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gfx::Rect(); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& ideal_bounds(view_model_->ideal_bounds(index)); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(TYPE_APP_LIST, model_->items()[index].type); 465f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ShelfButton* button = static_cast<ShelfButton*>(view_model_->view_at(index)); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect icon_bounds = button->GetIconBounds(); 467868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return gfx::Rect(GetMirroredXWithWidthInView( 468868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ideal_bounds.x() + icon_bounds.x(), icon_bounds.width()), 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ideal_bounds.y() + icon_bounds.y(), 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_bounds.width(), 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_bounds.height()); 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::UpdatePanelIconPosition(LauncherID id, 4758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const gfx::Point& midpoint) { 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int current_index = model_->ItemIndexByID(id); 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int first_panel_index = model_->FirstPanelIndex(); 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (current_index < first_panel_index) 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 481868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) gfx::Point midpoint_in_view(GetMirroredXInView(midpoint.x()), 482868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) midpoint.y()); 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int target_index = current_index; 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (target_index > first_panel_index && 4851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->PrimaryAxisValue( 4861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) view_model_->ideal_bounds(target_index).x(), 4871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) view_model_->ideal_bounds(target_index).y()) > 4881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->PrimaryAxisValue(midpoint_in_view.x(), 4891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) midpoint_in_view.y())) { 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) --target_index; 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (target_index < view_model_->view_size() - 1 && 4931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->PrimaryAxisValue( 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view_model_->ideal_bounds(target_index).right(), 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view_model_->ideal_bounds(target_index).bottom()) < 4961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->PrimaryAxisValue(midpoint_in_view.x(), 4971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) midpoint_in_view.y())) { 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++target_index; 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (current_index != target_index) 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model_->Move(current_index, target_index); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool ShelfView::IsShowingMenu() const { 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (launcher_menu_runner_.get() && 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) launcher_menu_runner_->IsRunning()); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool ShelfView::IsShowingOverflowBubble() const { 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return overflow_bubble_.get() && overflow_bubble_->IsShowing(); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)views::View* ShelfView::GetAppListButtonView() const { 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < model_->item_count(); ++i) { 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (model_->items()[i].type == TYPE_APP_LIST) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return view_model_->view_at(i); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Applist button not found"; 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 5248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// ShelfView, FocusTraversable implementation: 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)views::FocusSearch* ShelfView::GetFocusSearch() { 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return focus_search_.get(); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)views::FocusTraversable* ShelfView::GetFocusTraversableParent() { 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return parent()->GetFocusTraversable(); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)View* ShelfView::GetFocusTraversableParentView() { 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this; 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::CreateDragIconProxy( 539a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const gfx::Point& location_in_screen_coordinates, 540a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const gfx::ImageSkia& icon, 541a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) views::View* replaced_view, 542868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const gfx::Vector2d& cursor_offset_from_center, 543a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) float scale_factor) { 544a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) drag_replaced_view_ = replaced_view; 545a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) drag_image_.reset(new ash::internal::DragImageView( 5464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) drag_replaced_view_->GetWidget()->GetNativeWindow()->GetRootWindow(), 5474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE)); 548a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) drag_image_->SetImage(icon); 549a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) gfx::Size size = drag_image_->GetPreferredSize(); 550a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) size.set_width(size.width() * scale_factor); 551a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) size.set_height(size.height() * scale_factor); 552868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) drag_image_offset_ = gfx::Vector2d(size.width() / 2, size.height() / 2) + 553868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) cursor_offset_from_center; 554a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) gfx::Rect drag_image_bounds( 555f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) location_in_screen_coordinates - drag_image_offset_, 556f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) size); 557a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) drag_image_->SetBoundsInScreen(drag_image_bounds); 558a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) drag_image_->SetWidgetVisible(true); 559a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 560a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 5618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::UpdateDragIconProxy( 562a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const gfx::Point& location_in_screen_coordinates) { 563a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) drag_image_->SetScreenPosition( 564f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) location_in_screen_coordinates - drag_image_offset_); 565a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 566a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 5678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::DestroyDragIconProxy() { 568a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) drag_image_.reset(); 569a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) drag_image_offset_ = gfx::Vector2d(0, 0); 570a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 571a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 5728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool ShelfView::StartDrag(const std::string& app_id, 5738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const gfx::Point& location_in_screen_coordinates) { 574b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Bail if an operation is already going on - or the cursor is not inside. 575b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // This could happen if mouse / touch operations overlap. 576b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (drag_and_drop_launcher_id_ || 577b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) !GetBoundsInScreen().Contains(location_in_screen_coordinates)) 578b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return false; 579b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 580b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // If the AppsGridView (which was dispatching this event) was opened by our 5818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // button, ShelfView dragging operations are locked and we have to unlock. 582b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) CancelDrag(-1); 5837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) drag_and_drop_item_pinned_ = false; 584b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) drag_and_drop_app_id_ = app_id; 585b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) drag_and_drop_launcher_id_ = 586b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) delegate_->GetLauncherIDForAppID(drag_and_drop_app_id_); 5877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Check if the application is known and pinned - if not, we have to pin it so 5887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // that we can re-arrange the launcher order accordingly. Note that items have 5897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // to be pinned to give them the same (order) possibilities as a shortcut. 590a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // When an item is dragged from overflow to shelf, IsShowingOverflowBubble() 591a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // returns true. At this time, we don't need to pin the item. 592a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!IsShowingOverflowBubble() && 593a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) (!drag_and_drop_launcher_id_ || 594a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) !delegate_->IsAppPinned(app_id))) { 595b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) delegate_->PinAppWithID(app_id); 596b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) drag_and_drop_launcher_id_ = 597b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) delegate_->GetLauncherIDForAppID(drag_and_drop_app_id_); 598b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!drag_and_drop_launcher_id_) 599b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return false; 6007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) drag_and_drop_item_pinned_ = true; 601b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 602b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) views::View* drag_and_drop_view = view_model_->view_at( 603b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) model_->ItemIndexByID(drag_and_drop_launcher_id_)); 604b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(drag_and_drop_view); 605b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 606a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Since there is already an icon presented by the caller, we hide this item 607a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // for now. That has to be done by reducing the size since the visibility will 608a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // change once a regrouping animation is performed. 609a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) pre_drag_and_drop_size_ = drag_and_drop_view->size(); 610a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) drag_and_drop_view->SetSize(gfx::Size()); 611a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 612b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // First we have to center the mouse cursor over the item. 613b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) gfx::Point pt = drag_and_drop_view->GetBoundsInScreen().CenterPoint(); 614b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) views::View::ConvertPointFromScreen(drag_and_drop_view, &pt); 615f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Point point_in_root = location_in_screen_coordinates; 616f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::wm::ConvertPointFromScreen( 617f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::wm::GetRootWindowAt(location_in_screen_coordinates), 618f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &point_in_root); 619f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ui::MouseEvent event(ui::ET_MOUSE_PRESSED, pt, point_in_root, 0); 620f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PointerPressedOnButton(drag_and_drop_view, 621f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ShelfButtonHost::DRAG_AND_DROP, 622f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event); 623b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 624b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Drag the item where it really belongs. 625b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) Drag(location_in_screen_coordinates); 626b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return true; 627b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 628b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 6298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool ShelfView::Drag(const gfx::Point& location_in_screen_coordinates) { 630b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!drag_and_drop_launcher_id_ || 631b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) !GetBoundsInScreen().Contains(location_in_screen_coordinates)) 632b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return false; 633b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 634b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) gfx::Point pt = location_in_screen_coordinates; 635b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) views::View* drag_and_drop_view = view_model_->view_at( 636b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) model_->ItemIndexByID(drag_and_drop_launcher_id_)); 637f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ConvertPointFromScreen(drag_and_drop_view, &pt); 638f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Point point_in_root = location_in_screen_coordinates; 639f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::wm::ConvertPointFromScreen( 640f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::wm::GetRootWindowAt(location_in_screen_coordinates), 641f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &point_in_root); 642f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ui::MouseEvent event(ui::ET_MOUSE_DRAGGED, pt, point_in_root, 0); 643f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PointerDraggedOnButton(drag_and_drop_view, 644f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ShelfButtonHost::DRAG_AND_DROP, 645f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event); 646b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return true; 647b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 648b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 6498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::EndDrag(bool cancel) { 650b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!drag_and_drop_launcher_id_) 651b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return; 652b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 653b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) views::View* drag_and_drop_view = view_model_->view_at( 654b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) model_->ItemIndexByID(drag_and_drop_launcher_id_)); 655b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) PointerReleasedOnButton( 656f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) drag_and_drop_view, ShelfButtonHost::DRAG_AND_DROP, cancel); 657b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 658a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Either destroy the temporarily created item - or - make the item visible. 6597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (drag_and_drop_item_pinned_ && cancel) 660424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) delegate_->UnpinAppWithID(drag_and_drop_app_id_); 66158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) else if (drag_and_drop_view) { 66258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (cancel) { 66358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // When a hosted drag gets canceled, the item can remain in the same slot 66458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // and it might have moved within the bounds. In that case the item need 66558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // to animate back to its correct location. 66658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) AnimateToIdealBounds(); 66758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else { 66858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) drag_and_drop_view->SetSize(pre_drag_and_drop_size_); 66958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 67058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 671b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 672b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) drag_and_drop_launcher_id_ = 0; 673b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 674b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 6758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::LayoutToIdealBounds() { 6761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (bounds_animator_->IsAnimating()) { 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AnimateToIdealBounds(); 6781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return; 6791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) IdealBounds ideal_bounds; 6821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CalculateIdealBounds(&ideal_bounds); 6831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) views::ViewModelUtils::SetViewBoundsToIdealBounds(*view_model_); 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_button_->SetBoundsRect(ideal_bounds.overflow_bounds); 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 687a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ShelfView::UpdateAllButtonsVisibilityInOverflowMode() { 688a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // The overflow button is not shown in overflow mode. 689a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) overflow_button_->SetVisible(false); 690a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int last_button_index = model_->FirstPanelIndex() - 1; 691a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK_LT(last_visible_index_, view_model_->view_size()); 692a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (int i = 0; i < view_model_->view_size(); ++i) { 693a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool visible = i >= first_visible_index_ && 694a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) i <= last_visible_index_; 695a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!ash::switches::UseAlternateShelfLayout()) 696a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) visible &= i != last_button_index; 697a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 698a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // To track the dragging of |drag_view_| continuously, its visibility 699a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // should be always true regardless of its position. 700a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (dragged_off_from_overflow_to_shelf_ && 701a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) view_model_->view_at(i) == drag_view_) 702a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) view_model_->view_at(i)->SetVisible(true); 703a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) else 704a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) view_model_->view_at(i)->SetVisible(visible); 705a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 706a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 707a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 7088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::CalculateIdealBounds(IdealBounds* bounds) { 7091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int available_size = layout_manager_->PrimaryAxisValue(width(), height()); 7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(model_->item_count() == view_model_->view_size()); 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!available_size) 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int first_panel_index = model_->FirstPanelIndex(); 715ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int last_button_index = first_panel_index - 1; 7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initial x,y values account both leading_inset in primary 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // coordinate and secondary coordinate based on the dynamic edge of the 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // launcher (eg top edge on bottom-aligned launcher). 7201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int inset = ash::switches::UseAlternateShelfLayout() ? 0 : leading_inset_; 7211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int x = layout_manager_->SelectValueForShelfAlignment(inset, 0, 0, inset); 7221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int y = layout_manager_->SelectValueForShelfAlignment(0, inset, inset, 0); 723ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 724f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int button_size = GetButtonSize(); 725f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int button_spacing = GetButtonSpacing(); 726ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 7271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int w = layout_manager_->PrimaryAxisValue(button_size, width()); 7281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int h = layout_manager_->PrimaryAxisValue(height(), button_size); 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < view_model_->view_size(); ++i) { 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i < first_visible_index_) { 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->set_ideal_bounds(i, gfx::Rect(x, y, 0, 0)); 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->set_ideal_bounds(i, gfx::Rect(x, y, w, h)); 736ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (i != last_button_index) { 7371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) x = layout_manager_->PrimaryAxisValue(x + w + button_spacing, x); 7381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) y = layout_manager_->PrimaryAxisValue(y, y + h + button_spacing); 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_overflow_mode()) { 743a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) UpdateAllButtonsVisibilityInOverflowMode(); 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // To address Fitt's law, we make the first launcher button include the 7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // leading inset (if there is one). 749ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!ash::switches::UseAlternateShelfLayout()) { 750ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (view_model_->view_size() > 0) { 751ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch view_model_->set_ideal_bounds(0, gfx::Rect(gfx::Size( 7521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->PrimaryAxisValue(inset + w, w), 7531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->PrimaryAxisValue(h, inset + h)))); 754ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Right aligned icons. 758ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int end_position = available_size - button_spacing; 7591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) x = layout_manager_->PrimaryAxisValue(end_position, 0); 7601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) y = layout_manager_->PrimaryAxisValue(0, end_position); 7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = view_model_->view_size() - 1; 7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) i >= first_panel_index; --i) { 7631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) x = layout_manager_->PrimaryAxisValue(x - w - button_spacing, x); 7641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) y = layout_manager_->PrimaryAxisValue(y, y - h - button_spacing); 7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view_model_->set_ideal_bounds(i, gfx::Rect(x, y, w, h)); 7661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) end_position = layout_manager_->PrimaryAxisValue(x, y); 7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Icons on the left / top are guaranteed up to kLeftIconProportion of 7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the available space. 7711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int last_icon_position = layout_manager_->PrimaryAxisValue( 772ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch view_model_->ideal_bounds(last_button_index).right(), 773ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch view_model_->ideal_bounds(last_button_index).bottom()) 774ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch + button_size + inset; 775ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!ash::switches::UseAlternateShelfLayout()) 776ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch last_icon_position += button_size; 7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int reserved_icon_space = available_size * kReservedNonPanelIconProportion; 7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (last_icon_position < reserved_icon_space) 7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) end_position = last_icon_position; 7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) end_position = std::max(end_position, reserved_icon_space); 7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bounds->overflow_bounds.set_size( 7841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) gfx::Size(layout_manager_->PrimaryAxisValue(w, width()), 7851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->PrimaryAxisValue(height(), h))); 7864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (ash::switches::UseAlternateShelfLayout()) { 788ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch last_visible_index_ = DetermineLastVisibleIndex( 789ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch end_position - button_size); 7904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 791ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch last_visible_index_ = DetermineLastVisibleIndex( 792ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch end_position - inset - 2 * button_size); 7934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_hidden_index_ = DetermineFirstVisiblePanelIndex(end_position) - 1; 795ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bool show_overflow = 796ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ((ash::switches::UseAlternateShelfLayout() ? 0 : 1) + 797ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch last_visible_index_ < last_button_index || 798ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch last_hidden_index_ >= first_panel_index); 799ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 800ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Create Space for the overflow button 801ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (show_overflow && ash::switches::UseAlternateShelfLayout() && 80258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) last_visible_index_ > 0 && last_visible_index_ < last_button_index) 803ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch --last_visible_index_; 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < view_model_->view_size(); ++i) { 805ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bool visible = i <= last_visible_index_ || i > last_hidden_index_; 806ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Always show the app list. 807ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!ash::switches::UseAlternateShelfLayout()) 808ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch visible |= (i == last_button_index); 8094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // To receive drag event continously from |drag_view_| during the dragging 8104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // off from the shelf, don't make |drag_view_| invisible. It will be 8114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // eventually invisible and removed from the |view_model_| by 8124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // FinalizeRipOffDrag(). 8134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (dragged_off_shelf_ && view_model_->view_at(i) == drag_view_) 8144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) continue; 815ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch view_model_->view_at(i)->SetVisible(visible); 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_button_->SetVisible(show_overflow); 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (show_overflow) { 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(0, view_model_->view_size()); 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_visible_index_ == -1) { 8221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) x = layout_manager_->SelectValueForShelfAlignment(inset, 0, 0, inset); 8231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) y = layout_manager_->SelectValueForShelfAlignment(0, inset, inset, 0); 82458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else if (last_visible_index_ == last_button_index 82558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) && !ash::switches::UseAlternateShelfLayout()) { 8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) x = view_model_->ideal_bounds(last_visible_index_).x(); 8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) y = view_model_->ideal_bounds(last_visible_index_).y(); 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) x = layout_manager_->PrimaryAxisValue( 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->ideal_bounds(last_visible_index_).right(), 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->ideal_bounds(last_visible_index_).x()); 8321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) y = layout_manager_->PrimaryAxisValue( 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->ideal_bounds(last_visible_index_).y(), 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->ideal_bounds(last_visible_index_).bottom()); 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Set all hidden panel icon positions to be on the overflow button. 8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = first_panel_index; i <= last_hidden_index_; ++i) 8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view_model_->set_ideal_bounds(i, gfx::Rect(x, y, w, h)); 8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Add more space between last visible item and overflow button. 8411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Without this, two buttons look too close compared with other items. 8421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (ash::switches::UseAlternateShelfLayout()) { 8431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) x = layout_manager_->PrimaryAxisValue(x + button_spacing, x); 8441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) y = layout_manager_->PrimaryAxisValue(y, y + button_spacing); 8451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 8461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 847ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bounds->overflow_bounds.set_x(x); 848ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bounds->overflow_bounds.set_y(y); 849ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!ash::switches::UseAlternateShelfLayout()) { 850ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Position app list after overflow button. 851ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch gfx::Rect app_list_bounds = view_model_->ideal_bounds(last_button_index); 852ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 8531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) x = layout_manager_->PrimaryAxisValue(x + w + button_spacing, x); 8541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) y = layout_manager_->PrimaryAxisValue(y, y + h + button_spacing); 855ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch app_list_bounds.set_x(x); 856ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch app_list_bounds.set_y(y); 857ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch view_model_->set_ideal_bounds(last_button_index, app_list_bounds); 858ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (overflow_bubble_.get() && overflow_bubble_->IsShowing()) 8608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) UpdateOverflowRange(overflow_bubble_->shelf_view()); 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 862c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (overflow_bubble_) 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_bubble_->Hide(); 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int ShelfView::DetermineLastVisibleIndex(int max_value) const { 8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int index = model_->FirstPanelIndex() - 1; 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (index >= 0 && 8701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->PrimaryAxisValue( 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->ideal_bounds(index).right(), 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->ideal_bounds(index).bottom()) > max_value) { 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index--; 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return index; 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int ShelfView::DetermineFirstVisiblePanelIndex(int min_value) const { 8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int index = model_->FirstPanelIndex(); 8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (index < view_model_->view_size() && 8811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->PrimaryAxisValue( 8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view_model_->ideal_bounds(index).right(), 8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view_model_->ideal_bounds(index).bottom()) < min_value) { 8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++index; 8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return index; 8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ShelfView::AddIconObserver(ShelfIconObserver* observer) { 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_.AddObserver(observer); 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ShelfView::RemoveIconObserver(ShelfIconObserver* observer) { 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_.RemoveObserver(observer); 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::AnimateToIdealBounds() { 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IdealBounds ideal_bounds; 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CalculateIdealBounds(&ideal_bounds); 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < view_model_->view_size(); ++i) { 9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) View* view = view_model_->view_at(i); 9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bounds_animator_->AnimateViewTo(view, view_model_->ideal_bounds(i)); 9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Now that the item animation starts, we have to make sure that the 9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // padding of the first gets properly transferred to the new first item. 9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (i && view->border()) 9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view->set_border(NULL); 9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (!i && !view->border()) 9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateFirstButtonPadding(); 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_button_->SetBoundsRect(ideal_bounds.overflow_bounds); 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)views::View* ShelfView::CreateViewForItem(const LauncherItem& item) { 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* view = NULL; 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (item.type) { 91690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case TYPE_BROWSER_SHORTCUT: 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_APP_SHORTCUT: 9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case TYPE_WINDOWED_APP: 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_PLATFORM_APP: 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_APP_PANEL: { 921f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ShelfButton* button = ShelfButton::Create(this, this, layout_manager_); 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->SetImage(item.image); 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReflectItemStatus(item, button); 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view = button; 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_APP_LIST: { 929eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (ash::switches::UseAlternateShelfLayout()) { 9301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) view = new AlternateAppListButton(this, 9311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) this, 9321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->shelf_widget()); 933eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else { 934f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(dave): turn this into a ShelfButton too. 935eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AppListButton* button = new AppListButton(this, this); 936eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch button->SetImageAlignment( 9371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->SelectValueForShelfAlignment( 938eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::ImageButton::ALIGN_CENTER, 939eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::ImageButton::ALIGN_LEFT, 940eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::ImageButton::ALIGN_RIGHT, 941eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::ImageButton::ALIGN_CENTER), 9421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->SelectValueForShelfAlignment( 943eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::ImageButton::ALIGN_TOP, 944eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::ImageButton::ALIGN_MIDDLE, 945eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::ImageButton::ALIGN_MIDDLE, 946eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::ImageButton::ALIGN_BOTTOM)); 947eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch view = button; 948eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view->set_context_menu_controller(this); 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(view); 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConfigureChildView(view); 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return view; 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::FadeIn(views::View* view) { 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view->SetVisible(true); 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view->layer()->SetOpacity(0); 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AnimateToIdealBounds(); 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_animator_->SetAnimationDelegate( 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view, new FadeInAnimationDelegate(view), true); 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::PrepareForDrag(Pointer pointer, const ui::LocatedEvent& event) { 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!dragging()); 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(drag_view_); 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_pointer_ = pointer; 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_drag_index_ = view_model_->GetIndexOfView(drag_view_); 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 976424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (start_drag_index_== -1) { 977424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) CancelDrag(-1); 978424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 979424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 980424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the item is no longer draggable, bail out. 982a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ShelfItemDelegate* item_delegate = item_manager_->GetShelfItemDelegate( 9834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) model_->items()[start_drag_index_].id); 9844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!item_delegate->IsDraggable()) { 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelDrag(-1); 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Move the view to the front so that it appears on top of other views. 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReorderChildView(drag_view_, -1); 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_animator_->StopAnimatingView(drag_view_); 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::ContinueDrag(const ui::LocatedEvent& event) { 995424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Due to a syncing operation the application might have been removed. 996424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Bail if it is gone. 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int current_index = view_model_->GetIndexOfView(drag_view_); 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(-1, current_index); 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1000a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ShelfItemDelegate* item_delegate = item_manager_->GetShelfItemDelegate( 10014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) model_->items()[current_index].id); 10024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!item_delegate->IsDraggable()) { 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelDrag(-1); 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1007424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // If this is not a drag and drop host operation and not the app list item, 1008424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // check if the item got ripped off the shelf - if it did we are done. 1009424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!drag_and_drop_launcher_id_ && ash::switches::UseDragOffShelf() && 1010424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) RemovableByRipOff(current_index) != NOT_REMOVABLE) { 1011424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (HandleRipOffDrag(event)) 1012424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 1013424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // The rip off handler could have changed the location of the item. 1014424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) current_index = view_model_->GetIndexOfView(drag_view_); 1015424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1016424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 1017424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // TODO: I don't think this works correctly with RTL. 1018424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) gfx::Point drag_point(event.location()); 1019f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ConvertPointToTarget(drag_view_, this, &drag_point); 1020424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Constrain the location to the range of valid indices for the type. 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::pair<int, int> indices(GetDragRange(current_index)); 10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int first_drag_index = indices.first; 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int last_drag_index = indices.second; 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the last index isn't valid, we're overflowing. Constrain to the app list 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (which is the last visible item). 10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (first_drag_index < model_->FirstPanelIndex() && 10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_drag_index > last_visible_index_) 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_drag_index = last_visible_index_; 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x = 0, y = 0; 10311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (layout_manager_->IsHorizontalAlignment()) { 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x = std::max(view_model_->ideal_bounds(indices.first).x(), 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_point.x() - drag_offset_); 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x = std::min(view_model_->ideal_bounds(last_drag_index).right() - 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->ideal_bounds(current_index).width(), 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x); 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (drag_view_->x() == x) 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_view_->SetX(x); 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) y = std::max(view_model_->ideal_bounds(indices.first).y(), 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_point.y() - drag_offset_); 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) y = std::min(view_model_->ideal_bounds(last_drag_index).bottom() - 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->ideal_bounds(current_index).height(), 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) y); 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (drag_view_->y() == y) 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_view_->SetY(y); 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int target_index = 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::ViewModelUtils::DetermineMoveIndex( 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *view_model_, drag_view_, 10541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->IsHorizontalAlignment() ? 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::ViewModelUtils::HORIZONTAL : 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::ViewModelUtils::VERTICAL, 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x, y); 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_index = 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::min(indices.second, std::max(target_index, indices.first)); 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target_index == current_index) 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Change the model, the LauncherItemMoved() callback will handle the 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |view_model_| update. 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->Move(current_index, target_index); 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_animator_->StopAnimatingView(drag_view_); 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool ShelfView::HandleRipOffDrag(const ui::LocatedEvent& event) { 1070424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int current_index = view_model_->GetIndexOfView(drag_view_); 1071424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK_NE(-1, current_index); 1072a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::string dragged_app_id = 1073a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) delegate_->GetAppIDForLauncherID(model_->items()[current_index].id); 1074f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1075f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Point screen_location = event.root_location(); 1076f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::wm::ConvertPointToScreen(GetWidget()->GetNativeWindow()->GetRootWindow(), 1077f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &screen_location); 1078f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1079424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // To avoid ugly forwards and backwards flipping we use different constants 1080424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // for ripping off / re-inserting the items. 1081424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (dragged_off_shelf_) { 1082f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // If the shelf/overflow bubble bounds contains |screen_location| we insert 1083f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // the item back into the shelf. 1084f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (GetBoundsForDragInsertInScreen().Contains(screen_location)) { 1085a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (dragged_off_from_overflow_to_shelf_) { 1086a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // During the dragging an item from Shelf to Overflow, it can enter here 1087a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // directly because both are located very closly. 1088a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) main_shelf_->EndDrag(true); 1089a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Stops the animation of |drag_view_| and sets its bounds explicitly 1090a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // becase ContinueDrag() stops its animation. Without this, unexpected 1091a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // bounds will be set. 1092a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bounds_animator_->StopAnimatingView(drag_view_); 1093a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int drag_view_index = view_model_->GetIndexOfView(drag_view_); 1094a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) drag_view_->SetBoundsRect(view_model_->ideal_bounds(drag_view_index)); 1095a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) dragged_off_from_overflow_to_shelf_ = false; 1096a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 1097424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Destroy our proxy view item. 1098424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DestroyDragIconProxy(); 1099424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Re-insert the item and return simply false since the caller will handle 1100424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // the move as in any normal case. 1101424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) dragged_off_shelf_ = false; 1102424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) drag_view_->layer()->SetOpacity(1.0f); 1103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // The size of Overflow bubble should be updated immediately when an item 1104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // is re-inserted. 1105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (is_overflow_mode()) 1106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PreferredSizeChanged(); 1107424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 1108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else if (is_overflow_mode() && 1109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) main_shelf_->GetBoundsForDragInsertInScreen().Contains( 1110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) screen_location)) { 1111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!dragged_off_from_overflow_to_shelf_) { 1112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) dragged_off_from_overflow_to_shelf_ = true; 1113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) drag_image_->SetOpacity(1.0f); 1114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) main_shelf_->StartDrag(dragged_app_id, screen_location); 1115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else { 1116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) main_shelf_->Drag(screen_location); 1117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 1118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else if (dragged_off_from_overflow_to_shelf_) { 1119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Makes the |drag_image_| partially disappear again. 1120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) dragged_off_from_overflow_to_shelf_ = false; 1121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) drag_image_->SetOpacity(kDraggedImageOpacity); 1122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) main_shelf_->EndDrag(true); 1123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bounds_animator_->StopAnimatingView(drag_view_); 1124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int drag_view_index = view_model_->GetIndexOfView(drag_view_); 1125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) drag_view_->SetBoundsRect(view_model_->ideal_bounds(drag_view_index)); 1126424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1127424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Move our proxy view item. 1128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UpdateDragIconProxy(screen_location); 1129424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 1130424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1131424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Check if we are too far away from the shelf to enter the ripped off state. 1132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Determine the distance to the shelf. 1133d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) int delta = CalculateShelfDistance(screen_location); 1134424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (delta > kRipOffDistance) { 1135424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Create a proxy view item which can be moved anywhere. 1136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ShelfButton* button = static_cast<ShelfButton*>(drag_view_); 1137424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) CreateDragIconProxy(event.root_location(), 1138424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) button->GetImage(), 1139424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) drag_view_, 1140424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) gfx::Vector2d(0, 0), 1141424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) kDragAndDropProxyScale); 1142424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) drag_view_->layer()->SetOpacity(0.0f); 11434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) dragged_off_shelf_ = true; 1144424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (RemovableByRipOff(current_index) == REMOVABLE) { 11451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Move the item to the front of the first panel item and hide it. 11461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // LauncherItemMoved() callback will handle the |view_model_| update and 11471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // call AnimateToIdealBounds(). 1148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (current_index != model_->FirstPanelIndex() - 1) { 1149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) model_->Move(current_index, model_->FirstPanelIndex() - 1); 1150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) StartFadeInLastVisibleItem(); 1151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else if (is_overflow_mode()) { 1152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Overflow bubble should be shrunk when an item is ripped off. 1153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PreferredSizeChanged(); 1154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1155424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Make the item partially disappear to show that it will get removed if 1156424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // dropped. 1157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) drag_image_->SetOpacity(kDraggedImageOpacity); 1158424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1159424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 1160424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1161424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 1162424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 1163424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 11648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::FinalizeRipOffDrag(bool cancel) { 1165424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!dragged_off_shelf_) 1166424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 1167424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Make sure we do not come in here again. 1168424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) dragged_off_shelf_ = false; 1169424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 1170424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Coming here we should always have a |drag_view_|. 1171424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(drag_view_); 1172424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int current_index = view_model_->GetIndexOfView(drag_view_); 1173424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // If the view isn't part of the model anymore (|current_index| == -1), a sync 1174424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // operation must have removed it. In that case we shouldn't change the model 1175424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // and only delete the proxy image. 1176424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (current_index == -1) { 1177424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DestroyDragIconProxy(); 1178424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 1179424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1180424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 1181424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Set to true when the animation should snap back to where it was before. 1182424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bool snap_back = false; 1183424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Items which cannot be dragged off will be handled as a cancel. 1184424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!cancel) { 1185a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (dragged_off_from_overflow_to_shelf_) { 1186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) dragged_off_from_overflow_to_shelf_ = false; 1187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) main_shelf_->EndDrag(false); 1188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) drag_view_->layer()->SetOpacity(1.0f); 1189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else if (RemovableByRipOff(current_index) != REMOVABLE) { 1190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Make sure we do not try to remove un-removable items like items which 1191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // were not pinned or have to be always there. 1192424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cancel = true; 1193424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) snap_back = true; 1194424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else { 1195424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Make sure the item stays invisible upon removal. 1196424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) drag_view_->SetVisible(false); 1197424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) std::string app_id = 1198424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) delegate_->GetAppIDForLauncherID(model_->items()[current_index].id); 1199424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) delegate_->UnpinAppWithID(app_id); 1200424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1201424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1202424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (cancel || snap_back) { 1203a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (dragged_off_from_overflow_to_shelf_) { 1204a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) dragged_off_from_overflow_to_shelf_ = false; 1205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Main shelf handles revert of dragged item. 1206a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) main_shelf_->EndDrag(true); 1207a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) drag_view_->layer()->SetOpacity(1.0f); 1208a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else if (!cancelling_drag_model_changed_) { 1209424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Only do something if the change did not come through a model change. 1210424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) gfx::Rect drag_bounds = drag_image_->GetBoundsInScreen(); 1211424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) gfx::Point relative_to = GetBoundsInScreen().origin(); 1212424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) gfx::Rect target( 1213424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) gfx::PointAtOffsetFromOrigin(drag_bounds.origin()- relative_to), 1214424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) drag_bounds.size()); 1215424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) drag_view_->SetBoundsRect(target); 1216424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Hide the status from the active item since we snap it back now. Upon 1217424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // animation end the flag gets cleared if |snap_back_from_rip_off_view_| 1218424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // is set. 1219424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) snap_back_from_rip_off_view_ = drag_view_; 1220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ShelfButton* button = static_cast<ShelfButton*>(drag_view_); 1221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->AddState(ShelfButton::STATE_HIDDEN); 1222424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // When a canceling drag model is happening, the view model is diverged 1223424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // from the menu model and movements / animations should not be done. 1224424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) model_->Move(current_index, start_drag_index_); 1225424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) AnimateToIdealBounds(); 1226424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1227424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) drag_view_->layer()->SetOpacity(1.0f); 1228424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1229424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DestroyDragIconProxy(); 1230424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 1231424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 12328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)ShelfView::RemovableState ShelfView::RemovableByRipOff(int index) { 1233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(index >= 0 && index < model_->item_count()); 1234424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) LauncherItemType type = model_->items()[index].type; 123558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (type == TYPE_APP_LIST || !delegate_->CanPin()) 1236424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return NOT_REMOVABLE; 1237424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) std::string app_id = 1238424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) delegate_->GetAppIDForLauncherID(model_->items()[index].id); 1239424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Note: Only pinned app shortcuts can be removed! 1240424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return (type == TYPE_APP_SHORTCUT && delegate_->IsAppPinned(app_id)) ? 1241424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) REMOVABLE : DRAGGABLE; 1242424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 1243424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 12448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool ShelfView::SameDragType(LauncherItemType typea, 12458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) LauncherItemType typeb) const { 1246ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch switch (typea) { 1247ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case TYPE_APP_SHORTCUT: 1248ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case TYPE_BROWSER_SHORTCUT: 1249ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return (typeb == TYPE_APP_SHORTCUT || typeb == TYPE_BROWSER_SHORTCUT); 125068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case TYPE_APP_LIST: 1251424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case TYPE_PLATFORM_APP: 1252ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case TYPE_WINDOWED_APP: 1253ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case TYPE_APP_PANEL: 1254ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return typeb == typea; 1255424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case TYPE_UNDEFINED: 1256424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) NOTREACHED() << "LauncherItemType must be set."; 1257424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)std::pair<int, int> ShelfView::GetDragRange(int index) { 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int min_index = -1; 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_index = -1; 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LauncherItemType type = model_->items()[index].type; 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < model_->item_count(); ++i) { 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SameDragType(model_->items()[i].type, type)) { 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (min_index == -1) 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min_index = i; 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_index = i; 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::pair<int, int>(min_index, max_index); 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::ConfigureChildView(views::View* view) { 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view->SetPaintToLayer(true); 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view->layer()->SetFillsBoundsOpaquely(false); 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::ToggleOverflowBubble() { 12832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (IsShowingOverflowBubble()) { 12842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overflow_bubble_->Hide(); 12852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 12862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!overflow_bubble_) 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_bubble_.reset(new OverflowBubble()); 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ShelfView* overflow_view = 12921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) new ShelfView(model_, delegate_, layout_manager_); 1293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) overflow_view->overflow_mode_ = true; 12942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overflow_view->Init(); 12954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) overflow_view->set_owner_overflow_bubble(overflow_bubble_.get()); 12962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overflow_view->OnShelfAlignmentChanged(); 1297a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) overflow_view->main_shelf_ = this; 12982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateOverflowRange(overflow_view); 12992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overflow_bubble_->Show(overflow_button_, overflow_view); 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shell::GetInstance()->UpdateShelfVisibility(); 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::UpdateFirstButtonPadding() { 1306ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (ash::switches::UseAlternateShelfLayout()) 1307ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 1308ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates an empty border for first launcher button to make included leading 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // inset act as the button's padding. This is only needed on button creation 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and when shelf alignment changes. 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view_model_->view_size() > 0) { 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->view_at(0)->set_border(views::Border::CreateEmptyBorder( 13141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->PrimaryAxisValue(0, leading_inset_), 13151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->PrimaryAxisValue(leading_inset_, 0), 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0)); 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::OnFadeOutAnimationEnded() { 13222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AnimateToIdealBounds(); 13231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) StartFadeInLastVisibleItem(); 13241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 13252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ShelfView::StartFadeInLastVisibleItem() { 13272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If overflow button is visible and there is a valid new last item, fading 13282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the new last item in after sliding animation is finished. 13292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (overflow_button_->visible() && last_visible_index_ >= 0) { 13302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::View* last_visible_view = view_model_->view_at(last_visible_index_); 13312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_visible_view->layer()->SetOpacity(0); 13322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bounds_animator_->SetAnimationDelegate( 13332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_visible_view, 13348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) new ShelfView::StartFadeAnimationDelegate(this, last_visible_view), 13352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) true); 13362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 13372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 13382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::UpdateOverflowRange(ShelfView* overflow_view) { 13402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int first_overflow_index = last_visible_index_ + 1; 13412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int last_overflow_index = last_hidden_index_; 13422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_LE(first_overflow_index, last_overflow_index); 13432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_LT(last_overflow_index, view_model_->view_size()); 13442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overflow_view->first_visible_index_ = first_overflow_index; 13462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overflow_view->last_visible_index_ = last_overflow_index; 13472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 13482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)int ShelfView::GetButtonSize() const { 1350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return ash::switches::UseAlternateShelfLayout() ? 1351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) kButtonSize : kLauncherPreferredSize; 1352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 1353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)int ShelfView::GetButtonSpacing() const { 1355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return ash::switches::UseAlternateShelfLayout() ? 1356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) kAlternateButtonSpacing : kButtonSpacing; 1357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 1358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 13598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool ShelfView::ShouldHideTooltip(const gfx::Point& cursor_location) { 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect active_bounds; 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < child_count(); ++i) { 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* child = child_at(i); 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (child == overflow_button_) 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 13662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!ShouldShowTooltipForView(child)) 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect child_bounds = child->GetMirroredBounds(); 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_bounds.Union(child_bounds); 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !active_bounds.Contains(cursor_location); 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)gfx::Rect ShelfView::GetVisibleItemsBoundsInScreen() { 13774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) gfx::Size preferred_size = GetPreferredSize(); 13784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) gfx::Point origin(GetMirroredXWithWidthInView(0, preferred_size.width()), 0); 13794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ConvertPointToScreen(this, &origin); 13804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return gfx::Rect(origin, preferred_size); 13814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 13824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1383f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)gfx::Rect ShelfView::GetBoundsForDragInsertInScreen() { 1384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Size preferred_size; 1385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (is_overflow_mode()) { 1386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(owner_overflow_bubble_); 1387f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Rect bubble_bounds = 1388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) owner_overflow_bubble_->bubble_view()->GetBubbleBounds(); 1389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) preferred_size = bubble_bounds.size(); 1390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 1391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const int preferred_shelf_size = layout_manager_->GetPreferredShelfSize(); 1392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const int last_button_index = view_model_->view_size() - 1; 1394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Rect last_button_bounds = 1395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) view_model_->view_at(last_button_index)->bounds(); 1396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (overflow_button_->visible() && 1397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) model_->GetItemIndexForType(TYPE_APP_PANEL) == -1) { 1398f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // When overflow button is visible and shelf has no panel items, 1399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // last_button_bounds should be overflow button's bounds. 1400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) last_button_bounds = overflow_button_->bounds(); 1401f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (layout_manager_->IsHorizontalAlignment()) { 1404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) preferred_size = gfx::Size(last_button_bounds.right() + leading_inset_, 1405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) preferred_shelf_size); 1406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 1407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) preferred_size = gfx::Size(preferred_shelf_size, 1408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) last_button_bounds.bottom() + leading_inset_); 1409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Point origin(GetMirroredXWithWidthInView(0, preferred_size.width()), 0); 1412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // In overflow mode, we should use OverflowBubbleView as a source for 1414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // converting |origin| to screen coordinates. When a scroll operation is 1415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // occurred in OverflowBubble, the bounds of ShelfView in OverflowBubble can 1416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // be changed. 1417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (is_overflow_mode()) 1418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ConvertPointToScreen(owner_overflow_bubble_->bubble_view(), &origin); 1419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) else 1420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ConvertPointToScreen(this, &origin); 1421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return gfx::Rect(origin, preferred_size); 1423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 1424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 14258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int ShelfView::CancelDrag(int modified_index) { 1426424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FinalizeRipOffDrag(true); 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!drag_view_) 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return modified_index; 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool was_dragging = dragging(); 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int drag_view_index = view_model_->GetIndexOfView(drag_view_); 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_pointer_ = NONE; 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_view_ = NULL; 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (drag_view_index == modified_index) { 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The view that was being dragged is being modified. Don't do anything. 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return modified_index; 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!was_dragging) 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return modified_index; 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Restore previous position, tracking the position of the modified view. 14412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool at_end = modified_index == view_model_->view_size(); 14422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::View* modified_view = 14432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (modified_index >= 0 && !at_end) ? 14442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view_model_->view_at(modified_index) : NULL; 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->Move(drag_view_index, start_drag_index_); 14462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the modified view will be at the end of the list, return the new end of 14482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the list. 14492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (at_end) 14502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return view_model_->view_size(); 14512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return modified_view ? view_model_->GetIndexOfView(modified_view) : -1; 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)gfx::Size ShelfView::GetPreferredSize() { 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IdealBounds ideal_bounds; 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CalculateIdealBounds(&ideal_bounds); 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const int preferred_size = layout_manager_->GetPreferredShelfSize(); 14594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1460f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int last_button_index = is_overflow_mode() ? 1461f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) last_visible_index_ : view_model_->view_size() - 1; 1462f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1463f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // When an item is dragged off from the overflow bubble, it is moved to last 1464f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // position and and changed to invisible. Overflow bubble size should be 1465f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // shrunk to fit only for visible items. 1466a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // If |dragged_off_from_overflow_to_shelf_| is set, there will be no invisible 1467a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // items in the shelf. 1468a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (is_overflow_mode() && 1469a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) dragged_off_shelf_ && 1470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) !dragged_off_from_overflow_to_shelf_ && 1471f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RemovableByRipOff(view_model_->GetIndexOfView(drag_view_)) == REMOVABLE) 1472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) last_button_index--; 1473f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect last_button_bounds = 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_button_index >= first_visible_index_ ? 1476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) view_model_->ideal_bounds(last_button_index) : 14774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) gfx::Rect(gfx::Size(preferred_size, preferred_size)); 14782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (layout_manager_->IsHorizontalAlignment()) { 14801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return gfx::Size(last_button_bounds.right() + leading_inset_, 14814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) preferred_size); 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return gfx::Size(preferred_size, 14851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) last_button_bounds.bottom() + leading_inset_); 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::OnBoundsChanged(const gfx::Rect& previous_bounds) { 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LayoutToIdealBounds(); 14901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) FOR_EACH_OBSERVER(ShelfIconObserver, observers_, 14911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OnShelfIconPositionsChanged()); 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsShowingOverflowBubble()) 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_bubble_->Hide(); 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)views::FocusTraversable* ShelfView::GetPaneFocusTraversable() { 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this; 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::GetAccessibleState(ui::AccessibleViewState* state) { 150290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) state->role = ui::AccessibilityTypes::ROLE_TOOLBAR; 15032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch state->name = l10n_util::GetStringUTF16(IDS_ASH_SHELF_ACCESSIBLE_NAME); 150490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 150590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 15068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::OnGestureEvent(ui::GestureEvent* event) { 15072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (gesture_handler_.ProcessGestureEvent(*event)) 15082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event->StopPropagation(); 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1511f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ShelfView::ShelfItemAdded(int model_index) { 15122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 15132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AutoReset<bool> cancelling_drag( 15142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &cancelling_drag_model_changed_, true); 15152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model_index = CancelDrag(model_index); 15162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* view = CreateViewForItem(model_->items()[model_index]); 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildView(view); 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hide the view, it'll be made visible when the animation is done. Using 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // opacity 0 here to avoid messing with CalculateIdealBounds which touches 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the view's visibility. 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view->layer()->SetOpacity(0); 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->Add(view, model_index); 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Give the button its ideal bounds. That way if we end up animating the 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // button before this animation completes it doesn't appear at some random 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // spot (because it was in the middle of animating from 0,0 0x0 to its 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // target). 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IdealBounds ideal_bounds; 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CalculateIdealBounds(&ideal_bounds); 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view->SetBoundsRect(view_model_->ideal_bounds(model_index)); 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The first animation moves all the views to their target position. |view| 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is hidden, so it visually appears as though we are providing space for 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it. When done we'll fade the view in. 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AnimateToIdealBounds(); 15372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (model_index <= last_visible_index_ || 15382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model_index >= model_->FirstPanelIndex()) { 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_animator_->SetAnimationDelegate( 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view, new StartFadeAnimationDelegate(this, view), true); 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Undo the hiding if animation does not run. 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view->layer()->SetOpacity(1.0f); 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1547f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ShelfView::ShelfItemRemoved(int model_index, LauncherID id) { 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (id == context_menu_id_) 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) launcher_menu_runner_.reset(); 15502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 15512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AutoReset<bool> cancelling_drag( 15522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &cancelling_drag_model_changed_, true); 15532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model_index = CancelDrag(model_index); 15542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* view = view_model_->view_at(model_index); 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->Remove(model_index); 15570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 15580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // When the overflow bubble is visible, the overflow range needs to be set 15590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // before CalculateIdealBounds() gets called. Otherwise CalculateIdealBounds() 15600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // could trigger a LauncherItemChanged() by hiding the overflow bubble and 1561f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // since the overflow bubble is not yet synced with the ShelfModel this 15620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // could cause a crash. 15632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (overflow_bubble_ && overflow_bubble_->IsShowing()) { 15642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_hidden_index_ = std::min(last_hidden_index_, 15652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view_model_->view_size() - 1); 15668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) UpdateOverflowRange(overflow_bubble_->shelf_view()); 15672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1568d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 15690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (view->visible()) { 15700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // The first animation fades out the view. When done we'll animate the rest 15710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // of the views to their target location. 15720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) bounds_animator_->AnimateViewTo(view, view->bounds()); 15730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) bounds_animator_->SetAnimationDelegate( 15740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) view, new FadeOutAnimationDelegate(this, view), true); 15750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } else { 15760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // We don't need to show a fade out animation for invisible |view|. When an 15770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // item is ripped out from the shelf, its |view| is already invisible. 15780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) AnimateToIdealBounds(); 15790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 15800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1581d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Close the tooltip because it isn't needed any longer and its anchor view 1582d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // will be deleted soon. 1583d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (tooltip_->GetCurrentAnchorView() == view) 1584d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) tooltip_->Close(); 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1587f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ShelfView::ShelfItemChanged(int model_index, 1588f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const LauncherItem& old_item) { 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LauncherItem& item(model_->items()[model_index]); 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (old_item.type != item.type) { 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Type changed, swap the views. 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_index = CancelDrag(model_index); 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<views::View> old_view(view_model_->view_at(model_index)); 15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_animator_->StopAnimatingView(old_view.get()); 15953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Removing and re-inserting a view in our view model will strip the ideal 15963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // bounds from the item. To avoid recalculation of everything the bounds 15973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // get remembered and restored after the insertion to the previous value. 15983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) gfx::Rect old_ideal_bounds = view_model_->ideal_bounds(model_index); 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->Remove(model_index); 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* new_view = CreateViewForItem(item); 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildView(new_view); 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->Add(new_view, model_index); 16033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) view_model_->set_ideal_bounds(model_index, old_ideal_bounds); 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_view->SetBoundsRect(old_view->bounds()); 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* view = view_model_->view_at(model_index); 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (item.type) { 16102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case TYPE_BROWSER_SHORTCUT: 1611f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Fallthrough for the new Shelf since it needs to show the activation 16122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // change as well. 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_APP_SHORTCUT: 16142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case TYPE_WINDOWED_APP: 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_PLATFORM_APP: 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_APP_PANEL: { 1617f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ShelfButton* button = static_cast<ShelfButton*>(view); 16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReflectItemStatus(item, button); 16192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The browser shortcut is currently not a "real" item and as such the 16202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the image is bogous as well. We therefore keep the image as is for it. 16212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (item.type != TYPE_BROWSER_SHORTCUT) 16222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) button->SetImage(item.image); 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->SchedulePaint(); 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1632f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ShelfView::ShelfItemMoved(int start_index, int target_index) { 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->Move(start_index, target_index); 16342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // When cancelling a drag due to a launcher item being added, the currently 16352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // dragged item is moved back to its initial position. AnimateToIdealBounds 16362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // will be called again when the new item is added to the |view_model_| but 16372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // at this time the |view_model_| is inconsistent with the |model_|. 16382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!cancelling_drag_model_changed_) 16392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AnimateToIdealBounds(); 16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1642f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ShelfView::ShelfStatusChanged() { 1643eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (ash::switches::UseAlternateShelfLayout()) 1644eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppListButton* app_list_button = 16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<AppListButton*>(GetAppListButtonView()); 1647f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (model_->status() == ShelfModel::STATUS_LOADING) 16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) app_list_button->StartLoadingAnimation(); 16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) app_list_button->StopLoadingAnimation(); 16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::PointerPressedOnButton(views::View* view, 16548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Pointer pointer, 16558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const ui::LocatedEvent& event) { 16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (drag_view_) 16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = view_model_->GetIndexOfView(view); 1660424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (index == -1) 1661424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 1662424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 1663a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ShelfItemDelegate* item_delegate = item_manager_->GetShelfItemDelegate( 16644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) model_->items()[index].id); 16654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (view_model_->view_size() <= 1 || !item_delegate->IsDraggable()) 16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // View is being deleted or not draggable, ignore request. 16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_view_ = view; 16691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) drag_offset_ = layout_manager_->PrimaryAxisValue(event.x(), event.y()); 1670f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Ash.ShelfAlignmentUsage", 1671f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) layout_manager_->SelectValueForShelfAlignment( 1672f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SHELF_ALIGNMENT_UMA_ENUM_VALUE_BOTTOM, 1673f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SHELF_ALIGNMENT_UMA_ENUM_VALUE_LEFT, 1674f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SHELF_ALIGNMENT_UMA_ENUM_VALUE_RIGHT, 1675f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) -1), 1676f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SHELF_ALIGNMENT_UMA_ENUM_VALUE_COUNT); 16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::PointerDraggedOnButton(views::View* view, 16808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Pointer pointer, 16818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const ui::LocatedEvent& event) { 16820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // To prepare all drag types (moving an item in the shelf and dragging off), 16830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // we should check the x-axis and y-axis offset. 16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!dragging() && drag_view_ && 16850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ((abs(event.x() - drag_offset_) >= kMinimumDragDistance) || 16860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) (abs(event.y() - drag_offset_) >= kMinimumDragDistance))) { 16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrepareForDrag(pointer, event); 16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (drag_pointer_ == pointer) 16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContinueDrag(event); 16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::PointerReleasedOnButton(views::View* view, 16948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Pointer pointer, 16958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) bool canceled) { 16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (canceled) { 16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelDrag(-1); 16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (drag_pointer_ == pointer) { 1699424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FinalizeRipOffDrag(false); 17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_pointer_ = NONE; 17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AnimateToIdealBounds(); 17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1703ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // If the drag pointer is NONE, no drag operation is going on and the 1704ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // drag_view can be released. 1705ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (drag_pointer_ == NONE) 1706ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch drag_view_ = NULL; 17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::MouseMovedOverButton(views::View* view) { 17102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!ShouldShowTooltipForView(view)) 17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!tooltip_->IsVisible()) 17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tooltip_->ResetTimer(); 17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::MouseEnteredButton(views::View* view) { 17182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!ShouldShowTooltipForView(view)) 17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tooltip_->IsVisible()) { 17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tooltip_->ShowImmediately(view, GetAccessibleName(view)); 17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tooltip_->ShowDelayed(view, GetAccessibleName(view)); 17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::MouseExitedButton(views::View* view) { 17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!tooltip_->IsVisible()) 17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tooltip_->StopTimer(); 17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)base::string16 ShelfView::GetAccessibleName(const views::View* view) { 17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int view_index = view_model_->GetIndexOfView(view); 17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // May be -1 while in the process of animating closed. 17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view_index == -1) 1737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return base::string16(); 17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1739a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ShelfItemDelegate* item_delegate = item_manager_->GetShelfItemDelegate( 17404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) model_->items()[view_index].id); 17414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return item_delegate->GetTitle(); 17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::ButtonPressed(views::Button* sender, const ui::Event& event) { 17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do not handle mouse release during drag. 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dragging()) 17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sender == overflow_button_) { 17502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ToggleOverflowBubble(); 17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int view_index = view_model_->GetIndexOfView(sender); 17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // May be -1 while in the process of animating closed. 17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view_index == -1) 17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the previous menu was closed by the same event as this one, we ignore 17602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the call. 17612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!IsUsableEvent(event)) 17622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 17632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 1765a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedTargetRootWindow scoped_target( 1766a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) sender->GetWidget()->GetNativeView()->GetRootWindow()); 17672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Slow down activation animations if shift key is pressed. 17682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ui::ScopedAnimationDurationScaleMode> slowing_animations; 17692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (event.IsShiftDown()) { 17702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) slowing_animations.reset(new ui::ScopedAnimationDurationScaleMode( 17712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::ScopedAnimationDurationScaleMode::SLOW_DURATION)); 17722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 17732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1774b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Collect usage statistics before we decide what to do with the click. 1775b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) switch (model_->items()[view_index].type) { 1776b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) case TYPE_APP_SHORTCUT: 1777b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) case TYPE_WINDOWED_APP: 1778b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) case TYPE_PLATFORM_APP: 177990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case TYPE_BROWSER_SHORTCUT: 1780d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) Shell::GetInstance()->metrics()->RecordUserMetricsAction( 1781b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) UMA_LAUNCHER_CLICK_ON_APP); 1782b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) break; 17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1784b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) case TYPE_APP_LIST: 1785d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) Shell::GetInstance()->metrics()->RecordUserMetricsAction( 1786b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) UMA_LAUNCHER_CLICK_ON_APPLIST_BUTTON); 1787424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 1788424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 1789424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case TYPE_APP_PANEL: 1790424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 1791424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 1792424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case TYPE_UNDEFINED: 1793424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) NOTREACHED() << "LauncherItemType must be set."; 1794b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) break; 17952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1796424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 1797a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ShelfItemDelegate* item_delegate = 1798a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) item_manager_->GetShelfItemDelegate(model_->items()[view_index].id); 1799f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!item_delegate->ItemSelected(event)) 1800f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ShowListMenuForView(model_->items()[view_index], sender, event); 18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 18032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool ShelfView::ShowListMenuForView(const LauncherItem& item, 18058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) views::View* source, 18068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const ui::Event& event) { 1807a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<ShelfMenuModel> menu_model; 1808a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ShelfItemDelegate* item_delegate = 1809a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) item_manager_->GetShelfItemDelegate(item.id); 18104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) menu_model.reset(item_delegate->CreateApplicationMenu(event.flags())); 18112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make sure we have a menu and it has at least two items in addition to the 18132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // application title and the 3 spacing separators. 18142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!menu_model.get() || menu_model->GetItemCount() <= 5) 18152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 18162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ShowMenu(scoped_ptr<views::MenuModelAdapter>( 1818a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) new ShelfMenuModelAdapter(menu_model.get())), 18192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) source, 18202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Point(), 18217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) false, 18227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ui::GetMenuSourceTypeForEvent(event)); 18232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::ShowContextMenuForView(views::View* source, 18278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const gfx::Point& point, 18288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ui::MenuSourceType source_type) { 18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int view_index = view_model_->GetIndexOfView(source); 1830424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // TODO(simon.hong81): Create LauncherContextMenu for applist in its 1831a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // ShelfItemDelegate. 1832a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (view_index != -1 && model_->items()[view_index].type == TYPE_APP_LIST) { 18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_index = -1; 18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view_index == -1) { 18377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Shell::GetInstance()->ShowContextMenu(point, source_type); 18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1840424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<ui::MenuModel> menu_model; 1841a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ShelfItemDelegate* item_delegate = item_manager_->GetShelfItemDelegate( 18424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) model_->items()[view_index].id); 1843424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) menu_model.reset(item_delegate->CreateContextMenu( 18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source->GetWidget()->GetNativeView()->GetRootWindow())); 1845c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!menu_model) 18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1847424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 18482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AutoReset<LauncherID> reseter( 18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &context_menu_id_, 18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_index == -1 ? 0 : model_->items()[view_index].id); 18512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ShowMenu(scoped_ptr<views::MenuModelAdapter>( 18532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new views::MenuModelAdapter(menu_model.get())), 18542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) source, 18552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) point, 18567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) true, 18577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) source_type); 18582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 18592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::ShowMenu(scoped_ptr<views::MenuModelAdapter> menu_model_adapter, 18618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) views::View* source, 18628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const gfx::Point& click_point, 18638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) bool context_menu, 18648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ui::MenuSourceType source_type) { 18652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) closing_event_time_ = base::TimeDelta(); 18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) launcher_menu_runner_.reset( 18672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new views::MenuRunner(menu_model_adapter->CreateMenu())); 18682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1869a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedTargetRootWindow scoped_target( 1870a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) source->GetWidget()->GetNativeView()->GetRootWindow()); 1871a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 18722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Determine the menu alignment dependent on the shelf. 18732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::MenuItemView::AnchorPosition menu_alignment = 18742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::MenuItemView::TOPLEFT; 18752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect anchor_point = gfx::Rect(click_point, gfx::Size()); 18762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1877c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ShelfWidget* shelf = RootWindowController::ForLauncher( 1878c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetWidget()->GetNativeView())->shelf(); 18792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!context_menu) { 18802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Application lists use a bubble. 1881c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ash::ShelfAlignment align = shelf->GetAlignment(); 18822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) anchor_point = source->GetBoundsInScreen(); 18832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // It is possible to invoke the menu while it is sliding into view. To cover 18857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // that case, the screen coordinates are offsetted by the animation delta. 18867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) gfx::Vector2d offset = 18877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) source->GetWidget()->GetNativeWindow()->bounds().origin() - 18887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) source->GetWidget()->GetNativeWindow()->GetTargetBounds().origin(); 18897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) anchor_point.set_x(anchor_point.x() - offset.x()); 18907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) anchor_point.set_y(anchor_point.y() - offset.y()); 18917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1892f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Shelf items can have an asymmetrical border for spacing reasons. 18932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Adjust anchor location for this. 18942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (source->border()) 18952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) anchor_point.Inset(source->border()->GetInsets()); 18962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (align) { 18982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ash::SHELF_ALIGNMENT_BOTTOM: 18992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) menu_alignment = views::MenuItemView::BUBBLE_ABOVE; 19002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 19012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ash::SHELF_ALIGNMENT_LEFT: 19022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) menu_alignment = views::MenuItemView::BUBBLE_RIGHT; 19032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 19042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ash::SHELF_ALIGNMENT_RIGHT: 19052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) menu_alignment = views::MenuItemView::BUBBLE_LEFT; 19062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 19072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ash::SHELF_ALIGNMENT_TOP: 19082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) menu_alignment = views::MenuItemView::BUBBLE_BELOW; 19092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 19102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 19112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1912c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If this gets deleted while we are in the menu, the launcher will be gone 1913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // as well. 1914c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool got_deleted = false; 1915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) got_deleted_ = &got_deleted; 1916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1917c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shelf->ForceUndimming(true); 19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: if you convert to HAS_MNEMONICS be sure and update menu building 19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // code. 19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (launcher_menu_runner_->RunMenuAt( 19212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) source->GetWidget(), 19222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NULL, 19232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) anchor_point, 19242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) menu_alignment, 19257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) source_type, 19267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) context_menu ? views::MenuRunner::CONTEXT_MENU : 0) == 19277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) views::MenuRunner::MENU_DELETED) { 1928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!got_deleted) { 1929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) got_deleted_ = NULL; 1930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shelf->ForceUndimming(false); 1931c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1934c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) got_deleted_ = NULL; 1935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shelf->ForceUndimming(false); 19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // If it is a context menu and we are showing overflow bubble 19384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // we want to hide overflow bubble. 19394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (owner_overflow_bubble_) 19404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) owner_overflow_bubble_->HideBubbleAndRefreshButton(); 19414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 19422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Unpinning an item will reset the |launcher_menu_runner_| before coming 19432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // here. 1944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (launcher_menu_runner_) 19452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) closing_event_time_ = launcher_menu_runner_->closing_event_time(); 19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shell::GetInstance()->UpdateShelfVisibility(); 19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::OnBoundsAnimatorProgressed(views::BoundsAnimator* animator) { 19501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) FOR_EACH_OBSERVER(ShelfIconObserver, observers_, 19511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OnShelfIconPositionsChanged()); 19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PreferredSizeChanged(); 19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::OnBoundsAnimatorDone(views::BoundsAnimator* animator) { 1956424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (snap_back_from_rip_off_view_ && animator == bounds_animator_) { 1957424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!animator->IsAnimating(snap_back_from_rip_off_view_)) { 1958f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Coming here the animation of the ShelfButton is finished and the 1959424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // previously hidden status can be shown again. Since the button itself 1960424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // might have gone away or changed locations we check that the button 1961424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // is still in the shelf and show its status again. 1962424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (int index = 0; index < view_model_->view_size(); index++) { 1963424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) views::View* view = view_model_->view_at(index); 1964424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (view == snap_back_from_rip_off_view_) { 1965f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ShelfButton* button = static_cast<ShelfButton*>(view); 1966f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->ClearState(ShelfButton::STATE_HIDDEN); 1967424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 1968424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1969424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1970424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) snap_back_from_rip_off_view_ = NULL; 1971424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1972424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool ShelfView::IsUsableEvent(const ui::Event& event) { 19762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (closing_event_time_ == base::TimeDelta()) 19772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 19782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta delta = 19802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta(event.time_stamp() - closing_event_time_); 19812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) closing_event_time_ = base::TimeDelta(); 19822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(skuhne): This time seems excessive, but it appears that the reposting 19832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // takes that long. Need to come up with a better way of doing this. 19842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (delta.InMilliseconds() < 0 || delta.InMilliseconds() > 130); 19852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 19862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const LauncherItem* ShelfView::LauncherItemForView( 19882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const views::View* view) const { 19892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int view_index = view_model_->GetIndexOfView(view); 19902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (view_index == -1) 19912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 19922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return &(model_->items()[view_index]); 19932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 19942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool ShelfView::ShouldShowTooltipForView(const views::View* view) const { 19962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (view == GetAppListButtonView() && 19972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Shell::GetInstance()->GetAppListWindow()) 19982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 19992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LauncherItem* item = LauncherItemForView(view); 2000424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!item) 2001424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 2002a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ShelfItemDelegate* item_delegate = 2003a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) item_manager_->GetShelfItemDelegate(item->id); 20044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return item_delegate->ShouldShowTooltip(); 2005424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 2006424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 20078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int ShelfView::CalculateShelfDistance(const gfx::Point& coordinate) const { 2008424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ShelfWidget* shelf = RootWindowController::ForLauncher( 2009424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) GetWidget()->GetNativeView())->shelf(); 2010424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ash::ShelfAlignment align = shelf->GetAlignment(); 2011424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const gfx::Rect bounds = GetBoundsInScreen(); 2012424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int distance = 0; 2013424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) switch (align) { 2014424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case ash::SHELF_ALIGNMENT_BOTTOM: 2015424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) distance = bounds.y() - coordinate.y(); 2016424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 2017424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case ash::SHELF_ALIGNMENT_LEFT: 2018424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) distance = coordinate.x() - bounds.right(); 2019424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 2020424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case ash::SHELF_ALIGNMENT_RIGHT: 2021424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) distance = bounds.x() - coordinate.x(); 2022424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 2023424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case ash::SHELF_ALIGNMENT_TOP: 2024424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) distance = coordinate.y() - bounds.bottom(); 2025424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 2026424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 2027424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return distance > 0 ? distance : 0; 20282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 20292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace internal 20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ash 2032