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

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

Issue 2554913002: Prevent overlay scrollbars expand or hover together (Closed)
Patch Set: separate responsibilities of SACT and SSACT 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/scrollbar_animation_controller_thinning.h"
6 6
7 #include "base/memory/ptr_util.h" 7 #include "base/memory/ptr_util.h"
8 #include "base/time/time.h" 8 #include "base/time/time.h"
9 #include "cc/layers/layer_impl.h" 9 #include "cc/layers/layer_impl.h"
10 #include "cc/layers/scrollbar_layer_impl_base.h" 10 #include "cc/layers/scrollbar_layer_impl_base.h"
11 #include "cc/trees/layer_tree_impl.h" 11 #include "cc/trees/layer_tree_impl.h"
12 12
13 namespace {
14 const float kIdleThicknessScale = 0.4f;
15 const float kDefaultMouseMoveDistanceToTriggerAnimation = 25.f;
16 }
17
18 namespace cc { 13 namespace cc {
19 14
20 std::unique_ptr<ScrollbarAnimationControllerThinning> 15 std::unique_ptr<ScrollbarAnimationControllerThinning>
21 ScrollbarAnimationControllerThinning::Create( 16 ScrollbarAnimationControllerThinning::Create(
22 int scroll_layer_id, 17 int scroll_layer_id,
23 ScrollbarAnimationControllerClient* client, 18 ScrollbarAnimationControllerClient* client,
24 base::TimeDelta delay_before_starting, 19 base::TimeDelta delay_before_starting,
25 base::TimeDelta resize_delay_before_starting, 20 base::TimeDelta resize_delay_before_starting,
26 base::TimeDelta fade_duration, 21 base::TimeDelta fade_duration,
27 base::TimeDelta thinning_duration) { 22 base::TimeDelta thinning_duration) {
28 return base::WrapUnique(new ScrollbarAnimationControllerThinning( 23 return base::WrapUnique(new ScrollbarAnimationControllerThinning(
29 scroll_layer_id, client, delay_before_starting, 24 scroll_layer_id, client, delay_before_starting,
30 resize_delay_before_starting, fade_duration, thinning_duration)); 25 resize_delay_before_starting, fade_duration, thinning_duration));
31 } 26 }
32 27
33 ScrollbarAnimationControllerThinning::ScrollbarAnimationControllerThinning( 28 ScrollbarAnimationControllerThinning::ScrollbarAnimationControllerThinning(
34 int scroll_layer_id, 29 int scroll_layer_id,
35 ScrollbarAnimationControllerClient* client, 30 ScrollbarAnimationControllerClient* client,
36 base::TimeDelta delay_before_starting, 31 base::TimeDelta delay_before_starting,
37 base::TimeDelta resize_delay_before_starting, 32 base::TimeDelta resize_delay_before_starting,
38 base::TimeDelta fade_duration, 33 base::TimeDelta fade_duration,
39 base::TimeDelta thinning_duration) 34 base::TimeDelta thinning_duration)
40 : ScrollbarAnimationController(scroll_layer_id, 35 : ScrollbarAnimationController(scroll_layer_id,
41 client, 36 client,
42 delay_before_starting, 37 delay_before_starting,
43 resize_delay_before_starting), 38 resize_delay_before_starting),
44 opacity_(0.0f), 39 opacity_(1.0f),
bokan 2016/12/19 16:11:47 Why did we change starting opacity to 1? IIRC, sta
chaopeng 2016/12/20 20:05:55 Because scrollbars show when page load is done, th
bokan 2016/12/21 15:56:02 Right, but this worked before. Blink is responsibl
45 captured_(false), 40 fade_duration_(fade_duration) {
46 mouse_is_over_scrollbar_(false), 41 vertical_controller_ = SingleScrollbarAnimationControllerThinning::Create(
47 mouse_is_near_scrollbar_(false), 42 scroll_layer_id, ScrollbarOrientation::VERTICAL, client,
48 thickness_change_(NONE), 43 delayed_scrollbar_fade(), thinning_duration);
49 mouse_move_distance_to_trigger_animation_( 44 horizontal_controller_ = SingleScrollbarAnimationControllerThinning::Create(
50 kDefaultMouseMoveDistanceToTriggerAnimation), 45 scroll_layer_id, ScrollbarOrientation::HORIZONTAL, client,
51 fade_duration_(fade_duration), 46 delayed_scrollbar_fade(), thinning_duration);
52 thinning_duration_(thinning_duration),
53 current_animating_property_(OPACITY) {
54 ApplyOpacity(0.f);
55 ApplyThumbThicknessScale(kIdleThicknessScale);
56 } 47 }
57 48
58 ScrollbarAnimationControllerThinning::~ScrollbarAnimationControllerThinning() {} 49 ScrollbarAnimationControllerThinning::~ScrollbarAnimationControllerThinning() {}
59 50
60 void ScrollbarAnimationControllerThinning::RunAnimationFrame(float progress) { 51 SingleScrollbarAnimationControllerThinning&
61 if (captured_) 52 ScrollbarAnimationControllerThinning::GetScrollbarAnimationController(
62 return; 53 ScrollbarOrientation orientation) const {
63 54 if (orientation == ScrollbarOrientation::VERTICAL)
64 if (current_animating_property_ == OPACITY) 55 return *(vertical_controller_.get());
65 ApplyOpacity(1.f - progress);
66 else 56 else
67 ApplyThumbThicknessScale(ThumbThicknessScaleAt(progress)); 57 return *(horizontal_controller_.get());
68
69 client_->SetNeedsRedrawForScrollbarAnimation();
70 if (progress == 1.f) {
71 StopAnimation();
72 if (current_animating_property_ == THICKNESS) {
73 thickness_change_ = NONE;
74 SetCurrentAnimatingProperty(OPACITY);
75 if (!mouse_is_near_scrollbar_)
76 PostDelayedAnimationTask(false);
77 }
78 }
79 } 58 }
80 59
81 const base::TimeDelta& ScrollbarAnimationControllerThinning::Duration() { 60 bool ScrollbarAnimationControllerThinning::mouse_is_over_scrollbar(
82 if (current_animating_property_ == OPACITY) 61 ScrollbarOrientation orientation) const {
83 return fade_duration_; 62 return GetScrollbarAnimationController(orientation).mouse_is_over_scrollbar();
84 else
85 return thinning_duration_;
86 } 63 }
87 64
88 void ScrollbarAnimationControllerThinning::DidMouseDown() { 65 bool ScrollbarAnimationControllerThinning::mouse_is_near_scrollbar(
89 if (!mouse_is_over_scrollbar_ || opacity_ == 0.0f) 66 ScrollbarOrientation orientation) const {
90 return; 67 return GetScrollbarAnimationController(orientation).mouse_is_near_scrollbar();
91
92 StopAnimation();
93 captured_ = true;
94 ApplyOpacity(1.f);
95 ApplyThumbThicknessScale(1.f);
96 } 68 }
97 69
98 void ScrollbarAnimationControllerThinning::DidMouseUp() { 70 bool ScrollbarAnimationControllerThinning::mouse_is_near_any_scrollbar() const {
99 if (!captured_ || opacity_ == 0.0f) 71 return vertical_controller_->mouse_is_near_scrollbar() ||
100 return; 72 horizontal_controller_->mouse_is_near_scrollbar();
101
102 captured_ = false;
103 StopAnimation();
104
105 if (!mouse_is_near_scrollbar_) {
106 SetCurrentAnimatingProperty(THICKNESS);
107 thickness_change_ = DECREASE;
108 StartAnimation();
109 } else {
110 SetCurrentAnimatingProperty(OPACITY);
111 }
112 } 73 }
113 74
114 void ScrollbarAnimationControllerThinning::DidMouseLeave() { 75 bool ScrollbarAnimationControllerThinning::captured() const {
115 if (!mouse_is_over_scrollbar_ && !mouse_is_near_scrollbar_) 76 return vertical_controller_->captured() || horizontal_controller_->captured();
116 return;
117
118 mouse_is_over_scrollbar_ = false;
119 mouse_is_near_scrollbar_ = false;
120
121 if (captured_ || opacity_ == 0.0f)
122 return;
123
124 thickness_change_ = DECREASE;
125 SetCurrentAnimatingProperty(THICKNESS);
126 StartAnimation();
127 }
128
129 void ScrollbarAnimationControllerThinning::DidScrollUpdate(bool on_resize) {
130 if (captured_)
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;
154 bool mouse_is_near_scrollbar =
155 distance < mouse_move_distance_to_trigger_animation_;
156
157 if (captured_ || opacity_ == 0.0f) {
158 mouse_is_near_scrollbar_ = mouse_is_near_scrollbar;
159 mouse_is_over_scrollbar_ = mouse_is_over_scrollbar;
160 return;
161 }
162
163 if (mouse_is_over_scrollbar == mouse_is_over_scrollbar_ &&
164 mouse_is_near_scrollbar == mouse_is_near_scrollbar_)
165 return;
166
167 if (mouse_is_over_scrollbar_ != mouse_is_over_scrollbar)
168 mouse_is_over_scrollbar_ = mouse_is_over_scrollbar;
169
170 if (mouse_is_near_scrollbar_ != mouse_is_near_scrollbar) {
171 mouse_is_near_scrollbar_ = mouse_is_near_scrollbar;
172 thickness_change_ = mouse_is_near_scrollbar_ ? INCREASE : DECREASE;
173 }
174
175 SetCurrentAnimatingProperty(THICKNESS);
176 StartAnimation();
177 } 77 }
178 78
179 bool ScrollbarAnimationControllerThinning::ScrollbarsHidden() const { 79 bool ScrollbarAnimationControllerThinning::ScrollbarsHidden() const {
180 return opacity_ == 0.0f; 80 return opacity_ == 0.0f;
181 } 81 }
182 82
183 float ScrollbarAnimationControllerThinning::ThumbThicknessScaleAt( 83 void ScrollbarAnimationControllerThinning::set_mouse_move_distance_for_test(
184 float progress) { 84 float distance) {
185 if (thickness_change_ == NONE) 85 vertical_controller_->set_mouse_move_distance_for_test(distance);
186 return mouse_is_near_scrollbar_ ? 1.f : kIdleThicknessScale; 86 horizontal_controller_->set_mouse_move_distance_for_test(distance);
187 float factor = thickness_change_ == INCREASE ? progress : (1.f - progress);
188 return ((1.f - kIdleThicknessScale) * factor) + kIdleThicknessScale;
189 } 87 }
190 88
191 float ScrollbarAnimationControllerThinning::AdjustScale( 89 bool ScrollbarAnimationControllerThinning::Animate(base::TimeTicks now) {
192 float new_value, 90 if (animating())
193 float current_value, 91 return ScrollbarAnimationController::Animate(now);
bokan 2016/12/19 16:11:47 As I noted in a comment in the SingleScrollbar cla
194 AnimationChange animation_change, 92
195 float min_value, 93 bool need_animate = vertical_controller_->Animate(now);
196 float max_value) { 94 need_animate = horizontal_controller_->Animate(now) || need_animate;
bokan 2016/12/19 16:11:47 need_animate |=
197 float result; 95
198 if (animation_change == INCREASE && current_value > new_value) 96 if (need_animate) {
199 result = current_value; 97 client_->SetNeedsAnimateForScrollbarAnimation();
200 else if (animation_change == DECREASE && current_value < new_value) 98 } else if (vertical_controller_->ShouldFadeOut() &&
201 result = current_value; 99 horizontal_controller_->ShouldFadeOut()) {
202 else 100 PostDelayedAnimationTask(false);
203 result = new_value; 101 }
204 if (result > max_value) 102
205 return max_value; 103 return need_animate;
206 if (result < min_value) 104 }
207 return min_value; 105
208 return result; 106 void ScrollbarAnimationControllerThinning::RunAnimationFrame(float progress) {
107 ApplyOpacity(1.f - progress);
108 if (progress == 1.f)
109 StopAnimation();
110 }
111
112 const base::TimeDelta& ScrollbarAnimationControllerThinning::Duration() {
113 return fade_duration_;
114 }
115
116 void ScrollbarAnimationControllerThinning::DidMouseDown() {
117 vertical_controller_->DidMouseDown();
118 horizontal_controller_->DidMouseDown();
119 }
120
121 void ScrollbarAnimationControllerThinning::DidMouseUp() {
122 vertical_controller_->DidMouseUp();
123 horizontal_controller_->DidMouseUp();
124 }
125
126 void ScrollbarAnimationControllerThinning::DidMouseLeave() {
127 vertical_controller_->DidMouseLeave();
128 horizontal_controller_->DidMouseLeave();
129 }
130
131 void ScrollbarAnimationControllerThinning::DidMouseMoveNear(
132 ScrollbarOrientation orientation,
133 float distance) {
134 GetScrollbarAnimationController(orientation).DidMouseMoveNear(distance);
135 EnsureScrollbarFadeIn();
136 }
137
138 void ScrollbarAnimationControllerThinning::DidScrollUpdate(bool on_resize) {
139 if (captured())
140 return;
141
142 FadeIn();
143 vertical_controller_->UpdateThumbThicknessScale();
144 horizontal_controller_->UpdateThumbThicknessScale();
145
146 // Don't fade out the scrollbar when mouse is near.
147 if (!mouse_is_near_any_scrollbar())
148 PostDelayedAnimationTask(on_resize);
149 }
150
151 void ScrollbarAnimationControllerThinning::DidScrollEnd() {
152 ScrollbarAnimationController::DidScrollEnd();
153 EnsureScrollbarFadeIn();
154 }
155
156 void ScrollbarAnimationControllerThinning::EnsureScrollbarFadeIn() {
bokan 2016/12/19 16:11:47 Call this FadeInIfNeeded
157 // Don't fade out the scrollbar when mouse is near.
bokan 2016/12/19 16:11:47 I don't get why we need this method, the fade in/o
chaopeng 2016/12/20 20:05:54 I changed it to `if (mouse_is_near_any_scrollbar()
bokan 2016/12/21 15:56:02 Ah, ok. In that case, I would just inline this ins
158 if (mouse_is_near_any_scrollbar())
159 FadeIn();
160 }
161
162 void ScrollbarAnimationControllerThinning::FadeIn() {
163 ApplyOpacity(1);
164 StopAnimation();
209 } 165 }
210 166
211 void ScrollbarAnimationControllerThinning::ApplyOpacity(float opacity) { 167 void ScrollbarAnimationControllerThinning::ApplyOpacity(float opacity) {
212 for (ScrollbarLayerImplBase* scrollbar : Scrollbars()) { 168 for (ScrollbarLayerImplBase* scrollbar : Scrollbars()) {
213 if (!scrollbar->is_overlay_scrollbar()) 169 if (!scrollbar->is_overlay_scrollbar())
214 continue; 170 continue;
215 float effective_opacity = scrollbar->CanScrollOrientation() ? opacity : 0; 171 float effective_opacity = scrollbar->CanScrollOrientation() ? opacity : 0;
216 PropertyTrees* property_trees = 172 PropertyTrees* property_trees =
217 scrollbar->layer_tree_impl()->property_trees(); 173 scrollbar->layer_tree_impl()->property_trees();
218 // If this method is called during LayerImpl::PushPropertiesTo, we may not 174 // 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 175 // 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 176 // 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 177 // that case as we are only registering a scrollbar and because opacity will
222 // be overwritten anyway when property trees are pushed. 178 // be overwritten anyway when property trees are pushed.
223 if (property_trees->IsInIdToIndexMap(PropertyTrees::TreeType::EFFECT, 179 if (property_trees->IsInIdToIndexMap(PropertyTrees::TreeType::EFFECT,
224 scrollbar->id())) { 180 scrollbar->id())) {
225 property_trees->effect_tree.OnOpacityAnimated( 181 property_trees->effect_tree.OnOpacityAnimated(
226 effective_opacity, 182 effective_opacity,
227 property_trees->effect_id_to_index_map[scrollbar->id()], 183 property_trees->effect_id_to_index_map[scrollbar->id()],
228 scrollbar->layer_tree_impl()); 184 scrollbar->layer_tree_impl());
229 } 185 }
230 } 186 }
231 187
232 bool previouslyVisible = opacity_ > 0.0f; 188 bool previouslyVisible = opacity_ > 0.0f;
233 bool currentlyVisible = opacity > 0.0f; 189 bool currentlyVisible = opacity > 0.0f;
234 190
235 opacity_ = opacity; 191 opacity_ = opacity;
192 vertical_controller_->SetHidden(!currentlyVisible);
193 horizontal_controller_->SetHidden(!currentlyVisible);
236 194
237 if (previouslyVisible != currentlyVisible) 195 if (previouslyVisible != currentlyVisible)
238 client_->DidChangeScrollbarVisibility(); 196 client_->DidChangeScrollbarVisibility();
239 } 197 }
240 198
241 void ScrollbarAnimationControllerThinning::ApplyThumbThicknessScale(
242 float thumb_thickness_scale) {
243 for (ScrollbarLayerImplBase* scrollbar : Scrollbars()) {
244 if (!scrollbar->is_overlay_scrollbar())
245 continue;
246
247 scrollbar->SetThumbThicknessScaleFactor(AdjustScale(
248 thumb_thickness_scale, scrollbar->thumb_thickness_scale_factor(),
249 thickness_change_, kIdleThicknessScale, 1));
250 }
251 }
252
253 void ScrollbarAnimationControllerThinning::SetCurrentAnimatingProperty(
254 AnimatingProperty property) {
255 if (current_animating_property_ == property)
256 return;
257
258 StopAnimation();
259 current_animating_property_ = property;
260 if (current_animating_property_ == THICKNESS)
261 ApplyOpacity(1.f);
262 }
263
264 } // namespace cc 199 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698