OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "cc/animation/scrollbar_animation_controller_thinning.h" | |
6 | |
7 #include "cc/layers/solid_color_scrollbar_layer_impl.h" | |
8 #include "cc/test/fake_impl_proxy.h" | |
9 #include "cc/test/fake_layer_tree_host_impl.h" | |
10 #include "cc/test/geometry_test_utils.h" | |
11 #include "cc/test/test_shared_bitmap_manager.h" | |
12 #include "cc/test/test_task_graph_runner.h" | |
13 #include "cc/trees/layer_tree_impl.h" | |
14 #include "testing/gtest/include/gtest/gtest.h" | |
15 | |
16 namespace cc { | |
17 namespace { | |
18 | |
19 class ScrollbarAnimationControllerThinningTest | |
20 : public testing::Test, | |
21 public ScrollbarAnimationControllerClient { | |
22 public: | |
23 ScrollbarAnimationControllerThinningTest() | |
24 : host_impl_(&proxy_, &shared_bitmap_manager_, &task_graph_runner_) {} | |
25 | |
26 void StartAnimatingScrollbarAnimationController( | |
27 ScrollbarAnimationController* controller) override { | |
28 is_animating_ = true; | |
29 } | |
30 void StopAnimatingScrollbarAnimationController( | |
31 ScrollbarAnimationController* controller) override { | |
32 is_animating_ = false; | |
33 } | |
34 void PostDelayedScrollbarAnimationTask(const base::Closure& start_fade, | |
35 base::TimeDelta delay) override { | |
36 start_fade_ = start_fade; | |
37 delay_ = delay; | |
38 } | |
39 void SetNeedsRedrawForScrollbarAnimation() override { | |
40 did_request_redraw_ = true; | |
41 } | |
42 | |
43 protected: | |
44 void SetUp() override { | |
45 scoped_ptr<LayerImpl> scroll_layer = | |
46 LayerImpl::Create(host_impl_.active_tree(), 1); | |
47 clip_layer_ = LayerImpl::Create(host_impl_.active_tree(), 3); | |
48 scroll_layer->SetScrollClipLayer(clip_layer_->id()); | |
49 LayerImpl* scroll_layer_ptr = scroll_layer.get(); | |
50 clip_layer_->AddChild(scroll_layer.Pass()); | |
51 | |
52 const int kId = 2; | |
53 const int kThumbThickness = 10; | |
54 const int kTrackStart = 0; | |
55 const bool kIsLeftSideVerticalScrollbar = false; | |
56 const bool kIsOverlayScrollbar = true; | |
57 scrollbar_layer_ = | |
58 SolidColorScrollbarLayerImpl::Create(host_impl_.active_tree(), | |
59 kId, | |
60 HORIZONTAL, | |
61 kThumbThickness, | |
62 kTrackStart, | |
63 kIsLeftSideVerticalScrollbar, | |
64 kIsOverlayScrollbar); | |
65 | |
66 scrollbar_layer_->SetScrollLayerAndClipLayerByIds(scroll_layer_ptr->id(), | |
67 clip_layer_->id()); | |
68 clip_layer_->SetBounds(gfx::Size(100, 100)); | |
69 scroll_layer_ptr->SetBounds(gfx::Size(200, 200)); | |
70 | |
71 scrollbar_controller_ = ScrollbarAnimationControllerThinning::Create( | |
72 scroll_layer_ptr, this, base::TimeDelta::FromSeconds(2), | |
73 base::TimeDelta::FromSeconds(5), base::TimeDelta::FromSeconds(3)); | |
74 } | |
75 | |
76 FakeImplProxy proxy_; | |
77 TestSharedBitmapManager shared_bitmap_manager_; | |
78 TestTaskGraphRunner task_graph_runner_; | |
79 FakeLayerTreeHostImpl host_impl_; | |
80 scoped_ptr<ScrollbarAnimationControllerThinning> scrollbar_controller_; | |
81 scoped_ptr<LayerImpl> clip_layer_; | |
82 scoped_ptr<SolidColorScrollbarLayerImpl> scrollbar_layer_; | |
83 | |
84 base::Closure start_fade_; | |
85 base::TimeDelta delay_; | |
86 bool is_animating_; | |
87 bool did_request_redraw_; | |
88 }; | |
89 | |
90 // Check initialization of scrollbar. | |
91 TEST_F(ScrollbarAnimationControllerThinningTest, Idle) { | |
92 scrollbar_controller_->Animate(base::TimeTicks()); | |
93 EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity()); | |
94 EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
95 } | |
96 | |
97 // Check that scrollbar disappears when the layer becomes non-scrollable. | |
98 TEST_F(ScrollbarAnimationControllerThinningTest, HideOnResize) { | |
99 LayerImpl* scroll_layer = host_impl_.active_tree()->LayerById(1); | |
100 ASSERT_TRUE(scroll_layer); | |
101 EXPECT_EQ(gfx::Size(200, 200), scroll_layer->bounds()); | |
102 | |
103 EXPECT_EQ(HORIZONTAL, scrollbar_layer_->orientation()); | |
104 | |
105 // Shrink along X axis, horizontal scrollbar should appear. | |
106 clip_layer_->SetBounds(gfx::Size(100, 200)); | |
107 EXPECT_EQ(gfx::Size(100, 200), clip_layer_->bounds()); | |
108 | |
109 scrollbar_controller_->DidScrollBegin(); | |
110 | |
111 scrollbar_controller_->DidScrollUpdate(false); | |
112 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity()); | |
113 | |
114 scrollbar_controller_->DidScrollEnd(); | |
115 | |
116 // Shrink along Y axis and expand along X, horizontal scrollbar | |
117 // should disappear. | |
118 clip_layer_->SetBounds(gfx::Size(200, 100)); | |
119 EXPECT_EQ(gfx::Size(200, 100), clip_layer_->bounds()); | |
120 | |
121 scrollbar_controller_->DidScrollBegin(); | |
122 | |
123 scrollbar_controller_->DidScrollUpdate(false); | |
124 EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->opacity()); | |
125 | |
126 scrollbar_controller_->DidScrollEnd(); | |
127 } | |
128 | |
129 // Scroll content. Confirm the scrollbar gets dark and then becomes light | |
130 // after stopping. | |
131 TEST_F(ScrollbarAnimationControllerThinningTest, AwakenByProgrammaticScroll) { | |
132 base::TimeTicks time; | |
133 time += base::TimeDelta::FromSeconds(1); | |
134 scrollbar_controller_->DidScrollUpdate(false); | |
135 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity()); | |
136 // Scrollbar doesn't change size if triggered by scroll. | |
137 EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
138 | |
139 start_fade_.Run(); | |
140 | |
141 time += base::TimeDelta::FromSeconds(1); | |
142 scrollbar_controller_->Animate(time); | |
143 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity()); | |
144 EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
145 | |
146 // Subsequent scroll restarts animation. | |
147 scrollbar_controller_->DidScrollUpdate(false); | |
148 | |
149 start_fade_.Run(); | |
150 | |
151 time += base::TimeDelta::FromSeconds(2); | |
152 scrollbar_controller_->Animate(time); | |
153 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity()); | |
154 EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
155 | |
156 time += base::TimeDelta::FromSeconds(1); | |
157 scrollbar_controller_->Animate(time); | |
158 EXPECT_FLOAT_EQ(0.9f, scrollbar_layer_->opacity()); | |
159 EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
160 | |
161 time += base::TimeDelta::FromSeconds(1); | |
162 scrollbar_controller_->Animate(time); | |
163 EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->opacity()); | |
164 EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
165 | |
166 time += base::TimeDelta::FromSeconds(1); | |
167 scrollbar_controller_->Animate(time); | |
168 EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity()); | |
169 EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
170 } | |
171 | |
172 // Initiate a scroll when the pointer is already near the scrollbar. It should | |
173 // remain thick. | |
174 TEST_F(ScrollbarAnimationControllerThinningTest, ScrollWithMouseNear) { | |
175 base::TimeTicks time; | |
176 time += base::TimeDelta::FromSeconds(1); | |
177 | |
178 scrollbar_controller_->DidMouseMoveNear(1); | |
179 scrollbar_controller_->Animate(time); | |
180 time += base::TimeDelta::FromSeconds(3); | |
181 | |
182 scrollbar_controller_->Animate(time); | |
183 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
184 | |
185 scrollbar_controller_->DidScrollUpdate(false); | |
186 start_fade_.Run(); | |
187 scrollbar_controller_->Animate(time); | |
188 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity()); | |
189 // Scrollbar should still be thick. | |
190 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
191 | |
192 time += base::TimeDelta::FromSeconds(5); | |
193 scrollbar_controller_->Animate(time); | |
194 EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity()); | |
195 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
196 } | |
197 | |
198 // Move the pointer near the scrollbar. Confirm it gets thick and narrow when | |
199 // moved away. | |
200 TEST_F(ScrollbarAnimationControllerThinningTest, MouseNear) { | |
201 base::TimeTicks time; | |
202 time += base::TimeDelta::FromSeconds(1); | |
203 scrollbar_controller_->DidMouseMoveNear(1); | |
204 scrollbar_controller_->Animate(time); | |
205 EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity()); | |
206 EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
207 | |
208 // Should animate to thickened but not darken. | |
209 time += base::TimeDelta::FromSeconds(1); | |
210 scrollbar_controller_->Animate(time); | |
211 EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity()); | |
212 EXPECT_FLOAT_EQ(0.6f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
213 | |
214 time += base::TimeDelta::FromSeconds(1); | |
215 scrollbar_controller_->Animate(time); | |
216 EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity()); | |
217 EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
218 | |
219 time += base::TimeDelta::FromSeconds(1); | |
220 scrollbar_controller_->Animate(time); | |
221 EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity()); | |
222 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
223 | |
224 // Subsequent moves should not change anything. | |
225 scrollbar_controller_->DidMouseMoveNear(1); | |
226 scrollbar_controller_->Animate(time); | |
227 EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity()); | |
228 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
229 | |
230 // Now move away from bar. | |
231 time += base::TimeDelta::FromSeconds(1); | |
232 scrollbar_controller_->DidMouseMoveNear(26); | |
233 scrollbar_controller_->Animate(time); | |
234 EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity()); | |
235 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
236 | |
237 // Animate to narrow. | |
238 time += base::TimeDelta::FromSeconds(1); | |
239 scrollbar_controller_->Animate(time); | |
240 EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity()); | |
241 EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
242 | |
243 time += base::TimeDelta::FromSeconds(1); | |
244 scrollbar_controller_->Animate(time); | |
245 EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity()); | |
246 EXPECT_FLOAT_EQ(0.6f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
247 | |
248 time += base::TimeDelta::FromSeconds(1); | |
249 scrollbar_controller_->Animate(time); | |
250 EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity()); | |
251 EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
252 } | |
253 | |
254 // Move the pointer over the scrollbar. Make sure it gets thick and dark | |
255 // and that it gets thin and light when moved away. | |
256 TEST_F(ScrollbarAnimationControllerThinningTest, MouseOver) { | |
257 base::TimeTicks time; | |
258 time += base::TimeDelta::FromSeconds(1); | |
259 scrollbar_controller_->DidMouseMoveNear(0); | |
260 scrollbar_controller_->Animate(time); | |
261 EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity()); | |
262 EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
263 | |
264 // Should animate to thickened and darkened. | |
265 time += base::TimeDelta::FromSeconds(1); | |
266 scrollbar_controller_->Animate(time); | |
267 EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->opacity()); | |
268 EXPECT_FLOAT_EQ(0.6f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
269 | |
270 time += base::TimeDelta::FromSeconds(1); | |
271 scrollbar_controller_->Animate(time); | |
272 EXPECT_FLOAT_EQ(0.9f, scrollbar_layer_->opacity()); | |
273 EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
274 | |
275 time += base::TimeDelta::FromSeconds(1); | |
276 scrollbar_controller_->Animate(time); | |
277 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity()); | |
278 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
279 | |
280 // Subsequent moves should not change anything. | |
281 scrollbar_controller_->DidMouseMoveNear(0); | |
282 scrollbar_controller_->Animate(time); | |
283 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity()); | |
284 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
285 | |
286 // Now move away from bar. | |
287 time += base::TimeDelta::FromSeconds(1); | |
288 scrollbar_controller_->DidMouseMoveNear(26); | |
289 scrollbar_controller_->Animate(time); | |
290 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity()); | |
291 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
292 | |
293 // Animate to narrow. | |
294 time += base::TimeDelta::FromSeconds(1); | |
295 scrollbar_controller_->Animate(time); | |
296 EXPECT_FLOAT_EQ(0.9f, scrollbar_layer_->opacity()); | |
297 EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
298 | |
299 time += base::TimeDelta::FromSeconds(1); | |
300 scrollbar_controller_->Animate(time); | |
301 EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->opacity()); | |
302 EXPECT_FLOAT_EQ(0.6f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
303 | |
304 time += base::TimeDelta::FromSeconds(1); | |
305 scrollbar_controller_->Animate(time); | |
306 EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity()); | |
307 EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
308 } | |
309 | |
310 // First move the pointer near the scrollbar, then over it, then back near | |
311 // then far away. Confirm that first the bar gets thick, then dark, then light, | |
312 // then narrow. | |
313 TEST_F(ScrollbarAnimationControllerThinningTest, MouseNearThenOver) { | |
314 base::TimeTicks time; | |
315 time += base::TimeDelta::FromSeconds(1); | |
316 scrollbar_controller_->DidMouseMoveNear(1); | |
317 scrollbar_controller_->Animate(time); | |
318 EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity()); | |
319 EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
320 | |
321 // Should animate to thickened but not darken. | |
322 time += base::TimeDelta::FromSeconds(3); | |
323 scrollbar_controller_->Animate(time); | |
324 EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity()); | |
325 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
326 | |
327 // Now move over. | |
328 scrollbar_controller_->DidMouseMoveNear(0); | |
329 scrollbar_controller_->Animate(time); | |
330 | |
331 // Should animate to darkened. | |
332 time += base::TimeDelta::FromSeconds(1); | |
333 scrollbar_controller_->Animate(time); | |
334 EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->opacity()); | |
335 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
336 | |
337 time += base::TimeDelta::FromSeconds(1); | |
338 scrollbar_controller_->Animate(time); | |
339 EXPECT_FLOAT_EQ(0.9f, scrollbar_layer_->opacity()); | |
340 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
341 | |
342 time += base::TimeDelta::FromSeconds(1); | |
343 scrollbar_controller_->Animate(time); | |
344 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity()); | |
345 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
346 | |
347 // This is tricky. The DidMouseMoveOffScrollbar() is sent before the | |
348 // subsequent DidMouseMoveNear(), if the mouse moves in that direction. | |
349 // This results in the thumb thinning. We want to make sure that when the | |
350 // thumb starts expanding it doesn't first narrow to the idle thinness. | |
351 time += base::TimeDelta::FromSeconds(1); | |
352 scrollbar_controller_->DidMouseMoveOffScrollbar(); | |
353 scrollbar_controller_->Animate(time); | |
354 | |
355 time += base::TimeDelta::FromSeconds(1); | |
356 scrollbar_controller_->Animate(time); | |
357 EXPECT_FLOAT_EQ(0.9f, scrollbar_layer_->opacity()); | |
358 EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
359 | |
360 scrollbar_controller_->DidMouseMoveNear(1); | |
361 scrollbar_controller_->Animate(time); | |
362 // A new animation is kicked off. | |
363 | |
364 time += base::TimeDelta::FromSeconds(1); | |
365 scrollbar_controller_->Animate(time); | |
366 // We will initiate the narrowing again, but it won't get decremented until | |
367 // the new animation catches up to it. | |
368 EXPECT_FLOAT_EQ(0.9f, scrollbar_layer_->opacity()); | |
369 // Now the thickness should be increasing, but it shouldn't happen until the | |
370 // animation catches up. | |
371 EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
372 | |
373 time += base::TimeDelta::FromSeconds(1); | |
374 scrollbar_controller_->Animate(time); | |
375 EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->opacity()); | |
376 // The thickness now gets big again. | |
377 EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
378 | |
379 time += base::TimeDelta::FromSeconds(1); | |
380 scrollbar_controller_->Animate(time); | |
381 EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity()); | |
382 // The thickness now gets big again. | |
383 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); | |
384 } | |
385 | |
386 } // namespace | |
387 } // namespace cc | |
OLD | NEW |