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 |