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) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/app_list_controller.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 77d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ash/ash_switches.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/launcher/launcher.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/root_window_controller.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shelf/shelf_layout_manager.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell_delegate.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell_window_ids.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/property_util.h" 15bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "base/command_line.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/app_list/app_list_constants.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/app_list/pagination_model.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/app_list/views/app_list_view.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/client/focus_client.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/root_window.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/events/event.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/scoped_layer_animation_settings.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/transform_util.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Duration for show/hide animation in milliseconds. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kAnimationDurationMs = 200; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Offset in pixels to animation away/towards the launcher. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kAnimationOffset = 8; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The maximum shift in pixels when over-scroll happens. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxOverScrollShift = 48; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// The alternate shelf style adjusts the bubble to be flush with the shelf 43bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// when there is no bubble-tip. This is the tip height which needs to be 44bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// offsetted. 45bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochconst int kArrowTipHeight = 10; 46bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 47bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// The minimal anchor position offset to make sure that the bubble is still on 48bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// the screen with 8 pixels spacing on the left / right. This constant is a 49bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// result of minimal bubble arrow sizes and offsets. 50558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochconst int kMinimalAnchorPositionOffset = 57; 51bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::Layer* GetLayer(views::Widget* widget) { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return widget->GetNativeView()->layer(); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Gets arrow location based on shelf alignment. 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)views::BubbleBorder::Arrow GetBubbleArrow(aura::Window* window) { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(Shell::HasInstance()); 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ShelfLayoutManager::ForLauncher(window)-> 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SelectValueForShelfAlignment( 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::BubbleBorder::BOTTOM_CENTER, 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::BubbleBorder::LEFT_CENTER, 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::BubbleBorder::RIGHT_CENTER, 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::BubbleBorder::TOP_CENTER); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Offset given |rect| towards shelf. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect OffsetTowardsShelf(const gfx::Rect& rect, views::Widget* widget) { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(Shell::HasInstance()); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShelfAlignment shelf_alignment = Shell::GetInstance()->GetShelfAlignment( 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) widget->GetNativeView()->GetRootWindow()); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect offseted(rect); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (shelf_alignment) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SHELF_ALIGNMENT_BOTTOM: 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offseted.Offset(0, kAnimationOffset); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SHELF_ALIGNMENT_LEFT: 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offseted.Offset(-kAnimationOffset, 0); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SHELF_ALIGNMENT_RIGHT: 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offseted.Offset(kAnimationOffset, 0); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case SHELF_ALIGNMENT_TOP: 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) offseted.Offset(0, -kAnimationOffset); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return offseted; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 91bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// Using |button_bounds|, determine the anchor so that the bubble gets shown 92bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// above the shelf (used for the alternate shelf theme). 93bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochgfx::Point GetAdjustAnchorPositionToShelf( 94bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const gfx::Rect& button_bounds, views::Widget* widget) { 95bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch DCHECK(Shell::HasInstance()); 96bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch ShelfAlignment shelf_alignment = Shell::GetInstance()->GetShelfAlignment( 97bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch widget->GetNativeView()->GetRootWindow()); 98bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch gfx::Point anchor(button_bounds.CenterPoint()); 99bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch switch (shelf_alignment) { 100bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch case SHELF_ALIGNMENT_TOP: 101bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch case SHELF_ALIGNMENT_BOTTOM: 102bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch { 103bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (base::i18n::IsRTL()) { 104bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch int screen_width = widget->GetWorkAreaBoundsInScreen().width(); 105bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch anchor.set_x(std::min(screen_width - kMinimalAnchorPositionOffset, 106bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch anchor.x())); 107bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } else { 108bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch anchor.set_x(std::max(kMinimalAnchorPositionOffset, anchor.x())); 109bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 110bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch int offset = button_bounds.height() / 2 - kArrowTipHeight; 111bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (shelf_alignment == SHELF_ALIGNMENT_TOP) 112bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch offset = -offset; 113bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch anchor.set_y(anchor.y() - offset); 114bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 115bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch break; 116bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch case SHELF_ALIGNMENT_LEFT: 117bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch anchor.set_x(button_bounds.right() - kArrowTipHeight); 118bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch anchor.set_y(std::max(kMinimalAnchorPositionOffset, anchor.y())); 119bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch break; 120bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch case SHELF_ALIGNMENT_RIGHT: 121bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch anchor.set_x(button_bounds.x() + kArrowTipHeight); 122bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch anchor.set_y(std::max(kMinimalAnchorPositionOffset, anchor.y())); 123bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch break; 124bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 125bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 126bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch return anchor; 127bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 128bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppListController, public: 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppListController::AppListController() 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : pagination_model_(new app_list::PaginationModel), 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_visible_(false), 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_(NULL), 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) should_snap_back_(false) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shell::GetInstance()->AddShellObserver(this); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pagination_model_->AddObserver(this); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppListController::~AppListController() { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensures app list view goes before the controller since pagination model 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // lives in the controller and app list view would access it on destruction. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view_ && view_->GetWidget()) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->GetWidget()->CloseNow(); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shell::GetInstance()->RemoveShellObserver(this); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pagination_model_->RemoveObserver(this); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppListController::SetVisible(bool visible, aura::Window* window) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (visible == is_visible_) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_visible_ = visible; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // App list needs to know the new shelf layout in order to calculate its 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // UI layout when AppListView visibility changes. 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager()-> 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateAutoHideState(); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view_) { 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleAnimation(); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (is_visible_) { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // AppListModel and AppListViewDelegate are owned by AppListView. They 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will be released with AppListView on close. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) app_list::AppListView* view = new app_list::AppListView( 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shell::GetInstance()->delegate()->CreateAppListViewDelegate()); 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::Window* container = GetRootWindowController(window->GetRootWindow())-> 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetContainer(kShellWindowId_AppListContainer); 173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (ash::switches::UseAlternateShelfLayout()) { 174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gfx::Rect applist_button_bounds = Launcher::ForWindow(container)-> 175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GetAppListButtonView()->GetBoundsInScreen(); 176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch view->InitAsBubble( 177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch container, 178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pagination_model_.get(), 179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NULL, 180bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch GetAdjustAnchorPositionToShelf(applist_button_bounds, 181bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch Launcher::ForWindow(container)->GetAppListButtonView()-> 182bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch GetWidget()), 183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GetBubbleArrow(container), 184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch true /* border_accepts_events */); 185bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch view->SetArrowPaintType(views::BubbleBorder::PAINT_NONE); 186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else { 187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch view->InitAsBubble( 188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch container, 189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pagination_model_.get(), 190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Launcher::ForWindow(container)->GetAppListButtonView(), 191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gfx::Point(), 192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GetBubbleArrow(container), 193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch true /* border_accepts_events */); 194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetView(view); 196bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // By setting us as DnD recipient, the app list knows that we can 197bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // handle items. 198bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (!CommandLine::ForCurrentProcess()->HasSwitch( 199bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch ash::switches::kAshDisableDragAndDropAppListToLauncher)) { 200bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch SetDragAndDropHostOfCurrentAppList( 201bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch Launcher::ForWindow(window)->GetDragAndDropHostForAppList()); 202bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AppListController::IsVisible() const { 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return view_ && view_->GetWidget()->IsVisible(); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)aura::Window* AppListController::GetWindow() { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return is_visible_ && view_ ? view_->GetWidget()->GetNativeWindow() : NULL; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 214bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch//////////////////////////////////////////////////////////////////////////////// 215bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// AppListController, private: 216bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 217b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void AppListController::SetDragAndDropHostOfCurrentAppList( 218b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) app_list::ApplicationDragAndDropHost* drag_and_drop_host) { 219b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (view_ && is_visible_) 220b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) view_->SetDragAndDropHostOfCurrentAppList(drag_and_drop_host); 221b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 222b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListController::SetView(app_list::AppListView* view) { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(view_ == NULL); 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(is_visible_); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view_ = view; 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::Widget* widget = view_->GetWidget(); 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) widget->AddObserver(this); 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Shell::GetInstance()->AddPreTargetHandler(this); 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Launcher::ForWindow(widget->GetNativeWindow())->AddIconObserver(this); 2327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) widget->GetNativeView()->GetRootWindow()->AddObserver(this); 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::client::GetFocusClient(widget->GetNativeView())->AddObserver(this); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view_->ShowWhenReady(); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListController::ResetView() { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!view_) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::Widget* widget = view_->GetWidget(); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) widget->RemoveObserver(this); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetLayer(widget)->GetAnimator()->RemoveObserver(this); 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Shell::GetInstance()->RemovePreTargetHandler(this); 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Launcher::ForWindow(widget->GetNativeWindow())->RemoveIconObserver(this); 2477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) widget->GetNativeView()->GetRootWindow()->RemoveObserver(this); 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::client::GetFocusClient(widget->GetNativeView())->RemoveObserver(this); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_ = NULL; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListController::ScheduleAnimation() { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stop observing previous animation. 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopObservingImplicitAnimations(); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::Widget* widget = view_->GetWidget(); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::Layer* layer = GetLayer(widget); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layer->GetAnimator()->StopAnimating(); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect target_bounds; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_visible_) { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_bounds = widget->GetWindowBoundsInScreen(); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) widget->SetBounds(OffsetTowardsShelf(target_bounds, widget)); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_bounds = OffsetTowardsShelf(widget->GetWindowBoundsInScreen(), 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) widget); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::ScopedLayerAnimationSettings animation(layer->GetAnimator()); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) animation.SetTransitionDuration( 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds( 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_visible_ ? 0 : kAnimationDurationMs)); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) animation.AddObserver(this); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layer->SetOpacity(is_visible_ ? 1.0 : 0.0); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) widget->SetBounds(target_bounds); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppListController::ProcessLocatedEvent(ui::LocatedEvent* event) { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the event happened on a menu, then the event should not close the app 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // list. 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::Window* target = static_cast<aura::Window*>(event->target()); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target) { 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RootWindowController* root_controller = 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetRootWindowController(target->GetRootWindow()); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (root_controller) { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aura::Window* menu_container = root_controller->GetContainer( 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ash::internal::kShellWindowId_MenuContainer); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (menu_container->Contains(target)) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view_ && is_visible_) { 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aura::Window* window = view_->GetWidget()->GetNativeView(); 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Point window_local_point(event->root_location()); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aura::Window::ConvertPointToTarget(window->GetRootWindow(), 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window, 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &window_local_point); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use HitTest to respect the hit test mask of the bubble. 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!window->HitTest(window_local_point)) 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetVisible(false, window); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListController::UpdateBounds() { 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view_ && is_visible_) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->UpdateBounds(); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppListController, aura::EventFilter implementation: 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppListController::OnMouseEvent(ui::MouseEvent* event) { 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event->type() == ui::ET_MOUSE_PRESSED) 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProcessLocatedEvent(event); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppListController::OnGestureEvent(ui::GestureEvent* event) { 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (event->type() == ui::ET_GESTURE_TAP_DOWN) 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProcessLocatedEvent(event); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppListController, aura::FocusObserver implementation: 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppListController::OnWindowFocused(aura::Window* gained_focus, 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::Window* lost_focus) { 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (gained_focus && view_ && is_visible_) { 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::Window* applist_container = 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetRootWindowController(gained_focus->GetRootWindow())->GetContainer( 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kShellWindowId_AppListContainer); 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (gained_focus->parent() != applist_container) 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetVisible(false, gained_focus); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 3397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// AppListController, aura::WindowObserver implementation: 3407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void AppListController::OnWindowBoundsChanged(aura::Window* root, 3417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const gfx::Rect& old_bounds, 3427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const gfx::Rect& new_bounds) { 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateBounds(); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppListController, ui::ImplicitAnimationObserver implementation: 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListController::OnImplicitAnimationsCompleted() { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_visible_ ) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->GetWidget()->Activate(); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->GetWidget()->Close(); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppListController, views::WidgetObserver implementation: 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppListController::OnWidgetDestroying(views::Widget* widget) { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(view_->GetWidget() == widget); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_visible_) 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetVisible(false, widget->GetNativeView()); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetView(); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppListController, ShellObserver implementation: 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppListController::OnShelfAlignmentChanged(aura::RootWindow* root_window) { 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (view_) 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) view_->SetBubbleArrow(GetBubbleArrow(view_->GetWidget()->GetNativeView())); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppListController, LauncherIconObserver implementation: 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListController::OnLauncherIconPositionsChanged() { 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateBounds(); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppListController, PaginationModelObserver implementation: 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListController::TotalPagesChanged() { 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListController::SelectedPageChanged(int old_selected, 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int new_selected) { 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AppListController::TransitionStarted() { 3917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 3927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListController::TransitionChanged() { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |view_| could be NULL when app list is closed with a running transition. 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!view_) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const app_list::PaginationModel::Transition& transition = 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pagination_model_->transition(); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pagination_model_->is_valid_page(transition.target_page)) 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::Widget* widget = view_->GetWidget(); 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::LayerAnimator* widget_animator = GetLayer(widget)->GetAnimator(); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pagination_model_->IsRevertingCurrentTransition()) { 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Update cached |view_bounds_| if it is the first over-scroll move and 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // widget does not have running animations. 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!should_snap_back_ && !widget_animator->is_animating()) 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_bounds_ = widget->GetWindowBoundsInScreen(); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int current_page = pagination_model_->selected_page(); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int dir = transition.target_page > current_page ? -1 : 1; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const double progress = 1.0 - pow(1.0 - transition.progress, 4); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int shift = kMaxOverScrollShift * progress * dir; 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect shifted(view_bounds_); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shifted.set_x(shifted.x() + shift); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) widget->SetBounds(shifted); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) should_snap_back_ = true; 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (should_snap_back_) { 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) should_snap_back_ = false; 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::ScopedLayerAnimationSettings animation(widget_animator); 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) animation.SetTransitionDuration(base::TimeDelta::FromMilliseconds( 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) app_list::kOverscrollPageTransitionDurationMs)); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) widget->SetBounds(view_bounds_); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace internal 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ash 432