146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// found in the LICENSE file. 446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ash/wm/overview/window_grid.h" 646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 76e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "ash/ash_switches.h" 846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ash/screen_util.h" 946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ash/shell.h" 1046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ash/shell_window_ids.h" 1146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ash/wm/overview/scoped_transform_overview_window.h" 1246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ash/wm/overview/window_selector.h" 1346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ash/wm/overview/window_selector_item.h" 1446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ash/wm/overview/window_selector_panels.h" 1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ash/wm/overview/window_selector_window.h" 1646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ash/wm/window_state.h" 176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/command_line.h" 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/i18n/string_search.h" 1946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/memory/scoped_vector.h" 2046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "third_party/skia/include/core/SkColor.h" 2146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/aura/window.h" 2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/compositor/layer_animation_observer.h" 2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/compositor/scoped_layer_animation_settings.h" 2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/gfx/animation/tween.h" 2546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/gfx/vector2d.h" 2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/views/background.h" 2746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/views/view.h" 2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/views/widget/widget.h" 2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/wm/core/window_animations.h" 3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace ash { 3246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace { 3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// An observer which holds onto the passed widget until the animation is 3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// complete. 3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class CleanupWidgetAfterAnimationObserver 3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : public ui::ImplicitAnimationObserver { 3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public: 3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) explicit CleanupWidgetAfterAnimationObserver( 4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<views::Widget> widget); 4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual ~CleanupWidgetAfterAnimationObserver(); 4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // ui::ImplicitAnimationObserver: 4446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual void OnImplicitAnimationsCompleted() OVERRIDE; 4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private: 4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<views::Widget> widget_; 4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(CleanupWidgetAfterAnimationObserver); 5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}; 5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)CleanupWidgetAfterAnimationObserver::CleanupWidgetAfterAnimationObserver( 5346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<views::Widget> widget) 5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : widget_(widget.Pass()) { 5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 5646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 5746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)CleanupWidgetAfterAnimationObserver::~CleanupWidgetAfterAnimationObserver() { 5846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void CleanupWidgetAfterAnimationObserver::OnImplicitAnimationsCompleted() { 6146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) delete this; 6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 6446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// A comparator for locating a given target window. 6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)struct WindowSelectorItemComparator 6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : public std::unary_function<WindowSelectorItem*, bool> { 6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) explicit WindowSelectorItemComparator(const aura::Window* target_window) 6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : target(target_window) { 6946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool operator()(WindowSelectorItem* window) const { 7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return window->HasSelectableWindow(target); 7346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 7446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const aura::Window* target; 7646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}; 7746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 7846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// A comparator for locating a WindowSelectorItem given a targeted window. 7946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)struct WindowSelectorItemTargetComparator 8046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : public std::unary_function<WindowSelectorItem*, bool> { 8146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) explicit WindowSelectorItemTargetComparator(const aura::Window* target_window) 8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : target(target_window) { 8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool operator()(WindowSelectorItem* window) const { 8646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return window->Contains(target); 8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 8846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 8946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const aura::Window* target; 9046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}; 9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Conceptually the window overview is a table or grid of cells having this 9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// fixed aspect ratio. The number of columns is determined by maximizing the 9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// area of them based on the number of window_list. 9546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const float kCardAspectRatio = 4.0f / 3.0f; 9646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// The minimum number of cards along the major axis (i.e. horizontally on a 9846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// landscape orientation). 9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const int kMinCardsMajor = 3; 10046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 10146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const int kOverviewSelectorTransitionMilliseconds = 100; 10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 10346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// The color and opacity of the overview selector. 10446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const SkColor kWindowOverviewSelectionColor = SK_ColorBLACK; 10546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const unsigned char kWindowOverviewSelectorOpacity = 128; 10646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// The minimum amount of spacing between the bottom of the text filtering 1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// text field and the top of the selection widget on the first row of items. 1096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const int kTextFilterBottomMargin = 5; 1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 11146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Returns the vector for the fade in animation. 11246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)gfx::Vector2d GetSlideVectorForFadeIn(WindowSelector::Direction direction, 11346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const gfx::Rect& bounds) { 11446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) gfx::Vector2d vector; 11546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) switch (direction) { 11646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) case WindowSelector::DOWN: 11746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) vector.set_y(bounds.width()); 11846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) break; 11946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) case WindowSelector::RIGHT: 12046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) vector.set_x(bounds.height()); 12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) break; 12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) case WindowSelector::UP: 12346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) vector.set_y(-bounds.width()); 12446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) break; 12546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) case WindowSelector::LEFT: 12646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) vector.set_x(-bounds.height()); 12746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) break; 12846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 12946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return vector; 13046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 13146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 13246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} // namespace 13346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 13446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)WindowGrid::WindowGrid(aura::Window* root_window, 13546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::vector<aura::Window*>& windows, 13646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) WindowSelector* window_selector) 13746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : root_window_(root_window), 13846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) window_selector_(window_selector) { 13946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) WindowSelectorPanels* panels_item = NULL; 14046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (aura::Window::Windows::const_iterator iter = windows.begin(); 14146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) iter != windows.end(); ++iter) { 14246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if ((*iter)->GetRootWindow() != root_window) 14346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) continue; 14446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) (*iter)->AddObserver(this); 14546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) observed_windows_.insert(*iter); 14646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 14746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if ((*iter)->type() == ui::wm::WINDOW_TYPE_PANEL && 14846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) wm::GetWindowState(*iter)->panel_attached()) { 14946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Attached panel windows are grouped into a single overview item per 15046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // grid. 15146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!panels_item) { 152f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) panels_item = new WindowSelectorPanels(root_window_); 15346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) window_list_.push_back(panels_item); 15446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 15546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) panels_item->AddWindow(*iter); 15646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } else { 157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch window_list_.push_back(new WindowSelectorWindow(*iter)); 15846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 15946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 16046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (window_list_.empty()) 16146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; 16246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 16346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 16446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)WindowGrid::~WindowGrid() { 16546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (std::set<aura::Window*>::iterator iter = observed_windows_.begin(); 16646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) iter != observed_windows_.end(); iter++) { 16746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) (*iter)->RemoveObserver(this); 16846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 16946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 17046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 171116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WindowGrid::PrepareForOverview() { 172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (ScopedVector<WindowSelectorItem>::iterator iter = window_list_.begin(); 173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch iter != window_list_.end(); ++iter) { 174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (*iter)->PrepareForOverview(); 175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 17846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void WindowGrid::PositionWindows(bool animate) { 17946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CHECK(!window_list_.empty()); 18046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 18146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) gfx::Size window_size; 18246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) gfx::Rect total_bounds = ScreenUtil::ConvertRectToScreen( 18346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) root_window_, 18446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ScreenUtil::GetDisplayWorkAreaBoundsInParent( 18546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) Shell::GetContainer(root_window_, kShellWindowId_DefaultContainer))); 18646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // If the text filtering feature is enabled, reserve space at the top for the 1886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // text filtering textbox to appear. 1896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!CommandLine::ForCurrentProcess()->HasSwitch( 1906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) switches::kAshDisableTextFilteringInOverviewMode)) { 1916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) total_bounds.Inset( 1926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 0, 1936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) WindowSelector::kTextFilterBottomEdge + kTextFilterBottomMargin, 1946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 0, 1956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 0); 1966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 1976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 19846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Find the minimum number of windows per row that will fit all of the 19946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // windows on screen. 20046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) num_columns_ = std::max( 20146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) total_bounds.width() > total_bounds.height() ? kMinCardsMajor : 1, 20246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) static_cast<int>(ceil(sqrt(total_bounds.width() * window_list_.size() / 20346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) (kCardAspectRatio * total_bounds.height()))))); 20446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int num_rows = ((window_list_.size() + num_columns_ - 1) / num_columns_); 20546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) window_size.set_width(std::min( 20646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) static_cast<int>(total_bounds.width() / num_columns_), 20746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) static_cast<int>(total_bounds.height() * kCardAspectRatio / num_rows))); 20846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) window_size.set_height(window_size.width() / kCardAspectRatio); 20946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 21046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Calculate the X and Y offsets necessary to center the grid. 21146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int x_offset = total_bounds.x() + ((window_list_.size() >= num_columns_ ? 0 : 21246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) (num_columns_ - window_list_.size()) * window_size.width()) + 21346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) (total_bounds.width() - num_columns_ * window_size.width())) / 2; 21446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int y_offset = total_bounds.y() + (total_bounds.height() - 21546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) num_rows * window_size.height()) / 2; 216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 21746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (size_t i = 0; i < window_list_.size(); ++i) { 21846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) gfx::Transform transform; 21946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int column = i % num_columns_; 22046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int row = i / num_columns_; 22146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) gfx::Rect target_bounds(window_size.width() * column + x_offset, 22246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) window_size.height() * row + y_offset, 22346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) window_size.width(), 22446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) window_size.height()); 22546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) window_list_[i]->SetBounds(root_window_, target_bounds, animate); 22646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 22746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 22846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // If we have less than |kMinCardsMajor| windows, adjust the column_ value to 22946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // reflect how many "real" columns we have. 23046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (num_columns_ > window_list_.size()) 23146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) num_columns_ = window_list_.size(); 23246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 23346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // If the selection widget is active, reposition it without any animation. 23446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (selection_widget_) 23546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) MoveSelectionWidgetToTarget(animate); 23646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 23746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 238116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool WindowGrid::Move(WindowSelector::Direction direction, bool animate) { 23946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool recreate_selection_widget = false; 24046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool out_of_bounds = false; 24146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!selection_widget_) { 24246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) switch (direction) { 24346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) case WindowSelector::LEFT: 24446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) selected_index_ = window_list_.size() - 1; 24546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) break; 24646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) case WindowSelector::UP: 24746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) selected_index_ = 24846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) (window_list_.size() / num_columns_) * num_columns_ - 1; 24946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) break; 25046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) case WindowSelector::RIGHT: 25146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) case WindowSelector::DOWN: 25246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) selected_index_ = 0; 25346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) break; 25446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 255116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch while (SelectedWindow()->dimmed() || selection_widget_) { 25746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) switch (direction) { 25846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) case WindowSelector::RIGHT: 25946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (selected_index_ >= window_list_.size() - 1) 26046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) out_of_bounds = true; 26146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) selected_index_++; 26246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (selected_index_ % num_columns_ == 0) 26346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) recreate_selection_widget = true; 26446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) break; 26546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) case WindowSelector::LEFT: 26646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (selected_index_ == 0) 26746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) out_of_bounds = true; 26846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) selected_index_--; 26946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if ((selected_index_ + 1) % num_columns_ == 0) 27046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) recreate_selection_widget = true; 27146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) break; 27246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) case WindowSelector::DOWN: 27346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) selected_index_ += num_columns_; 27446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (selected_index_ >= window_list_.size()) { 27546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) selected_index_ = (selected_index_ + 1) % num_columns_; 27646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (selected_index_ == 0) 27746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) out_of_bounds = true; 27846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) recreate_selection_widget = true; 27946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 28046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) break; 28146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) case WindowSelector::UP: 28246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (selected_index_ == 0) 28346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) out_of_bounds = true; 28446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (selected_index_ < num_columns_) { 28546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) selected_index_ += num_columns_ * 28646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ((window_list_.size() - selected_index_) / num_columns_) - 1; 28746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) recreate_selection_widget = true; 28846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } else { 28946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) selected_index_ -= num_columns_; 29046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 29146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) break; 29246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 293116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Exit the loop if we broke free from the grid or found an active item. 294116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (out_of_bounds || !SelectedWindow()->dimmed()) 295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch break; 29646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 29746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 298116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MoveSelectionWidget(direction, recreate_selection_widget, 299116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch out_of_bounds, animate); 30046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return out_of_bounds; 30146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 30246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 30346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)WindowSelectorItem* WindowGrid::SelectedWindow() const { 30446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CHECK(selected_index_ < window_list_.size()); 30546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return window_list_[selected_index_]; 30646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 30746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 30846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool WindowGrid::Contains(const aura::Window* window) const { 30946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return std::find_if(window_list_.begin(), window_list_.end(), 31046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) WindowSelectorItemTargetComparator(window)) != 31146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) window_list_.end(); 31246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 31346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 314116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WindowGrid::FilterItems(const base::string16& pattern) { 315116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents finder(pattern); 316116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (ScopedVector<WindowSelectorItem>::iterator iter = window_list_.begin(); 317116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch iter != window_list_.end(); iter++) { 318116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (finder.Search((*iter)->SelectionWindow()->title(), NULL, NULL)) { 319116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (*iter)->SetDimmed(false); 320116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 321116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (*iter)->SetDimmed(true); 322116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (selection_widget_ && SelectedWindow() == *iter) 323116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch selection_widget_.reset(); 324116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 325116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 326116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 327116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 32846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void WindowGrid::OnWindowDestroying(aura::Window* window) { 32946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) window->RemoveObserver(this); 33046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) observed_windows_.erase(window); 33146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ScopedVector<WindowSelectorItem>::iterator iter = 33246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::find_if(window_list_.begin(), window_list_.end(), 33346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) WindowSelectorItemComparator(window)); 33446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 33546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(iter != window_list_.end()); 33646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 33746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) (*iter)->RemoveWindow(window); 33846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 33946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // If there are still windows in this selector entry then the overview is 34046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // still active and the active selection remains the same. 34146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!(*iter)->empty()) 34246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; 34346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 34446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) size_t removed_index = iter - window_list_.begin(); 34546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) window_list_.erase(iter); 34646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 34746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (empty()) { 34846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // If the grid is now empty, notify the window selector so that it erases us 34946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // from its grid list. 35046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) window_selector_->OnGridEmpty(this); 35146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; 35246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 35346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 35446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // If selecting, update the selection index. 35546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (selection_widget_) { 35646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool send_focus_alert = selected_index_ == removed_index; 35746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (selected_index_ >= removed_index && selected_index_ != 0) 35846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) selected_index_--; 35946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (send_focus_alert) 36046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) SelectedWindow()->SendFocusAlert(); 36146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 36246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 36346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PositionWindows(true); 36446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 36546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 36646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void WindowGrid::OnWindowBoundsChanged(aura::Window* window, 36746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const gfx::Rect& old_bounds, 36846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const gfx::Rect& new_bounds) { 36946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ScopedVector<WindowSelectorItem>::const_iterator iter = 37046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::find_if(window_list_.begin(), window_list_.end(), 37146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) WindowSelectorItemTargetComparator(window)); 37246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(iter != window_list_.end()); 37346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 37446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Immediately finish any active bounds animation. 37546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) window->layer()->GetAnimator()->StopAnimatingProperty( 37646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ui::LayerAnimationElement::BOUNDS); 37746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 37846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Recompute the transform for the window. 37946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) (*iter)->RecomputeWindowTransforms(); 38046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 38146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 38246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void WindowGrid::InitSelectionWidget(WindowSelector::Direction direction) { 38346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) selection_widget_.reset(new views::Widget); 38446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) views::Widget::InitParams params; 38546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) params.type = views::Widget::InitParams::TYPE_POPUP; 38646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) params.keep_on_top = false; 38746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 38846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; 38946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) params.parent = Shell::GetContainer(root_window_, 39046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) kShellWindowId_DefaultContainer); 39146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) params.accept_events = false; 39246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) selection_widget_->set_focus_on_creation(false); 39346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) selection_widget_->Init(params); 39446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Disable the "bounce in" animation when showing the window. 39546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ::wm::SetWindowVisibilityAnimationTransition( 39646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) selection_widget_->GetNativeWindow(), ::wm::ANIMATE_NONE); 3976d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // The selection widget should not activate the shelf when passing under it. 3986d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) ash::wm::GetWindowState(selection_widget_->GetNativeWindow())-> 3996d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) set_ignored_by_shelf(true); 4006d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 40146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) views::View* content_view = new views::View; 40246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) content_view->set_background( 40346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) views::Background::CreateSolidBackground(kWindowOverviewSelectionColor)); 40446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) selection_widget_->SetContentsView(content_view); 40546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) selection_widget_->GetNativeWindow()->parent()->StackChildAtBottom( 40646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) selection_widget_->GetNativeWindow()); 40746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) selection_widget_->Show(); 40846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // New selection widget starts with 0 opacity and then fades in. 40946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) selection_widget_->GetNativeWindow()->layer()->SetOpacity(0); 41046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 41146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const gfx::Rect target_bounds = SelectedWindow()->target_bounds(); 41246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) gfx::Vector2d fade_out_direction = 41346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) GetSlideVectorForFadeIn(direction, target_bounds); 41446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) gfx::Display dst_display = gfx::Screen::GetScreenFor(root_window_)-> 41546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) GetDisplayMatching(target_bounds); 41646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) selection_widget_->GetNativeWindow()->SetBoundsInScreen( 41746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) target_bounds - fade_out_direction, dst_display); 41846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 41946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 42046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void WindowGrid::MoveSelectionWidget(WindowSelector::Direction direction, 42146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool recreate_selection_widget, 422116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool out_of_bounds, 423116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool animate) { 42446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // If the selection widget is already active, fade it out in the selection 42546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // direction. 42646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (selection_widget_ && (recreate_selection_widget || out_of_bounds)) { 42746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Animate the old selection widget and then destroy it. 42846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) views::Widget* old_selection = selection_widget_.get(); 42946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) gfx::Vector2d fade_out_direction = 43046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) GetSlideVectorForFadeIn( 43146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) direction, old_selection->GetNativeWindow()->bounds()); 43246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 43346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ui::ScopedLayerAnimationSettings animation_settings( 43446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) old_selection->GetNativeWindow()->layer()->GetAnimator()); 43546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) animation_settings.SetTransitionDuration( 43646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::TimeDelta::FromMilliseconds( 43746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) kOverviewSelectorTransitionMilliseconds)); 43846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) animation_settings.SetPreemptionStrategy( 43946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); 44046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) animation_settings.SetTweenType(gfx::Tween::FAST_OUT_LINEAR_IN); 44146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // CleanupWidgetAfterAnimationObserver will delete itself (and the 44246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // widget) when the movement animation is complete. 44346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) animation_settings.AddObserver( 44446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) new CleanupWidgetAfterAnimationObserver(selection_widget_.Pass())); 44546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) old_selection->SetOpacity(0); 44646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) old_selection->GetNativeWindow()->SetBounds( 44746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) old_selection->GetNativeWindow()->bounds() + fade_out_direction); 44846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) old_selection->Hide(); 44946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 45046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (out_of_bounds) 45146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; 45246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 45346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!selection_widget_) 45446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) InitSelectionWidget(direction); 45546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Send an a11y alert so that if ChromeVox is enabled, the item label is 45646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // read. 45746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) SelectedWindow()->SendFocusAlert(); 45846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // The selection widget is moved to the newly selected item in the same 45946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // grid. 460116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MoveSelectionWidgetToTarget(animate); 46146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 46246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 46346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void WindowGrid::MoveSelectionWidgetToTarget(bool animate) { 46446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (animate) { 46546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ui::ScopedLayerAnimationSettings animation_settings( 46646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) selection_widget_->GetNativeWindow()->layer()->GetAnimator()); 46746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) animation_settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds( 46846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) kOverviewSelectorTransitionMilliseconds)); 46946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) animation_settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN); 47046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) animation_settings.SetPreemptionStrategy( 47146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); 47246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) selection_widget_->SetBounds(SelectedWindow()->target_bounds()); 47346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) selection_widget_->SetOpacity(kWindowOverviewSelectorOpacity); 47446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; 47546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 47646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) selection_widget_->SetBounds(SelectedWindow()->target_bounds()); 47746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) selection_widget_->SetOpacity(kWindowOverviewSelectorOpacity); 47846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 47946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 48046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} // namespace ash 481