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

Unified 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, 4 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 side-by-side diff with in-line comments
Download patch
« ash/wm/session_state_animator.h ('K') | « ash/wm/session_state_animator.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ash/wm/session_state_animator.cc
diff --git a/ash/wm/session_state_animator.cc b/ash/wm/session_state_animator.cc
new file mode 100644
index 0000000000000000000000000000000000000000..5b8311488e495c7b86f07396357969a73fbd504f
--- /dev/null
+++ b/ash/wm/session_state_animator.cc
@@ -0,0 +1,304 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/wm/session_state_animator.h"
+
+#include "ash/shell.h"
+#include "ash/shell_delegate.h"
+#include "ash/shell_window_ids.h"
+#include "base/time.h"
+#include "third_party/skia/include/core/SkColor.h"
+#include "ui/aura/root_window.h"
+#include "ui/aura/window.h"
+#include "ui/compositor/layer.h"
+#include "ui/compositor/layer_animation_element.h"
+#include "ui/compositor/layer_animation_sequence.h"
+#include "ui/compositor/layer_animator.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/rect.h"
+#include "ui/gfx/size.h"
+#include "ui/gfx/transform.h"
+
+namespace ash {
+
+namespace {
+
+// Amount of time taken to scale the snapshot of the screen down to a
+// slightly-smaller size once the user starts holding the power button. Used
+// for both the pre-lock and pre-shutdown animations.
+const int kSlowCloseAnimMs = 400;
+
+// Amount of time taken to scale the snapshot of the screen back to its original
+// size when the button is released.
+const int kUndoSlowCloseAnimMs = 100;
+
+// Amount of time taken to scale the snapshot down to a point in the center of
+// the screen once the screen has been locked or we've been notified that the
+// system is shutting down.
+const int kFastCloseAnimMs = 150;
+
+// Amount of time taken to make the lock window fade in when the screen is
+// locked.
+const int kLockFadeInAnimMs = 500;
+
+// Slightly-smaller size that we scale the screen down to for the pre-lock and
+// pre-shutdown states.
+const float kSlowCloseSizeRatio = 0.95f;
+
+// Returns the transform that should be applied to containers for the slow-close
+// animation.
+ui::Transform GetSlowCloseTransform() {
+ gfx::Size root_size = Shell::GetPrimaryRootWindow()->bounds().size();
+ ui::Transform transform;
+ transform.SetScale(kSlowCloseSizeRatio, kSlowCloseSizeRatio);
+ transform.ConcatTranslate(
+ floor(0.5 * (1.0 - kSlowCloseSizeRatio) * root_size.width() + 0.5),
+ floor(0.5 * (1.0 - kSlowCloseSizeRatio) * root_size.height() + 0.5));
+ return transform;
+}
+
+// Returns the transform that should be applied to containers for the fast-close
+// animation.
+ui::Transform GetFastCloseTransform() {
+ gfx::Size root_size = Shell::GetPrimaryRootWindow()->bounds().size();
+ ui::Transform transform;
+ transform.SetScale(0.0, 0.0);
+ transform.ConcatTranslate(floor(0.5 * root_size.width() + 0.5),
+ floor(0.5 * root_size.height() + 0.5));
+ return transform;
+}
+
+// Slowly shrinks |window| to a slightly-smaller size.
+void StartSlowCloseAnimationForWindow(aura::Window* window) {
+ ui::LayerAnimator* animator = window->layer()->GetAnimator();
+ animator->set_preemption_strategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ animator->StartAnimation(
+ new ui::LayerAnimationSequence(
+ ui::LayerAnimationElement::CreateTransformElement(
+ GetSlowCloseTransform(),
+ base::TimeDelta::FromMilliseconds(kSlowCloseAnimMs))));
+}
+
+// Quickly undoes the effects of the slow-close animation on |window|.
+void StartUndoSlowCloseAnimationForWindow(aura::Window* window) {
+ ui::LayerAnimator* animator = window->layer()->GetAnimator();
+ animator->set_preemption_strategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ animator->StartAnimation(
+ new ui::LayerAnimationSequence(
+ ui::LayerAnimationElement::CreateTransformElement(
+ ui::Transform(),
+ base::TimeDelta::FromMilliseconds(kUndoSlowCloseAnimMs))));
+}
+
+// Quickly shrinks |window| down to a point in the center of the screen and
+// fades it out to 0 opacity.
+void StartFastCloseAnimationForWindow(aura::Window* window) {
+ ui::LayerAnimator* animator = window->layer()->GetAnimator();
+ animator->set_preemption_strategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ animator->StartAnimation(
+ new ui::LayerAnimationSequence(
+ ui::LayerAnimationElement::CreateTransformElement(
+ GetFastCloseTransform(),
+ base::TimeDelta::FromMilliseconds(kFastCloseAnimMs))));
+ animator->StartAnimation(
+ new ui::LayerAnimationSequence(
+ ui::LayerAnimationElement::CreateOpacityElement(
+ 0.0, base::TimeDelta::FromMilliseconds(kFastCloseAnimMs))));
+}
+
+// Fades |window| in to full opacity.
+void FadeInWindow(aura::Window* window) {
+ ui::LayerAnimator* animator = window->layer()->GetAnimator();
+ animator->set_preemption_strategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ animator->StartAnimation(
+ new ui::LayerAnimationSequence(
+ ui::LayerAnimationElement::CreateOpacityElement(
+ 1.0, base::TimeDelta::FromMilliseconds(kLockFadeInAnimMs))));
+}
+
+// Makes |window| fully transparent instantaneously.
+void HideWindow(aura::Window* window) {
+ window->layer()->SetOpacity(0.0);
+}
+
+// Restores |window| to its original position and scale and full opacity
+// instantaneously.
+void RestoreWindow(aura::Window* window) {
+ window->layer()->SetTransform(ui::Transform());
+ window->layer()->SetOpacity(1.0);
+}
+
+} // namespace
+
+bool SessionStateAnimator::TestApi::ContainerGroupIsAnimated(
+ ContainerGroup group, AnimationType type) const {
+ aura::Window::Windows containers;
+ animator_->GetContainers(group, &containers);
+ for (aura::Window::Windows::const_iterator it = containers.begin();
+ it != containers.end(); ++it) {
+ aura::Window* window = *it;
+ ui::Layer* layer = window->layer();
+
+ switch (type) {
+ case SLOW_CLOSE:
+ if (layer->GetTargetTransform() != GetSlowCloseTransform())
+ return false;
+ break;
+ case UNDO_SLOW_CLOSE:
+ if (layer->GetTargetTransform() != ui::Transform())
+ return false;
+ break;
+ case FAST_CLOSE:
+ if (layer->GetTargetTransform() != GetFastCloseTransform() ||
+ layer->GetTargetOpacity() > 0.0001)
+ return false;
+ break;
+ case FADE_IN:
+ if (layer->GetTargetOpacity() < 0.9999)
+ return false;
+ break;
+ case HIDE:
+ if (layer->GetTargetOpacity() > 0.0001)
+ return false;
+ break;
+ case RESTORE:
+ if (layer->opacity() < 0.9999 || layer->transform() != ui::Transform())
+ return false;
+ break;
+ default:
+ NOTREACHED() << "Unhandled animation type " << type;
+ return false;
+ }
+ }
+ return true;
+}
+
+bool SessionStateAnimator::TestApi::BackgroundLayerIsVisible() const {
+ return animator_->background_layer_.get() &&
+ animator_->background_layer_->visible();
+}
+
+gfx::Rect SessionStateAnimator::TestApi::GetBackgroundLayerBounds() const {
+ ui::Layer* layer = animator_->background_layer_.get();
+ return layer ? layer->bounds() : gfx::Rect();
+}
+
+SessionStateAnimator::SessionStateAnimator() {
+ Shell::GetPrimaryRootWindow()->AddRootWindowObserver(this);
+}
+
+SessionStateAnimator::~SessionStateAnimator() {
+ Shell::GetPrimaryRootWindow()->RemoveRootWindowObserver(this);
+}
+
+// Fills |containers| with the containers described by |group|.
+void SessionStateAnimator::GetContainers(ContainerGroup group,
+ 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.
+ aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
+
+ aura::Window* non_lock_screen_containers = Shell::GetContainer(
+ root_window,
+ internal::kShellWindowId_NonLockScreenContainersContainer);
+ aura::Window* lock_screen_containers = Shell::GetContainer(
+ root_window,
+ internal::kShellWindowId_LockScreenContainersContainer);
+ aura::Window* lock_screen_related_containers = Shell::GetContainer(
+ root_window,
+ internal::kShellWindowId_LockScreenRelatedContainersContainer);
+
+ containers->clear();
+ switch (group) {
+ case ALL_CONTAINERS:
+ containers->push_back(non_lock_screen_containers);
+ containers->push_back(lock_screen_containers);
+ containers->push_back(lock_screen_related_containers);
+ break;
+ case SCREEN_LOCKER_CONTAINERS:
+ containers->push_back(lock_screen_containers);
+ break;
+ case SCREEN_LOCKER_AND_RELATED_CONTAINERS:
+ containers->push_back(lock_screen_containers);
+ containers->push_back(lock_screen_related_containers);
+ break;
+ case ALL_BUT_SCREEN_LOCKER_AND_RELATED_CONTAINERS:
+ containers->push_back(non_lock_screen_containers);
+ break;
+ default:
+ NOTREACHED() << "Unhandled container group " << group;
+ }
+}
+
+// Apply animation |type| to all containers described by |group|.
+void SessionStateAnimator::StartAnimation(ContainerGroup group,
+ AnimationType type) {
+ aura::Window::Windows containers;
+ GetContainers(group, &containers);
+
+ for (aura::Window::Windows::const_iterator it = containers.begin();
+ it != containers.end(); ++it) {
+ aura::Window* window = *it;
+ switch (type) {
+ case SLOW_CLOSE:
+ StartSlowCloseAnimationForWindow(window);
+ break;
+ case UNDO_SLOW_CLOSE:
+ StartUndoSlowCloseAnimationForWindow(window);
+ break;
+ case FAST_CLOSE:
+ StartFastCloseAnimationForWindow(window);
+ break;
+ case FADE_IN:
+ FadeInWindow(window);
+ break;
+ case HIDE:
+ HideWindow(window);
+ break;
+ case RESTORE:
+ RestoreWindow(window);
+ break;
+ default:
+ NOTREACHED() << "Unhandled animation type " << type;
+ }
+ }
+}
+
+void SessionStateAnimator::OnRootWindowResized(const aura::RootWindow* root,
+ const gfx::Size& new_size) {
+ if (background_layer_.get())
+ background_layer_->SetBounds(gfx::Rect(root->bounds().size()));
+}
+
+void SessionStateAnimator::ShowBackgroundLayer() {
+ if (hide_background_layer_timer_.IsRunning())
+ hide_background_layer_timer_.Stop();
+
+ if (!background_layer_.get()) {
+ background_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR));
+ background_layer_->SetColor(SK_ColorBLACK);
+
+ ui::Layer* root_layer = Shell::GetPrimaryRootWindow()->layer();
+ background_layer_->SetBounds(root_layer->bounds());
+ root_layer->Add(background_layer_.get());
+ root_layer->StackAtBottom(background_layer_.get());
+ }
+ background_layer_->SetVisible(true);
+}
+
+void SessionStateAnimator::HideBackgroundLayer() {
+ background_layer_.reset();
+}
+
+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.
+ hide_background_layer_timer_.Stop();
+ hide_background_layer_timer_.Start(
+ FROM_HERE,
+ base::TimeDelta::FromMilliseconds(kUndoSlowCloseAnimMs),
+ this, &SessionStateAnimator::HideBackgroundLayer);
+}
+
+} // namespace ash
« 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