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