OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 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/common/shelf/shelf_background_animator.h" |
| 6 |
| 7 #include <algorithm> |
| 8 |
| 9 #include "ash/common/material_design/material_design_controller.h" |
| 10 #include "ash/common/shelf/shelf_background_animator_observer.h" |
| 11 #include "ash/common/shelf/shelf_constants.h" |
| 12 #include "ash/common/shelf/wm_shelf.h" |
| 13 |
| 14 namespace ash { |
| 15 |
| 16 namespace { |
| 17 // The total number of animators that will call BackgroundAnimationEnded(). |
| 18 const int kNumAnimators = 3; |
| 19 |
| 20 const int kMaxAlpha = 255; |
| 21 } // namespace |
| 22 |
| 23 ShelfBackgroundAnimator::ShelfBackgroundAnimator( |
| 24 ShelfBackgroundType background_type, |
| 25 WmShelf* wm_shelf) |
| 26 : wm_shelf_(wm_shelf) { |
| 27 if (wm_shelf_) |
| 28 wm_shelf_->AddObserver(this); |
| 29 // Initialize animators so that adding observers get notified with consistent |
| 30 // values. |
| 31 AnimateBackground(background_type, BACKGROUND_CHANGE_IMMEDIATE); |
| 32 } |
| 33 |
| 34 ShelfBackgroundAnimator::~ShelfBackgroundAnimator() { |
| 35 if (wm_shelf_) |
| 36 wm_shelf_->RemoveObserver(this); |
| 37 } |
| 38 |
| 39 void ShelfBackgroundAnimator::AddObserver( |
| 40 ShelfBackgroundAnimatorObserver* observer) { |
| 41 observers_.AddObserver(observer); |
| 42 |
| 43 observer->UpdateShelfOpaqueBackground(opaque_background_animator_->alpha()); |
| 44 observer->UpdateShelfAssetBackground(asset_background_animator_->alpha()); |
| 45 observer->UpdateShelfItemBackground(item_background_animator_->alpha()); |
| 46 } |
| 47 |
| 48 void ShelfBackgroundAnimator::RemoveObserver( |
| 49 ShelfBackgroundAnimatorObserver* observer) { |
| 50 observers_.RemoveObserver(observer); |
| 51 } |
| 52 |
| 53 void ShelfBackgroundAnimator::PaintBackground( |
| 54 ShelfBackgroundType background_type, |
| 55 BackgroundAnimatorChangeType change_type) { |
| 56 if (target_background_type_ == background_type && |
| 57 change_type == BACKGROUND_CHANGE_ANIMATE) { |
| 58 return; |
| 59 } |
| 60 |
| 61 AnimateBackground(background_type, change_type); |
| 62 } |
| 63 |
| 64 void ShelfBackgroundAnimator::OnBackgroundTypeChanged( |
| 65 ShelfBackgroundType background_type, |
| 66 BackgroundAnimatorChangeType change_type) { |
| 67 PaintBackground(background_type, change_type); |
| 68 } |
| 69 |
| 70 void ShelfBackgroundAnimator::UpdateBackground(BackgroundAnimator* animator, |
| 71 int alpha) { |
| 72 OnAlphaChanged(animator, alpha); |
| 73 } |
| 74 |
| 75 void ShelfBackgroundAnimator::BackgroundAnimationEnded( |
| 76 BackgroundAnimator* animator) { |
| 77 ++successful_animator_count_; |
| 78 DCHECK_LE(successful_animator_count_, kNumAnimators); |
| 79 // UpdateBackground() is only called when alpha values change, this ensures |
| 80 // observers are always notified for every background change. |
| 81 OnAlphaChanged(animator, animator->alpha()); |
| 82 } |
| 83 |
| 84 void ShelfBackgroundAnimator::OnAlphaChanged(BackgroundAnimator* animator, |
| 85 int alpha) { |
| 86 if (animator == opaque_background_animator_.get()) { |
| 87 FOR_EACH_OBSERVER(ShelfBackgroundAnimatorObserver, observers_, |
| 88 UpdateShelfOpaqueBackground(alpha)); |
| 89 } else if (animator == asset_background_animator_.get()) { |
| 90 FOR_EACH_OBSERVER(ShelfBackgroundAnimatorObserver, observers_, |
| 91 UpdateShelfAssetBackground(alpha)); |
| 92 } else if (animator == item_background_animator_.get()) { |
| 93 FOR_EACH_OBSERVER(ShelfBackgroundAnimatorObserver, observers_, |
| 94 UpdateShelfItemBackground(alpha)); |
| 95 } else { |
| 96 NOTREACHED(); |
| 97 } |
| 98 } |
| 99 |
| 100 void ShelfBackgroundAnimator::AnimateBackground( |
| 101 ShelfBackgroundType background_type, |
| 102 BackgroundAnimatorChangeType change_type) { |
| 103 // Ensure BackgroundAnimationEnded() has been called for all the |
| 104 // BackgroundAnimators owned by this so that |successful_animator_count_| |
| 105 // is stable and doesn't get updated as a side effect of destroying/animating |
| 106 // the animators. |
| 107 StopAnimators(); |
| 108 |
| 109 bool show_background = true; |
| 110 if (can_reuse_animators_ && previous_background_type_ == background_type) { |
| 111 DCHECK_EQ(opaque_background_animator_->paints_background(), |
| 112 asset_background_animator_->paints_background()); |
| 113 DCHECK_EQ(asset_background_animator_->paints_background(), |
| 114 item_background_animator_->paints_background()); |
| 115 |
| 116 show_background = !opaque_background_animator_->paints_background(); |
| 117 } else { |
| 118 CreateAnimators(background_type, change_type); |
| 119 |
| 120 // If all the previous animators completed successfully and the animation |
| 121 // was between 2 distinct states, then the last alpha values are valid |
| 122 // end state values. |
| 123 can_reuse_animators_ = target_background_type_ != background_type && |
| 124 successful_animator_count_ == kNumAnimators; |
| 125 } |
| 126 |
| 127 successful_animator_count_ = 0; |
| 128 |
| 129 opaque_background_animator_->SetPaintsBackground(show_background, |
| 130 change_type); |
| 131 asset_background_animator_->SetPaintsBackground(show_background, change_type); |
| 132 item_background_animator_->SetPaintsBackground(show_background, change_type); |
| 133 |
| 134 if (target_background_type_ != background_type) { |
| 135 previous_background_type_ = target_background_type_; |
| 136 target_background_type_ = background_type; |
| 137 } |
| 138 } |
| 139 |
| 140 void ShelfBackgroundAnimator::CreateAnimators( |
| 141 ShelfBackgroundType background_type, |
| 142 BackgroundAnimatorChangeType change_type) { |
| 143 const int opaque_background_alpha = |
| 144 opaque_background_animator_ ? opaque_background_animator_->alpha() : 0; |
| 145 const int asset_background_alpha = |
| 146 asset_background_animator_ ? asset_background_animator_->alpha() : 0; |
| 147 const int item_background_alpha = |
| 148 item_background_animator_ ? item_background_animator_->alpha() : 0; |
| 149 |
| 150 const bool is_material = MaterialDesignController::IsShelfMaterial(); |
| 151 int duration_ms = 0; |
| 152 |
| 153 switch (background_type) { |
| 154 case SHELF_BACKGROUND_DEFAULT: |
| 155 duration_ms = is_material ? 500 : 1000; |
| 156 opaque_background_animator_.reset( |
| 157 new BackgroundAnimator(this, opaque_background_alpha, 0)); |
| 158 asset_background_animator_.reset( |
| 159 new BackgroundAnimator(this, asset_background_alpha, 0)); |
| 160 item_background_animator_.reset( |
| 161 new BackgroundAnimator(this, item_background_alpha, |
| 162 GetShelfConstant(SHELF_BACKGROUND_ALPHA))); |
| 163 break; |
| 164 case SHELF_BACKGROUND_OVERLAP: |
| 165 duration_ms = is_material ? 500 : 1000; |
| 166 opaque_background_animator_.reset(new BackgroundAnimator( |
| 167 this, opaque_background_alpha, |
| 168 is_material ? GetShelfConstant(SHELF_BACKGROUND_ALPHA) : 0)); |
| 169 asset_background_animator_.reset(new BackgroundAnimator( |
| 170 this, asset_background_alpha, |
| 171 is_material ? 0 : GetShelfConstant(SHELF_BACKGROUND_ALPHA))); |
| 172 item_background_animator_.reset(new BackgroundAnimator( |
| 173 this, item_background_alpha, |
| 174 is_material ? 0 : GetShelfConstant(SHELF_BACKGROUND_ALPHA))); |
| 175 break; |
| 176 case SHELF_BACKGROUND_MAXIMIZED: |
| 177 duration_ms = is_material ? 250 : 1000; |
| 178 opaque_background_animator_.reset( |
| 179 new BackgroundAnimator(this, opaque_background_alpha, kMaxAlpha)); |
| 180 asset_background_animator_.reset(new BackgroundAnimator( |
| 181 this, asset_background_alpha, |
| 182 is_material ? 0 : GetShelfConstant(SHELF_BACKGROUND_ALPHA))); |
| 183 item_background_animator_.reset(new BackgroundAnimator( |
| 184 this, item_background_alpha, is_material ? 0 : kMaxAlpha)); |
| 185 break; |
| 186 } |
| 187 |
| 188 opaque_background_animator_->SetDuration(duration_ms); |
| 189 asset_background_animator_->SetDuration(duration_ms); |
| 190 item_background_animator_->SetDuration(duration_ms); |
| 191 } |
| 192 |
| 193 void ShelfBackgroundAnimator::StopAnimators() { |
| 194 if (opaque_background_animator_) |
| 195 opaque_background_animator_->Stop(); |
| 196 if (asset_background_animator_) |
| 197 asset_background_animator_->Stop(); |
| 198 if (item_background_animator_) |
| 199 item_background_animator_->Stop(); |
| 200 } |
| 201 |
| 202 } // namespace ash |
OLD | NEW |