Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(169)

Side by Side Diff: ash/wm/session_state_animator.cc

Issue 10914016: ash: Extract animator from PowerButtonController (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Naming fixes Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2012 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.
4
5 #include "ash/wm/session_state_animator.h"
6
7 #include "ash/shell.h"
8 #include "ash/shell_delegate.h"
9 #include "ash/shell_window_ids.h"
10 #include "base/time.h"
11 #include "third_party/skia/include/core/SkColor.h"
12 #include "ui/aura/root_window.h"
13 #include "ui/aura/window.h"
14 #include "ui/compositor/layer.h"
15 #include "ui/compositor/layer_animation_element.h"
16 #include "ui/compositor/layer_animation_sequence.h"
17 #include "ui/compositor/layer_animator.h"
18 #include "ui/gfx/canvas.h"
19 #include "ui/gfx/rect.h"
20 #include "ui/gfx/size.h"
21 #include "ui/gfx/transform.h"
22
23 namespace ash {
24
25 namespace {
26
27 // Amount of time taken to scale the snapshot of the screen down to a
28 // slightly-smaller size once the user starts holding the power button. Used
29 // for both the pre-lock and pre-shutdown animations.
30 const int kSlowCloseAnimMs = 400;
31
32 // Amount of time taken to scale the snapshot of the screen back to its original
33 // size when the button is released.
34 const int kUndoSlowCloseAnimMs = 100;
35
36 // Amount of time taken to scale the snapshot down to a point in the center of
37 // the screen once the screen has been locked or we've been notified that the
38 // system is shutting down.
39 const int kFastCloseAnimMs = 150;
40
41 // Amount of time taken to make the lock window fade in when the screen is
42 // locked.
43 const int kLockFadeInAnimMs = 500;
44
45 // Slightly-smaller size that we scale the screen down to for the pre-lock and
46 // pre-shutdown states.
47 const float kSlowCloseSizeRatio = 0.95f;
48
49 // Returns the transform that should be applied to containers for the slow-close
50 // animation.
51 ui::Transform GetSlowCloseTransform() {
52 gfx::Size root_size = Shell::GetPrimaryRootWindow()->bounds().size();
53 ui::Transform transform;
54 transform.SetScale(kSlowCloseSizeRatio, kSlowCloseSizeRatio);
55 transform.ConcatTranslate(
56 floor(0.5 * (1.0 - kSlowCloseSizeRatio) * root_size.width() + 0.5),
57 floor(0.5 * (1.0 - kSlowCloseSizeRatio) * root_size.height() + 0.5));
58 return transform;
59 }
60
61 // Returns the transform that should be applied to containers for the fast-close
62 // animation.
63 ui::Transform GetFastCloseTransform() {
64 gfx::Size root_size = Shell::GetPrimaryRootWindow()->bounds().size();
65 ui::Transform transform;
66 transform.SetScale(0.0, 0.0);
67 transform.ConcatTranslate(floor(0.5 * root_size.width() + 0.5),
68 floor(0.5 * root_size.height() + 0.5));
69 return transform;
70 }
71
72 // Slowly shrinks |window| to a slightly-smaller size.
73 void StartSlowCloseAnimationForWindow(aura::Window* window) {
74 ui::LayerAnimator* animator = window->layer()->GetAnimator();
75 animator->set_preemption_strategy(
76 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
77 animator->StartAnimation(
78 new ui::LayerAnimationSequence(
79 ui::LayerAnimationElement::CreateTransformElement(
80 GetSlowCloseTransform(),
81 base::TimeDelta::FromMilliseconds(kSlowCloseAnimMs))));
82 }
83
84 // Quickly undoes the effects of the slow-close animation on |window|.
85 void StartUndoSlowCloseAnimationForWindow(aura::Window* window) {
86 ui::LayerAnimator* animator = window->layer()->GetAnimator();
87 animator->set_preemption_strategy(
88 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
89 animator->StartAnimation(
90 new ui::LayerAnimationSequence(
91 ui::LayerAnimationElement::CreateTransformElement(
92 ui::Transform(),
93 base::TimeDelta::FromMilliseconds(kUndoSlowCloseAnimMs))));
94 }
95
96 // Quickly shrinks |window| down to a point in the center of the screen and
97 // fades it out to 0 opacity.
98 void StartFastCloseAnimationForWindow(aura::Window* window) {
99 ui::LayerAnimator* animator = window->layer()->GetAnimator();
100 animator->set_preemption_strategy(
101 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
102 animator->StartAnimation(
103 new ui::LayerAnimationSequence(
104 ui::LayerAnimationElement::CreateTransformElement(
105 GetFastCloseTransform(),
106 base::TimeDelta::FromMilliseconds(kFastCloseAnimMs))));
107 animator->StartAnimation(
108 new ui::LayerAnimationSequence(
109 ui::LayerAnimationElement::CreateOpacityElement(
110 0.0, base::TimeDelta::FromMilliseconds(kFastCloseAnimMs))));
111 }
112
113 // Fades |window| in to full opacity.
114 void FadeInWindow(aura::Window* window) {
115 ui::LayerAnimator* animator = window->layer()->GetAnimator();
116 animator->set_preemption_strategy(
117 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
118 animator->StartAnimation(
119 new ui::LayerAnimationSequence(
120 ui::LayerAnimationElement::CreateOpacityElement(
121 1.0, base::TimeDelta::FromMilliseconds(kLockFadeInAnimMs))));
122 }
123
124 // Makes |window| fully transparent instantaneously.
125 void HideWindow(aura::Window* window) {
126 window->layer()->SetOpacity(0.0);
127 }
128
129 // Restores |window| to its original position and scale and full opacity
130 // instantaneously.
131 void RestoreWindow(aura::Window* window) {
132 window->layer()->SetTransform(ui::Transform());
133 window->layer()->SetOpacity(1.0);
134 }
135
136 } // namespace
137
138 bool SessionStateAnimator::TestApi::ContainerGroupIsAnimated(
139 ContainerGroup group, AnimationType type) const {
140 aura::Window::Windows containers;
141 animator_->GetContainers(group, &containers);
142 for (aura::Window::Windows::const_iterator it = containers.begin();
143 it != containers.end(); ++it) {
144 aura::Window* window = *it;
145 ui::Layer* layer = window->layer();
146
147 switch (type) {
148 case SLOW_CLOSE:
149 if (layer->GetTargetTransform() != GetSlowCloseTransform())
150 return false;
151 break;
152 case UNDO_SLOW_CLOSE:
153 if (layer->GetTargetTransform() != ui::Transform())
154 return false;
155 break;
156 case FAST_CLOSE:
157 if (layer->GetTargetTransform() != GetFastCloseTransform() ||
158 layer->GetTargetOpacity() > 0.0001)
159 return false;
160 break;
161 case FADE_IN:
162 if (layer->GetTargetOpacity() < 0.9999)
163 return false;
164 break;
165 case HIDE:
166 if (layer->GetTargetOpacity() > 0.0001)
167 return false;
168 break;
169 case RESTORE:
170 if (layer->opacity() < 0.9999 || layer->transform() != ui::Transform())
171 return false;
172 break;
173 default:
174 NOTREACHED() << "Unhandled animation type " << type;
175 return false;
176 }
177 }
178 return true;
179 }
180
181 bool SessionStateAnimator::TestApi::BackgroundLayerIsVisible() const {
182 return animator_->background_layer_.get() &&
183 animator_->background_layer_->visible();
184 }
185
186 gfx::Rect SessionStateAnimator::TestApi::GetBackgroundLayerBounds() const {
187 ui::Layer* layer = animator_->background_layer_.get();
188 return layer ? layer->bounds() : gfx::Rect();
189 }
190
191 SessionStateAnimator::SessionStateAnimator() {
192 Shell::GetPrimaryRootWindow()->AddRootWindowObserver(this);
193 }
194
195 SessionStateAnimator::~SessionStateAnimator() {
196 Shell::GetPrimaryRootWindow()->RemoveRootWindowObserver(this);
197 }
198
199 // Fills |containers| with the containers described by |group|.
200 void SessionStateAnimator::GetContainers(ContainerGroup group,
201 aura::Window::Windows* containers) {
Daniel Erat 2012/08/31 17:02:12 nit: fix indenting
Denis Kuznetsov (DE-MUC) 2012/09/28 11:52:43 Done.
202 aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
203
204 aura::Window* non_lock_screen_containers = Shell::GetContainer(
205 root_window,
206 internal::kShellWindowId_NonLockScreenContainersContainer);
207 aura::Window* lock_screen_containers = Shell::GetContainer(
208 root_window,
209 internal::kShellWindowId_LockScreenContainersContainer);
210 aura::Window* lock_screen_related_containers = Shell::GetContainer(
211 root_window,
212 internal::kShellWindowId_LockScreenRelatedContainersContainer);
213
214 containers->clear();
215 switch (group) {
216 case ALL_CONTAINERS:
217 containers->push_back(non_lock_screen_containers);
218 containers->push_back(lock_screen_containers);
219 containers->push_back(lock_screen_related_containers);
220 break;
221 case SCREEN_LOCKER_CONTAINERS:
222 containers->push_back(lock_screen_containers);
223 break;
224 case SCREEN_LOCKER_AND_RELATED_CONTAINERS:
225 containers->push_back(lock_screen_containers);
226 containers->push_back(lock_screen_related_containers);
227 break;
228 case ALL_BUT_SCREEN_LOCKER_AND_RELATED_CONTAINERS:
229 containers->push_back(non_lock_screen_containers);
230 break;
231 default:
232 NOTREACHED() << "Unhandled container group " << group;
233 }
234 }
235
236 // Apply animation |type| to all containers described by |group|.
237 void SessionStateAnimator::StartAnimation(ContainerGroup group,
238 AnimationType type) {
239 aura::Window::Windows containers;
240 GetContainers(group, &containers);
241
242 for (aura::Window::Windows::const_iterator it = containers.begin();
243 it != containers.end(); ++it) {
244 aura::Window* window = *it;
245 switch (type) {
246 case SLOW_CLOSE:
247 StartSlowCloseAnimationForWindow(window);
248 break;
249 case UNDO_SLOW_CLOSE:
250 StartUndoSlowCloseAnimationForWindow(window);
251 break;
252 case FAST_CLOSE:
253 StartFastCloseAnimationForWindow(window);
254 break;
255 case FADE_IN:
256 FadeInWindow(window);
257 break;
258 case HIDE:
259 HideWindow(window);
260 break;
261 case RESTORE:
262 RestoreWindow(window);
263 break;
264 default:
265 NOTREACHED() << "Unhandled animation type " << type;
266 }
267 }
268 }
269
270 void SessionStateAnimator::OnRootWindowResized(const aura::RootWindow* root,
271 const gfx::Size& new_size) {
272 if (background_layer_.get())
273 background_layer_->SetBounds(gfx::Rect(root->bounds().size()));
274 }
275
276 void SessionStateAnimator::ShowBackgroundLayer() {
277 if (hide_background_layer_timer_.IsRunning())
278 hide_background_layer_timer_.Stop();
279
280 if (!background_layer_.get()) {
281 background_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR));
282 background_layer_->SetColor(SK_ColorBLACK);
283
284 ui::Layer* root_layer = Shell::GetPrimaryRootWindow()->layer();
285 background_layer_->SetBounds(root_layer->bounds());
286 root_layer->Add(background_layer_.get());
287 root_layer->StackAtBottom(background_layer_.get());
288 }
289 background_layer_->SetVisible(true);
290 }
291
292 void SessionStateAnimator::HideBackgroundLayer() {
293 background_layer_.reset();
294 }
295
296 void SessionStateAnimator::DropBackgroundLayer() {
Daniel Erat 2012/08/31 17:02:12 both this method and HideBackgroundLayer drop the
Denis Kuznetsov (DE-MUC) 2012/09/28 11:52:43 Done.
297 hide_background_layer_timer_.Stop();
298 hide_background_layer_timer_.Start(
299 FROM_HERE,
300 base::TimeDelta::FromMilliseconds(kUndoSlowCloseAnimMs),
301 this, &SessionStateAnimator::HideBackgroundLayer);
302 }
303
304 } // namespace ash
OLDNEW
« ash/wm/session_state_animator.h ('K') | « ash/wm/session_state_animator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698