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

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

Issue 2554913002: Prevent overlay scrollbars expand or hover together (Closed)
Patch Set: fix for fade in/out together Created 4 years 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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_thinning.h" 5 #include "cc/input/single_scrollbar_animation_controller_thinning.h"
6
7 #include <algorithm>
6 8
7 #include "base/memory/ptr_util.h" 9 #include "base/memory/ptr_util.h"
8 #include "base/time/time.h" 10 #include "base/time/time.h"
9 #include "cc/layers/layer_impl.h" 11 #include "cc/layers/layer_impl.h"
10 #include "cc/layers/scrollbar_layer_impl_base.h" 12 #include "cc/layers/scrollbar_layer_impl_base.h"
11 #include "cc/trees/layer_tree_impl.h" 13 #include "cc/trees/layer_tree_impl.h"
12 14
13 namespace { 15 namespace {
14 const float kIdleThicknessScale = 0.4f; 16 const float kIdleThicknessScale = 0.4f;
15 const float kDefaultMouseMoveDistanceToTriggerAnimation = 25.f; 17 const float kDefaultMouseMoveDistanceToTriggerAnimation = 25.f;
16 } 18 }
17 19
18 namespace cc { 20 namespace cc {
19 21
20 std::unique_ptr<ScrollbarAnimationControllerThinning> 22 std::unique_ptr<SingleScrollbarAnimationControllerThinning>
21 ScrollbarAnimationControllerThinning::Create( 23 SingleScrollbarAnimationControllerThinning::Create(
22 int scroll_layer_id, 24 int scroll_layer_id,
25 ScrollbarOrientation orientation,
23 ScrollbarAnimationControllerClient* client, 26 ScrollbarAnimationControllerClient* client,
24 base::TimeDelta delay_before_starting, 27 base::CancelableClosure* delayed_scrollbar_fade,
25 base::TimeDelta resize_delay_before_starting,
26 base::TimeDelta fade_duration, 28 base::TimeDelta fade_duration,
27 base::TimeDelta thinning_duration) { 29 base::TimeDelta thinning_duration) {
28 return base::WrapUnique(new ScrollbarAnimationControllerThinning( 30 return base::WrapUnique(new SingleScrollbarAnimationControllerThinning(
29 scroll_layer_id, client, delay_before_starting, 31 scroll_layer_id, orientation, client, delayed_scrollbar_fade,
30 resize_delay_before_starting, fade_duration, thinning_duration)); 32 fade_duration, thinning_duration));
31 } 33 }
32 34
33 ScrollbarAnimationControllerThinning::ScrollbarAnimationControllerThinning( 35 SingleScrollbarAnimationControllerThinning::
34 int scroll_layer_id, 36 SingleScrollbarAnimationControllerThinning(
35 ScrollbarAnimationControllerClient* client, 37 int scroll_layer_id,
36 base::TimeDelta delay_before_starting, 38 ScrollbarOrientation orientation,
37 base::TimeDelta resize_delay_before_starting, 39 ScrollbarAnimationControllerClient* client,
38 base::TimeDelta fade_duration, 40 base::CancelableClosure* delayed_scrollbar_fade,
39 base::TimeDelta thinning_duration) 41 base::TimeDelta fade_duration,
40 : ScrollbarAnimationController(scroll_layer_id, 42 base::TimeDelta thinning_duration)
41 client, 43 : client_(client),
42 delay_before_starting, 44 delayed_scrollbar_fade_(delayed_scrollbar_fade),
43 resize_delay_before_starting), 45 is_animating_(false),
46 scroll_layer_id_(scroll_layer_id),
47 orientation_(orientation),
44 opacity_(0.0f), 48 opacity_(0.0f),
45 captured_(false), 49 captured_(false),
46 mouse_is_over_scrollbar_(false), 50 mouse_is_over_scrollbar_(false),
47 mouse_is_near_scrollbar_(false), 51 mouse_is_near_scrollbar_(false),
48 thickness_change_(NONE), 52 thickness_change_(NONE),
49 mouse_move_distance_to_trigger_animation_( 53 mouse_move_distance_to_trigger_animation_(
50 kDefaultMouseMoveDistanceToTriggerAnimation), 54 kDefaultMouseMoveDistanceToTriggerAnimation),
51 fade_duration_(fade_duration), 55 fade_duration_(fade_duration),
52 thinning_duration_(thinning_duration), 56 thinning_duration_(thinning_duration),
53 current_animating_property_(OPACITY) { 57 current_animating_property_(OPACITY) {
54 ApplyOpacity(0.f); 58 ApplyOpacity(0.f);
55 ApplyThumbThicknessScale(kIdleThicknessScale); 59 ApplyThumbThicknessScale(kIdleThicknessScale);
56 } 60 }
57 61
58 ScrollbarAnimationControllerThinning::~ScrollbarAnimationControllerThinning() {} 62 ScrollbarSet SingleScrollbarAnimationControllerThinning::Scrollbars() const {
63 return client_->ScrollbarsFor(scroll_layer_id_);
64 }
59 65
60 void ScrollbarAnimationControllerThinning::RunAnimationFrame(float progress) { 66 bool SingleScrollbarAnimationControllerThinning::Animate(base::TimeTicks now) {
67 if (!is_animating_)
68 return false;
69
70 if (last_awaken_time_.is_null())
71 last_awaken_time_ = now;
72
73 float progress = AnimationProgressAtTime(now);
74 RunAnimationFrame(progress);
75
76 return true;
77 }
78
79 float SingleScrollbarAnimationControllerThinning::AnimationProgressAtTime(
80 base::TimeTicks now) {
81 base::TimeDelta delta = now - last_awaken_time_;
82 float progress = delta.InSecondsF() / Duration().InSecondsF();
83 return std::max(std::min(progress, 1.f), 0.f);
84 }
85
86 const base::TimeDelta& SingleScrollbarAnimationControllerThinning::Duration() {
87 if (current_animating_property_ == OPACITY)
88 return fade_duration_;
89 else
90 return thinning_duration_;
91 }
92
93 void SingleScrollbarAnimationControllerThinning::RunAnimationFrame(
94 float progress) {
61 if (captured_) 95 if (captured_)
62 return; 96 return;
63 97
64 if (current_animating_property_ == OPACITY) 98 if (current_animating_property_ == OPACITY)
65 ApplyOpacity(1.f - progress); 99 ApplyOpacity(1.f - progress);
bokan 2016/12/16 14:57:42 I think you should move opacity to be scrolled on
66 else 100 else
67 ApplyThumbThicknessScale(ThumbThicknessScaleAt(progress)); 101 ApplyThumbThicknessScale(ThumbThicknessScaleAt(progress));
68 102
69 client_->SetNeedsRedrawForScrollbarAnimation(); 103 client_->SetNeedsRedrawForScrollbarAnimation();
70 if (progress == 1.f) { 104 if (progress == 1.f) {
71 StopAnimation(); 105 StopAnimation();
72 if (current_animating_property_ == THICKNESS) { 106 if (current_animating_property_ == THICKNESS) {
73 thickness_change_ = NONE; 107 thickness_change_ = NONE;
74 SetCurrentAnimatingProperty(OPACITY); 108 SetCurrentAnimatingProperty(OPACITY);
75 if (!mouse_is_near_scrollbar_)
76 PostDelayedAnimationTask(false);
77 } 109 }
78 } 110 }
79 } 111 }
80 112
81 const base::TimeDelta& ScrollbarAnimationControllerThinning::Duration() { 113 void SingleScrollbarAnimationControllerThinning::StartAnimation() {
82 if (current_animating_property_ == OPACITY) 114 delayed_scrollbar_fade_->Cancel();
83 return fade_duration_; 115 is_animating_ = true;
84 else 116 last_awaken_time_ = base::TimeTicks();
85 return thinning_duration_; 117 client_->SetNeedsAnimateForScrollbarAnimation();
86 } 118 }
87 119
88 void ScrollbarAnimationControllerThinning::DidMouseDown() { 120 void SingleScrollbarAnimationControllerThinning::StopAnimation() {
121 delayed_scrollbar_fade_->Cancel();
122 is_animating_ = false;
123 }
124
125 void SingleScrollbarAnimationControllerThinning::FadeIn() {
126 if (captured_)
127 return;
128
129 if (current_animating_property_ == OPACITY)
130 StopAnimation();
131
132 ApplyOpacity(1.f);
133 ApplyThumbThicknessScale(mouse_is_near_scrollbar_ ? 1.f
134 : kIdleThicknessScale);
135 }
136
137 bool SingleScrollbarAnimationControllerThinning::ShouldFadeOut() const {
138 return !captured_ && !mouse_is_near_scrollbar_ && !is_animating_ &&
139 current_animating_property_ == OPACITY && !ScrollbarsHidden();
140 }
141
142 void SingleScrollbarAnimationControllerThinning::DidMouseDown() {
89 if (!mouse_is_over_scrollbar_ || opacity_ == 0.0f) 143 if (!mouse_is_over_scrollbar_ || opacity_ == 0.0f)
90 return; 144 return;
91 145
92 StopAnimation(); 146 StopAnimation();
93 captured_ = true; 147 captured_ = true;
94 ApplyOpacity(1.f); 148 ApplyOpacity(1.f);
95 ApplyThumbThicknessScale(1.f); 149 ApplyThumbThicknessScale(1.f);
96 } 150 }
97 151
98 void ScrollbarAnimationControllerThinning::DidMouseUp() { 152 void SingleScrollbarAnimationControllerThinning::DidMouseUp() {
99 if (!captured_ || opacity_ == 0.0f) 153 if (!captured_ || opacity_ == 0.0f)
100 return; 154 return;
101 155
102 captured_ = false; 156 captured_ = false;
103 StopAnimation(); 157 StopAnimation();
104 158
105 if (!mouse_is_near_scrollbar_) { 159 if (!mouse_is_near_scrollbar_) {
106 SetCurrentAnimatingProperty(THICKNESS); 160 SetCurrentAnimatingProperty(THICKNESS);
107 thickness_change_ = DECREASE; 161 thickness_change_ = DECREASE;
108 StartAnimation(); 162 StartAnimation();
109 } else { 163 } else {
110 SetCurrentAnimatingProperty(OPACITY); 164 SetCurrentAnimatingProperty(OPACITY);
111 } 165 }
112 } 166 }
113 167
114 void ScrollbarAnimationControllerThinning::DidMouseLeave() { 168 void SingleScrollbarAnimationControllerThinning::DidMouseLeave() {
115 if (!mouse_is_over_scrollbar_ && !mouse_is_near_scrollbar_) 169 if (!mouse_is_over_scrollbar_ && !mouse_is_near_scrollbar_)
116 return; 170 return;
117 171
118 mouse_is_over_scrollbar_ = false; 172 mouse_is_over_scrollbar_ = false;
119 mouse_is_near_scrollbar_ = false; 173 mouse_is_near_scrollbar_ = false;
120 174
121 if (captured_ || opacity_ == 0.0f) 175 if (captured_ || opacity_ == 0.0f)
122 return; 176 return;
123 177
124 thickness_change_ = DECREASE; 178 thickness_change_ = DECREASE;
125 SetCurrentAnimatingProperty(THICKNESS); 179 SetCurrentAnimatingProperty(THICKNESS);
126 StartAnimation(); 180 StartAnimation();
127 } 181 }
128 182
129 void ScrollbarAnimationControllerThinning::DidScrollUpdate(bool on_resize) { 183 void SingleScrollbarAnimationControllerThinning::DidMouseMoveNear(
130 if (captured_) 184 float distance) {
131 return;
132
133 ScrollbarAnimationController::DidScrollUpdate(on_resize);
134 ApplyOpacity(1.f);
135 ApplyThumbThicknessScale(mouse_is_near_scrollbar_ ? 1.f
136 : kIdleThicknessScale);
137 SetCurrentAnimatingProperty(OPACITY);
138
139 // Don't fade out the scrollbar when mouse is near.
140 if (mouse_is_near_scrollbar_)
141 StopAnimation();
142 }
143
144 void ScrollbarAnimationControllerThinning::DidScrollEnd() {
145 ScrollbarAnimationController::DidScrollEnd();
146
147 // Don't fade out the scrollbar when mouse is near.
148 if (mouse_is_near_scrollbar_)
149 StopAnimation();
150 }
151
152 void ScrollbarAnimationControllerThinning::DidMouseMoveNear(float distance) {
153 bool mouse_is_over_scrollbar = distance == 0.0f; 185 bool mouse_is_over_scrollbar = distance == 0.0f;
154 bool mouse_is_near_scrollbar = 186 bool mouse_is_near_scrollbar =
155 distance < mouse_move_distance_to_trigger_animation_; 187 distance < mouse_move_distance_to_trigger_animation_;
156 188
157 if (captured_ || opacity_ == 0.0f) { 189 if (captured_ || opacity_ == 0.0f) {
158 mouse_is_near_scrollbar_ = mouse_is_near_scrollbar; 190 mouse_is_near_scrollbar_ = mouse_is_near_scrollbar;
159 mouse_is_over_scrollbar_ = mouse_is_over_scrollbar; 191 mouse_is_over_scrollbar_ = mouse_is_over_scrollbar;
160 return; 192 return;
161 } 193 }
162 194
163 if (mouse_is_over_scrollbar == mouse_is_over_scrollbar_ && 195 if (mouse_is_over_scrollbar == mouse_is_over_scrollbar_ &&
164 mouse_is_near_scrollbar == mouse_is_near_scrollbar_) 196 mouse_is_near_scrollbar == mouse_is_near_scrollbar_)
165 return; 197 return;
166 198
167 if (mouse_is_over_scrollbar_ != mouse_is_over_scrollbar) 199 if (mouse_is_over_scrollbar_ != mouse_is_over_scrollbar)
168 mouse_is_over_scrollbar_ = mouse_is_over_scrollbar; 200 mouse_is_over_scrollbar_ = mouse_is_over_scrollbar;
169 201
170 if (mouse_is_near_scrollbar_ != mouse_is_near_scrollbar) { 202 if (mouse_is_near_scrollbar_ != mouse_is_near_scrollbar) {
171 mouse_is_near_scrollbar_ = mouse_is_near_scrollbar; 203 mouse_is_near_scrollbar_ = mouse_is_near_scrollbar;
172 thickness_change_ = mouse_is_near_scrollbar_ ? INCREASE : DECREASE; 204 thickness_change_ = mouse_is_near_scrollbar_ ? INCREASE : DECREASE;
173 } 205 }
174 206
175 SetCurrentAnimatingProperty(THICKNESS); 207 SetCurrentAnimatingProperty(THICKNESS);
176 StartAnimation(); 208 StartAnimation();
177 } 209 }
178 210
179 bool ScrollbarAnimationControllerThinning::ScrollbarsHidden() const { 211 bool SingleScrollbarAnimationControllerThinning::ScrollbarsHidden() const {
180 return opacity_ == 0.0f; 212 return opacity_ == 0.0f;
181 } 213 }
182 214
183 float ScrollbarAnimationControllerThinning::ThumbThicknessScaleAt( 215 float SingleScrollbarAnimationControllerThinning::ThumbThicknessScaleAt(
184 float progress) { 216 float progress) {
185 if (thickness_change_ == NONE) 217 if (thickness_change_ == NONE)
186 return mouse_is_near_scrollbar_ ? 1.f : kIdleThicknessScale; 218 return mouse_is_near_scrollbar_ ? 1.f : kIdleThicknessScale;
187 float factor = thickness_change_ == INCREASE ? progress : (1.f - progress); 219 float factor = thickness_change_ == INCREASE ? progress : (1.f - progress);
188 return ((1.f - kIdleThicknessScale) * factor) + kIdleThicknessScale; 220 return ((1.f - kIdleThicknessScale) * factor) + kIdleThicknessScale;
189 } 221 }
190 222
191 float ScrollbarAnimationControllerThinning::AdjustScale( 223 float SingleScrollbarAnimationControllerThinning::AdjustScale(
192 float new_value, 224 float new_value,
193 float current_value, 225 float current_value,
194 AnimationChange animation_change, 226 AnimationChange animation_change,
195 float min_value, 227 float min_value,
196 float max_value) { 228 float max_value) {
197 float result; 229 float result;
198 if (animation_change == INCREASE && current_value > new_value) 230 if (animation_change == INCREASE && current_value > new_value)
199 result = current_value; 231 result = current_value;
200 else if (animation_change == DECREASE && current_value < new_value) 232 else if (animation_change == DECREASE && current_value < new_value)
201 result = current_value; 233 result = current_value;
202 else 234 else
203 result = new_value; 235 result = new_value;
204 if (result > max_value) 236 if (result > max_value)
205 return max_value; 237 return max_value;
206 if (result < min_value) 238 if (result < min_value)
207 return min_value; 239 return min_value;
208 return result; 240 return result;
209 } 241 }
210 242
211 void ScrollbarAnimationControllerThinning::ApplyOpacity(float opacity) { 243 void SingleScrollbarAnimationControllerThinning::ApplyOpacity(float opacity) {
212 for (ScrollbarLayerImplBase* scrollbar : Scrollbars()) { 244 for (ScrollbarLayerImplBase* scrollbar : Scrollbars()) {
245 if (scrollbar->orientation() != orientation_)
246 continue;
213 if (!scrollbar->is_overlay_scrollbar()) 247 if (!scrollbar->is_overlay_scrollbar())
214 continue; 248 continue;
249
215 float effective_opacity = scrollbar->CanScrollOrientation() ? opacity : 0; 250 float effective_opacity = scrollbar->CanScrollOrientation() ? opacity : 0;
216 PropertyTrees* property_trees = 251 PropertyTrees* property_trees =
217 scrollbar->layer_tree_impl()->property_trees(); 252 scrollbar->layer_tree_impl()->property_trees();
218 // If this method is called during LayerImpl::PushPropertiesTo, we may not 253 // If this method is called during LayerImpl::PushPropertiesTo, we may not
219 // yet have valid effect_id_to_index_map entries as property trees are 254 // yet have valid effect_id_to_index_map entries as property trees are
220 // pushed after layers during activation. We can skip updating opacity in 255 // pushed after layers during activation. We can skip updating opacity in
221 // that case as we are only registering a scrollbar and because opacity will 256 // that case as we are only registering a scrollbar and because opacity will
222 // be overwritten anyway when property trees are pushed. 257 // be overwritten anyway when property trees are pushed.
223 if (property_trees->IsInIdToIndexMap(PropertyTrees::TreeType::EFFECT, 258 if (property_trees->IsInIdToIndexMap(PropertyTrees::TreeType::EFFECT,
224 scrollbar->id())) { 259 scrollbar->id())) {
225 property_trees->effect_tree.OnOpacityAnimated( 260 property_trees->effect_tree.OnOpacityAnimated(
226 effective_opacity, 261 effective_opacity,
227 property_trees->effect_id_to_index_map[scrollbar->id()], 262 property_trees->effect_id_to_index_map[scrollbar->id()],
228 scrollbar->layer_tree_impl()); 263 scrollbar->layer_tree_impl());
229 } 264 }
230 } 265 }
231 266
232 bool previouslyVisible = opacity_ > 0.0f;
233 bool currentlyVisible = opacity > 0.0f;
234
235 opacity_ = opacity; 267 opacity_ = opacity;
236
237 if (previouslyVisible != currentlyVisible)
238 client_->DidChangeScrollbarVisibility();
239 } 268 }
240 269
241 void ScrollbarAnimationControllerThinning::ApplyThumbThicknessScale( 270 void SingleScrollbarAnimationControllerThinning::ApplyThumbThicknessScale(
242 float thumb_thickness_scale) { 271 float thumb_thickness_scale) {
243 for (ScrollbarLayerImplBase* scrollbar : Scrollbars()) { 272 for (ScrollbarLayerImplBase* scrollbar : Scrollbars()) {
273 if (scrollbar->orientation() != orientation_)
274 continue;
244 if (!scrollbar->is_overlay_scrollbar()) 275 if (!scrollbar->is_overlay_scrollbar())
245 continue; 276 continue;
246 277
247 scrollbar->SetThumbThicknessScaleFactor(AdjustScale( 278 float scale = AdjustScale(thumb_thickness_scale,
248 thumb_thickness_scale, scrollbar->thumb_thickness_scale_factor(), 279 scrollbar->thumb_thickness_scale_factor(),
249 thickness_change_, kIdleThicknessScale, 1)); 280 thickness_change_, kIdleThicknessScale, 1);
281
282 scrollbar->SetThumbThicknessScaleFactor(scale);
250 } 283 }
251 } 284 }
252 285
253 void ScrollbarAnimationControllerThinning::SetCurrentAnimatingProperty( 286 void SingleScrollbarAnimationControllerThinning::SetCurrentAnimatingProperty(
254 AnimatingProperty property) { 287 AnimatingProperty property) {
255 if (current_animating_property_ == property) 288 if (current_animating_property_ == property)
256 return; 289 return;
257 290
258 StopAnimation(); 291 StopAnimation();
259 current_animating_property_ = property; 292 current_animating_property_ = property;
260 if (current_animating_property_ == THICKNESS) 293 if (current_animating_property_ == THICKNESS)
261 ApplyOpacity(1.f); 294 ApplyOpacity(1.f);
262 } 295 }
263 296
264 } // namespace cc 297 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698