1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ash/wm/overview/window_selector_panels.h"
7 #include "ash/screen_ash.h"
9 #include "ash/shell_window_ids.h"
10 #include "ash/wm/overview/scoped_transform_overview_window.h"
11 #include "ash/wm/panels/panel_layout_manager.h"
12 #include "ui/aura/client/screen_position_client.h"
13 #include "ui/aura/window.h"
14 #include "ui/compositor/layer.h"
15 #include "ui/compositor/layer_animation_observer.h"
16 #include "ui/compositor/layer_animation_sequence.h"
17 #include "ui/views/widget/widget.h"
23 const int kPanelCalloutFadeInDurationMilliseconds
= 50;
25 // This class extends ScopedTransformOverviewMode to hide and show the callout
26 // widget for a panel window when entering / leaving overview mode.
27 class ScopedTransformPanelWindow
: public ScopedTransformOverviewWindow
{
29 ScopedTransformPanelWindow(aura::Window
* window
);
30 virtual ~ScopedTransformPanelWindow();
32 // ScopedTransformOverviewWindow overrides:
33 virtual void PrepareForOverview() OVERRIDE
;
36 // Returns the callout widget for the transformed panel.
37 views::Widget
* GetCalloutWidget();
39 // Restores the callout visibility.
40 void RestoreCallout();
45 bool callout_visible_
;
47 DISALLOW_COPY_AND_ASSIGN(ScopedTransformPanelWindow
);
50 ScopedTransformPanelWindow::ScopedTransformPanelWindow(aura::Window
* window
)
51 : ScopedTransformOverviewWindow(window
) {
54 ScopedTransformPanelWindow::~ScopedTransformPanelWindow() {
55 // window() will be NULL if the window was destroyed.
60 void ScopedTransformPanelWindow::PrepareForOverview() {
61 ScopedTransformOverviewWindow::PrepareForOverview();
62 GetCalloutWidget()->GetLayer()->SetOpacity(0.0f
);
65 views::Widget
* ScopedTransformPanelWindow::GetCalloutWidget() {
66 DCHECK(window()->parent()->id() == internal::kShellWindowId_PanelContainer
);
67 internal::PanelLayoutManager
* panel_layout_manager
=
68 static_cast<internal::PanelLayoutManager
*>(
69 window()->parent()->layout_manager());
70 return panel_layout_manager
->GetCalloutWidgetForPanel(window());
73 void ScopedTransformPanelWindow::RestoreCallout() {
74 scoped_ptr
<ui::LayerAnimationSequence
> sequence(
75 new ui::LayerAnimationSequence
);
76 ui::LayerAnimationElement::AnimatableProperties paused_properties
;
77 paused_properties
.insert(ui::LayerAnimationElement::OPACITY
);
78 sequence
->AddElement(ui::LayerAnimationElement::CreatePauseElement(
79 paused_properties
, base::TimeDelta::FromMilliseconds(
80 ScopedTransformOverviewWindow::kTransitionMilliseconds
)));
81 sequence
->AddElement(ui::LayerAnimationElement::CreateOpacityElement(1,
82 base::TimeDelta::FromMilliseconds(
83 kPanelCalloutFadeInDurationMilliseconds
)));
84 GetCalloutWidget()->GetLayer()->GetAnimator()->StartAnimation(
90 WindowSelectorPanels::WindowSelectorPanels() {
93 WindowSelectorPanels::~WindowSelectorPanels() {
96 void WindowSelectorPanels::AddWindow(aura::Window
* window
) {
97 transform_windows_
.push_back(new ScopedTransformPanelWindow(window
));
100 aura::RootWindow
* WindowSelectorPanels::GetRootWindow() {
101 return transform_windows_
.front()->window()->GetRootWindow();
104 aura::Window
* WindowSelectorPanels::TargetedWindow(const aura::Window
* target
) {
105 for (WindowList::const_iterator iter
= transform_windows_
.begin();
106 iter
!= transform_windows_
.end(); ++iter
) {
107 if ((*iter
)->Contains(target
))
108 return (*iter
)->window();
113 void WindowSelectorPanels::RestoreWindowOnExit(aura::Window
* window
) {
114 for (WindowList::iterator iter
= transform_windows_
.begin();
115 iter
!= transform_windows_
.end(); ++iter
) {
116 if ((*iter
)->Contains(window
)) {
117 (*iter
)->RestoreWindowOnExit();
123 aura::Window
* WindowSelectorPanels::SelectionWindow() {
124 return transform_windows_
.front()->window();
127 void WindowSelectorPanels::RemoveWindow(const aura::Window
* window
) {
128 for (WindowList::iterator iter
= transform_windows_
.begin();
129 iter
!= transform_windows_
.end(); ++iter
) {
130 if ((*iter
)->Contains(window
)) {
131 (*iter
)->OnWindowDestroyed();
132 transform_windows_
.erase(iter
);
138 bool WindowSelectorPanels::empty() const {
139 return transform_windows_
.empty();
142 void WindowSelectorPanels::PrepareForOverview() {
143 for (WindowList::iterator iter
= transform_windows_
.begin();
144 iter
!= transform_windows_
.end(); ++iter
) {
145 (*iter
)->PrepareForOverview();
149 void WindowSelectorPanels::SetItemBounds(aura::RootWindow
* root_window
,
150 const gfx::Rect
& target_bounds
,
152 gfx::Rect bounding_rect
;
153 for (WindowList::iterator iter
= transform_windows_
.begin();
154 iter
!= transform_windows_
.end(); ++iter
) {
155 bounding_rect
.Union((*iter
)->GetBoundsInScreen());
157 set_bounds(ScopedTransformOverviewWindow::
158 ShrinkRectToFitPreservingAspectRatio(bounding_rect
, target_bounds
));
159 gfx::Transform bounding_transform
=
160 ScopedTransformOverviewWindow::GetTransformForRect(bounding_rect
,
162 for (WindowList::iterator iter
= transform_windows_
.begin();
163 iter
!= transform_windows_
.end(); ++iter
) {
164 gfx::Transform transform
;
165 gfx::Rect bounds
= (*iter
)->GetBoundsInScreen();
166 transform
.Translate(bounding_rect
.x() - bounds
.x(),
167 bounding_rect
.y() - bounds
.y());
168 transform
.PreconcatTransform(bounding_transform
);
169 transform
.Translate(bounds
.x() - bounding_rect
.x(),
170 bounds
.y() - bounding_rect
.y());
171 (*iter
)->SetTransform(root_window
, transform
, animate
);