| 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/animation/animation_change_type.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 #include "ash/common/wallpaper/wallpaper_controller.h" | |
| 14 #include "ui/gfx/animation/slide_animation.h" | |
| 15 #include "ui/gfx/color_utils.h" | |
| 16 | |
| 17 namespace ash { | |
| 18 | |
| 19 ShelfBackgroundAnimator::AnimationValues::AnimationValues() {} | |
| 20 | |
| 21 ShelfBackgroundAnimator::AnimationValues::~AnimationValues() {} | |
| 22 | |
| 23 void ShelfBackgroundAnimator::AnimationValues::UpdateCurrentValues(double t) { | |
| 24 current_color_ = | |
| 25 gfx::Tween::ColorValueBetween(t, initial_color_, target_color_); | |
| 26 } | |
| 27 | |
| 28 void ShelfBackgroundAnimator::AnimationValues::SetTargetValues( | |
| 29 SkColor target_color) { | |
| 30 initial_color_ = current_color_; | |
| 31 target_color_ = target_color; | |
| 32 } | |
| 33 | |
| 34 bool ShelfBackgroundAnimator::AnimationValues::InitialValuesEqualTargetValuesOf( | |
| 35 const AnimationValues& other) const { | |
| 36 return initial_color_ == other.target_color_; | |
| 37 } | |
| 38 | |
| 39 ShelfBackgroundAnimator::ShelfBackgroundAnimator( | |
| 40 ShelfBackgroundType background_type, | |
| 41 WmShelf* wm_shelf, | |
| 42 WallpaperController* wallpaper_controller) | |
| 43 : wm_shelf_(wm_shelf), wallpaper_controller_(wallpaper_controller) { | |
| 44 if (wallpaper_controller_) | |
| 45 wallpaper_controller_->AddObserver(this); | |
| 46 if (wm_shelf_) | |
| 47 wm_shelf_->AddObserver(this); | |
| 48 | |
| 49 // Initialize animators so that adding observers get notified with consistent | |
| 50 // values. | |
| 51 AnimateBackground(background_type, AnimationChangeType::IMMEDIATE); | |
| 52 } | |
| 53 | |
| 54 ShelfBackgroundAnimator::~ShelfBackgroundAnimator() { | |
| 55 if (wallpaper_controller_) | |
| 56 wallpaper_controller_->RemoveObserver(this); | |
| 57 if (wm_shelf_) | |
| 58 wm_shelf_->RemoveObserver(this); | |
| 59 } | |
| 60 | |
| 61 void ShelfBackgroundAnimator::AddObserver( | |
| 62 ShelfBackgroundAnimatorObserver* observer) { | |
| 63 observers_.AddObserver(observer); | |
| 64 NotifyObserver(observer); | |
| 65 } | |
| 66 | |
| 67 void ShelfBackgroundAnimator::RemoveObserver( | |
| 68 ShelfBackgroundAnimatorObserver* observer) { | |
| 69 observers_.RemoveObserver(observer); | |
| 70 } | |
| 71 | |
| 72 void ShelfBackgroundAnimator::NotifyObserver( | |
| 73 ShelfBackgroundAnimatorObserver* observer) { | |
| 74 observer->UpdateShelfBackground(shelf_background_values_.current_color()); | |
| 75 observer->UpdateShelfItemBackground(item_background_values_.current_color()); | |
| 76 } | |
| 77 | |
| 78 void ShelfBackgroundAnimator::PaintBackground( | |
| 79 ShelfBackgroundType background_type, | |
| 80 AnimationChangeType change_type) { | |
| 81 if (target_background_type_ == background_type && | |
| 82 change_type == AnimationChangeType::ANIMATE) { | |
| 83 return; | |
| 84 } | |
| 85 | |
| 86 AnimateBackground(background_type, change_type); | |
| 87 } | |
| 88 | |
| 89 void ShelfBackgroundAnimator::AnimationProgressed( | |
| 90 const gfx::Animation* animation) { | |
| 91 DCHECK_EQ(animation, animator_.get()); | |
| 92 SetAnimationValues(animation->GetCurrentValue()); | |
| 93 } | |
| 94 | |
| 95 void ShelfBackgroundAnimator::AnimationEnded(const gfx::Animation* animation) { | |
| 96 DCHECK_EQ(animation, animator_.get()); | |
| 97 SetAnimationValues(animation->GetCurrentValue()); | |
| 98 animator_.reset(); | |
| 99 } | |
| 100 | |
| 101 void ShelfBackgroundAnimator::AnimationCanceled( | |
| 102 const gfx::Animation* animation) { | |
| 103 DCHECK_EQ(animation, animator_.get()); | |
| 104 SetAnimationValues(animator_->IsShowing() ? 1.0 : 0.0); | |
| 105 // Animations are only cancelled when they are being pre-empted so we don't | |
| 106 // destroy the |animator_| because it may be re-used immediately. | |
| 107 } | |
| 108 | |
| 109 void ShelfBackgroundAnimator::OnWallpaperDataChanged() {} | |
| 110 | |
| 111 void ShelfBackgroundAnimator::OnWallpaperColorsChanged() { | |
| 112 AnimateBackground(target_background_type_, AnimationChangeType::ANIMATE); | |
| 113 } | |
| 114 | |
| 115 void ShelfBackgroundAnimator::OnBackgroundTypeChanged( | |
| 116 ShelfBackgroundType background_type, | |
| 117 AnimationChangeType change_type) { | |
| 118 PaintBackground(background_type, change_type); | |
| 119 } | |
| 120 | |
| 121 void ShelfBackgroundAnimator::NotifyObservers() { | |
| 122 for (auto& observer : observers_) | |
| 123 NotifyObserver(&observer); | |
| 124 } | |
| 125 | |
| 126 void ShelfBackgroundAnimator::AnimateBackground( | |
| 127 ShelfBackgroundType background_type, | |
| 128 AnimationChangeType change_type) { | |
| 129 StopAnimator(); | |
| 130 | |
| 131 if (change_type == AnimationChangeType::IMMEDIATE) { | |
| 132 animator_.reset(); | |
| 133 SetTargetValues(background_type); | |
| 134 SetAnimationValues(1.0); | |
| 135 } else if (CanReuseAnimator(background_type)) { | |
| 136 // |animator_| should not be null here as CanReuseAnimator() returns false | |
| 137 // when it is null. | |
| 138 if (animator_->IsShowing()) | |
| 139 animator_->Hide(); | |
| 140 else | |
| 141 animator_->Show(); | |
| 142 } else { | |
| 143 CreateAnimator(background_type); | |
| 144 SetTargetValues(background_type); | |
| 145 animator_->Show(); | |
| 146 } | |
| 147 | |
| 148 if (target_background_type_ != background_type) { | |
| 149 previous_background_type_ = target_background_type_; | |
| 150 target_background_type_ = background_type; | |
| 151 } | |
| 152 } | |
| 153 | |
| 154 bool ShelfBackgroundAnimator::CanReuseAnimator( | |
| 155 ShelfBackgroundType background_type) const { | |
| 156 if (!animator_) | |
| 157 return false; | |
| 158 | |
| 159 AnimationValues target_shelf_background_values; | |
| 160 AnimationValues target_item_background_values; | |
| 161 GetTargetValues(background_type, &target_shelf_background_values, | |
| 162 &target_item_background_values); | |
| 163 | |
| 164 return previous_background_type_ == background_type && | |
| 165 shelf_background_values_.InitialValuesEqualTargetValuesOf( | |
| 166 target_shelf_background_values) && | |
| 167 item_background_values_.InitialValuesEqualTargetValuesOf( | |
| 168 target_item_background_values); | |
| 169 } | |
| 170 | |
| 171 void ShelfBackgroundAnimator::CreateAnimator( | |
| 172 ShelfBackgroundType background_type) { | |
| 173 int duration_ms = 0; | |
| 174 | |
| 175 switch (background_type) { | |
| 176 case SHELF_BACKGROUND_DEFAULT: | |
| 177 duration_ms = 500; | |
| 178 break; | |
| 179 case SHELF_BACKGROUND_OVERLAP: | |
| 180 duration_ms = 500; | |
| 181 break; | |
| 182 case SHELF_BACKGROUND_MAXIMIZED: | |
| 183 duration_ms = 250; | |
| 184 break; | |
| 185 } | |
| 186 | |
| 187 animator_.reset(new gfx::SlideAnimation(this)); | |
| 188 animator_->SetSlideDuration(duration_ms); | |
| 189 } | |
| 190 | |
| 191 void ShelfBackgroundAnimator::StopAnimator() { | |
| 192 if (animator_) | |
| 193 animator_->Stop(); | |
| 194 } | |
| 195 | |
| 196 void ShelfBackgroundAnimator::SetTargetValues( | |
| 197 ShelfBackgroundType background_type) { | |
| 198 GetTargetValues(background_type, &shelf_background_values_, | |
| 199 &item_background_values_); | |
| 200 } | |
| 201 | |
| 202 void ShelfBackgroundAnimator::GetTargetValues( | |
| 203 ShelfBackgroundType background_type, | |
| 204 AnimationValues* shelf_background_values, | |
| 205 AnimationValues* item_background_values) const { | |
| 206 int target_shelf_background_alpha = 0; | |
| 207 int target_shelf_item_background_alpha = 0; | |
| 208 | |
| 209 switch (background_type) { | |
| 210 case SHELF_BACKGROUND_DEFAULT: | |
| 211 target_shelf_background_alpha = 0; | |
| 212 target_shelf_item_background_alpha = kShelfTranslucentAlpha; | |
| 213 break; | |
| 214 case SHELF_BACKGROUND_OVERLAP: | |
| 215 target_shelf_background_alpha = kShelfTranslucentAlpha; | |
| 216 target_shelf_item_background_alpha = 0; | |
| 217 break; | |
| 218 case SHELF_BACKGROUND_MAXIMIZED: | |
| 219 target_shelf_background_alpha = kMaxAlpha; | |
| 220 target_shelf_item_background_alpha = 0; | |
| 221 break; | |
| 222 } | |
| 223 | |
| 224 SkColor target_color = wallpaper_controller_ | |
| 225 ? wallpaper_controller_->prominent_color() | |
| 226 : kShelfDefaultBaseColor; | |
| 227 | |
| 228 if (target_color == SK_ColorTRANSPARENT) | |
| 229 target_color = kShelfDefaultBaseColor; | |
| 230 | |
| 231 shelf_background_values->SetTargetValues( | |
| 232 SkColorSetA(target_color, target_shelf_background_alpha)); | |
| 233 item_background_values->SetTargetValues( | |
| 234 SkColorSetA(target_color, target_shelf_item_background_alpha)); | |
| 235 } | |
| 236 | |
| 237 void ShelfBackgroundAnimator::SetAnimationValues(double t) { | |
| 238 DCHECK_GE(t, 0.0); | |
| 239 DCHECK_LE(t, 1.0); | |
| 240 shelf_background_values_.UpdateCurrentValues(t); | |
| 241 item_background_values_.UpdateCurrentValues(t); | |
| 242 NotifyObservers(); | |
| 243 } | |
| 244 | |
| 245 } // namespace ash | |
| OLD | NEW |