Index: ash/common/shelf/shelf_background_animator.cc |
diff --git a/ash/common/shelf/shelf_background_animator.cc b/ash/common/shelf/shelf_background_animator.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..4f3c0df2014a558df27ed3d6c04d3bee49cccb7b |
--- /dev/null |
+++ b/ash/common/shelf/shelf_background_animator.cc |
@@ -0,0 +1,200 @@ |
+// Copyright 2016 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/common/shelf/shelf_background_animator.h" |
+ |
+#include <algorithm> |
+ |
+#include "ash/common/material_design/material_design_controller.h" |
+#include "ash/common/shelf/shelf_background_animator_observer.h" |
+#include "ash/common/shelf/shelf_constants.h" |
+#include "ui/gfx/animation/tween.h" |
+ |
+namespace ash { |
+ |
+namespace { |
+// The total number of animators that will call BackgroundAnimationEnded(). |
+const int kNumAnimators = 3; |
+ |
+const int kMaxAlpha = 255; |
+} // namespace |
+ |
+ShelfBackgroundAnimator::ShelfBackgroundAnimator() |
+ : target_background_type_(SHELF_BACKGROUND_DEFAULT), |
James Cook
2016/06/14 17:50:00
optional: You could init these in the header
bruthig
2016/07/26 19:50:01
Done.
|
+ previous_background_type_(SHELF_BACKGROUND_MAXIMIZED), |
+ previous_opaque_background_alpha_(0), |
+ previous_asset_background_alpha_(0), |
+ previous_item_background_alpha_(0), |
+ can_reuse_animators_(false), |
+ successful_animator_count_(0), |
+ has_animated_once_(false) {} |
+ |
+ShelfBackgroundAnimator::~ShelfBackgroundAnimator() {} |
+ |
+void ShelfBackgroundAnimator::AddObserver( |
+ ShelfBackgroundAnimatorObserver* observer) { |
+ observers_.AddObserver(observer); |
+} |
+ |
+void ShelfBackgroundAnimator::RemoveObserver( |
+ ShelfBackgroundAnimatorObserver* observer) { |
+ observers_.RemoveObserver(observer); |
+} |
+ |
+void ShelfBackgroundAnimator::PaintBackground( |
+ ShelfBackgroundType background_type, |
+ BackgroundAnimatorChangeType change_type) { |
+ // The first call to animate should always succeed so that observers can |
+ // initialize themselves. |
+ // |
+ // It simplifies animator re-use logic if the first/existing animation request |
+ // wins. The BackgroundAnimator performs a similar check anyway. |
+ if (has_animated_once_ && target_background_type_ == background_type) { |
James Cook
2016/06/14 17:50:01
I don't understand how this matches the comment. I
bruthig
2016/07/26 19:50:01
Updated, PTAL.
|
+ return; |
+ } |
James Cook
2016/06/14 17:50:01
nit: no braces
bruthig
2016/07/26 19:50:01
Done.
|
+ |
+ // Ensure BackgroundAnimationEnded() has been called for all the |
+ // BackgroundAnimators owned by this so that |successful_animator_count_| |
+ // is stable and doesn't get updated as a side effect of destroying/animating |
+ // the animators. |
+ StopAnimators(); |
+ |
+ bool show_background = true; |
+ if (can_reuse_animators_ && previous_background_type_ == background_type) { |
+ DCHECK_EQ(opaque_background_animator_->paints_background(), |
+ asset_background_animator_->paints_background()); |
+ DCHECK_EQ(asset_background_animator_->paints_background(), |
+ item_background_animator_->paints_background()); |
+ |
+ show_background = !opaque_background_animator_->paints_background(); |
+ } else { |
+ CreateAnimators(background_type, change_type); |
+ ConfigureAnimators(background_type, change_type); |
+ |
+ // If all the previous animators completed successfully, then all the |
+ // |previous_shelf_*_alpha_| values are valid end state values. |
+ can_reuse_animators_ = successful_animator_count_ == kNumAnimators; |
+ } |
+ |
+ successful_animator_count_ = 0; |
+ |
+ opaque_background_animator_->SetPaintsBackground(show_background, |
+ change_type); |
+ asset_background_animator_->SetPaintsBackground(show_background, change_type); |
+ item_background_animator_->SetPaintsBackground(show_background, change_type); |
+ |
+ if (target_background_type_ != background_type) { |
+ previous_background_type_ = target_background_type_; |
+ target_background_type_ = background_type; |
+ } |
+ |
+ has_animated_once_ = true; |
+} |
+ |
+void ShelfBackgroundAnimator::OnBackgroundUpdated( |
James Cook
2016/06/14 17:50:01
Per earlier comment about notifications - are you
bruthig
2016/07/26 19:50:02
Yeah, this is ok, the ShelfBackgroundAnimator only
|
+ ShelfBackgroundType background_type, |
+ BackgroundAnimatorChangeType change_type) { |
+ PaintBackground(background_type, change_type); |
+} |
+ |
+void ShelfBackgroundAnimator::UpdateBackground(BackgroundAnimator* animator, |
+ int alpha) { |
+ if (animator == opaque_background_animator_.get()) { |
+ FOR_EACH_OBSERVER(ShelfBackgroundAnimatorObserver, observers_, |
+ UpdateShelfOpaqueBackground(alpha)); |
+ previous_opaque_background_alpha_ = alpha; |
+ } else if (animator == asset_background_animator_.get()) { |
+ FOR_EACH_OBSERVER(ShelfBackgroundAnimatorObserver, observers_, |
+ UpdateShelfAssetBackground(alpha)); |
+ previous_asset_background_alpha_ = alpha; |
+ } else if (animator == item_background_animator_.get()) { |
+ FOR_EACH_OBSERVER(ShelfBackgroundAnimatorObserver, observers_, |
+ UpdateShelfItemBackground(alpha)); |
+ previous_item_background_alpha_ = alpha; |
+ } else { |
+ NOTREACHED(); |
+ } |
+} |
+ |
+void ShelfBackgroundAnimator::BackgroundAnimationEnded( |
+ BackgroundAnimator* animator, |
+ bool successful) { |
+ if (successful) { |
+ ++successful_animator_count_; |
+ DCHECK_LE(successful_animator_count_, kNumAnimators); |
+ } |
+} |
+ |
+void ShelfBackgroundAnimator::CreateAnimators( |
+ ShelfBackgroundType background_type, |
+ BackgroundAnimatorChangeType change_type) { |
+ const bool is_material = MaterialDesignController::IsShelfMaterial(); |
+ |
+ switch (background_type) { |
+ case SHELF_BACKGROUND_DEFAULT: |
+ opaque_background_animator_.reset( |
+ new BackgroundAnimator(this, previous_opaque_background_alpha_, 0)); |
+ asset_background_animator_.reset( |
+ new BackgroundAnimator(this, previous_asset_background_alpha_, 0)); |
+ item_background_animator_.reset( |
+ new BackgroundAnimator(this, previous_item_background_alpha_, |
+ GetShelfConstant(SHELF_BACKGROUND_ALPHA))); |
+ break; |
+ case SHELF_BACKGROUND_OVERLAP: |
+ opaque_background_animator_.reset(new BackgroundAnimator( |
+ this, previous_opaque_background_alpha_, |
+ is_material ? GetShelfConstant(SHELF_BACKGROUND_ALPHA) : 0)); |
+ asset_background_animator_.reset(new BackgroundAnimator( |
+ this, previous_asset_background_alpha_, |
+ is_material ? 0 : GetShelfConstant(SHELF_BACKGROUND_ALPHA))); |
+ item_background_animator_.reset(new BackgroundAnimator( |
+ this, previous_item_background_alpha_, |
+ is_material ? 0 : GetShelfConstant(SHELF_BACKGROUND_ALPHA))); |
+ break; |
+ case SHELF_BACKGROUND_MAXIMIZED: |
+ opaque_background_animator_.reset(new BackgroundAnimator( |
+ this, previous_opaque_background_alpha_, kMaxAlpha)); |
+ asset_background_animator_.reset(new BackgroundAnimator( |
+ this, previous_asset_background_alpha_, |
+ is_material ? 0 : GetShelfConstant(SHELF_BACKGROUND_ALPHA))); |
+ item_background_animator_.reset(new BackgroundAnimator( |
+ this, previous_item_background_alpha_, is_material ? 0 : kMaxAlpha)); |
+ break; |
+ } |
+} |
+ |
+void ShelfBackgroundAnimator::StopAnimators() { |
+ if (opaque_background_animator_) |
+ opaque_background_animator_->Stop(); |
+ if (asset_background_animator_) |
+ asset_background_animator_->Stop(); |
+ if (item_background_animator_) |
+ item_background_animator_->Stop(); |
+} |
+ |
+void ShelfBackgroundAnimator::ConfigureAnimators( |
+ ShelfBackgroundType background_type, |
+ BackgroundAnimatorChangeType change_type) { |
+ const bool is_material = MaterialDesignController::IsShelfMaterial(); |
+ int duration_ms = 0; |
+ if (change_type != BACKGROUND_CHANGE_IMMEDIATE) { |
+ switch (background_type) { |
+ case SHELF_BACKGROUND_DEFAULT: |
+ duration_ms = is_material ? 500 : 1000; |
+ break; |
+ case SHELF_BACKGROUND_OVERLAP: |
+ duration_ms = is_material ? 500 : 1000; |
+ break; |
+ case SHELF_BACKGROUND_MAXIMIZED: |
+ duration_ms = is_material ? 250 : 1000; |
+ break; |
+ } |
+ } |
+ |
+ opaque_background_animator_->SetDuration(duration_ms); |
+ asset_background_animator_->SetDuration(duration_ms); |
+ item_background_animator_->SetDuration(duration_ms); |
+} |
+ |
+} // namespace ash |