app_list_controller.cc revision 7d4cd473f85ac64c3747c96c277f9e506a0d2246
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" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/app_list/app_list_constants.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/app_list/pagination_model.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/app_list/views/app_list_view.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/client/focus_client.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/root_window.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/events/event.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/scoped_layer_animation_settings.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/transform_util.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Duration for show/hide animation in milliseconds. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kAnimationDurationMs = 200; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Offset in pixels to animation away/towards the launcher. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kAnimationOffset = 8; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The maximum shift in pixels when over-scroll happens. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxOverScrollShift = 48; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::Layer* GetLayer(views::Widget* widget) { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return widget->GetNativeView()->layer(); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Gets arrow location based on shelf alignment. 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)views::BubbleBorder::Arrow GetBubbleArrow(aura::Window* window) { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(Shell::HasInstance()); 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ShelfLayoutManager::ForLauncher(window)-> 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SelectValueForShelfAlignment( 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::BubbleBorder::BOTTOM_CENTER, 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::BubbleBorder::LEFT_CENTER, 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::BubbleBorder::RIGHT_CENTER, 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::BubbleBorder::TOP_CENTER); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Offset given |rect| towards shelf. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect OffsetTowardsShelf(const gfx::Rect& rect, views::Widget* widget) { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(Shell::HasInstance()); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShelfAlignment shelf_alignment = Shell::GetInstance()->GetShelfAlignment( 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) widget->GetNativeView()->GetRootWindow()); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect offseted(rect); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (shelf_alignment) { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SHELF_ALIGNMENT_BOTTOM: 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offseted.Offset(0, kAnimationOffset); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SHELF_ALIGNMENT_LEFT: 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offseted.Offset(-kAnimationOffset, 0); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SHELF_ALIGNMENT_RIGHT: 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offseted.Offset(kAnimationOffset, 0); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case SHELF_ALIGNMENT_TOP: 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) offseted.Offset(0, -kAnimationOffset); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return offseted; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppListController, public: 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppListController::AppListController() 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : pagination_model_(new app_list::PaginationModel), 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_visible_(false), 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_(NULL), 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) should_snap_back_(false) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shell::GetInstance()->AddShellObserver(this); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pagination_model_->AddObserver(this); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppListController::~AppListController() { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensures app list view goes before the controller since pagination model 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // lives in the controller and app list view would access it on destruction. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view_ && view_->GetWidget()) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->GetWidget()->CloseNow(); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shell::GetInstance()->RemoveShellObserver(this); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pagination_model_->RemoveObserver(this); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppListController::SetVisible(bool visible, aura::Window* window) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (visible == is_visible_) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_visible_ = visible; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // App list needs to know the new shelf layout in order to calculate its 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // UI layout when AppListView visibility changes. 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager()-> 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateAutoHideState(); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view_) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleAnimation(); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (is_visible_) { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // AppListModel and AppListViewDelegate are owned by AppListView. They 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will be released with AppListView on close. 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) app_list::AppListView* view = new app_list::AppListView( 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shell::GetInstance()->delegate()->CreateAppListViewDelegate()); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::Window* container = GetRootWindowController(window->GetRootWindow())-> 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetContainer(kShellWindowId_AppListContainer); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view->InitAsBubble( 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) container, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pagination_model_.get(), 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Launcher::ForWindow(container)->GetAppListButtonView(), 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Point(), 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetBubbleArrow(container), 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) true /* border_accepts_events */); 1317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (ash::switches::UseAlternateShelfLayout()) 1327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) view->SetArrowPaintType(views::BubbleBorder::PAINT_NONE); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetView(view); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AppListController::IsVisible() const { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return view_ && view_->GetWidget()->IsVisible(); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)aura::Window* AppListController::GetWindow() { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return is_visible_ && view_ ? view_->GetWidget()->GetNativeWindow() : NULL; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void AppListController::SetDragAndDropHostOfCurrentAppList( 146b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) app_list::ApplicationDragAndDropHost* drag_and_drop_host) { 147b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (view_ && is_visible_) 148b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) view_->SetDragAndDropHostOfCurrentAppList(drag_and_drop_host); 149b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 150b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppListController, private: 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListController::SetView(app_list::AppListView* view) { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(view_ == NULL); 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(is_visible_); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view_ = view; 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::Widget* widget = view_->GetWidget(); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) widget->AddObserver(this); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Shell::GetInstance()->AddPreTargetHandler(this); 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Launcher::ForWindow(widget->GetNativeWindow())->AddIconObserver(this); 1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) widget->GetNativeView()->GetRootWindow()->AddObserver(this); 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::client::GetFocusClient(widget->GetNativeView())->AddObserver(this); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view_->ShowWhenReady(); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListController::ResetView() { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!view_) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::Widget* widget = view_->GetWidget(); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) widget->RemoveObserver(this); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetLayer(widget)->GetAnimator()->RemoveObserver(this); 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Shell::GetInstance()->RemovePreTargetHandler(this); 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Launcher::ForWindow(widget->GetNativeWindow())->RemoveIconObserver(this); 1787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) widget->GetNativeView()->GetRootWindow()->RemoveObserver(this); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::client::GetFocusClient(widget->GetNativeView())->RemoveObserver(this); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_ = NULL; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListController::ScheduleAnimation() { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stop observing previous animation. 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopObservingImplicitAnimations(); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::Widget* widget = view_->GetWidget(); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::Layer* layer = GetLayer(widget); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layer->GetAnimator()->StopAnimating(); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect target_bounds; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_visible_) { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_bounds = widget->GetWindowBoundsInScreen(); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) widget->SetBounds(OffsetTowardsShelf(target_bounds, widget)); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_bounds = OffsetTowardsShelf(widget->GetWindowBoundsInScreen(), 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) widget); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::ScopedLayerAnimationSettings animation(layer->GetAnimator()); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) animation.SetTransitionDuration( 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds( 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_visible_ ? 0 : kAnimationDurationMs)); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) animation.AddObserver(this); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layer->SetOpacity(is_visible_ ? 1.0 : 0.0); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) widget->SetBounds(target_bounds); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppListController::ProcessLocatedEvent(ui::LocatedEvent* event) { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the event happened on a menu, then the event should not close the app 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // list. 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::Window* target = static_cast<aura::Window*>(event->target()); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target) { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RootWindowController* root_controller = 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetRootWindowController(target->GetRootWindow()); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (root_controller) { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aura::Window* menu_container = root_controller->GetContainer( 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ash::internal::kShellWindowId_MenuContainer); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (menu_container->Contains(target)) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view_ && is_visible_) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aura::Window* window = view_->GetWidget()->GetNativeView(); 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Point window_local_point(event->root_location()); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aura::Window::ConvertPointToTarget(window->GetRootWindow(), 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window, 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &window_local_point); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use HitTest to respect the hit test mask of the bubble. 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!window->HitTest(window_local_point)) 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetVisible(false, window); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListController::UpdateBounds() { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view_ && is_visible_) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->UpdateBounds(); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppListController, aura::EventFilter implementation: 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppListController::OnMouseEvent(ui::MouseEvent* event) { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event->type() == ui::ET_MOUSE_PRESSED) 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProcessLocatedEvent(event); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppListController::OnGestureEvent(ui::GestureEvent* event) { 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (event->type() == ui::ET_GESTURE_TAP_DOWN) 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProcessLocatedEvent(event); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppListController, aura::FocusObserver implementation: 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppListController::OnWindowFocused(aura::Window* gained_focus, 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::Window* lost_focus) { 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (gained_focus && view_ && is_visible_) { 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::Window* applist_container = 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetRootWindowController(gained_focus->GetRootWindow())->GetContainer( 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kShellWindowId_AppListContainer); 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (gained_focus->parent() != applist_container) 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetVisible(false, gained_focus); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 2707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// AppListController, aura::WindowObserver implementation: 2717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void AppListController::OnWindowBoundsChanged(aura::Window* root, 2727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const gfx::Rect& old_bounds, 2737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const gfx::Rect& new_bounds) { 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateBounds(); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppListController, ui::ImplicitAnimationObserver implementation: 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListController::OnImplicitAnimationsCompleted() { 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_visible_ ) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->GetWidget()->Activate(); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->GetWidget()->Close(); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppListController, views::WidgetObserver implementation: 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppListController::OnWidgetDestroying(views::Widget* widget) { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(view_->GetWidget() == widget); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_visible_) 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetVisible(false, widget->GetNativeView()); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetView(); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppListController, ShellObserver implementation: 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppListController::OnShelfAlignmentChanged(aura::RootWindow* root_window) { 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (view_) 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) view_->SetBubbleArrow(GetBubbleArrow(view_->GetWidget()->GetNativeView())); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppListController, LauncherIconObserver implementation: 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListController::OnLauncherIconPositionsChanged() { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateBounds(); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppListController, PaginationModelObserver implementation: 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListController::TotalPagesChanged() { 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListController::SelectedPageChanged(int old_selected, 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int new_selected) { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListController::TransitionChanged() { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |view_| could be NULL when app list is closed with a running transition. 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!view_) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const app_list::PaginationModel::Transition& transition = 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pagination_model_->transition(); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pagination_model_->is_valid_page(transition.target_page)) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::Widget* widget = view_->GetWidget(); 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::LayerAnimator* widget_animator = GetLayer(widget)->GetAnimator(); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pagination_model_->IsRevertingCurrentTransition()) { 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Update cached |view_bounds_| if it is the first over-scroll move and 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // widget does not have running animations. 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!should_snap_back_ && !widget_animator->is_animating()) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_bounds_ = widget->GetWindowBoundsInScreen(); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int current_page = pagination_model_->selected_page(); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int dir = transition.target_page > current_page ? -1 : 1; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const double progress = 1.0 - pow(1.0 - transition.progress, 4); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int shift = kMaxOverScrollShift * progress * dir; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect shifted(view_bounds_); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shifted.set_x(shifted.x() + shift); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) widget->SetBounds(shifted); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) should_snap_back_ = true; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (should_snap_back_) { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) should_snap_back_ = false; 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::ScopedLayerAnimationSettings animation(widget_animator); 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) animation.SetTransitionDuration(base::TimeDelta::FromMilliseconds( 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) app_list::kOverscrollPageTransitionDurationMs)); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) widget->SetBounds(view_bounds_); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace internal 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ash 360