Chromium Code Reviews| 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 |