shelf_view.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
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" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (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" 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/shelf/shelf_constants.h" 22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ash/shelf/shelf_delegate.h" 231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ash/shelf/shelf_icon_observer.h" 24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ash/shelf/shelf_item_delegate.h" 25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ash/shelf/shelf_item_delegate_manager.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shelf/shelf_layout_manager.h" 27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ash/shelf/shelf_menu_model.h" 28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/shelf/shelf_model.h" 294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/shelf/shelf_tooltip_manager.h" 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shelf/shelf_widget.h" 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/shell.h" 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/wm/coordinate_conversion.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/auto_reset.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/metrics/histogram.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_resources.h" 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "grit/ash_strings.h" 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/accessibility/ax_view_state.h" 39a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "ui/aura/client/screen_position_client.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window.h" 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/models/simple_menu_model.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer_animator.h" 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/scoped_animation_duration_scale_mode.h" 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h" 497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/gfx/point.h" 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/animation/bounds_animator.h" 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/border.h" 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/controls/button/image_button.h" 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/menu/menu_model_adapter.h" 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/menu/menu_runner.h" 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/focus/focus_search.h" 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/view_model.h" 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/view_model_utils.h" 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h" 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using gfx::Animation; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using views::View; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash { 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) 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// The proportion of the shelf 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) 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// A class to temporarily disable a given bounds animator. 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class BoundsAnimatorDisabler { 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BoundsAnimatorDisabler(views::BoundsAnimator* bounds_animator) 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : old_duration_(bounds_animator->GetAnimationDuration()), 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bounds_animator_(bounds_animator) { 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bounds_animator_->SetAnimationDuration(1); 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ~BoundsAnimatorDisabler() { 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bounds_animator_->SetAnimationDuration(old_duration_); 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The previous animation duration. 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int old_duration_; 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The bounds animator which gets used. 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) views::BoundsAnimator* bounds_animator_; 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(BoundsAnimatorDisabler); 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The MenuModelAdapter gets slightly changed to adapt the menu appearance to 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// our requirements. 147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class ShelfMenuModelAdapter : public views::MenuModelAdapter { 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) explicit ShelfMenuModelAdapter(ShelfMenuModel* menu_model); 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // views::MenuModelAdapter: 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual const gfx::FontList* GetLabelFontList(int command_id) const OVERRIDE; 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool IsCommandEnabled(int id) const OVERRIDE; 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void GetHorizontalIconMargins(int id, 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int icon_size, 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int* left_margin, 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int* right_margin) const OVERRIDE; 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool GetForegroundColor(int command_id, 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_hovered, 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkColor* override_color) const OVERRIDE; 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool GetBackgroundColor(int command_id, 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_hovered, 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkColor* override_color) const OVERRIDE; 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual int GetMaxWidthForMenu(views::MenuItemView* menu) OVERRIDE; 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool ShouldReserveSpaceForSubmenuIndicator() const OVERRIDE; 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ShelfMenuModel* menu_model_; 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ShelfMenuModelAdapter); 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)ShelfMenuModelAdapter::ShelfMenuModelAdapter(ShelfMenuModel* menu_model) 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : MenuModelAdapter(menu_model), 175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) menu_model_(menu_model) { 176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const gfx::FontList* ShelfMenuModelAdapter::GetLabelFontList( 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int command_id) const { 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (command_id != kCommandIdOfMenuName) 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return MenuModelAdapter::GetLabelFontList(command_id); 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return &rb.GetFontList(ui::ResourceBundle::BoldFont); 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool ShelfMenuModelAdapter::IsCommandEnabled(int id) const { 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return id != kCommandIdOfMenuName; 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool ShelfMenuModelAdapter::GetForegroundColor(int command_id, 192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool is_hovered, 193a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SkColor* override_color) const { 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (command_id != kCommandIdOfMenuName) 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *override_color = kCaptionItemForegroundColor; 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 201a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool ShelfMenuModelAdapter::GetBackgroundColor(int command_id, 202a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool is_hovered, 203a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SkColor* override_color) const { 204a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!menu_model_->IsCommandActive(command_id)) 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *override_color = is_hovered ? kFocusedActiveListItemBackgroundColor : 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kActiveListItemBackgroundColor; 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ShelfMenuModelAdapter::GetHorizontalIconMargins(int command_id, 213a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int icon_size, 214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int* left_margin, 215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int* right_margin) const { 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *left_margin = kHorizontalIconSpacing; 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *right_margin = (command_id != kCommandIdOfMenuName) ? 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kHorizontalIconSpacing : -(icon_size + kHorizontalNoIconInsetSpacing); 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)int ShelfMenuModelAdapter::GetMaxWidthForMenu(views::MenuItemView* menu) { 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return kMaximumAppMenuItemLength; 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool ShelfMenuModelAdapter::ShouldReserveSpaceForSubmenuIndicator() const { 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Custom FocusSearch used to navigate the shelf in the order items are in 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the ViewModel. 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ShelfFocusSearch : public views::FocusSearch { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) explicit ShelfFocusSearch(views::ViewModel* view_model) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : FocusSearch(NULL, true, true), 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_(view_model) {} 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~ShelfFocusSearch() {} 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // views::FocusSearch overrides: 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual View* FindNextFocusableView( 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) View* starting_view, 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool reverse, 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Direction direction, 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool check_starting_view, 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::FocusTraversable** focus_traversable, 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) View** focus_traversable_view) OVERRIDE { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = view_model_->GetIndexOfView(starting_view); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index == -1) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return view_model_->view_at(0); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (reverse) { 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) --index; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index < 0) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index = view_model_->view_size() - 1; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++index; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index >= view_model_->view_size()) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index = 0; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return view_model_->view_at(index); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::ViewModel* view_model_; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ShelfFocusSearch); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AnimationDelegate used when inserting a new item. This steadily increases the 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// opacity of the layer as the animation progress. 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FadeInAnimationDelegate 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public views::BoundsAnimator::OwnedAnimationDelegate { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit FadeInAnimationDelegate(views::View* view) : view_(view) {} 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~FadeInAnimationDelegate() {} 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // AnimationDelegate overrides: 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AnimationProgressed(const Animation* animation) OVERRIDE { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->layer()->SetOpacity(animation->GetCurrentValue()); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->layer()->ScheduleDraw(); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AnimationEnded(const Animation* animation) OVERRIDE { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->layer()->SetOpacity(1.0f); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->layer()->ScheduleDraw(); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AnimationCanceled(const Animation* animation) OVERRIDE { 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->layer()->SetOpacity(1.0f); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->layer()->ScheduleDraw(); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* view_; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(FadeInAnimationDelegate); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ReflectItemStatus(const ShelfItem& item, ShelfButton* button) { 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (item.status) { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATUS_CLOSED: 299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->ClearState(ShelfButton::STATE_ACTIVE); 300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->ClearState(ShelfButton::STATE_RUNNING); 301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->ClearState(ShelfButton::STATE_ATTENTION); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATUS_RUNNING: 304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->ClearState(ShelfButton::STATE_ACTIVE); 305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->AddState(ShelfButton::STATE_RUNNING); 306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->ClearState(ShelfButton::STATE_ATTENTION); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATUS_ACTIVE: 309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->AddState(ShelfButton::STATE_ACTIVE); 310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->ClearState(ShelfButton::STATE_RUNNING); 311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->ClearState(ShelfButton::STATE_ATTENTION); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATUS_ATTENTION: 314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->ClearState(ShelfButton::STATE_ACTIVE); 315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->ClearState(ShelfButton::STATE_RUNNING); 316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->AddState(ShelfButton::STATE_ATTENTION); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// AnimationDelegate used when deleting an item. This steadily decreased the 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// opacity of the layer as the animation progress. 3258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)class ShelfView::FadeOutAnimationDelegate 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public views::BoundsAnimator::OwnedAnimationDelegate { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) FadeOutAnimationDelegate(ShelfView* host, views::View* view) 3298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) : shelf_view_(host), 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_(view) {} 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~FadeOutAnimationDelegate() {} 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // AnimationDelegate overrides: 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AnimationProgressed(const Animation* animation) OVERRIDE { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->layer()->SetOpacity(1 - animation->GetCurrentValue()); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->layer()->ScheduleDraw(); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AnimationEnded(const Animation* animation) OVERRIDE { 3398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) shelf_view_->OnFadeOutAnimationEnded(); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AnimationCanceled(const Animation* animation) OVERRIDE { 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ShelfView* shelf_view_; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<views::View> view_; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(FadeOutAnimationDelegate); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AnimationDelegate used to trigger fading an element in. When an item is 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// inserted this delegate is attached to the animation that expands the size of 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the item. When done it kicks off another animation to fade the item in. 3548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)class ShelfView::StartFadeAnimationDelegate 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public views::BoundsAnimator::OwnedAnimationDelegate { 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) StartFadeAnimationDelegate(ShelfView* host, 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* view) 3598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) : shelf_view_(host), 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_(view) {} 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~StartFadeAnimationDelegate() {} 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // AnimationDelegate overrides: 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AnimationEnded(const Animation* animation) OVERRIDE { 3658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) shelf_view_->FadeIn(view_); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AnimationCanceled(const Animation* animation) OVERRIDE { 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->layer()->SetOpacity(1.0f); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ShelfView* shelf_view_; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* view_; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(StartFadeAnimationDelegate); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ShelfView::ShelfView(ShelfModel* model, 379a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ShelfDelegate* delegate, 380a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ShelfLayoutManager* manager) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : model_(model), 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_(delegate), 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_(new views::ViewModel), 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_visible_index_(0), 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_visible_index_(-1), 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_button_(NULL), 3874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) owner_overflow_bubble_(NULL), 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_pointer_(NONE), 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_view_(NULL), 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_offset_(0), 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_drag_index_(-1), 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_menu_id_(0), 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) leading_inset_(kDefaultLeadingInset), 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cancelling_drag_model_changed_(false), 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_hidden_index_(0), 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) closing_event_time_(base::TimeDelta()), 397b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) got_deleted_(NULL), 3987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) drag_and_drop_item_pinned_(false), 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) drag_and_drop_shelf_id_(0), 400424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) dragged_off_shelf_(false), 401424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) snap_back_from_rip_off_view_(NULL), 402a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) item_manager_(Shell::GetInstance()->shelf_item_delegate_manager()), 403a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) layout_manager_(manager), 404a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) overflow_mode_(false), 405a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) main_shelf_(NULL), 406a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) dragged_off_from_overflow_to_shelf_(false) { 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(model_); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_animator_.reset(new views::BoundsAnimator(this)); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_animator_->AddObserver(this); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_context_menu_controller(this); 4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) focus_search_.reset(new ShelfFocusSearch(view_model_.get())); 412a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) tooltip_.reset(new ShelfTooltipManager(manager, this)); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)ShelfView::~ShelfView() { 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_animator_->RemoveObserver(this); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->RemoveObserver(this); 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If we are inside the MenuRunner, we need to know if we were getting 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // deleted while it was running. 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (got_deleted_) 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *got_deleted_ = true; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::Init() { 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->AddObserver(this); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ShelfItems& items(model_->items()); 4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (ShelfItems::const_iterator i = items.begin(); i != items.end(); ++i) { 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* child = CreateViewForItem(*i); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child->SetPaintToLayer(true); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->Add(child, static_cast<int>(i - items.begin())); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildView(child); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ShelfStatusChanged(); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_button_ = new OverflowButton(this); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_button_->set_context_menu_controller(this); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConfigureChildView(overflow_button_); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildView(overflow_button_); 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateFirstButtonPadding(); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We'll layout when our bounds change. 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::OnShelfAlignmentChanged() { 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateFirstButtonPadding(); 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overflow_button_->OnShelfAlignmentChanged(); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LayoutToIdealBounds(); 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i=0; i < view_model_->view_size(); ++i) { 449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO: remove when AppIcon is a Shelf Button. 450eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (TYPE_APP_LIST == model_->items()[i].type && 451eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch !ash::switches::UseAlternateShelfLayout()) { 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<AppListButton*>(view_model_->view_at(i))->SetImageAlignment( 4531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->SelectValueForShelfAlignment( 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::ImageButton::ALIGN_CENTER, 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::ImageButton::ALIGN_LEFT, 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::ImageButton::ALIGN_RIGHT, 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::ImageButton::ALIGN_CENTER), 4581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->SelectValueForShelfAlignment( 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::ImageButton::ALIGN_TOP, 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::ImageButton::ALIGN_MIDDLE, 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::ImageButton::ALIGN_MIDDLE, 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::ImageButton::ALIGN_BOTTOM)); 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (i >= first_visible_index_ && i <= last_visible_index_) 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view_model_->view_at(i)->Layout(); 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 467d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) tooltip_->Close(); 468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (overflow_bubble_) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_bubble_->Hide(); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::SchedulePaintForAllButtons() { 473ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = 0; i < view_model_->view_size(); ++i) { 474ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (i >= first_visible_index_ && i <= last_visible_index_) 475ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch view_model_->view_at(i)->SchedulePaint(); 476ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 477ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (overflow_button_ && overflow_button_->visible()) 478ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch overflow_button_->SchedulePaint(); 479ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 480ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)gfx::Rect ShelfView::GetIdealBoundsOfItemIcon(ShelfID id) { 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = model_->ItemIndexByID(id); 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (index == -1 || (index > last_visible_index_ && 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) index < model_->FirstPanelIndex())) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gfx::Rect(); 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& ideal_bounds(view_model_->ideal_bounds(index)); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(TYPE_APP_LIST, model_->items()[index].type); 488f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ShelfButton* button = static_cast<ShelfButton*>(view_model_->view_at(index)); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect icon_bounds = button->GetIconBounds(); 490868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return gfx::Rect(GetMirroredXWithWidthInView( 491868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ideal_bounds.x() + icon_bounds.x(), icon_bounds.width()), 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ideal_bounds.y() + icon_bounds.y(), 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_bounds.width(), 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_bounds.height()); 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ShelfView::UpdatePanelIconPosition(ShelfID id, 4988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const gfx::Point& midpoint) { 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int current_index = model_->ItemIndexByID(id); 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int first_panel_index = model_->FirstPanelIndex(); 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (current_index < first_panel_index) 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 504868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) gfx::Point midpoint_in_view(GetMirroredXInView(midpoint.x()), 505868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) midpoint.y()); 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int target_index = current_index; 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (target_index > first_panel_index && 5081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->PrimaryAxisValue( 5091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) view_model_->ideal_bounds(target_index).x(), 5101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) view_model_->ideal_bounds(target_index).y()) > 5111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->PrimaryAxisValue(midpoint_in_view.x(), 5121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) midpoint_in_view.y())) { 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) --target_index; 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (target_index < view_model_->view_size() - 1 && 5161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->PrimaryAxisValue( 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view_model_->ideal_bounds(target_index).right(), 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view_model_->ideal_bounds(target_index).bottom()) < 5191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->PrimaryAxisValue(midpoint_in_view.x(), 5201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) midpoint_in_view.y())) { 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++target_index; 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (current_index != target_index) 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model_->Move(current_index, target_index); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool ShelfView::IsShowingMenu() const { 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (launcher_menu_runner_.get() && 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) launcher_menu_runner_->IsRunning()); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool ShelfView::IsShowingOverflowBubble() const { 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return overflow_bubble_.get() && overflow_bubble_->IsShowing(); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)views::View* ShelfView::GetAppListButtonView() const { 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < model_->item_count(); ++i) { 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (model_->items()[i].type == TYPE_APP_LIST) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return view_model_->view_at(i); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Applist button not found"; 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 5478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// ShelfView, FocusTraversable implementation: 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)views::FocusSearch* ShelfView::GetFocusSearch() { 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return focus_search_.get(); 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)views::FocusTraversable* ShelfView::GetFocusTraversableParent() { 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return parent()->GetFocusTraversable(); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)View* ShelfView::GetFocusTraversableParentView() { 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this; 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::CreateDragIconProxy( 562a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const gfx::Point& location_in_screen_coordinates, 563a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const gfx::ImageSkia& icon, 564a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) views::View* replaced_view, 565868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const gfx::Vector2d& cursor_offset_from_center, 566a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) float scale_factor) { 567a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) drag_replaced_view_ = replaced_view; 568c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch drag_image_.reset(new ash::DragImageView( 5694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) drag_replaced_view_->GetWidget()->GetNativeWindow()->GetRootWindow(), 5704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE)); 571a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) drag_image_->SetImage(icon); 572a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) gfx::Size size = drag_image_->GetPreferredSize(); 573a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) size.set_width(size.width() * scale_factor); 574a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) size.set_height(size.height() * scale_factor); 575868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) drag_image_offset_ = gfx::Vector2d(size.width() / 2, size.height() / 2) + 576868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) cursor_offset_from_center; 577a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) gfx::Rect drag_image_bounds( 578f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) location_in_screen_coordinates - drag_image_offset_, 579f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) size); 580a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) drag_image_->SetBoundsInScreen(drag_image_bounds); 581a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) drag_image_->SetWidgetVisible(true); 582a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 583a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 5848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::UpdateDragIconProxy( 585a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const gfx::Point& location_in_screen_coordinates) { 586a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(jennyz): Investigate why drag_image_ becomes NULL at this point per 587a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // crbug.com/34722, while the app list item is still being dragged around. 588a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (drag_image_) { 589a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) drag_image_->SetScreenPosition( 590a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) location_in_screen_coordinates - drag_image_offset_); 591a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 592a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 593a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 5948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::DestroyDragIconProxy() { 595a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) drag_image_.reset(); 596a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) drag_image_offset_ = gfx::Vector2d(0, 0); 597a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 598a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 5998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool ShelfView::StartDrag(const std::string& app_id, 6008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const gfx::Point& location_in_screen_coordinates) { 601b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Bail if an operation is already going on - or the cursor is not inside. 602b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // This could happen if mouse / touch operations overlap. 6035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (drag_and_drop_shelf_id_ || 604b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) !GetBoundsInScreen().Contains(location_in_screen_coordinates)) 605b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return false; 606b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 607b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // If the AppsGridView (which was dispatching this event) was opened by our 6088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // button, ShelfView dragging operations are locked and we have to unlock. 609b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) CancelDrag(-1); 6107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) drag_and_drop_item_pinned_ = false; 611b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) drag_and_drop_app_id_ = app_id; 6125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) drag_and_drop_shelf_id_ = 6135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delegate_->GetShelfIDForAppID(drag_and_drop_app_id_); 6147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Check if the application is known and pinned - if not, we have to pin it so 6155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // that we can re-arrange the shelf order accordingly. Note that items have 6167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // to be pinned to give them the same (order) possibilities as a shortcut. 617a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // When an item is dragged from overflow to shelf, IsShowingOverflowBubble() 618a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // returns true. At this time, we don't need to pin the item. 619a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!IsShowingOverflowBubble() && 6205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (!drag_and_drop_shelf_id_ || 621a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) !delegate_->IsAppPinned(app_id))) { 622b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) delegate_->PinAppWithID(app_id); 6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) drag_and_drop_shelf_id_ = 6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delegate_->GetShelfIDForAppID(drag_and_drop_app_id_); 6255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!drag_and_drop_shelf_id_) 626b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return false; 6277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) drag_and_drop_item_pinned_ = true; 628b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 629b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) views::View* drag_and_drop_view = view_model_->view_at( 6305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) model_->ItemIndexByID(drag_and_drop_shelf_id_)); 631b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(drag_and_drop_view); 632b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 633a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Since there is already an icon presented by the caller, we hide this item 634a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // for now. That has to be done by reducing the size since the visibility will 635a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // change once a regrouping animation is performed. 636a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) pre_drag_and_drop_size_ = drag_and_drop_view->size(); 637a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) drag_and_drop_view->SetSize(gfx::Size()); 638a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 639b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // First we have to center the mouse cursor over the item. 640b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) gfx::Point pt = drag_and_drop_view->GetBoundsInScreen().CenterPoint(); 641b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) views::View::ConvertPointFromScreen(drag_and_drop_view, &pt); 642f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Point point_in_root = location_in_screen_coordinates; 643f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::wm::ConvertPointFromScreen( 644f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::wm::GetRootWindowAt(location_in_screen_coordinates), 645f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &point_in_root); 6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui::MouseEvent event(ui::ET_MOUSE_PRESSED, pt, point_in_root, 0, 0); 647f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PointerPressedOnButton(drag_and_drop_view, 648f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ShelfButtonHost::DRAG_AND_DROP, 649f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event); 650b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 651b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Drag the item where it really belongs. 652b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) Drag(location_in_screen_coordinates); 653b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return true; 654b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 655b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 6568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool ShelfView::Drag(const gfx::Point& location_in_screen_coordinates) { 6575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!drag_and_drop_shelf_id_ || 658b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) !GetBoundsInScreen().Contains(location_in_screen_coordinates)) 659b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return false; 660b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 661b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) gfx::Point pt = location_in_screen_coordinates; 662b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) views::View* drag_and_drop_view = view_model_->view_at( 6635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) model_->ItemIndexByID(drag_and_drop_shelf_id_)); 664f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ConvertPointFromScreen(drag_and_drop_view, &pt); 665f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Point point_in_root = location_in_screen_coordinates; 666f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::wm::ConvertPointFromScreen( 667f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::wm::GetRootWindowAt(location_in_screen_coordinates), 668f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &point_in_root); 6695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui::MouseEvent event(ui::ET_MOUSE_DRAGGED, pt, point_in_root, 0, 0); 670f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PointerDraggedOnButton(drag_and_drop_view, 671f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ShelfButtonHost::DRAG_AND_DROP, 672f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event); 673b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return true; 674b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 675b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 6768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::EndDrag(bool cancel) { 6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!drag_and_drop_shelf_id_) 678b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return; 679b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 680b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) views::View* drag_and_drop_view = view_model_->view_at( 6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) model_->ItemIndexByID(drag_and_drop_shelf_id_)); 682b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) PointerReleasedOnButton( 683f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) drag_and_drop_view, ShelfButtonHost::DRAG_AND_DROP, cancel); 684b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 685a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Either destroy the temporarily created item - or - make the item visible. 6867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (drag_and_drop_item_pinned_ && cancel) 687424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) delegate_->UnpinAppWithID(drag_and_drop_app_id_); 68858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) else if (drag_and_drop_view) { 68958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (cancel) { 69058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // When a hosted drag gets canceled, the item can remain in the same slot 69158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // and it might have moved within the bounds. In that case the item need 69258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // to animate back to its correct location. 69358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) AnimateToIdealBounds(); 69458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else { 69558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) drag_and_drop_view->SetSize(pre_drag_and_drop_size_); 69658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 69758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 698b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 6995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) drag_and_drop_shelf_id_ = 0; 700b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 701b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 7028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::LayoutToIdealBounds() { 7031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (bounds_animator_->IsAnimating()) { 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AnimateToIdealBounds(); 7051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return; 7061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) IdealBounds ideal_bounds; 7091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CalculateIdealBounds(&ideal_bounds); 7101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) views::ViewModelUtils::SetViewBoundsToIdealBounds(*view_model_); 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_button_->SetBoundsRect(ideal_bounds.overflow_bounds); 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 714a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ShelfView::UpdateAllButtonsVisibilityInOverflowMode() { 715a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // The overflow button is not shown in overflow mode. 716a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) overflow_button_->SetVisible(false); 717a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int last_button_index = model_->FirstPanelIndex() - 1; 718a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK_LT(last_visible_index_, view_model_->view_size()); 719a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (int i = 0; i < view_model_->view_size(); ++i) { 720a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool visible = i >= first_visible_index_ && 721a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) i <= last_visible_index_; 722a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!ash::switches::UseAlternateShelfLayout()) 723a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) visible &= i != last_button_index; 724a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 725a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // To track the dragging of |drag_view_| continuously, its visibility 726a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // should be always true regardless of its position. 727a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (dragged_off_from_overflow_to_shelf_ && 728a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) view_model_->view_at(i) == drag_view_) 729a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) view_model_->view_at(i)->SetVisible(true); 730a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) else 731a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) view_model_->view_at(i)->SetVisible(visible); 732a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 733a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 734a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 7358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::CalculateIdealBounds(IdealBounds* bounds) { 7361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int available_size = layout_manager_->PrimaryAxisValue(width(), height()); 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(model_->item_count() == view_model_->view_size()); 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!available_size) 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int first_panel_index = model_->FirstPanelIndex(); 742ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int last_button_index = first_panel_index - 1; 7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initial x,y values account both leading_inset in primary 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // coordinate and secondary coordinate based on the dynamic edge of the 7465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // shelf (eg top edge on bottom-aligned shelf). 7471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int inset = ash::switches::UseAlternateShelfLayout() ? 0 : leading_inset_; 7481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int x = layout_manager_->SelectValueForShelfAlignment(inset, 0, 0, inset); 7491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int y = layout_manager_->SelectValueForShelfAlignment(0, inset, inset, 0); 750ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 751f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int button_size = GetButtonSize(); 752f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int button_spacing = GetButtonSpacing(); 753ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 7541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int w = layout_manager_->PrimaryAxisValue(button_size, width()); 7551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int h = layout_manager_->PrimaryAxisValue(height(), button_size); 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < view_model_->view_size(); ++i) { 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i < first_visible_index_) { 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->set_ideal_bounds(i, gfx::Rect(x, y, 0, 0)); 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->set_ideal_bounds(i, gfx::Rect(x, y, w, h)); 763ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (i != last_button_index) { 7641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) x = layout_manager_->PrimaryAxisValue(x + w + button_spacing, x); 7651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) y = layout_manager_->PrimaryAxisValue(y, y + h + button_spacing); 7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_overflow_mode()) { 770a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) UpdateAllButtonsVisibilityInOverflowMode(); 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // To address Fitt's law, we make the first shelf button include the 7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // leading inset (if there is one). 776ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!ash::switches::UseAlternateShelfLayout()) { 777ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (view_model_->view_size() > 0) { 778ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch view_model_->set_ideal_bounds(0, gfx::Rect(gfx::Size( 7791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->PrimaryAxisValue(inset + w, w), 7801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->PrimaryAxisValue(h, inset + h)))); 781ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Right aligned icons. 785ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int end_position = available_size - button_spacing; 7861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) x = layout_manager_->PrimaryAxisValue(end_position, 0); 7871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) y = layout_manager_->PrimaryAxisValue(0, end_position); 7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = view_model_->view_size() - 1; 7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) i >= first_panel_index; --i) { 7901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) x = layout_manager_->PrimaryAxisValue(x - w - button_spacing, x); 7911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) y = layout_manager_->PrimaryAxisValue(y, y - h - button_spacing); 7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view_model_->set_ideal_bounds(i, gfx::Rect(x, y, w, h)); 7931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) end_position = layout_manager_->PrimaryAxisValue(x, y); 7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Icons on the left / top are guaranteed up to kLeftIconProportion of 7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the available space. 7981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int last_icon_position = layout_manager_->PrimaryAxisValue( 799ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch view_model_->ideal_bounds(last_button_index).right(), 800ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch view_model_->ideal_bounds(last_button_index).bottom()) 801ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch + button_size + inset; 802ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!ash::switches::UseAlternateShelfLayout()) 803ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch last_icon_position += button_size; 8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int reserved_icon_space = available_size * kReservedNonPanelIconProportion; 8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (last_icon_position < reserved_icon_space) 8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) end_position = last_icon_position; 8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) end_position = std::max(end_position, reserved_icon_space); 8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bounds->overflow_bounds.set_size( 8111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) gfx::Size(layout_manager_->PrimaryAxisValue(w, width()), 8121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->PrimaryAxisValue(height(), h))); 8134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 8144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (ash::switches::UseAlternateShelfLayout()) { 815ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch last_visible_index_ = DetermineLastVisibleIndex( 816ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch end_position - button_size); 8174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 818ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch last_visible_index_ = DetermineLastVisibleIndex( 819ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch end_position - inset - 2 * button_size); 8204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_hidden_index_ = DetermineFirstVisiblePanelIndex(end_position) - 1; 822ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bool show_overflow = 823ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ((ash::switches::UseAlternateShelfLayout() ? 0 : 1) + 824ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch last_visible_index_ < last_button_index || 825ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch last_hidden_index_ >= first_panel_index); 826ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 827ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Create Space for the overflow button 828ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (show_overflow && ash::switches::UseAlternateShelfLayout() && 82958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) last_visible_index_ > 0 && last_visible_index_ < last_button_index) 830ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch --last_visible_index_; 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < view_model_->view_size(); ++i) { 832ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bool visible = i <= last_visible_index_ || i > last_hidden_index_; 833ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Always show the app list. 834ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!ash::switches::UseAlternateShelfLayout()) 835ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch visible |= (i == last_button_index); 8364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // To receive drag event continously from |drag_view_| during the dragging 8374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // off from the shelf, don't make |drag_view_| invisible. It will be 8384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // eventually invisible and removed from the |view_model_| by 8394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // FinalizeRipOffDrag(). 8404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (dragged_off_shelf_ && view_model_->view_at(i) == drag_view_) 8414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) continue; 842ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch view_model_->view_at(i)->SetVisible(visible); 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_button_->SetVisible(show_overflow); 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (show_overflow) { 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(0, view_model_->view_size()); 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_visible_index_ == -1) { 8491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) x = layout_manager_->SelectValueForShelfAlignment(inset, 0, 0, inset); 8501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) y = layout_manager_->SelectValueForShelfAlignment(0, inset, inset, 0); 85158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else if (last_visible_index_ == last_button_index 85258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) && !ash::switches::UseAlternateShelfLayout()) { 8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) x = view_model_->ideal_bounds(last_visible_index_).x(); 8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) y = view_model_->ideal_bounds(last_visible_index_).y(); 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) x = layout_manager_->PrimaryAxisValue( 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->ideal_bounds(last_visible_index_).right(), 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->ideal_bounds(last_visible_index_).x()); 8591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) y = layout_manager_->PrimaryAxisValue( 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->ideal_bounds(last_visible_index_).y(), 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->ideal_bounds(last_visible_index_).bottom()); 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Set all hidden panel icon positions to be on the overflow button. 8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = first_panel_index; i <= last_hidden_index_; ++i) 8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view_model_->set_ideal_bounds(i, gfx::Rect(x, y, w, h)); 8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Add more space between last visible item and overflow button. 8681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Without this, two buttons look too close compared with other items. 8691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (ash::switches::UseAlternateShelfLayout()) { 8701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) x = layout_manager_->PrimaryAxisValue(x + button_spacing, x); 8711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) y = layout_manager_->PrimaryAxisValue(y, y + button_spacing); 8721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 8731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 874ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bounds->overflow_bounds.set_x(x); 875ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bounds->overflow_bounds.set_y(y); 876ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!ash::switches::UseAlternateShelfLayout()) { 877ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Position app list after overflow button. 878ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch gfx::Rect app_list_bounds = view_model_->ideal_bounds(last_button_index); 879ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 8801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) x = layout_manager_->PrimaryAxisValue(x + w + button_spacing, x); 8811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) y = layout_manager_->PrimaryAxisValue(y, y + h + button_spacing); 882ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch app_list_bounds.set_x(x); 883ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch app_list_bounds.set_y(y); 884ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch view_model_->set_ideal_bounds(last_button_index, app_list_bounds); 885ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (overflow_bubble_.get() && overflow_bubble_->IsShowing()) 8878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) UpdateOverflowRange(overflow_bubble_->shelf_view()); 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (overflow_bubble_) 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_bubble_->Hide(); 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int ShelfView::DetermineLastVisibleIndex(int max_value) const { 8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int index = model_->FirstPanelIndex() - 1; 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (index >= 0 && 8971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->PrimaryAxisValue( 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->ideal_bounds(index).right(), 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->ideal_bounds(index).bottom()) > max_value) { 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index--; 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return index; 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int ShelfView::DetermineFirstVisiblePanelIndex(int min_value) const { 9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int index = model_->FirstPanelIndex(); 9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (index < view_model_->view_size() && 9081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->PrimaryAxisValue( 9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view_model_->ideal_bounds(index).right(), 9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view_model_->ideal_bounds(index).bottom()) < min_value) { 9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++index; 9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return index; 9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ShelfView::AddIconObserver(ShelfIconObserver* observer) { 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_.AddObserver(observer); 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ShelfView::RemoveIconObserver(ShelfIconObserver* observer) { 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_.RemoveObserver(observer); 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::AnimateToIdealBounds() { 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IdealBounds ideal_bounds; 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CalculateIdealBounds(&ideal_bounds); 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < view_model_->view_size(); ++i) { 9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) View* view = view_model_->view_at(i); 9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bounds_animator_->AnimateViewTo(view, view_model_->ideal_bounds(i)); 9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Now that the item animation starts, we have to make sure that the 9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // padding of the first gets properly transferred to the new first item. 9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (i && view->border()) 9335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) view->SetBorder(views::Border::NullBorder()); 9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (!i && !view->border()) 9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateFirstButtonPadding(); 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_button_->SetBoundsRect(ideal_bounds.overflow_bounds); 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)views::View* ShelfView::CreateViewForItem(const ShelfItem& item) { 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* view = NULL; 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (item.type) { 94390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case TYPE_BROWSER_SHORTCUT: 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_APP_SHORTCUT: 9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case TYPE_WINDOWED_APP: 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_PLATFORM_APP: 9475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case TYPE_DIALOG: 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_APP_PANEL: { 949f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ShelfButton* button = ShelfButton::Create(this, this, layout_manager_); 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->SetImage(item.image); 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReflectItemStatus(item, button); 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view = button; 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_APP_LIST: { 957eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (ash::switches::UseAlternateShelfLayout()) { 9581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) view = new AlternateAppListButton(this, 9591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) this, 9601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->shelf_widget()); 961eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else { 962f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(dave): turn this into a ShelfButton too. 963eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AppListButton* button = new AppListButton(this, this); 964eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch button->SetImageAlignment( 9651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->SelectValueForShelfAlignment( 966eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::ImageButton::ALIGN_CENTER, 967eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::ImageButton::ALIGN_LEFT, 968eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::ImageButton::ALIGN_RIGHT, 969eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::ImageButton::ALIGN_CENTER), 9701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->SelectValueForShelfAlignment( 971eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::ImageButton::ALIGN_TOP, 972eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::ImageButton::ALIGN_MIDDLE, 973eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::ImageButton::ALIGN_MIDDLE, 974eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::ImageButton::ALIGN_BOTTOM)); 975eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch view = button; 976eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view->set_context_menu_controller(this); 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(view); 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConfigureChildView(view); 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return view; 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::FadeIn(views::View* view) { 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view->SetVisible(true); 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view->layer()->SetOpacity(0); 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AnimateToIdealBounds(); 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_animator_->SetAnimationDelegate( 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view, new FadeInAnimationDelegate(view), true); 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::PrepareForDrag(Pointer pointer, const ui::LocatedEvent& event) { 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!dragging()); 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(drag_view_); 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_pointer_ = pointer; 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_drag_index_ = view_model_->GetIndexOfView(drag_view_); 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1004424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (start_drag_index_== -1) { 1005424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) CancelDrag(-1); 1006424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 1007424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1008424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the item is no longer draggable, bail out. 1010a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ShelfItemDelegate* item_delegate = item_manager_->GetShelfItemDelegate( 10114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) model_->items()[start_drag_index_].id); 10124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!item_delegate->IsDraggable()) { 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelDrag(-1); 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Move the view to the front so that it appears on top of other views. 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReorderChildView(drag_view_, -1); 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_animator_->StopAnimatingView(drag_view_); 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::ContinueDrag(const ui::LocatedEvent& event) { 1023424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Due to a syncing operation the application might have been removed. 1024424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Bail if it is gone. 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int current_index = view_model_->GetIndexOfView(drag_view_); 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(-1, current_index); 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1028a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ShelfItemDelegate* item_delegate = item_manager_->GetShelfItemDelegate( 10294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) model_->items()[current_index].id); 10304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!item_delegate->IsDraggable()) { 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelDrag(-1); 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // If this is not a drag and drop host operation and not the app list item, 1036424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // check if the item got ripped off the shelf - if it did we are done. 1037a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!drag_and_drop_shelf_id_ && 1038424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) RemovableByRipOff(current_index) != NOT_REMOVABLE) { 1039424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (HandleRipOffDrag(event)) 1040424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 1041424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // The rip off handler could have changed the location of the item. 1042424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) current_index = view_model_->GetIndexOfView(drag_view_); 1043424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1044424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 1045424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // TODO: I don't think this works correctly with RTL. 1046424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) gfx::Point drag_point(event.location()); 1047f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ConvertPointToTarget(drag_view_, this, &drag_point); 1048424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Constrain the location to the range of valid indices for the type. 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::pair<int, int> indices(GetDragRange(current_index)); 10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int first_drag_index = indices.first; 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int last_drag_index = indices.second; 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the last index isn't valid, we're overflowing. Constrain to the app list 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (which is the last visible item). 10552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (first_drag_index < model_->FirstPanelIndex() && 10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_drag_index > last_visible_index_) 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_drag_index = last_visible_index_; 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x = 0, y = 0; 10591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (layout_manager_->IsHorizontalAlignment()) { 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x = std::max(view_model_->ideal_bounds(indices.first).x(), 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_point.x() - drag_offset_); 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x = std::min(view_model_->ideal_bounds(last_drag_index).right() - 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->ideal_bounds(current_index).width(), 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x); 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (drag_view_->x() == x) 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_view_->SetX(x); 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) y = std::max(view_model_->ideal_bounds(indices.first).y(), 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_point.y() - drag_offset_); 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) y = std::min(view_model_->ideal_bounds(last_drag_index).bottom() - 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->ideal_bounds(current_index).height(), 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) y); 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (drag_view_->y() == y) 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_view_->SetY(y); 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int target_index = 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::ViewModelUtils::DetermineMoveIndex( 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *view_model_, drag_view_, 10821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->IsHorizontalAlignment() ? 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::ViewModelUtils::HORIZONTAL : 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::ViewModelUtils::VERTICAL, 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x, y); 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_index = 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::min(indices.second, std::max(target_index, indices.first)); 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target_index == current_index) 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Change the model, the ShelfItemMoved() callback will handle the 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |view_model_| update. 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->Move(current_index, target_index); 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_animator_->StopAnimatingView(drag_view_); 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool ShelfView::HandleRipOffDrag(const ui::LocatedEvent& event) { 1098424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int current_index = view_model_->GetIndexOfView(drag_view_); 1099424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK_NE(-1, current_index); 1100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::string dragged_app_id = 11015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delegate_->GetAppIDForShelfID(model_->items()[current_index].id); 1102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Point screen_location = event.root_location(); 1104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::wm::ConvertPointToScreen(GetWidget()->GetNativeWindow()->GetRootWindow(), 1105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &screen_location); 1106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1107424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // To avoid ugly forwards and backwards flipping we use different constants 1108424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // for ripping off / re-inserting the items. 1109424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (dragged_off_shelf_) { 1110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // If the shelf/overflow bubble bounds contains |screen_location| we insert 1111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // the item back into the shelf. 1112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (GetBoundsForDragInsertInScreen().Contains(screen_location)) { 1113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (dragged_off_from_overflow_to_shelf_) { 1114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // During the dragging an item from Shelf to Overflow, it can enter here 1115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // directly because both are located very closly. 1116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) main_shelf_->EndDrag(true); 1117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Stops the animation of |drag_view_| and sets its bounds explicitly 1118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // becase ContinueDrag() stops its animation. Without this, unexpected 1119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // bounds will be set. 1120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bounds_animator_->StopAnimatingView(drag_view_); 1121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int drag_view_index = view_model_->GetIndexOfView(drag_view_); 1122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) drag_view_->SetBoundsRect(view_model_->ideal_bounds(drag_view_index)); 1123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) dragged_off_from_overflow_to_shelf_ = false; 1124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 1125424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Destroy our proxy view item. 1126424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DestroyDragIconProxy(); 1127424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Re-insert the item and return simply false since the caller will handle 1128424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // the move as in any normal case. 1129424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) dragged_off_shelf_ = false; 1130424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) drag_view_->layer()->SetOpacity(1.0f); 1131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // The size of Overflow bubble should be updated immediately when an item 1132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // is re-inserted. 1133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (is_overflow_mode()) 1134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PreferredSizeChanged(); 1135424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 1136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else if (is_overflow_mode() && 1137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) main_shelf_->GetBoundsForDragInsertInScreen().Contains( 1138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) screen_location)) { 1139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!dragged_off_from_overflow_to_shelf_) { 1140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) dragged_off_from_overflow_to_shelf_ = true; 1141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) drag_image_->SetOpacity(1.0f); 1142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) main_shelf_->StartDrag(dragged_app_id, screen_location); 1143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else { 1144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) main_shelf_->Drag(screen_location); 1145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 1146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else if (dragged_off_from_overflow_to_shelf_) { 1147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Makes the |drag_image_| partially disappear again. 1148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) dragged_off_from_overflow_to_shelf_ = false; 1149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) drag_image_->SetOpacity(kDraggedImageOpacity); 1150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) main_shelf_->EndDrag(true); 1151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bounds_animator_->StopAnimatingView(drag_view_); 1152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int drag_view_index = view_model_->GetIndexOfView(drag_view_); 1153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) drag_view_->SetBoundsRect(view_model_->ideal_bounds(drag_view_index)); 1154424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1155424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Move our proxy view item. 1156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UpdateDragIconProxy(screen_location); 1157424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 1158424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1159424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Check if we are too far away from the shelf to enter the ripped off state. 1160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Determine the distance to the shelf. 11615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int delta = CalculateShelfDistance(screen_location); 1162424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (delta > kRipOffDistance) { 1163424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Create a proxy view item which can be moved anywhere. 1164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ShelfButton* button = static_cast<ShelfButton*>(drag_view_); 1165424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) CreateDragIconProxy(event.root_location(), 1166424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) button->GetImage(), 1167424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) drag_view_, 1168424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) gfx::Vector2d(0, 0), 1169424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) kDragAndDropProxyScale); 1170424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) drag_view_->layer()->SetOpacity(0.0f); 11714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) dragged_off_shelf_ = true; 1172424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (RemovableByRipOff(current_index) == REMOVABLE) { 11731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Move the item to the front of the first panel item and hide it. 11745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // ShelfItemMoved() callback will handle the |view_model_| update and 11751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // call AnimateToIdealBounds(). 1176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (current_index != model_->FirstPanelIndex() - 1) { 1177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) model_->Move(current_index, model_->FirstPanelIndex() - 1); 1178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) StartFadeInLastVisibleItem(); 1179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else if (is_overflow_mode()) { 1180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Overflow bubble should be shrunk when an item is ripped off. 1181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PreferredSizeChanged(); 1182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1183424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Make the item partially disappear to show that it will get removed if 1184424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // dropped. 1185a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) drag_image_->SetOpacity(kDraggedImageOpacity); 1186424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1187424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 1188424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1189424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 1190424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 1191424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 11928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::FinalizeRipOffDrag(bool cancel) { 1193424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!dragged_off_shelf_) 1194424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 1195424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Make sure we do not come in here again. 1196424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) dragged_off_shelf_ = false; 1197424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 1198424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Coming here we should always have a |drag_view_|. 1199424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(drag_view_); 1200424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int current_index = view_model_->GetIndexOfView(drag_view_); 1201424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // If the view isn't part of the model anymore (|current_index| == -1), a sync 1202424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // operation must have removed it. In that case we shouldn't change the model 1203424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // and only delete the proxy image. 1204424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (current_index == -1) { 1205424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DestroyDragIconProxy(); 1206424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 1207424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1208424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 1209424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Set to true when the animation should snap back to where it was before. 1210424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bool snap_back = false; 1211424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Items which cannot be dragged off will be handled as a cancel. 1212424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!cancel) { 1213a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (dragged_off_from_overflow_to_shelf_) { 1214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) dragged_off_from_overflow_to_shelf_ = false; 1215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) main_shelf_->EndDrag(false); 1216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) drag_view_->layer()->SetOpacity(1.0f); 1217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else if (RemovableByRipOff(current_index) != REMOVABLE) { 1218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Make sure we do not try to remove un-removable items like items which 1219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // were not pinned or have to be always there. 1220424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cancel = true; 1221424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) snap_back = true; 1222424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else { 1223424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Make sure the item stays invisible upon removal. 1224424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) drag_view_->SetVisible(false); 1225424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) std::string app_id = 12265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delegate_->GetAppIDForShelfID(model_->items()[current_index].id); 1227424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) delegate_->UnpinAppWithID(app_id); 1228424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1229424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1230424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (cancel || snap_back) { 1231a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (dragged_off_from_overflow_to_shelf_) { 1232a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) dragged_off_from_overflow_to_shelf_ = false; 1233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Main shelf handles revert of dragged item. 1234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) main_shelf_->EndDrag(true); 1235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) drag_view_->layer()->SetOpacity(1.0f); 1236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else if (!cancelling_drag_model_changed_) { 1237424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Only do something if the change did not come through a model change. 1238424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) gfx::Rect drag_bounds = drag_image_->GetBoundsInScreen(); 1239424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) gfx::Point relative_to = GetBoundsInScreen().origin(); 1240424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) gfx::Rect target( 1241424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) gfx::PointAtOffsetFromOrigin(drag_bounds.origin()- relative_to), 1242424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) drag_bounds.size()); 1243424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) drag_view_->SetBoundsRect(target); 1244424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Hide the status from the active item since we snap it back now. Upon 1245424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // animation end the flag gets cleared if |snap_back_from_rip_off_view_| 1246424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // is set. 1247424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) snap_back_from_rip_off_view_ = drag_view_; 1248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ShelfButton* button = static_cast<ShelfButton*>(drag_view_); 1249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->AddState(ShelfButton::STATE_HIDDEN); 1250424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // When a canceling drag model is happening, the view model is diverged 1251424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // from the menu model and movements / animations should not be done. 1252424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) model_->Move(current_index, start_drag_index_); 1253424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) AnimateToIdealBounds(); 1254424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1255424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) drag_view_->layer()->SetOpacity(1.0f); 1256424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1257424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DestroyDragIconProxy(); 1258424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 1259424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 12608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)ShelfView::RemovableState ShelfView::RemovableByRipOff(int index) { 1261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(index >= 0 && index < model_->item_count()); 12625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ShelfItemType type = model_->items()[index].type; 12635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (type == TYPE_APP_LIST || type == TYPE_DIALOG || !delegate_->CanPin()) 1264424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return NOT_REMOVABLE; 12655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string app_id = delegate_->GetAppIDForShelfID(model_->items()[index].id); 1267424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Note: Only pinned app shortcuts can be removed! 1268424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return (type == TYPE_APP_SHORTCUT && delegate_->IsAppPinned(app_id)) ? 1269424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) REMOVABLE : DRAGGABLE; 1270424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 1271424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 12725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ShelfView::SameDragType(ShelfItemType typea, ShelfItemType typeb) const { 1273ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch switch (typea) { 1274ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case TYPE_APP_SHORTCUT: 1275ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case TYPE_BROWSER_SHORTCUT: 1276ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return (typeb == TYPE_APP_SHORTCUT || typeb == TYPE_BROWSER_SHORTCUT); 127768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case TYPE_APP_LIST: 1278424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case TYPE_PLATFORM_APP: 1279ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case TYPE_WINDOWED_APP: 1280ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case TYPE_APP_PANEL: 12815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case TYPE_DIALOG: 1282ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return typeb == typea; 1283424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case TYPE_UNDEFINED: 12845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOTREACHED() << "ShelfItemType must be set."; 1285424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)std::pair<int, int> ShelfView::GetDragRange(int index) { 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int min_index = -1; 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_index = -1; 12945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ShelfItemType type = model_->items()[index].type; 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < model_->item_count(); ++i) { 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SameDragType(model_->items()[i].type, type)) { 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (min_index == -1) 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min_index = i; 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_index = i; 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::pair<int, int>(min_index, max_index); 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::ConfigureChildView(views::View* view) { 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view->SetPaintToLayer(true); 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view->layer()->SetFillsBoundsOpaquely(false); 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::ToggleOverflowBubble() { 13112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (IsShowingOverflowBubble()) { 13122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overflow_bubble_->Hide(); 13132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 13142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!overflow_bubble_) 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_bubble_.reset(new OverflowBubble()); 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ShelfView* overflow_view = 13201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) new ShelfView(model_, delegate_, layout_manager_); 1321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) overflow_view->overflow_mode_ = true; 13222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overflow_view->Init(); 13234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) overflow_view->set_owner_overflow_bubble(overflow_bubble_.get()); 13242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overflow_view->OnShelfAlignmentChanged(); 1325a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) overflow_view->main_shelf_ = this; 13262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateOverflowRange(overflow_view); 13272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overflow_bubble_->Show(overflow_button_, overflow_view); 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shell::GetInstance()->UpdateShelfVisibility(); 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::UpdateFirstButtonPadding() { 1334ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (ash::switches::UseAlternateShelfLayout()) 1335ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 1336ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 13375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Creates an empty border for first shelf button to make included leading 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // inset act as the button's padding. This is only needed on button creation 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and when shelf alignment changes. 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view_model_->view_size() > 0) { 13415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) view_model_->view_at(0)->SetBorder(views::Border::CreateEmptyBorder( 13421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->PrimaryAxisValue(0, leading_inset_), 13431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) layout_manager_->PrimaryAxisValue(leading_inset_, 0), 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0)); 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::OnFadeOutAnimationEnded() { 13502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AnimateToIdealBounds(); 13511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) StartFadeInLastVisibleItem(); 13521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 13532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ShelfView::StartFadeInLastVisibleItem() { 13552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If overflow button is visible and there is a valid new last item, fading 13562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the new last item in after sliding animation is finished. 13572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (overflow_button_->visible() && last_visible_index_ >= 0) { 13582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::View* last_visible_view = view_model_->view_at(last_visible_index_); 13592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_visible_view->layer()->SetOpacity(0); 13602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bounds_animator_->SetAnimationDelegate( 13612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_visible_view, 13628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) new ShelfView::StartFadeAnimationDelegate(this, last_visible_view), 13632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) true); 13642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 13652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 13662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::UpdateOverflowRange(ShelfView* overflow_view) { 13682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int first_overflow_index = last_visible_index_ + 1; 13692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int last_overflow_index = last_hidden_index_; 13702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_LE(first_overflow_index, last_overflow_index); 13712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_LT(last_overflow_index, view_model_->view_size()); 13722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overflow_view->first_visible_index_ = first_overflow_index; 13742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overflow_view->last_visible_index_ = last_overflow_index; 13752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 13762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)int ShelfView::GetButtonSize() const { 1378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return ash::switches::UseAlternateShelfLayout() ? 13795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kButtonSize : kShelfPreferredSize; 1380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 1381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)int ShelfView::GetButtonSpacing() const { 1383f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return ash::switches::UseAlternateShelfLayout() ? 1384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) kAlternateButtonSpacing : kButtonSpacing; 1385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 1386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 13878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool ShelfView::ShouldHideTooltip(const gfx::Point& cursor_location) { 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect active_bounds; 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < child_count(); ++i) { 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* child = child_at(i); 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (child == overflow_button_) 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 13942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!ShouldShowTooltipForView(child)) 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect child_bounds = child->GetMirroredBounds(); 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_bounds.Union(child_bounds); 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !active_bounds.Contains(cursor_location); 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)gfx::Rect ShelfView::GetVisibleItemsBoundsInScreen() { 14054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) gfx::Size preferred_size = GetPreferredSize(); 14064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) gfx::Point origin(GetMirroredXWithWidthInView(0, preferred_size.width()), 0); 14074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ConvertPointToScreen(this, &origin); 14084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return gfx::Rect(origin, preferred_size); 14094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 14104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)gfx::Rect ShelfView::GetBoundsForDragInsertInScreen() { 1412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Size preferred_size; 1413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (is_overflow_mode()) { 1414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(owner_overflow_bubble_); 1415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Rect bubble_bounds = 1416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) owner_overflow_bubble_->bubble_view()->GetBubbleBounds(); 1417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) preferred_size = bubble_bounds.size(); 1418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 1419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const int preferred_shelf_size = layout_manager_->GetPreferredShelfSize(); 1420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const int last_button_index = view_model_->view_size() - 1; 1422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Rect last_button_bounds = 1423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) view_model_->view_at(last_button_index)->bounds(); 1424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (overflow_button_->visible() && 1425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) model_->GetItemIndexForType(TYPE_APP_PANEL) == -1) { 1426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // When overflow button is visible and shelf has no panel items, 1427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // last_button_bounds should be overflow button's bounds. 1428f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) last_button_bounds = overflow_button_->bounds(); 1429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (layout_manager_->IsHorizontalAlignment()) { 1432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) preferred_size = gfx::Size(last_button_bounds.right() + leading_inset_, 1433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) preferred_shelf_size); 1434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 1435f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) preferred_size = gfx::Size(preferred_shelf_size, 1436f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) last_button_bounds.bottom() + leading_inset_); 1437f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1438f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1439f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Point origin(GetMirroredXWithWidthInView(0, preferred_size.width()), 0); 1440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1441f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // In overflow mode, we should use OverflowBubbleView as a source for 1442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // converting |origin| to screen coordinates. When a scroll operation is 1443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // occurred in OverflowBubble, the bounds of ShelfView in OverflowBubble can 1444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // be changed. 1445f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (is_overflow_mode()) 1446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ConvertPointToScreen(owner_overflow_bubble_->bubble_view(), &origin); 1447f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) else 1448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ConvertPointToScreen(this, &origin); 1449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return gfx::Rect(origin, preferred_size); 1451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 1452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 14538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int ShelfView::CancelDrag(int modified_index) { 1454424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FinalizeRipOffDrag(true); 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!drag_view_) 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return modified_index; 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool was_dragging = dragging(); 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int drag_view_index = view_model_->GetIndexOfView(drag_view_); 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_pointer_ = NONE; 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_view_ = NULL; 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (drag_view_index == modified_index) { 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The view that was being dragged is being modified. Don't do anything. 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return modified_index; 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!was_dragging) 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return modified_index; 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Restore previous position, tracking the position of the modified view. 14692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool at_end = modified_index == view_model_->view_size(); 14702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::View* modified_view = 14712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (modified_index >= 0 && !at_end) ? 14722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view_model_->view_at(modified_index) : NULL; 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->Move(drag_view_index, start_drag_index_); 14742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the modified view will be at the end of the list, return the new end of 14762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the list. 14772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (at_end) 14782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return view_model_->view_size(); 14792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return modified_view ? view_model_->GetIndexOfView(modified_view) : -1; 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)gfx::Size ShelfView::GetPreferredSize() { 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IdealBounds ideal_bounds; 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CalculateIdealBounds(&ideal_bounds); 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const int preferred_size = layout_manager_->GetPreferredShelfSize(); 14874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1488f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int last_button_index = is_overflow_mode() ? 1489f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) last_visible_index_ : view_model_->view_size() - 1; 1490f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1491f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // When an item is dragged off from the overflow bubble, it is moved to last 1492f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // position and and changed to invisible. Overflow bubble size should be 1493f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // shrunk to fit only for visible items. 1494a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // If |dragged_off_from_overflow_to_shelf_| is set, there will be no invisible 1495a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // items in the shelf. 1496a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (is_overflow_mode() && 1497a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) dragged_off_shelf_ && 1498a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) !dragged_off_from_overflow_to_shelf_ && 1499f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RemovableByRipOff(view_model_->GetIndexOfView(drag_view_)) == REMOVABLE) 1500f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) last_button_index--; 1501f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect last_button_bounds = 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_button_index >= first_visible_index_ ? 1504f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) view_model_->ideal_bounds(last_button_index) : 15054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) gfx::Rect(gfx::Size(preferred_size, preferred_size)); 15062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 15071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (layout_manager_->IsHorizontalAlignment()) { 15081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return gfx::Size(last_button_bounds.right() + leading_inset_, 15094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) preferred_size); 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return gfx::Size(preferred_size, 15131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) last_button_bounds.bottom() + leading_inset_); 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::OnBoundsChanged(const gfx::Rect& previous_bounds) { 15175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This bounds change is produced by the shelf movement and all content has 15185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // to follow. Using an animation at that time would produce a time lag since 15195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the animation of the BoundsAnimator has itself a delay before it arrives 15205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // at the required location. As such we tell the animator to go there 15215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // immediately. 15225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BoundsAnimatorDisabler disabler(bounds_animator_.get()); 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LayoutToIdealBounds(); 15241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) FOR_EACH_OBSERVER(ShelfIconObserver, observers_, 15251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OnShelfIconPositionsChanged()); 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsShowingOverflowBubble()) 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_bubble_->Hide(); 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)views::FocusTraversable* ShelfView::GetPaneFocusTraversable() { 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this; 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ShelfView::GetAccessibleState(ui::AXViewState* state) { 1536a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) state->role = ui::AX_ROLE_TOOLBAR; 15372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch state->name = l10n_util::GetStringUTF16(IDS_ASH_SHELF_ACCESSIBLE_NAME); 153890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 153990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 15408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::OnGestureEvent(ui::GestureEvent* event) { 15412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (gesture_handler_.ProcessGestureEvent(*event)) 15422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event->StopPropagation(); 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ShelfView::ShelfItemAdded(int model_index) { 15462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 15472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AutoReset<bool> cancelling_drag( 15482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &cancelling_drag_model_changed_, true); 15492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model_index = CancelDrag(model_index); 15502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* view = CreateViewForItem(model_->items()[model_index]); 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildView(view); 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hide the view, it'll be made visible when the animation is done. Using 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // opacity 0 here to avoid messing with CalculateIdealBounds which touches 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the view's visibility. 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view->layer()->SetOpacity(0); 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->Add(view, model_index); 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Give the button its ideal bounds. That way if we end up animating the 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // button before this animation completes it doesn't appear at some random 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // spot (because it was in the middle of animating from 0,0 0x0 to its 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // target). 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IdealBounds ideal_bounds; 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CalculateIdealBounds(&ideal_bounds); 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view->SetBoundsRect(view_model_->ideal_bounds(model_index)); 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The first animation moves all the views to their target position. |view| 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is hidden, so it visually appears as though we are providing space for 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it. When done we'll fade the view in. 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AnimateToIdealBounds(); 15712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (model_index <= last_visible_index_ || 15722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model_index >= model_->FirstPanelIndex()) { 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_animator_->SetAnimationDelegate( 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view, new StartFadeAnimationDelegate(this, view), true); 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Undo the hiding if animation does not run. 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view->layer()->SetOpacity(1.0f); 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ShelfView::ShelfItemRemoved(int model_index, ShelfID id) { 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (id == context_menu_id_) 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) launcher_menu_runner_.reset(); 15842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 15852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AutoReset<bool> cancelling_drag( 15862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &cancelling_drag_model_changed_, true); 15872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model_index = CancelDrag(model_index); 15882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* view = view_model_->view_at(model_index); 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->Remove(model_index); 15910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 15920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // When the overflow bubble is visible, the overflow range needs to be set 15930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // before CalculateIdealBounds() gets called. Otherwise CalculateIdealBounds() 15945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // could trigger a ShelfItemChanged() by hiding the overflow bubble and 1595f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // since the overflow bubble is not yet synced with the ShelfModel this 15960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // could cause a crash. 15972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (overflow_bubble_ && overflow_bubble_->IsShowing()) { 15982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_hidden_index_ = std::min(last_hidden_index_, 15992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view_model_->view_size() - 1); 16008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) UpdateOverflowRange(overflow_bubble_->shelf_view()); 16012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1602d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 16030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (view->visible()) { 16040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // The first animation fades out the view. When done we'll animate the rest 16050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // of the views to their target location. 16060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) bounds_animator_->AnimateViewTo(view, view->bounds()); 16070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) bounds_animator_->SetAnimationDelegate( 16080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) view, new FadeOutAnimationDelegate(this, view), true); 16090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } else { 16100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // We don't need to show a fade out animation for invisible |view|. When an 16110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // item is ripped out from the shelf, its |view| is already invisible. 16120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) AnimateToIdealBounds(); 16130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 16140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1615d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Close the tooltip because it isn't needed any longer and its anchor view 1616d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // will be deleted soon. 1617d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (tooltip_->GetCurrentAnchorView() == view) 1618d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) tooltip_->Close(); 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ShelfView::ShelfItemChanged(int model_index, const ShelfItem& old_item) { 16225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ShelfItem& item(model_->items()[model_index]); 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (old_item.type != item.type) { 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Type changed, swap the views. 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_index = CancelDrag(model_index); 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<views::View> old_view(view_model_->view_at(model_index)); 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_animator_->StopAnimatingView(old_view.get()); 16283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Removing and re-inserting a view in our view model will strip the ideal 16293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // bounds from the item. To avoid recalculation of everything the bounds 16303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // get remembered and restored after the insertion to the previous value. 16313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) gfx::Rect old_ideal_bounds = view_model_->ideal_bounds(model_index); 16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->Remove(model_index); 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* new_view = CreateViewForItem(item); 16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildView(new_view); 16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->Add(new_view, model_index); 16363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) view_model_->set_ideal_bounds(model_index, old_ideal_bounds); 16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_view->SetBoundsRect(old_view->bounds()); 16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* view = view_model_->view_at(model_index); 16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (item.type) { 16432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case TYPE_BROWSER_SHORTCUT: 1644f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Fallthrough for the new Shelf since it needs to show the activation 16452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // change as well. 16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_APP_SHORTCUT: 16472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case TYPE_WINDOWED_APP: 16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_PLATFORM_APP: 16495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case TYPE_DIALOG: 16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_APP_PANEL: { 1651f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ShelfButton* button = static_cast<ShelfButton*>(view); 16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReflectItemStatus(item, button); 16532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The browser shortcut is currently not a "real" item and as such the 16542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the image is bogous as well. We therefore keep the image as is for it. 16552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (item.type != TYPE_BROWSER_SHORTCUT) 16562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) button->SetImage(item.image); 16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->SchedulePaint(); 16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1666f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ShelfView::ShelfItemMoved(int start_index, int target_index) { 16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_model_->Move(start_index, target_index); 16685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // When cancelling a drag due to a shelf item being added, the currently 16692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // dragged item is moved back to its initial position. AnimateToIdealBounds 16702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // will be called again when the new item is added to the |view_model_| but 16712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // at this time the |view_model_| is inconsistent with the |model_|. 16722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!cancelling_drag_model_changed_) 16732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AnimateToIdealBounds(); 16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1676f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ShelfView::ShelfStatusChanged() { 1677eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (ash::switches::UseAlternateShelfLayout()) 1678eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppListButton* app_list_button = 16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<AppListButton*>(GetAppListButtonView()); 1681f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (model_->status() == ShelfModel::STATUS_LOADING) 16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) app_list_button->StartLoadingAnimation(); 16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) app_list_button->StopLoadingAnimation(); 16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::PointerPressedOnButton(views::View* view, 16888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Pointer pointer, 16898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const ui::LocatedEvent& event) { 16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (drag_view_) 16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = view_model_->GetIndexOfView(view); 1694424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (index == -1) 1695424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 1696424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 1697a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ShelfItemDelegate* item_delegate = item_manager_->GetShelfItemDelegate( 16984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) model_->items()[index].id); 16994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (view_model_->view_size() <= 1 || !item_delegate->IsDraggable()) 17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // View is being deleted or not draggable, ignore request. 17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_view_ = view; 17031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) drag_offset_ = layout_manager_->PrimaryAxisValue(event.x(), event.y()); 1704f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Ash.ShelfAlignmentUsage", 1705f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) layout_manager_->SelectValueForShelfAlignment( 1706f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SHELF_ALIGNMENT_UMA_ENUM_VALUE_BOTTOM, 1707f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SHELF_ALIGNMENT_UMA_ENUM_VALUE_LEFT, 1708f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SHELF_ALIGNMENT_UMA_ENUM_VALUE_RIGHT, 1709f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) -1), 1710f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SHELF_ALIGNMENT_UMA_ENUM_VALUE_COUNT); 17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::PointerDraggedOnButton(views::View* view, 17148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Pointer pointer, 17158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const ui::LocatedEvent& event) { 17160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // To prepare all drag types (moving an item in the shelf and dragging off), 17170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // we should check the x-axis and y-axis offset. 17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!dragging() && drag_view_ && 17190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ((abs(event.x() - drag_offset_) >= kMinimumDragDistance) || 17200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) (abs(event.y() - drag_offset_) >= kMinimumDragDistance))) { 17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrepareForDrag(pointer, event); 17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (drag_pointer_ == pointer) 17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContinueDrag(event); 17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::PointerReleasedOnButton(views::View* view, 17288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Pointer pointer, 17298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) bool canceled) { 17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (canceled) { 17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelDrag(-1); 17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (drag_pointer_ == pointer) { 1733424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FinalizeRipOffDrag(false); 17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_pointer_ = NONE; 17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AnimateToIdealBounds(); 17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1737ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // If the drag pointer is NONE, no drag operation is going on and the 1738ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // drag_view can be released. 1739ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (drag_pointer_ == NONE) 1740ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch drag_view_ = NULL; 17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::MouseMovedOverButton(views::View* view) { 17442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!ShouldShowTooltipForView(view)) 17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!tooltip_->IsVisible()) 17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tooltip_->ResetTimer(); 17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::MouseEnteredButton(views::View* view) { 17522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!ShouldShowTooltipForView(view)) 17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tooltip_->IsVisible()) { 17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tooltip_->ShowImmediately(view, GetAccessibleName(view)); 17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tooltip_->ShowDelayed(view, GetAccessibleName(view)); 17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::MouseExitedButton(views::View* view) { 17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!tooltip_->IsVisible()) 17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tooltip_->StopTimer(); 17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)base::string16 ShelfView::GetAccessibleName(const views::View* view) { 17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int view_index = view_model_->GetIndexOfView(view); 17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // May be -1 while in the process of animating closed. 17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view_index == -1) 1771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return base::string16(); 17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1773a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ShelfItemDelegate* item_delegate = item_manager_->GetShelfItemDelegate( 17744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) model_->items()[view_index].id); 17754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return item_delegate->GetTitle(); 17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::ButtonPressed(views::Button* sender, const ui::Event& event) { 17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do not handle mouse release during drag. 17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dragging()) 17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sender == overflow_button_) { 17842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ToggleOverflowBubble(); 17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int view_index = view_model_->GetIndexOfView(sender); 17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // May be -1 while in the process of animating closed. 17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view_index == -1) 17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the previous menu was closed by the same event as this one, we ignore 17942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the call. 17952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!IsUsableEvent(event)) 17962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 17972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 1799a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedTargetRootWindow scoped_target( 1800a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) sender->GetWidget()->GetNativeView()->GetRootWindow()); 18012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Slow down activation animations if shift key is pressed. 18022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ui::ScopedAnimationDurationScaleMode> slowing_animations; 18032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (event.IsShiftDown()) { 18042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) slowing_animations.reset(new ui::ScopedAnimationDurationScaleMode( 18052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::ScopedAnimationDurationScaleMode::SLOW_DURATION)); 18062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 18072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1808b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Collect usage statistics before we decide what to do with the click. 1809b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) switch (model_->items()[view_index].type) { 1810b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) case TYPE_APP_SHORTCUT: 1811b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) case TYPE_WINDOWED_APP: 1812b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) case TYPE_PLATFORM_APP: 181390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case TYPE_BROWSER_SHORTCUT: 18145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Shell::GetInstance()->metrics()->RecordUserMetricsAction( 1815b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) UMA_LAUNCHER_CLICK_ON_APP); 1816b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) break; 18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1818b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) case TYPE_APP_LIST: 18195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Shell::GetInstance()->metrics()->RecordUserMetricsAction( 1820b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) UMA_LAUNCHER_CLICK_ON_APPLIST_BUTTON); 1821424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 1822424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 1823424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case TYPE_APP_PANEL: 18245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case TYPE_DIALOG: 1825424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 1826424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 1827424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case TYPE_UNDEFINED: 18285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOTREACHED() << "ShelfItemType must be set."; 1829b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) break; 18302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1831424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 1832a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ShelfItemDelegate* item_delegate = 1833a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) item_manager_->GetShelfItemDelegate(model_->items()[view_index].id); 1834f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!item_delegate->ItemSelected(event)) 1835f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ShowListMenuForView(model_->items()[view_index], sender, event); 18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 18382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ShelfView::ShowListMenuForView(const ShelfItem& item, 18408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) views::View* source, 18418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const ui::Event& event) { 1842a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<ShelfMenuModel> menu_model; 1843a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ShelfItemDelegate* item_delegate = 1844a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) item_manager_->GetShelfItemDelegate(item.id); 18454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) menu_model.reset(item_delegate->CreateApplicationMenu(event.flags())); 18462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make sure we have a menu and it has at least two items in addition to the 18482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // application title and the 3 spacing separators. 18492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!menu_model.get() || menu_model->GetItemCount() <= 5) 18502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 18512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ShowMenu(scoped_ptr<views::MenuModelAdapter>( 1853a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) new ShelfMenuModelAdapter(menu_model.get())), 18542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) source, 18552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Point(), 18567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) false, 18577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ui::GetMenuSourceTypeForEvent(event)); 18582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::ShowContextMenuForView(views::View* source, 18628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const gfx::Point& point, 18638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ui::MenuSourceType source_type) { 18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int view_index = view_model_->GetIndexOfView(source); 18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view_index == -1) { 18667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Shell::GetInstance()->ShowContextMenu(point, source_type); 18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1870424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<ui::MenuModel> menu_model; 1871a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ShelfItemDelegate* item_delegate = item_manager_->GetShelfItemDelegate( 18724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) model_->items()[view_index].id); 1873424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) menu_model.reset(item_delegate->CreateContextMenu( 18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source->GetWidget()->GetNativeView()->GetRootWindow())); 1875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!menu_model) 18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1877424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 18785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::AutoReset<ShelfID> reseter( 18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &context_menu_id_, 18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_index == -1 ? 0 : model_->items()[view_index].id); 18812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ShowMenu(scoped_ptr<views::MenuModelAdapter>( 18832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new views::MenuModelAdapter(menu_model.get())), 18842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) source, 18852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) point, 18867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) true, 18877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) source_type); 18882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 18892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::ShowMenu(scoped_ptr<views::MenuModelAdapter> menu_model_adapter, 18918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) views::View* source, 18928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const gfx::Point& click_point, 18938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) bool context_menu, 18948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ui::MenuSourceType source_type) { 18952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) closing_event_time_ = base::TimeDelta(); 18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) launcher_menu_runner_.reset( 18972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new views::MenuRunner(menu_model_adapter->CreateMenu())); 18982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1899a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedTargetRootWindow scoped_target( 1900a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) source->GetWidget()->GetNativeView()->GetRootWindow()); 1901a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 19022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Determine the menu alignment dependent on the shelf. 19032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::MenuItemView::AnchorPosition menu_alignment = 19042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::MenuItemView::TOPLEFT; 19052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect anchor_point = gfx::Rect(click_point, gfx::Size()); 19062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ShelfWidget* shelf = RootWindowController::ForShelf( 1908c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetWidget()->GetNativeView())->shelf(); 19092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!context_menu) { 19102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Application lists use a bubble. 19115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ShelfAlignment align = shelf->GetAlignment(); 19122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) anchor_point = source->GetBoundsInScreen(); 19132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // It is possible to invoke the menu while it is sliding into view. To cover 19157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // that case, the screen coordinates are offsetted by the animation delta. 19167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) gfx::Vector2d offset = 19177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) source->GetWidget()->GetNativeWindow()->bounds().origin() - 19187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) source->GetWidget()->GetNativeWindow()->GetTargetBounds().origin(); 19197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) anchor_point.set_x(anchor_point.x() - offset.x()); 19207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) anchor_point.set_y(anchor_point.y() - offset.y()); 19217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1922f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Shelf items can have an asymmetrical border for spacing reasons. 19232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Adjust anchor location for this. 19242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (source->border()) 19252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) anchor_point.Inset(source->border()->GetInsets()); 19262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (align) { 19285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case SHELF_ALIGNMENT_BOTTOM: 19292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) menu_alignment = views::MenuItemView::BUBBLE_ABOVE; 19302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 19315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case SHELF_ALIGNMENT_LEFT: 19322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) menu_alignment = views::MenuItemView::BUBBLE_RIGHT; 19332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 19345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case SHELF_ALIGNMENT_RIGHT: 19352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) menu_alignment = views::MenuItemView::BUBBLE_LEFT; 19362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 19375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case SHELF_ALIGNMENT_TOP: 19382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) menu_alignment = views::MenuItemView::BUBBLE_BELOW; 19392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 19402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 19412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 19425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If this gets deleted while we are in the menu, the shelf will be gone 1943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // as well. 1944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool got_deleted = false; 1945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) got_deleted_ = &got_deleted; 1946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shelf->ForceUndimming(true); 19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: if you convert to HAS_MNEMONICS be sure and update menu building 19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // code. 19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (launcher_menu_runner_->RunMenuAt( 19512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) source->GetWidget(), 19522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NULL, 19532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) anchor_point, 19542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) menu_alignment, 19557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) source_type, 19567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) context_menu ? views::MenuRunner::CONTEXT_MENU : 0) == 19577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) views::MenuRunner::MENU_DELETED) { 1958c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!got_deleted) { 1959c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) got_deleted_ = NULL; 1960c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shelf->ForceUndimming(false); 1961c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) got_deleted_ = NULL; 1965c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shelf->ForceUndimming(false); 19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // If it is a context menu and we are showing overflow bubble 19684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // we want to hide overflow bubble. 19694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (owner_overflow_bubble_) 19704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) owner_overflow_bubble_->HideBubbleAndRefreshButton(); 19714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 19722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Unpinning an item will reset the |launcher_menu_runner_| before coming 19732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // here. 1974c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (launcher_menu_runner_) 19752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) closing_event_time_ = launcher_menu_runner_->closing_event_time(); 19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shell::GetInstance()->UpdateShelfVisibility(); 19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::OnBoundsAnimatorProgressed(views::BoundsAnimator* animator) { 19801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) FOR_EACH_OBSERVER(ShelfIconObserver, observers_, 19811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OnShelfIconPositionsChanged()); 19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PreferredSizeChanged(); 19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ShelfView::OnBoundsAnimatorDone(views::BoundsAnimator* animator) { 1986424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (snap_back_from_rip_off_view_ && animator == bounds_animator_) { 1987424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!animator->IsAnimating(snap_back_from_rip_off_view_)) { 1988f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Coming here the animation of the ShelfButton is finished and the 1989424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // previously hidden status can be shown again. Since the button itself 1990424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // might have gone away or changed locations we check that the button 1991424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // is still in the shelf and show its status again. 1992424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (int index = 0; index < view_model_->view_size(); index++) { 1993424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) views::View* view = view_model_->view_at(index); 1994424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (view == snap_back_from_rip_off_view_) { 1995f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ShelfButton* button = static_cast<ShelfButton*>(view); 1996f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) button->ClearState(ShelfButton::STATE_HIDDEN); 1997424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 1998424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1999424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 2000424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) snap_back_from_rip_off_view_ = NULL; 2001424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 2002424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool ShelfView::IsUsableEvent(const ui::Event& event) { 20062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (closing_event_time_ == base::TimeDelta()) 20072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 20082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta delta = 20102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta(event.time_stamp() - closing_event_time_); 20112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) closing_event_time_ = base::TimeDelta(); 20122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(skuhne): This time seems excessive, but it appears that the reposting 20132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // takes that long. Need to come up with a better way of doing this. 20142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (delta.InMilliseconds() < 0 || delta.InMilliseconds() > 130); 20152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 20162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const ShelfItem* ShelfView::ShelfItemForView(const views::View* view) const { 20182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int view_index = view_model_->GetIndexOfView(view); 20192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (view_index == -1) 20202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 20212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return &(model_->items()[view_index]); 20222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 20232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool ShelfView::ShouldShowTooltipForView(const views::View* view) const { 20252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (view == GetAppListButtonView() && 20262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Shell::GetInstance()->GetAppListWindow()) 20272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 20285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ShelfItem* item = ShelfItemForView(view); 2029424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!item) 2030424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 2031a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ShelfItemDelegate* item_delegate = 2032a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) item_manager_->GetShelfItemDelegate(item->id); 20334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return item_delegate->ShouldShowTooltip(); 2034424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 2035424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 20368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int ShelfView::CalculateShelfDistance(const gfx::Point& coordinate) const { 20375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ShelfWidget* shelf = RootWindowController::ForShelf( 2038424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) GetWidget()->GetNativeView())->shelf(); 20395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ShelfAlignment align = shelf->GetAlignment(); 2040424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const gfx::Rect bounds = GetBoundsInScreen(); 2041424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int distance = 0; 2042424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) switch (align) { 20435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case SHELF_ALIGNMENT_BOTTOM: 2044424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) distance = bounds.y() - coordinate.y(); 2045424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 20465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case SHELF_ALIGNMENT_LEFT: 2047424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) distance = coordinate.x() - bounds.right(); 2048424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 20495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case SHELF_ALIGNMENT_RIGHT: 2050424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) distance = bounds.x() - coordinate.x(); 2051424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 20525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case SHELF_ALIGNMENT_TOP: 2053424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) distance = coordinate.y() - bounds.bottom(); 2054424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 2055424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 2056424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return distance > 0 ? distance : 0; 20572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 20582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ash 2060