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 |