Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ash/common/shelf/shelf_background_animator.h" | 5 #include "ash/common/shelf/shelf_background_animator.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "ash/common/material_design/material_design_controller.h" | 9 #include "ash/common/material_design/material_design_controller.h" |
| 10 #include "ash/common/shelf/shelf_background_animator_observer.h" | 10 #include "ash/common/shelf/shelf_background_animator_observer.h" |
| 11 #include "ash/common/shelf/shelf_constants.h" | 11 #include "ash/common/shelf/shelf_constants.h" |
| 12 #include "ash/common/shelf/wm_shelf.h" | 12 #include "ash/common/shelf/wm_shelf.h" |
| 13 #include "ui/gfx/animation/slide_animation.h" | |
| 13 | 14 |
| 14 namespace ash { | 15 namespace ash { |
| 15 | 16 |
| 16 namespace { | 17 const int ShelfBackgroundAnimator::kMaxAlpha = 255; |
|
James Cook
2017/02/08 00:31:27
Can this be initialized in header?
bruthig
2017/02/10 18:49:09
Done.
| |
| 17 // The total number of animators that will call BackgroundAnimationEnded(). | |
| 18 const int kNumAnimators = 3; | |
| 19 | 18 |
| 20 const int kMaxAlpha = 255; | 19 void ShelfBackgroundAnimator::AnimationValues::UpdateCurrentValues(double t) { |
| 21 } // namespace | 20 current_alpha_ = |
| 21 gfx::Tween::IntValueBetween(t, initial_alpha_, target_alpha_); | |
| 22 } | |
| 23 | |
| 24 void ShelfBackgroundAnimator::AnimationValues::SetTargetValues( | |
| 25 int target_alpha) { | |
| 26 DCHECK_LE(target_alpha, kMaxAlpha); | |
| 27 DCHECK_GE(target_alpha, 0); | |
| 28 initial_alpha_ = current_alpha_; | |
| 29 target_alpha_ = target_alpha; | |
| 30 } | |
| 22 | 31 |
| 23 ShelfBackgroundAnimator::ShelfBackgroundAnimator( | 32 ShelfBackgroundAnimator::ShelfBackgroundAnimator( |
| 24 ShelfBackgroundType background_type, | 33 ShelfBackgroundType background_type, |
| 25 WmShelf* wm_shelf) | 34 WmShelf* wm_shelf) |
| 26 : wm_shelf_(wm_shelf) { | 35 : wm_shelf_(wm_shelf) { |
| 27 if (wm_shelf_) | 36 if (wm_shelf_) |
| 28 wm_shelf_->AddObserver(this); | 37 wm_shelf_->AddObserver(this); |
| 29 // Initialize animators so that adding observers get notified with consistent | 38 // Initialize animators so that adding observers get notified with consistent |
| 30 // values. | 39 // values. |
| 31 AnimateBackground(background_type, BACKGROUND_CHANGE_IMMEDIATE); | 40 AnimateBackground(background_type, gfx::ANIMATION_CHANGE_IMMEDIATE); |
| 32 } | 41 } |
| 33 | 42 |
| 34 ShelfBackgroundAnimator::~ShelfBackgroundAnimator() { | 43 ShelfBackgroundAnimator::~ShelfBackgroundAnimator() { |
| 35 if (wm_shelf_) | 44 if (wm_shelf_) |
| 36 wm_shelf_->RemoveObserver(this); | 45 wm_shelf_->RemoveObserver(this); |
| 37 } | 46 } |
| 38 | 47 |
| 39 void ShelfBackgroundAnimator::AddObserver( | 48 void ShelfBackgroundAnimator::AddObserver( |
| 40 ShelfBackgroundAnimatorObserver* observer) { | 49 ShelfBackgroundAnimatorObserver* observer) { |
| 41 observers_.AddObserver(observer); | 50 observers_.AddObserver(observer); |
| 42 Initialize(observer); | 51 NotifyObserver(observer); |
| 43 } | 52 } |
| 44 | 53 |
| 45 void ShelfBackgroundAnimator::RemoveObserver( | 54 void ShelfBackgroundAnimator::RemoveObserver( |
| 46 ShelfBackgroundAnimatorObserver* observer) { | 55 ShelfBackgroundAnimatorObserver* observer) { |
| 47 observers_.RemoveObserver(observer); | 56 observers_.RemoveObserver(observer); |
| 48 } | 57 } |
| 49 | 58 |
| 50 void ShelfBackgroundAnimator::Initialize( | 59 void ShelfBackgroundAnimator::NotifyObserver( |
| 51 ShelfBackgroundAnimatorObserver* observer) const { | 60 ShelfBackgroundAnimatorObserver* observer) { |
| 52 observer->UpdateShelfOpaqueBackground(opaque_background_animator_->alpha()); | 61 observer->UpdateShelfBackground(shelf_background_values_.current_alpha()); |
| 53 observer->UpdateShelfItemBackground(item_background_animator_->alpha()); | 62 observer->UpdateShelfItemBackground(item_background_values_.current_alpha()); |
| 54 } | 63 } |
| 55 | 64 |
| 56 void ShelfBackgroundAnimator::PaintBackground( | 65 void ShelfBackgroundAnimator::PaintBackground( |
| 57 ShelfBackgroundType background_type, | 66 ShelfBackgroundType background_type, |
| 58 BackgroundAnimatorChangeType change_type) { | 67 gfx::AnimationChangeType change_type) { |
| 59 if (target_background_type_ == background_type && | 68 if (target_background_type_ == background_type && |
| 60 change_type == BACKGROUND_CHANGE_ANIMATE) { | 69 change_type == gfx::ANIMATION_CHANGE_ANIMATE) { |
| 61 return; | 70 return; |
| 62 } | 71 } |
| 63 | 72 |
| 64 AnimateBackground(background_type, change_type); | 73 AnimateBackground(background_type, change_type); |
| 65 } | 74 } |
| 66 | 75 |
| 76 void ShelfBackgroundAnimator::AnimationProgressed( | |
| 77 const gfx::Animation* animation) { | |
| 78 shelf_background_values_.UpdateCurrentValues(animation->GetCurrentValue()); | |
| 79 item_background_values_.UpdateCurrentValues(animation->GetCurrentValue()); | |
| 80 NotifyObservers(); | |
| 81 } | |
| 82 | |
| 83 void ShelfBackgroundAnimator::AnimationEnded(const gfx::Animation* animation) { | |
| 84 shelf_background_values_.UpdateCurrentValues(animation->GetCurrentValue()); | |
| 85 item_background_values_.UpdateCurrentValues(animation->GetCurrentValue()); | |
| 86 NotifyObservers(); | |
| 87 } | |
| 88 | |
| 67 void ShelfBackgroundAnimator::OnBackgroundTypeChanged( | 89 void ShelfBackgroundAnimator::OnBackgroundTypeChanged( |
| 68 ShelfBackgroundType background_type, | 90 ShelfBackgroundType background_type, |
| 69 BackgroundAnimatorChangeType change_type) { | 91 gfx::AnimationChangeType change_type) { |
| 70 PaintBackground(background_type, change_type); | 92 PaintBackground(background_type, change_type); |
| 71 } | 93 } |
| 72 | 94 |
| 73 void ShelfBackgroundAnimator::UpdateBackground(BackgroundAnimator* animator, | 95 void ShelfBackgroundAnimator::NotifyObservers() { |
| 74 int alpha) { | 96 for (auto& observer : observers_) |
| 75 OnAlphaChanged(animator, alpha); | 97 NotifyObserver(&observer); |
| 76 } | |
| 77 | |
| 78 void ShelfBackgroundAnimator::BackgroundAnimationEnded( | |
| 79 BackgroundAnimator* animator) { | |
| 80 ++successful_animator_count_; | |
| 81 DCHECK_LE(successful_animator_count_, kNumAnimators); | |
| 82 // UpdateBackground() is only called when alpha values change, this ensures | |
| 83 // observers are always notified for every background change. | |
| 84 OnAlphaChanged(animator, animator->alpha()); | |
| 85 } | |
| 86 | |
| 87 void ShelfBackgroundAnimator::OnAlphaChanged(BackgroundAnimator* animator, | |
| 88 int alpha) { | |
| 89 if (animator == opaque_background_animator_.get()) { | |
| 90 for (auto& observer : observers_) | |
| 91 observer.UpdateShelfOpaqueBackground(alpha); | |
| 92 } else if (animator == item_background_animator_.get()) { | |
| 93 for (auto& observer : observers_) | |
| 94 observer.UpdateShelfItemBackground(alpha); | |
| 95 } else { | |
| 96 NOTREACHED(); | |
| 97 } | |
| 98 } | 98 } |
| 99 | 99 |
| 100 void ShelfBackgroundAnimator::AnimateBackground( | 100 void ShelfBackgroundAnimator::AnimateBackground( |
| 101 ShelfBackgroundType background_type, | 101 ShelfBackgroundType background_type, |
| 102 BackgroundAnimatorChangeType change_type) { | 102 gfx::AnimationChangeType change_type) { |
| 103 // Ensure BackgroundAnimationEnded() has been called for all the | 103 const bool was_animating = animator_ && animator_->is_animating(); |
| 104 // BackgroundAnimators owned by this so that |successful_animator_count_| | 104 StopAnimator(); |
| 105 // is stable and doesn't get updated as a side effect of destroying/animating | |
| 106 // the animators. | |
| 107 StopAnimators(); | |
| 108 | 105 |
| 109 bool show_background = true; | 106 const bool change_immediately = |
| 110 if (can_reuse_animators_ && previous_background_type_ == background_type) { | 107 change_type == gfx::ANIMATION_CHANGE_IMMEDIATE; |
| 111 DCHECK_EQ(opaque_background_animator_->paints_background(), | 108 if (can_reuse_animator_ && previous_background_type_ == background_type) { |
| 112 item_background_animator_->paints_background()); | 109 if (animator_->IsShowing()) { |
|
James Cook
2017/02/08 00:31:27
You're checking for null animator_ on line 103. Ca
bruthig
2017/02/10 18:49:09
Comment added, WDYT?
| |
| 110 if (change_immediately) | |
| 111 animator_->HideImmediately(); | |
| 112 else | |
| 113 animator_->Hide(); | |
| 114 } else { | |
| 115 if (change_immediately) | |
| 116 animator_->ShowImmediately(); | |
| 117 else | |
| 118 animator_->Show(); | |
| 119 } | |
| 120 } else { | |
| 121 // If the previous animator completed successfully and the animation was | |
| 122 // between 2 distinct states, then the last values are valid end state | |
| 123 // values. | |
| 124 can_reuse_animator_ = | |
| 125 target_background_type_ != background_type && !was_animating; | |
| 113 | 126 |
| 114 show_background = !opaque_background_animator_->paints_background(); | 127 CreateAnimator(background_type); |
| 115 } else { | |
| 116 CreateAnimators(background_type, change_type); | |
| 117 | 128 |
| 118 // If all the previous animators completed successfully and the animation | 129 if (change_immediately) |
| 119 // was between 2 distinct states, then the last alpha values are valid | 130 animator_->ShowImmediately(); |
| 120 // end state values. | 131 else |
| 121 can_reuse_animators_ = target_background_type_ != background_type && | 132 animator_->Show(); |
| 122 successful_animator_count_ == kNumAnimators; | |
| 123 } | 133 } |
| 124 | 134 |
| 125 successful_animator_count_ = 0; | |
| 126 | |
| 127 opaque_background_animator_->SetPaintsBackground(show_background, | |
| 128 change_type); | |
| 129 item_background_animator_->SetPaintsBackground(show_background, change_type); | |
| 130 | |
| 131 if (target_background_type_ != background_type) { | 135 if (target_background_type_ != background_type) { |
| 132 previous_background_type_ = target_background_type_; | 136 previous_background_type_ = target_background_type_; |
| 133 target_background_type_ = background_type; | 137 target_background_type_ = background_type; |
| 134 } | 138 } |
| 135 } | 139 } |
| 136 | 140 |
| 137 void ShelfBackgroundAnimator::CreateAnimators( | 141 void ShelfBackgroundAnimator::CreateAnimator( |
| 138 ShelfBackgroundType background_type, | 142 ShelfBackgroundType background_type) { |
| 139 BackgroundAnimatorChangeType change_type) { | |
| 140 const int opaque_background_alpha = | |
| 141 opaque_background_animator_ ? opaque_background_animator_->alpha() : 0; | |
| 142 const int item_background_alpha = | |
| 143 item_background_animator_ ? item_background_animator_->alpha() : 0; | |
| 144 | |
| 145 const bool is_material = MaterialDesignController::IsShelfMaterial(); | |
| 146 int duration_ms = 0; | 143 int duration_ms = 0; |
| 144 int target_shelf_background = 0; | |
| 145 int target_shelf_item_background = 0; | |
| 147 | 146 |
| 148 switch (background_type) { | 147 switch (background_type) { |
| 149 case SHELF_BACKGROUND_DEFAULT: | 148 case SHELF_BACKGROUND_DEFAULT: |
| 150 duration_ms = is_material ? 500 : 1000; | 149 duration_ms = 500; |
| 151 opaque_background_animator_.reset( | 150 target_shelf_background = 0; |
| 152 new BackgroundAnimator(this, opaque_background_alpha, 0)); | 151 target_shelf_item_background = kShelfTranslucentAlpha; |
| 153 item_background_animator_.reset( | |
| 154 new BackgroundAnimator(this, item_background_alpha, | |
| 155 GetShelfConstant(SHELF_BACKGROUND_ALPHA))); | |
| 156 break; | 152 break; |
| 157 case SHELF_BACKGROUND_OVERLAP: | 153 case SHELF_BACKGROUND_OVERLAP: |
| 158 duration_ms = is_material ? 500 : 1000; | 154 duration_ms = 500; |
| 159 opaque_background_animator_.reset(new BackgroundAnimator( | 155 target_shelf_background = kShelfTranslucentAlpha; |
| 160 this, opaque_background_alpha, | 156 target_shelf_item_background = 0; |
| 161 is_material ? GetShelfConstant(SHELF_BACKGROUND_ALPHA) : 0)); | |
| 162 item_background_animator_.reset(new BackgroundAnimator( | |
| 163 this, item_background_alpha, | |
| 164 is_material ? 0 : GetShelfConstant(SHELF_BACKGROUND_ALPHA))); | |
| 165 break; | 157 break; |
| 166 case SHELF_BACKGROUND_MAXIMIZED: | 158 case SHELF_BACKGROUND_MAXIMIZED: |
| 167 duration_ms = is_material ? 250 : 1000; | 159 duration_ms = 250; |
| 168 opaque_background_animator_.reset( | 160 target_shelf_background = kMaxAlpha; |
| 169 new BackgroundAnimator(this, opaque_background_alpha, kMaxAlpha)); | 161 target_shelf_item_background = 0; |
| 170 item_background_animator_.reset(new BackgroundAnimator( | |
| 171 this, item_background_alpha, is_material ? 0 : kMaxAlpha)); | |
| 172 break; | 162 break; |
| 173 } | 163 } |
| 174 | 164 |
| 175 opaque_background_animator_->SetDuration(duration_ms); | 165 animator_.reset(new gfx::SlideAnimation(this)); |
| 176 item_background_animator_->SetDuration(duration_ms); | 166 animator_->SetSlideDuration(duration_ms); |
| 167 shelf_background_values_.SetTargetValues(target_shelf_background); | |
| 168 item_background_values_.SetTargetValues(target_shelf_item_background); | |
| 177 } | 169 } |
| 178 | 170 |
| 179 void ShelfBackgroundAnimator::StopAnimators() { | 171 void ShelfBackgroundAnimator::StopAnimator() { |
| 180 if (opaque_background_animator_) | 172 if (animator_) |
| 181 opaque_background_animator_->Stop(); | 173 animator_->Stop(); |
| 182 if (item_background_animator_) | |
| 183 item_background_animator_->Stop(); | |
| 184 } | 174 } |
| 185 | 175 |
| 186 } // namespace ash | 176 } // namespace ash |
| OLD | NEW |