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/animation/animation_change_type.h" |
9 #include "ash/common/shelf/shelf_background_animator_observer.h" | 10 #include "ash/common/shelf/shelf_background_animator_observer.h" |
10 #include "ash/common/shelf/shelf_constants.h" | 11 #include "ash/common/shelf/shelf_constants.h" |
11 #include "ash/common/shelf/wm_shelf.h" | 12 #include "ash/common/shelf/wm_shelf.h" |
| 13 #include "ui/gfx/animation/slide_animation.h" |
12 | 14 |
13 namespace ash { | 15 namespace ash { |
14 | 16 |
15 namespace { | 17 ShelfBackgroundAnimator::AnimationValues::AnimationValues() {} |
16 // The total number of animators that will call BackgroundAnimationEnded(). | |
17 const int kNumAnimators = 2; | |
18 | 18 |
19 const int kMaxAlpha = 255; | 19 ShelfBackgroundAnimator::AnimationValues::~AnimationValues() {} |
20 } // namespace | 20 |
| 21 void ShelfBackgroundAnimator::AnimationValues::UpdateCurrentValues(double t) { |
| 22 current_alpha_ = |
| 23 gfx::Tween::IntValueBetween(t, initial_alpha_, target_alpha_); |
| 24 } |
| 25 |
| 26 void ShelfBackgroundAnimator::AnimationValues::SetTargetValues( |
| 27 int target_alpha) { |
| 28 DCHECK_LE(target_alpha, kMaxAlpha); |
| 29 DCHECK_GE(target_alpha, 0); |
| 30 initial_alpha_ = current_alpha_; |
| 31 target_alpha_ = target_alpha; |
| 32 } |
| 33 |
| 34 bool ShelfBackgroundAnimator::AnimationValues::InitialValuesEqualTargetValuesOf( |
| 35 const AnimationValues& other) const { |
| 36 return initial_alpha_ == other.target_alpha_; |
| 37 } |
21 | 38 |
22 ShelfBackgroundAnimator::ShelfBackgroundAnimator( | 39 ShelfBackgroundAnimator::ShelfBackgroundAnimator( |
23 ShelfBackgroundType background_type, | 40 ShelfBackgroundType background_type, |
24 WmShelf* wm_shelf) | 41 WmShelf* wm_shelf) |
25 : wm_shelf_(wm_shelf) { | 42 : wm_shelf_(wm_shelf) { |
26 if (wm_shelf_) | 43 if (wm_shelf_) |
27 wm_shelf_->AddObserver(this); | 44 wm_shelf_->AddObserver(this); |
28 // Initialize animators so that adding observers get notified with consistent | 45 // Initialize animators so that adding observers get notified with consistent |
29 // values. | 46 // values. |
30 AnimateBackground(background_type, BACKGROUND_CHANGE_IMMEDIATE); | 47 AnimateBackground(background_type, AnimationChangeType::IMMEDIATE); |
31 } | 48 } |
32 | 49 |
33 ShelfBackgroundAnimator::~ShelfBackgroundAnimator() { | 50 ShelfBackgroundAnimator::~ShelfBackgroundAnimator() { |
34 if (wm_shelf_) | 51 if (wm_shelf_) |
35 wm_shelf_->RemoveObserver(this); | 52 wm_shelf_->RemoveObserver(this); |
36 } | 53 } |
37 | 54 |
38 void ShelfBackgroundAnimator::AddObserver( | 55 void ShelfBackgroundAnimator::AddObserver( |
39 ShelfBackgroundAnimatorObserver* observer) { | 56 ShelfBackgroundAnimatorObserver* observer) { |
40 observers_.AddObserver(observer); | 57 observers_.AddObserver(observer); |
41 Initialize(observer); | 58 NotifyObserver(observer); |
42 } | 59 } |
43 | 60 |
44 void ShelfBackgroundAnimator::RemoveObserver( | 61 void ShelfBackgroundAnimator::RemoveObserver( |
45 ShelfBackgroundAnimatorObserver* observer) { | 62 ShelfBackgroundAnimatorObserver* observer) { |
46 observers_.RemoveObserver(observer); | 63 observers_.RemoveObserver(observer); |
47 } | 64 } |
48 | 65 |
49 void ShelfBackgroundAnimator::Initialize( | 66 void ShelfBackgroundAnimator::NotifyObserver( |
50 ShelfBackgroundAnimatorObserver* observer) const { | 67 ShelfBackgroundAnimatorObserver* observer) { |
51 observer->UpdateShelfOpaqueBackground(opaque_background_animator_->alpha()); | 68 observer->UpdateShelfBackground(shelf_background_values_.current_alpha()); |
52 observer->UpdateShelfItemBackground(item_background_animator_->alpha()); | 69 observer->UpdateShelfItemBackground(item_background_values_.current_alpha()); |
53 } | 70 } |
54 | 71 |
55 void ShelfBackgroundAnimator::PaintBackground( | 72 void ShelfBackgroundAnimator::PaintBackground( |
56 ShelfBackgroundType background_type, | 73 ShelfBackgroundType background_type, |
57 BackgroundAnimatorChangeType change_type) { | 74 AnimationChangeType change_type) { |
58 if (target_background_type_ == background_type && | 75 if (target_background_type_ == background_type && |
59 change_type == BACKGROUND_CHANGE_ANIMATE) { | 76 change_type == AnimationChangeType::ANIMATE) { |
60 return; | 77 return; |
61 } | 78 } |
62 | 79 |
63 AnimateBackground(background_type, change_type); | 80 AnimateBackground(background_type, change_type); |
64 } | 81 } |
65 | 82 |
| 83 void ShelfBackgroundAnimator::AnimationProgressed( |
| 84 const gfx::Animation* animation) { |
| 85 DCHECK_EQ(animation, animator_.get()); |
| 86 SetAnimationValues(animation->GetCurrentValue()); |
| 87 } |
| 88 |
| 89 void ShelfBackgroundAnimator::AnimationEnded(const gfx::Animation* animation) { |
| 90 DCHECK_EQ(animation, animator_.get()); |
| 91 SetAnimationValues(animation->GetCurrentValue()); |
| 92 animator_.reset(); |
| 93 } |
| 94 |
| 95 void ShelfBackgroundAnimator::AnimationCanceled( |
| 96 const gfx::Animation* animation) { |
| 97 DCHECK_EQ(animation, animator_.get()); |
| 98 SetAnimationValues(animator_->IsShowing() ? 1.0 : 0.0); |
| 99 // Animations are only cancelled when they are being pre-empted so we don't |
| 100 // destroy the |animator_| because it may be re-used immediately. |
| 101 } |
| 102 |
66 void ShelfBackgroundAnimator::OnBackgroundTypeChanged( | 103 void ShelfBackgroundAnimator::OnBackgroundTypeChanged( |
67 ShelfBackgroundType background_type, | 104 ShelfBackgroundType background_type, |
68 BackgroundAnimatorChangeType change_type) { | 105 AnimationChangeType change_type) { |
69 PaintBackground(background_type, change_type); | 106 PaintBackground(background_type, change_type); |
70 } | 107 } |
71 | 108 |
72 void ShelfBackgroundAnimator::UpdateBackground(BackgroundAnimator* animator, | 109 void ShelfBackgroundAnimator::NotifyObservers() { |
73 int alpha) { | 110 for (auto& observer : observers_) |
74 OnAlphaChanged(animator, alpha); | 111 NotifyObserver(&observer); |
75 } | |
76 | |
77 void ShelfBackgroundAnimator::BackgroundAnimationEnded( | |
78 BackgroundAnimator* animator) { | |
79 ++successful_animator_count_; | |
80 DCHECK_LE(successful_animator_count_, kNumAnimators); | |
81 // UpdateBackground() is only called when alpha values change, this ensures | |
82 // observers are always notified for every background change. | |
83 OnAlphaChanged(animator, animator->alpha()); | |
84 } | |
85 | |
86 void ShelfBackgroundAnimator::OnAlphaChanged(BackgroundAnimator* animator, | |
87 int alpha) { | |
88 if (animator == opaque_background_animator_.get()) { | |
89 for (auto& observer : observers_) | |
90 observer.UpdateShelfOpaqueBackground(alpha); | |
91 } else if (animator == item_background_animator_.get()) { | |
92 for (auto& observer : observers_) | |
93 observer.UpdateShelfItemBackground(alpha); | |
94 } else { | |
95 NOTREACHED(); | |
96 } | |
97 } | 112 } |
98 | 113 |
99 void ShelfBackgroundAnimator::AnimateBackground( | 114 void ShelfBackgroundAnimator::AnimateBackground( |
100 ShelfBackgroundType background_type, | 115 ShelfBackgroundType background_type, |
101 BackgroundAnimatorChangeType change_type) { | 116 AnimationChangeType change_type) { |
102 // Ensure BackgroundAnimationEnded() has been called for all the | 117 StopAnimator(); |
103 // BackgroundAnimators owned by this so that |successful_animator_count_| | |
104 // is stable and doesn't get updated as a side effect of destroying/animating | |
105 // the animators. | |
106 StopAnimators(); | |
107 | 118 |
108 bool show_background = true; | 119 if (change_type == AnimationChangeType::IMMEDIATE) { |
109 if (can_reuse_animators_ && previous_background_type_ == background_type) { | 120 animator_.reset(); |
110 DCHECK_EQ(opaque_background_animator_->paints_background(), | 121 SetTargetValues(background_type); |
111 item_background_animator_->paints_background()); | 122 SetAnimationValues(1.0); |
112 | 123 } else if (CanReuseAnimator(background_type)) { |
113 show_background = !opaque_background_animator_->paints_background(); | 124 // |animator_| should not be null here as CanReuseAnimator() returns false |
| 125 // when it is null. |
| 126 if (animator_->IsShowing()) |
| 127 animator_->Hide(); |
| 128 else |
| 129 animator_->Show(); |
114 } else { | 130 } else { |
115 CreateAnimators(background_type, change_type); | 131 CreateAnimator(background_type); |
116 | 132 SetTargetValues(background_type); |
117 // If all the previous animators completed successfully and the animation | 133 animator_->Show(); |
118 // was between 2 distinct states, then the last alpha values are valid | |
119 // end state values. | |
120 can_reuse_animators_ = target_background_type_ != background_type && | |
121 successful_animator_count_ == kNumAnimators; | |
122 } | 134 } |
123 | 135 |
124 successful_animator_count_ = 0; | |
125 | |
126 opaque_background_animator_->SetPaintsBackground(show_background, | |
127 change_type); | |
128 item_background_animator_->SetPaintsBackground(show_background, change_type); | |
129 | |
130 if (target_background_type_ != background_type) { | 136 if (target_background_type_ != background_type) { |
131 previous_background_type_ = target_background_type_; | 137 previous_background_type_ = target_background_type_; |
132 target_background_type_ = background_type; | 138 target_background_type_ = background_type; |
133 } | 139 } |
134 } | 140 } |
135 | 141 |
136 void ShelfBackgroundAnimator::CreateAnimators( | 142 bool ShelfBackgroundAnimator::CanReuseAnimator( |
137 ShelfBackgroundType background_type, | 143 ShelfBackgroundType background_type) const { |
138 BackgroundAnimatorChangeType change_type) { | 144 if (!animator_) |
139 const int opaque_background_alpha = | 145 return false; |
140 opaque_background_animator_ ? opaque_background_animator_->alpha() : 0; | |
141 const int item_background_alpha = | |
142 item_background_animator_ ? item_background_animator_->alpha() : 0; | |
143 | 146 |
| 147 AnimationValues target_shelf_background_values; |
| 148 AnimationValues target_item_background_values; |
| 149 GetTargetValues(background_type, &target_shelf_background_values, |
| 150 &target_item_background_values); |
| 151 |
| 152 return previous_background_type_ == background_type && |
| 153 shelf_background_values_.InitialValuesEqualTargetValuesOf( |
| 154 target_shelf_background_values) && |
| 155 item_background_values_.InitialValuesEqualTargetValuesOf( |
| 156 target_item_background_values); |
| 157 } |
| 158 |
| 159 void ShelfBackgroundAnimator::CreateAnimator( |
| 160 ShelfBackgroundType background_type) { |
144 int duration_ms = 0; | 161 int duration_ms = 0; |
145 | 162 |
146 switch (background_type) { | 163 switch (background_type) { |
147 case SHELF_BACKGROUND_DEFAULT: | 164 case SHELF_BACKGROUND_DEFAULT: |
148 duration_ms = 500; | 165 duration_ms = 500; |
149 opaque_background_animator_.reset( | |
150 new BackgroundAnimator(this, opaque_background_alpha, 0)); | |
151 item_background_animator_.reset(new BackgroundAnimator( | |
152 this, item_background_alpha, kShelfTranslucentAlpha)); | |
153 break; | 166 break; |
154 case SHELF_BACKGROUND_OVERLAP: | 167 case SHELF_BACKGROUND_OVERLAP: |
155 duration_ms = 500; | 168 duration_ms = 500; |
156 opaque_background_animator_.reset(new BackgroundAnimator( | |
157 this, opaque_background_alpha, kShelfTranslucentAlpha)); | |
158 item_background_animator_.reset( | |
159 new BackgroundAnimator(this, item_background_alpha, 0)); | |
160 break; | 169 break; |
161 case SHELF_BACKGROUND_MAXIMIZED: | 170 case SHELF_BACKGROUND_MAXIMIZED: |
162 duration_ms = 250; | 171 duration_ms = 250; |
163 opaque_background_animator_.reset( | |
164 new BackgroundAnimator(this, opaque_background_alpha, kMaxAlpha)); | |
165 item_background_animator_.reset( | |
166 new BackgroundAnimator(this, item_background_alpha, 0)); | |
167 break; | 172 break; |
168 } | 173 } |
169 | 174 |
170 opaque_background_animator_->SetDuration(duration_ms); | 175 animator_.reset(new gfx::SlideAnimation(this)); |
171 item_background_animator_->SetDuration(duration_ms); | 176 animator_->SetSlideDuration(duration_ms); |
172 } | 177 } |
173 | 178 |
174 void ShelfBackgroundAnimator::StopAnimators() { | 179 void ShelfBackgroundAnimator::StopAnimator() { |
175 if (opaque_background_animator_) | 180 if (animator_) |
176 opaque_background_animator_->Stop(); | 181 animator_->Stop(); |
177 if (item_background_animator_) | 182 } |
178 item_background_animator_->Stop(); | 183 |
| 184 void ShelfBackgroundAnimator::SetTargetValues( |
| 185 ShelfBackgroundType background_type) { |
| 186 GetTargetValues(background_type, &shelf_background_values_, |
| 187 &item_background_values_); |
| 188 } |
| 189 |
| 190 void ShelfBackgroundAnimator::GetTargetValues( |
| 191 ShelfBackgroundType background_type, |
| 192 AnimationValues* shelf_background_values, |
| 193 AnimationValues* item_background_values) const { |
| 194 int target_shelf_background = 0; |
| 195 int target_shelf_item_background = 0; |
| 196 |
| 197 switch (background_type) { |
| 198 case SHELF_BACKGROUND_DEFAULT: |
| 199 target_shelf_background = 0; |
| 200 target_shelf_item_background = kShelfTranslucentAlpha; |
| 201 break; |
| 202 case SHELF_BACKGROUND_OVERLAP: |
| 203 target_shelf_background = kShelfTranslucentAlpha; |
| 204 target_shelf_item_background = 0; |
| 205 break; |
| 206 case SHELF_BACKGROUND_MAXIMIZED: |
| 207 target_shelf_background = kMaxAlpha; |
| 208 target_shelf_item_background = 0; |
| 209 break; |
| 210 } |
| 211 shelf_background_values->SetTargetValues(target_shelf_background); |
| 212 item_background_values->SetTargetValues(target_shelf_item_background); |
| 213 } |
| 214 |
| 215 void ShelfBackgroundAnimator::SetAnimationValues(double t) { |
| 216 DCHECK_GE(t, 0.0); |
| 217 DCHECK_LE(t, 1.0); |
| 218 shelf_background_values_.UpdateCurrentValues(t); |
| 219 item_background_values_.UpdateCurrentValues(t); |
| 220 NotifyObservers(); |
179 } | 221 } |
180 | 222 |
181 } // namespace ash | 223 } // namespace ash |
OLD | NEW |