Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1255)

Side by Side Diff: cc/input/scrollbar_animation_controller.cc

Issue 2692243005: Merge Compositor's ScrollbarAnimationControllers into single class (Closed)
Patch Set: fix confict constant Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "cc/input/scrollbar_animation_controller.h" 5 #include "cc/input/scrollbar_animation_controller.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/time/time.h" 9 #include "base/time/time.h"
10 #include "cc/trees/layer_tree_impl.h" 10 #include "cc/trees/layer_tree_impl.h"
11 11
12 namespace cc { 12 namespace cc {
13 13
14 std::unique_ptr<ScrollbarAnimationController>
15 ScrollbarAnimationController::CreateScrollbarAnimationControllerAndroid(
16 int scroll_layer_id,
17 ScrollbarAnimationControllerClient* client,
18 base::TimeDelta delay_before_starting,
19 base::TimeDelta resize_delay_before_starting,
20 base::TimeDelta fade_duration) {
21 return base::WrapUnique(new ScrollbarAnimationController(
22 scroll_layer_id, client, delay_before_starting,
23 resize_delay_before_starting, fade_duration));
24 }
25
26 std::unique_ptr<ScrollbarAnimationController>
27 ScrollbarAnimationController::CreateScrollbarAnimationControllerAuraOverlay(
28 int scroll_layer_id,
29 ScrollbarAnimationControllerClient* client,
30 base::TimeDelta delay_before_starting,
31 base::TimeDelta resize_delay_before_starting,
32 base::TimeDelta fade_duration,
33 base::TimeDelta thinning_duration) {
34 return base::WrapUnique(new ScrollbarAnimationController(
35 scroll_layer_id, client, delay_before_starting,
36 resize_delay_before_starting, fade_duration, thinning_duration));
37 }
38
14 ScrollbarAnimationController::ScrollbarAnimationController( 39 ScrollbarAnimationController::ScrollbarAnimationController(
15 int scroll_layer_id, 40 int scroll_layer_id,
16 ScrollbarAnimationControllerClient* client, 41 ScrollbarAnimationControllerClient* client,
17 base::TimeDelta delay_before_starting, 42 base::TimeDelta delay_before_starting,
18 base::TimeDelta resize_delay_before_starting) 43 base::TimeDelta resize_delay_before_starting,
44 base::TimeDelta fade_duration)
19 : client_(client), 45 : client_(client),
20 delay_before_starting_(delay_before_starting), 46 delay_before_starting_(delay_before_starting),
21 resize_delay_before_starting_(resize_delay_before_starting), 47 resize_delay_before_starting_(resize_delay_before_starting),
22 is_animating_(false), 48 is_animating_(false),
23 scroll_layer_id_(scroll_layer_id), 49 scroll_layer_id_(scroll_layer_id),
24 currently_scrolling_(false), 50 currently_scrolling_(false),
25 scroll_gesture_has_scrolled_(false), 51 scroll_gesture_has_scrolled_(false),
52 opacity_(0.0f),
53 fade_duration_(fade_duration),
54 need_thinning_animation_(false),
26 weak_factory_(this) { 55 weak_factory_(this) {
56 ApplyOpacityToScrollbars(0.0f);
57 }
58
59 ScrollbarAnimationController::ScrollbarAnimationController(
60 int scroll_layer_id,
61 ScrollbarAnimationControllerClient* client,
62 base::TimeDelta delay_before_starting,
63 base::TimeDelta resize_delay_before_starting,
64 base::TimeDelta fade_duration,
65 base::TimeDelta thinning_duration)
66 : client_(client),
67 delay_before_starting_(delay_before_starting),
68 resize_delay_before_starting_(resize_delay_before_starting),
69 is_animating_(false),
70 scroll_layer_id_(scroll_layer_id),
71 currently_scrolling_(false),
72 scroll_gesture_has_scrolled_(false),
73 opacity_(0.0f),
74 fade_duration_(fade_duration),
75 need_thinning_animation_(true),
76 weak_factory_(this) {
77 vertical_controller_ = SingleScrollbarAnimationControllerThinning::Create(
78 scroll_layer_id, ScrollbarOrientation::VERTICAL, client,
79 thinning_duration);
80 horizontal_controller_ = SingleScrollbarAnimationControllerThinning::Create(
81 scroll_layer_id, ScrollbarOrientation::HORIZONTAL, client,
82 thinning_duration);
83 ApplyOpacityToScrollbars(0.0f);
27 } 84 }
28 85
29 ScrollbarAnimationController::~ScrollbarAnimationController() {} 86 ScrollbarAnimationController::~ScrollbarAnimationController() {}
30 87
88 ScrollbarSet ScrollbarAnimationController::Scrollbars() const {
89 return client_->ScrollbarsFor(scroll_layer_id_);
90 }
91
31 SingleScrollbarAnimationControllerThinning& 92 SingleScrollbarAnimationControllerThinning&
32 ScrollbarAnimationController::GetScrollbarAnimationController( 93 ScrollbarAnimationController::GetScrollbarAnimationController(
33 ScrollbarOrientation orientation) const { 94 ScrollbarOrientation orientation) const {
34 DCHECK(NeedThinningAnimation()); 95 DCHECK(need_thinning_animation_);
35 if (orientation == ScrollbarOrientation::VERTICAL) 96 if (orientation == ScrollbarOrientation::VERTICAL)
36 return *(vertical_controller_.get()); 97 return *(vertical_controller_.get());
37 else 98 else
38 return *(horizontal_controller_.get()); 99 return *(horizontal_controller_.get());
39 } 100 }
40 101
102 void ScrollbarAnimationController::StartAnimation() {
103 delayed_scrollbar_fade_.Cancel();
104 is_animating_ = true;
105 last_awaken_time_ = base::TimeTicks();
106 client_->SetNeedsAnimateForScrollbarAnimation();
107 }
108
109 void ScrollbarAnimationController::StopAnimation() {
110 delayed_scrollbar_fade_.Cancel();
111 is_animating_ = false;
112 }
113
114 void ScrollbarAnimationController::PostDelayedAnimationTask(bool on_resize) {
115 base::TimeDelta delay =
116 on_resize ? resize_delay_before_starting_ : delay_before_starting_;
117 delayed_scrollbar_fade_.Reset(
118 base::Bind(&ScrollbarAnimationController::StartAnimation,
119 weak_factory_.GetWeakPtr()));
120 client_->PostDelayedScrollbarAnimationTask(delayed_scrollbar_fade_.callback(),
121 delay);
122 }
123
41 bool ScrollbarAnimationController::Animate(base::TimeTicks now) { 124 bool ScrollbarAnimationController::Animate(base::TimeTicks now) {
42 bool animated = false; 125 bool animated = false;
43 126
44 if (is_animating_) { 127 if (is_animating_) {
45 if (last_awaken_time_.is_null()) 128 if (last_awaken_time_.is_null())
46 last_awaken_time_ = now; 129 last_awaken_time_ = now;
47 130
48 float progress = AnimationProgressAtTime(now); 131 float progress = AnimationProgressAtTime(now);
49 RunAnimationFrame(progress); 132 RunAnimationFrame(progress);
50 133
51 if (is_animating_) 134 if (is_animating_)
52 client_->SetNeedsAnimateForScrollbarAnimation(); 135 client_->SetNeedsAnimateForScrollbarAnimation();
53 animated = true; 136 animated = true;
54 } 137 }
55 138
56 if (NeedThinningAnimation()) { 139 if (need_thinning_animation_) {
57 animated |= vertical_controller_->Animate(now); 140 animated |= vertical_controller_->Animate(now);
58 animated |= horizontal_controller_->Animate(now); 141 animated |= horizontal_controller_->Animate(now);
59 } 142 }
60 143
61 return animated; 144 return animated;
62 } 145 }
63 146
64 bool ScrollbarAnimationController::ScrollbarsHidden() const {
65 return false;
66 }
67
68 bool ScrollbarAnimationController::NeedThinningAnimation() const {
69 return false;
70 }
71
72 float ScrollbarAnimationController::AnimationProgressAtTime( 147 float ScrollbarAnimationController::AnimationProgressAtTime(
73 base::TimeTicks now) { 148 base::TimeTicks now) {
74 base::TimeDelta delta = now - last_awaken_time_; 149 base::TimeDelta delta = now - last_awaken_time_;
75 float progress = delta.InSecondsF() / Duration().InSecondsF(); 150 float progress = delta.InSecondsF() / fade_duration_.InSecondsF();
76 return std::max(std::min(progress, 1.f), 0.f); 151 return std::max(std::min(progress, 1.f), 0.f);
77 } 152 }
78 153
79 void ScrollbarAnimationController::DidScrollBegin() { 154 void ScrollbarAnimationController::DidScrollBegin() {
80 currently_scrolling_ = true; 155 currently_scrolling_ = true;
81 } 156 }
82 157
158 void ScrollbarAnimationController::RunAnimationFrame(float progress) {
159 ApplyOpacityToScrollbars(1.f - progress);
160 client_->SetNeedsRedrawForScrollbarAnimation();
161 if (progress == 1.f)
162 StopAnimation();
163 }
164
83 void ScrollbarAnimationController::DidScrollUpdate(bool on_resize) { 165 void ScrollbarAnimationController::DidScrollUpdate(bool on_resize) {
166 if (need_thinning_animation_ && Captured())
167 return;
168
84 StopAnimation(); 169 StopAnimation();
85 170
86 // As an optimization, we avoid spamming fade delay tasks during active fast 171 // As an optimization, we avoid spamming fade delay tasks during active fast
87 // scrolls. But if we're not within one, we need to post every scroll update. 172 // scrolls. But if we're not within one, we need to post every scroll update.
88 if (!currently_scrolling_) 173 if (!currently_scrolling_) {
89 PostDelayedAnimationTask(on_resize); 174 // We don't fade out scrollbar if they need thinning animation and mouse is
90 else 175 // near.
176 if (!need_thinning_animation_ || !mouse_is_near_any_scrollbar())
177 PostDelayedAnimationTask(on_resize);
178 } else {
91 scroll_gesture_has_scrolled_ = true; 179 scroll_gesture_has_scrolled_ = true;
180 }
181
182 ApplyOpacityToScrollbars(1);
183
184 if (need_thinning_animation_) {
185 vertical_controller_->UpdateThumbThicknessScale();
186 horizontal_controller_->UpdateThumbThicknessScale();
187 }
92 } 188 }
93 189
94 void ScrollbarAnimationController::DidScrollEnd() { 190 void ScrollbarAnimationController::DidScrollEnd() {
95 if (scroll_gesture_has_scrolled_) { 191 bool has_scrolled = scroll_gesture_has_scrolled_;
96 PostDelayedAnimationTask(false); 192 scroll_gesture_has_scrolled_ = false;
97 scroll_gesture_has_scrolled_ = false;
98 }
99 193
100 currently_scrolling_ = false; 194 currently_scrolling_ = false;
195
196 // We don't fade out scrollbar if they need thinning animation and mouse is
197 // near.
198 if (need_thinning_animation_ && mouse_is_near_any_scrollbar())
199 return;
200
201 if (has_scrolled)
202 PostDelayedAnimationTask(false);
101 } 203 }
102 204
103 void ScrollbarAnimationController::DidMouseDown() { 205 void ScrollbarAnimationController::DidMouseDown() {
104 if (!NeedThinningAnimation() || ScrollbarsHidden()) 206 if (!need_thinning_animation_ || ScrollbarsHidden())
105 return; 207 return;
106 208
107 vertical_controller_->DidMouseDown(); 209 vertical_controller_->DidMouseDown();
108 horizontal_controller_->DidMouseDown(); 210 horizontal_controller_->DidMouseDown();
109 } 211 }
110 212
111 void ScrollbarAnimationController::DidMouseUp() { 213 void ScrollbarAnimationController::DidMouseUp() {
112 if (!NeedThinningAnimation()) 214 if (!need_thinning_animation_)
113 return; 215 return;
114 216
115 vertical_controller_->DidMouseUp(); 217 vertical_controller_->DidMouseUp();
116 horizontal_controller_->DidMouseUp(); 218 horizontal_controller_->DidMouseUp();
117 219
118 if (!mouse_is_near_any_scrollbar()) 220 if (!mouse_is_near_any_scrollbar())
119 PostDelayedAnimationTask(false); 221 PostDelayedAnimationTask(false);
120 } 222 }
121 223
122 void ScrollbarAnimationController::DidMouseLeave() { 224 void ScrollbarAnimationController::DidMouseLeave() {
123 if (!NeedThinningAnimation()) 225 if (!need_thinning_animation_)
124 return; 226 return;
125 227
126 vertical_controller_->DidMouseLeave(); 228 vertical_controller_->DidMouseLeave();
127 horizontal_controller_->DidMouseLeave(); 229 horizontal_controller_->DidMouseLeave();
128 230
129 if (ScrollbarsHidden() || Captured()) 231 if (ScrollbarsHidden() || Captured())
130 return; 232 return;
131 233
132 PostDelayedAnimationTask(false); 234 PostDelayedAnimationTask(false);
133 } 235 }
134 236
135 void ScrollbarAnimationController::DidMouseMoveNear( 237 void ScrollbarAnimationController::DidMouseMoveNear(
136 ScrollbarOrientation orientation, 238 ScrollbarOrientation orientation,
137 float distance) { 239 float distance) {
138 if (!NeedThinningAnimation()) 240 if (!need_thinning_animation_)
139 return; 241 return;
140 242
141 GetScrollbarAnimationController(orientation).DidMouseMoveNear(distance); 243 GetScrollbarAnimationController(orientation).DidMouseMoveNear(distance);
142 244
143 if (ScrollbarsHidden() || Captured()) 245 if (ScrollbarsHidden() || Captured())
144 return; 246 return;
145 247
146 if (mouse_is_near_any_scrollbar()) { 248 if (mouse_is_near_any_scrollbar()) {
147 ApplyOpacityToScrollbars(1); 249 ApplyOpacityToScrollbars(1);
148 StopAnimation(); 250 StopAnimation();
149 } else if (!animating_fade()) { 251 } else if (!is_animating_) {
150 PostDelayedAnimationTask(false); 252 PostDelayedAnimationTask(false);
151 } 253 }
152 } 254 }
153 255
154 bool ScrollbarAnimationController::mouse_is_over_scrollbar( 256 bool ScrollbarAnimationController::mouse_is_over_scrollbar(
155 ScrollbarOrientation orientation) const { 257 ScrollbarOrientation orientation) const {
156 DCHECK(NeedThinningAnimation()); 258 DCHECK(need_thinning_animation_);
157 return GetScrollbarAnimationController(orientation).mouse_is_over_scrollbar(); 259 return GetScrollbarAnimationController(orientation).mouse_is_over_scrollbar();
158 } 260 }
159 261
160 bool ScrollbarAnimationController::mouse_is_near_scrollbar( 262 bool ScrollbarAnimationController::mouse_is_near_scrollbar(
161 ScrollbarOrientation orientation) const { 263 ScrollbarOrientation orientation) const {
162 DCHECK(NeedThinningAnimation()); 264 DCHECK(need_thinning_animation_);
163 return GetScrollbarAnimationController(orientation).mouse_is_near_scrollbar(); 265 return GetScrollbarAnimationController(orientation).mouse_is_near_scrollbar();
164 } 266 }
165 267
166 bool ScrollbarAnimationController::mouse_is_near_any_scrollbar() const { 268 bool ScrollbarAnimationController::mouse_is_near_any_scrollbar() const {
167 DCHECK(NeedThinningAnimation()); 269 DCHECK(need_thinning_animation_);
168 return vertical_controller_->mouse_is_near_scrollbar() || 270 return vertical_controller_->mouse_is_near_scrollbar() ||
169 horizontal_controller_->mouse_is_near_scrollbar(); 271 horizontal_controller_->mouse_is_near_scrollbar();
170 } 272 }
171 273
274 bool ScrollbarAnimationController::ScrollbarsHidden() const {
275 return opacity_ == 0.0f;
276 }
277
172 bool ScrollbarAnimationController::Captured() const { 278 bool ScrollbarAnimationController::Captured() const {
173 DCHECK(NeedThinningAnimation()); 279 DCHECK(need_thinning_animation_);
174 return vertical_controller_->captured() || horizontal_controller_->captured(); 280 return vertical_controller_->captured() || horizontal_controller_->captured();
175 } 281 }
176 282
177 void ScrollbarAnimationController::PostDelayedAnimationTask(bool on_resize) { 283 void ScrollbarAnimationController::ApplyOpacityToScrollbars(float opacity) {
178 base::TimeDelta delay = 284 for (ScrollbarLayerImplBase* scrollbar : Scrollbars()) {
179 on_resize ? resize_delay_before_starting_ : delay_before_starting_; 285 if (!scrollbar->is_overlay_scrollbar())
180 delayed_scrollbar_fade_.Reset( 286 continue;
181 base::Bind(&ScrollbarAnimationController::StartAnimation, 287 float effective_opacity = scrollbar->CanScrollOrientation() ? opacity : 0;
182 weak_factory_.GetWeakPtr())); 288 PropertyTrees* property_trees =
183 client_->PostDelayedScrollbarAnimationTask(delayed_scrollbar_fade_.callback(), 289 scrollbar->layer_tree_impl()->property_trees();
184 delay); 290 // If this method is called during LayerImpl::PushPropertiesTo, we may not
185 } 291 // yet have valid layer_id_to_effect_node_index entries as property trees
292 // are pushed after layers during activation. We can skip updating opacity
293 // in that case as we are only registering a scrollbar and because opacity
294 // will be overwritten anyway when property trees are pushed.
295 if (property_trees->IsInIdToIndexMap(PropertyTrees::TreeType::EFFECT,
296 scrollbar->id())) {
297 property_trees->effect_tree.OnOpacityAnimated(
298 effective_opacity,
299 property_trees->layer_id_to_effect_node_index[scrollbar->id()],
300 scrollbar->layer_tree_impl());
301 }
302 }
186 303
187 void ScrollbarAnimationController::StartAnimation() { 304 bool previouslyVisible = opacity_ > 0.0f;
188 delayed_scrollbar_fade_.Cancel(); 305 bool currentlyVisible = opacity > 0.0f;
189 is_animating_ = true;
190 last_awaken_time_ = base::TimeTicks();
191 client_->SetNeedsAnimateForScrollbarAnimation();
192 }
193 306
194 void ScrollbarAnimationController::StopAnimation() { 307 opacity_ = opacity;
195 delayed_scrollbar_fade_.Cancel();
196 is_animating_ = false;
197 }
198 308
199 ScrollbarSet ScrollbarAnimationController::Scrollbars() const { 309 if (previouslyVisible != currentlyVisible)
200 return client_->ScrollbarsFor(scroll_layer_id_); 310 client_->DidChangeScrollbarVisibility();
201 }
202
203 void ScrollbarAnimationController::set_mouse_move_distance_for_test(
204 float distance) {
205 vertical_controller_->set_mouse_move_distance_for_test(distance);
206 horizontal_controller_->set_mouse_move_distance_for_test(distance);
207 } 311 }
208 312
209 } // namespace cc 313 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698