Chromium Code Reviews| Index: ash/wm/window_animations.cc |
| diff --git a/ash/wm/window_animations.cc b/ash/wm/window_animations.cc |
| index d644f2e9301a2a60d3f20f010c8560ce5becf7b0..bf25c3f81b61c624d885056b4a1e8ad953d771ff 100644 |
| --- a/ash/wm/window_animations.cc |
| +++ b/ash/wm/window_animations.cc |
| @@ -7,6 +7,8 @@ |
| #include "base/compiler_specific.h" |
| #include "base/logging.h" |
| #include "base/message_loop.h" |
| +#include "base/stl_util.h" |
| +#include "base/time.h" |
| #include "ui/aura/client/aura_constants.h" |
| #include "ui/aura/window.h" |
| #include "ui/aura/window_observer.h" |
| @@ -17,6 +19,12 @@ namespace ash { |
| namespace internal { |
| const char kWindowVisibilityAnimationTypeKey[] = |
| "WindowVisibilityAnimationType"; |
| + |
| +const char kWindowVisibilityAnimationDurationKey[] = |
| + "WindowVisibilityAnimationDuration"; |
| + |
| +const char kWindowVisibilityAnimationTransitionKey[] = |
| + "WindowVisibilityAnimationTransition"; |
| } // namespace internal |
| void SetWindowVisibilityAnimationType(aura::Window* window, |
| @@ -24,6 +32,27 @@ void SetWindowVisibilityAnimationType(aura::Window* window, |
| window->SetIntProperty(internal::kWindowVisibilityAnimationTypeKey, type); |
| } |
| +void SetWindowVisibilityAnimationTransition( |
| + aura::Window* window, |
| + WindowVisibilityAnimationTransition transition) { |
| + window->SetIntProperty(internal::kWindowVisibilityAnimationTransitionKey, |
| + transition); |
| +} |
| + |
| +void SetWindowVisibilityAnimationDuration(aura::Window* window, |
| + const base::TimeDelta& duration) { |
| + window->SetIntProperty(internal::kWindowVisibilityAnimationDurationKey, |
| + static_cast<int>(duration.ToInternalValue())); |
| +} |
| + |
| +bool HasWindowVisibilityAnimationTransition( |
| + aura::Window* window, |
| + WindowVisibilityAnimationTransition transition) { |
| + int prop = window->GetIntProperty( |
| + internal::kWindowVisibilityAnimationTransitionKey); |
| + return !prop || (prop & transition) != 0; |
| +} |
| + |
| namespace internal { |
| namespace { |
| @@ -67,7 +96,9 @@ class HidingWindowAnimationObserver : public ui::ImplicitAnimationObserver, |
| : window_(window) { |
| window_->AddObserver(this); |
| } |
| - virtual ~HidingWindowAnimationObserver() {} |
| + virtual ~HidingWindowAnimationObserver() { |
| + STLDeleteElements(&layers_); |
| + } |
| private: |
| // Overridden from ui::ImplicitAnimationObserver: |
| @@ -84,15 +115,26 @@ class HidingWindowAnimationObserver : public ui::ImplicitAnimationObserver, |
| // Overridden from aura::WindowObserver: |
| virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { |
| DCHECK_EQ(window, window_); |
| - layer_.reset(window_->AcquireLayer()); |
| + DCHECK_EQ(0u, layers_.size()); |
|
Ben Goodger (Google)
2012/01/31 00:50:19
or layers_.empty()
oshima
2012/01/31 01:52:32
Done.
|
| + AcquireAllLayers(window_); |
| window_->RemoveObserver(this); |
| window_ = NULL; |
| } |
| - ui::Layer* layer() { return window_ ? window_->layer() : layer_.get(); } |
| + void AcquireAllLayers(aura::Window* window) { |
| + ui::Layer* layer = window->AcquireLayer(); |
| + if (layer) |
|
Ben Goodger (Google)
2012/01/31 00:50:19
can this ever be NULL?
oshima
2012/01/31 01:52:32
Technically yes. (If someone called AcquireLayer o
|
| + layers_.push_back(layer); |
| + for (aura::Window::Windows::const_iterator it = window->children().begin(); |
| + it != window->children().end(); |
| + ++it) |
| + AcquireAllLayers(*it); |
| + } |
| + |
| + ui::Layer* layer() { return window_ ? window_->layer() : layers_[0]; } |
| aura::Window* window_; |
| - scoped_ptr<ui::Layer> layer_; |
| + std::vector<ui::Layer*> layers_; |
| DISALLOW_COPY_AND_ASSIGN(HidingWindowAnimationObserver); |
| }; |
| @@ -109,6 +151,13 @@ void AnimateShowWindowCommon(aura::Window* window, |
| { |
| // Property sets within this scope will be implicitly animated. |
| ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); |
| + int duration = |
| + window->GetIntProperty(internal::kWindowVisibilityAnimationDurationKey); |
| + if (duration > 0) { |
| + settings.SetTransitionDuration( |
| + base::TimeDelta::FromInternalValue(duration)); |
| + } |
| + |
| window->layer()->SetTransform(end_transform); |
| window->layer()->SetOpacity(kWindowAnimation_ShowOpacity); |
| } |
| @@ -123,6 +172,12 @@ void AnimateHideWindowCommon(aura::Window* window, |
| // Property sets within this scope will be implicitly animated. |
| ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); |
| settings.AddImplicitObserver(new HidingWindowAnimationObserver(window)); |
| + int duration = |
| + window->GetIntProperty(internal::kWindowVisibilityAnimationDurationKey); |
| + if (duration > 0) { |
| + settings.SetTransitionDuration( |
| + base::TimeDelta::FromInternalValue(duration)); |
| + } |
| window->layer()->SetOpacity(kWindowAnimation_HideOpacity); |
| window->layer()->SetTransform(end_transform); |
| @@ -171,37 +226,43 @@ void AnimateHideWindow_Fade(aura::Window* window) { |
| AnimateHideWindowCommon(window, ui::Transform()); |
| } |
| -void AnimateShowWindow(aura::Window* window) { |
| +bool AnimateShowWindow(aura::Window* window) { |
| + if (!HasWindowVisibilityAnimationTransition(window, ANIMATE_SHOW)) |
| + return false; |
| + |
| switch (GetWindowVisibilityAnimationType(window)) { |
| case WINDOW_VISIBILITY_ANIMATION_TYPE_DROP: |
| AnimateShowWindow_Drop(window); |
| - break; |
| + return true; |
| case WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL: |
| AnimateShowWindow_Vertical(window); |
| - break; |
| + return true; |
| case WINDOW_VISIBILITY_ANIMATION_TYPE_FADE: |
| AnimateShowWindow_Fade(window); |
| - break; |
| + return true; |
| default: |
| NOTREACHED(); |
| - break; |
| + return false; |
| } |
| } |
| -void AnimateHideWindow(aura::Window* window) { |
| +bool AnimateHideWindow(aura::Window* window) { |
| + if (!HasWindowVisibilityAnimationTransition(window, ANIMATE_HIDE)) |
| + return false; |
| + |
| switch (GetWindowVisibilityAnimationType(window)) { |
| case WINDOW_VISIBILITY_ANIMATION_TYPE_DROP: |
| AnimateHideWindow_Drop(window); |
| - break; |
| + return true; |
| case WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL: |
| AnimateHideWindow_Vertical(window); |
| - break; |
| + return true; |
| case WINDOW_VISIBILITY_ANIMATION_TYPE_FADE: |
| AnimateHideWindow_Fade(window); |
| - break; |
| + return true; |
| default: |
| NOTREACHED(); |
| - break; |
| + return false; |
| } |
| } |
| @@ -210,15 +271,15 @@ void AnimateHideWindow(aura::Window* window) { |
| //////////////////////////////////////////////////////////////////////////////// |
| // WindowAnimation, public: |
| -void AnimateOnChildWindowVisibilityChanged(aura::Window* window, bool visible) { |
| +bool AnimateOnChildWindowVisibilityChanged(aura::Window* window, bool visible) { |
| if (window->GetIntProperty(aura::client::kAnimationsDisabledKey) == 1) |
| - return; |
| + return false; |
| if (visible) { |
| - AnimateShowWindow(window); |
| + return AnimateShowWindow(window); |
| } else { |
| // Don't start hiding the window again if it's already being hidden. |
| - if (window->layer()->GetTargetOpacity() != 0.0f) |
| - AnimateHideWindow(window); |
| + return window->layer()->GetTargetOpacity() != 0.0f && |
| + AnimateHideWindow(window); |
| } |
| } |