OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "ui/views/animation/ink_drop_animation.h" | 5 #include "ui/views/animation/ink_drop_animation.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "third_party/skia/include/core/SkColor.h" | 11 #include "third_party/skia/include/core/SkColor.h" |
12 #include "third_party/skia/include/core/SkPaint.h" | 12 #include "third_party/skia/include/core/SkPaint.h" |
13 #include "ui/base/ui_base_switches.h" | 13 #include "ui/base/ui_base_switches.h" |
14 #include "ui/compositor/callback_layer_animation_observer.h" | |
14 #include "ui/compositor/layer.h" | 15 #include "ui/compositor/layer.h" |
15 #include "ui/compositor/layer_animation_observer.h" | |
16 #include "ui/compositor/layer_animation_sequence.h" | 16 #include "ui/compositor/layer_animation_sequence.h" |
17 #include "ui/compositor/paint_recorder.h" | 17 #include "ui/compositor/paint_recorder.h" |
18 #include "ui/compositor/scoped_layer_animation_settings.h" | 18 #include "ui/compositor/scoped_layer_animation_settings.h" |
19 #include "ui/gfx/canvas.h" | 19 #include "ui/gfx/canvas.h" |
20 #include "ui/gfx/transform_util.h" | 20 #include "ui/gfx/transform_util.h" |
21 #include "ui/views/animation/ink_drop_animation_observer.h" | |
21 #include "ui/views/view.h" | 22 #include "ui/views/view.h" |
22 | 23 |
23 namespace { | 24 namespace { |
24 | 25 |
25 // The minimum scale factor to use when scaling rectangle layers. Smaller values | 26 // The minimum scale factor to use when scaling rectangle layers. Smaller values |
26 // were causing visual anomalies. | 27 // were causing visual anomalies. |
27 const float kMinimumRectScale = 0.0001f; | 28 const float kMinimumRectScale = 0.0001f; |
28 | 29 |
29 // The minimum scale factor to use when scaling circle layers. Smaller values | 30 // The minimum scale factor to use when scaling circle layers. Smaller values |
30 // were causing visual anomalies. | 31 // were causing visual anomalies. |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
246 rect_layer_delegate_( | 247 rect_layer_delegate_( |
247 new RectangleLayerDelegate(kInkDropColor, large_size_)), | 248 new RectangleLayerDelegate(kInkDropColor, large_size_)), |
248 root_layer_(new ui::Layer(ui::LAYER_NOT_DRAWN)), | 249 root_layer_(new ui::Layer(ui::LAYER_NOT_DRAWN)), |
249 ink_drop_state_(InkDropState::HIDDEN) { | 250 ink_drop_state_(InkDropState::HIDDEN) { |
250 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) | 251 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) |
251 AddPaintLayer(static_cast<PaintedShape>(i)); | 252 AddPaintLayer(static_cast<PaintedShape>(i)); |
252 | 253 |
253 root_layer_->SetMasksToBounds(false); | 254 root_layer_->SetMasksToBounds(false); |
254 root_layer_->SetBounds(gfx::Rect(large_size_)); | 255 root_layer_->SetBounds(gfx::Rect(large_size_)); |
255 | 256 |
256 ResetTransformsToMinSize(); | 257 SetStateToHidden(); |
257 | |
258 SetOpacity(kHiddenOpacity); | |
259 } | 258 } |
260 | 259 |
261 InkDropAnimation::~InkDropAnimation() {} | 260 InkDropAnimation::~InkDropAnimation() { |
261 // Explicitly aborting all the animations ensures all callbacks are invoked | |
262 // while this instance still exists. | |
263 AbortAllAnimations(); | |
264 } | |
265 | |
266 void InkDropAnimation::AddObserver(InkDropAnimationObserver* observer) { | |
267 if (!observers_.HasObserver(observer)) | |
varkha
2015/10/06 20:58:38
When is this the case? Do we need this?
sadrul
2015/10/08 01:06:01
+1 Let's remove this.
bruthig
2015/10/08 21:42:55
It was originally intended as a safe-guard to ensu
| |
268 observers_.AddObserver(observer); | |
269 } | |
270 | |
271 void InkDropAnimation::RemoveObserver(InkDropAnimationObserver* observer) { | |
272 observers_.RemoveObserver(observer); | |
273 } | |
262 | 274 |
263 void InkDropAnimation::AnimateToState(InkDropState ink_drop_state) { | 275 void InkDropAnimation::AnimateToState(InkDropState ink_drop_state) { |
264 if (ink_drop_state_ == ink_drop_state) | 276 // |animation_observer| will be deleted when AnimationEndedCallback() returns |
265 return; | 277 // true. |
278 ui::CallbackLayerAnimationObserver* animation_observer = | |
279 new ui::CallbackLayerAnimationObserver( | |
280 base::Bind(&InkDropAnimation::AnimationStartedCallback, | |
281 base::Unretained(this), ink_drop_state), | |
282 base::Bind(&InkDropAnimation::AnimationEndedCallback, | |
283 base::Unretained(this), ink_drop_state)); | |
284 AnimateToStateInternal(ink_drop_state, animation_observer); | |
285 animation_observer->SetActive(); | |
286 } | |
287 | |
288 void InkDropAnimation::AnimateToStateInternal( | |
289 InkDropState ink_drop_state, | |
290 ui::LayerAnimationObserver* animation_observer) { | |
291 ink_drop_state_ = ink_drop_state; | |
266 | 292 |
267 if (ink_drop_state_ == InkDropState::HIDDEN) { | 293 if (ink_drop_state_ == InkDropState::HIDDEN) { |
268 ResetTransformsToMinSize(); | 294 // Animating to the HIDDEN state doesn't actually use any |
269 SetOpacity(kVisibleOpacity); | 295 // LayerAnimationSequences so we need to explicitly abort any running ones |
296 // so that observers receive an InkDropAnimationEnded() event for the | |
297 // running animation prior to receiving an InkDropAnimationStarted() event | |
298 // for the HIDDEN 'animation'. | |
299 AbortAllAnimations(); | |
300 root_layer_->SetVisible(false); | |
301 SetStateToHidden(); | |
302 return; | |
270 } | 303 } |
271 | 304 |
272 InkDropTransforms transforms; | 305 InkDropTransforms transforms; |
273 | 306 root_layer_->SetVisible(true); |
274 // Must set the |ink_drop_state_| before handling the state change because | |
275 // some state changes make recursive calls to AnimateToState() and the last | |
276 // call should 'win'. | |
277 ink_drop_state_ = ink_drop_state; | |
278 | 307 |
279 switch (ink_drop_state_) { | 308 switch (ink_drop_state_) { |
280 case InkDropState::HIDDEN: | 309 case InkDropState::HIDDEN: |
281 GetCurrentTansforms(&transforms); | 310 // This case is handled above in a short circuit return. |
282 AnimateToTransforms(transforms, kHiddenOpacity, | |
283 GetAnimationDuration(InkDropState::HIDDEN), | |
284 ui::LayerAnimator::ENQUEUE_NEW_ANIMATION); | |
285 break; | 311 break; |
286 case InkDropState::ACTION_PENDING: | 312 case InkDropState::ACTION_PENDING: |
287 CalculateCircleTransforms(large_size_, &transforms); | 313 CalculateCircleTransforms(large_size_, &transforms); |
288 AnimateToTransforms(transforms, kVisibleOpacity, | 314 AnimateToTransforms(transforms, kVisibleOpacity, |
289 GetAnimationDuration(InkDropState::ACTION_PENDING), | 315 GetAnimationDuration(InkDropState::ACTION_PENDING), |
290 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 316 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, |
317 animation_observer); | |
291 break; | 318 break; |
292 case InkDropState::QUICK_ACTION: | 319 case InkDropState::QUICK_ACTION: |
293 CalculateCircleTransforms(large_size_, &transforms); | 320 CalculateCircleTransforms(large_size_, &transforms); |
294 AnimateToTransforms(transforms, kHiddenOpacity, | 321 AnimateToTransforms(transforms, kHiddenOpacity, |
295 GetAnimationDuration(InkDropState::QUICK_ACTION), | 322 GetAnimationDuration(InkDropState::QUICK_ACTION), |
296 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 323 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, |
297 AnimateToState(InkDropState::HIDDEN); | 324 animation_observer); |
298 break; | 325 break; |
299 case InkDropState::SLOW_ACTION_PENDING: | 326 case InkDropState::SLOW_ACTION_PENDING: |
300 CalculateRectTransforms(small_size_, small_corner_radius_, &transforms); | 327 CalculateRectTransforms(small_size_, small_corner_radius_, &transforms); |
301 AnimateToTransforms( | 328 AnimateToTransforms( |
302 transforms, kVisibleOpacity, | 329 transforms, kVisibleOpacity, |
303 GetAnimationDuration(InkDropState::SLOW_ACTION_PENDING), | 330 GetAnimationDuration(InkDropState::SLOW_ACTION_PENDING), |
304 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 331 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, |
332 animation_observer); | |
305 break; | 333 break; |
306 case InkDropState::SLOW_ACTION: | 334 case InkDropState::SLOW_ACTION: |
307 CalculateRectTransforms(large_size_, large_corner_radius_, &transforms); | 335 CalculateRectTransforms(large_size_, large_corner_radius_, &transforms); |
308 AnimateToTransforms(transforms, kHiddenOpacity, | 336 AnimateToTransforms(transforms, kHiddenOpacity, |
309 GetAnimationDuration(InkDropState::SLOW_ACTION), | 337 GetAnimationDuration(InkDropState::SLOW_ACTION), |
310 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 338 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, |
311 AnimateToState(InkDropState::HIDDEN); | 339 animation_observer); |
312 break; | 340 break; |
313 case InkDropState::ACTIVATED: | 341 case InkDropState::ACTIVATED: |
314 CalculateRectTransforms(small_size_, small_corner_radius_, &transforms); | 342 CalculateRectTransforms(small_size_, small_corner_radius_, &transforms); |
315 AnimateToTransforms(transforms, kVisibleOpacity, | 343 AnimateToTransforms(transforms, kVisibleOpacity, |
316 GetAnimationDuration(InkDropState::ACTIVATED), | 344 GetAnimationDuration(InkDropState::ACTIVATED), |
317 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 345 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, |
346 animation_observer); | |
318 break; | 347 break; |
319 case InkDropState::DEACTIVATED: | 348 case InkDropState::DEACTIVATED: |
320 CalculateRectTransforms(large_size_, large_corner_radius_, &transforms); | 349 CalculateRectTransforms(large_size_, large_corner_radius_, &transforms); |
321 AnimateToTransforms(transforms, kHiddenOpacity, | 350 AnimateToTransforms(transforms, kHiddenOpacity, |
322 GetAnimationDuration(InkDropState::DEACTIVATED), | 351 GetAnimationDuration(InkDropState::DEACTIVATED), |
323 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 352 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, |
324 AnimateToState(InkDropState::HIDDEN); | 353 animation_observer); |
325 break; | 354 break; |
326 } | 355 } |
327 } | 356 } |
328 | 357 |
329 void InkDropAnimation::AnimateToTransforms( | 358 void InkDropAnimation::AnimateToTransforms( |
330 const InkDropTransforms transforms, | 359 const InkDropTransforms transforms, |
331 float opacity, | 360 float opacity, |
332 base::TimeDelta duration, | 361 base::TimeDelta duration, |
333 ui::LayerAnimator::PreemptionStrategy preemption_strategy) { | 362 ui::LayerAnimator::PreemptionStrategy preemption_strategy, |
363 ui::LayerAnimationObserver* animation_observer) { | |
334 ui::LayerAnimator* root_animator = root_layer_->GetAnimator(); | 364 ui::LayerAnimator* root_animator = root_layer_->GetAnimator(); |
335 ui::ScopedLayerAnimationSettings root_animation(root_animator); | 365 ui::ScopedLayerAnimationSettings root_animation(root_animator); |
336 root_animation.SetPreemptionStrategy(preemption_strategy); | 366 root_animation.SetPreemptionStrategy(preemption_strategy); |
337 ui::LayerAnimationElement* root_element = | 367 ui::LayerAnimationElement* root_element = |
338 ui::LayerAnimationElement::CreateOpacityElement(opacity, duration); | 368 ui::LayerAnimationElement::CreateOpacityElement(opacity, duration); |
339 ui::LayerAnimationSequence* root_sequence = | 369 ui::LayerAnimationSequence* root_sequence = |
340 new ui::LayerAnimationSequence(root_element); | 370 new ui::LayerAnimationSequence(root_element); |
371 | |
372 if (animation_observer) | |
373 root_sequence->AddObserver(animation_observer); | |
374 | |
341 root_animator->StartAnimation(root_sequence); | 375 root_animator->StartAnimation(root_sequence); |
342 | 376 |
343 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) { | 377 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) { |
344 ui::LayerAnimator* animator = painted_layers_[i]->GetAnimator(); | 378 ui::LayerAnimator* animator = painted_layers_[i]->GetAnimator(); |
345 ui::ScopedLayerAnimationSettings animation(animator); | 379 ui::ScopedLayerAnimationSettings animation(animator); |
346 animation.SetPreemptionStrategy(preemption_strategy); | 380 animation.SetPreemptionStrategy(preemption_strategy); |
347 ui::LayerAnimationElement* element = | 381 ui::LayerAnimationElement* element = |
348 ui::LayerAnimationElement::CreateTransformElement(transforms[i], | 382 ui::LayerAnimationElement::CreateTransformElement(transforms[i], |
349 duration); | 383 duration); |
350 ui::LayerAnimationSequence* sequence = | 384 ui::LayerAnimationSequence* sequence = |
351 new ui::LayerAnimationSequence(element); | 385 new ui::LayerAnimationSequence(element); |
386 | |
387 if (animation_observer) | |
388 sequence->AddObserver(animation_observer); | |
389 | |
352 animator->StartAnimation(sequence); | 390 animator->StartAnimation(sequence); |
353 } | 391 } |
354 } | 392 } |
355 | 393 |
356 void InkDropAnimation::ResetTransformsToMinSize() { | 394 void InkDropAnimation::SetStateToHidden() { |
357 InkDropTransforms transforms; | 395 InkDropTransforms transforms; |
358 // Using a size of 0x0 creates visual anomalies. | 396 // Using a size of 0x0 creates visual anomalies. |
359 CalculateCircleTransforms(gfx::Size(1, 1), &transforms); | 397 CalculateCircleTransforms(gfx::Size(1, 1), &transforms); |
360 SetTransforms(transforms); | 398 SetTransforms(transforms); |
399 SetOpacity(kHiddenOpacity); | |
361 } | 400 } |
362 | 401 |
363 void InkDropAnimation::SetTransforms(const InkDropTransforms transforms) { | 402 void InkDropAnimation::SetTransforms(const InkDropTransforms transforms) { |
364 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) | 403 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) |
365 painted_layers_[i]->SetTransform(transforms[i]); | 404 painted_layers_[i]->SetTransform(transforms[i]); |
366 } | 405 } |
367 | 406 |
368 void InkDropAnimation::SetOpacity(float opacity) { | 407 void InkDropAnimation::SetOpacity(float opacity) { |
369 root_layer_->SetOpacity(opacity); | 408 root_layer_->SetOpacity(opacity); |
370 } | 409 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
429 (size.width() - 2.0f * corner_radius) / rect_delegate_width), | 468 (size.width() - 2.0f * corner_radius) / rect_delegate_width), |
430 std::max(kMinimumRectScale, size.height() / rect_delegate_height)); | 469 std::max(kMinimumRectScale, size.height() / rect_delegate_height)); |
431 } | 470 } |
432 | 471 |
433 void InkDropAnimation::GetCurrentTansforms( | 472 void InkDropAnimation::GetCurrentTansforms( |
434 InkDropTransforms* transforms_out) const { | 473 InkDropTransforms* transforms_out) const { |
435 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) | 474 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) |
436 (*transforms_out)[i] = painted_layers_[i]->GetTargetTransform(); | 475 (*transforms_out)[i] = painted_layers_[i]->GetTargetTransform(); |
437 } | 476 } |
438 | 477 |
439 void InkDropAnimation::SetCenterPoint(const gfx::Point& center_point) { | 478 void InkDropAnimation::SetCenterPoint(const gfx::Point& center_point) { |
varkha
2015/10/06 20:58:37
nit: Should probably be moved above to reflect the
bruthig
2015/10/08 21:42:55
Done.
| |
440 gfx::Transform transform; | 479 gfx::Transform transform; |
441 transform.Translate(center_point.x(), center_point.y()); | 480 transform.Translate(center_point.x(), center_point.y()); |
442 root_layer_->SetTransform(transform); | 481 root_layer_->SetTransform(transform); |
443 } | 482 } |
444 | 483 |
445 void InkDropAnimation::AddPaintLayer(PaintedShape painted_shape) { | 484 void InkDropAnimation::AddPaintLayer(PaintedShape painted_shape) { |
446 ui::LayerDelegate* delegate = nullptr; | 485 ui::LayerDelegate* delegate = nullptr; |
447 switch (painted_shape) { | 486 switch (painted_shape) { |
448 case TOP_LEFT_CIRCLE: | 487 case TOP_LEFT_CIRCLE: |
449 case TOP_RIGHT_CIRCLE: | 488 case TOP_RIGHT_CIRCLE: |
(...skipping 16 matching lines...) Expand all Loading... | |
466 layer->SetBounds(gfx::Rect(large_size_)); | 505 layer->SetBounds(gfx::Rect(large_size_)); |
467 layer->SetFillsBoundsOpaquely(false); | 506 layer->SetFillsBoundsOpaquely(false); |
468 layer->set_delegate(delegate); | 507 layer->set_delegate(delegate); |
469 layer->SetVisible(true); | 508 layer->SetVisible(true); |
470 layer->SetOpacity(1.0); | 509 layer->SetOpacity(1.0); |
471 layer->SetMasksToBounds(false); | 510 layer->SetMasksToBounds(false); |
472 | 511 |
473 painted_layers_[painted_shape].reset(layer); | 512 painted_layers_[painted_shape].reset(layer); |
474 } | 513 } |
475 | 514 |
515 void InkDropAnimation::AbortAllAnimations() { | |
516 root_layer_->GetAnimator()->AbortAllAnimations(); | |
517 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) | |
varkha
2015/10/06 20:58:38
Will range syntax work here (and in SetTransforms
bruthig
2015/10/08 21:42:55
It appears there isn't built in support for range
| |
518 painted_layers_[i]->GetAnimator()->AbortAllAnimations(); | |
519 } | |
520 | |
521 void InkDropAnimation::AnimationStartedCallback( | |
522 InkDropState ink_drop_state, | |
523 const ui::CallbackLayerAnimationObserver& observer) { | |
524 FOR_EACH_OBSERVER(InkDropAnimationObserver, observers_, | |
525 InkDropAnimationStarted(ink_drop_state)); | |
526 } | |
527 | |
528 bool InkDropAnimation::AnimationEndedCallback( | |
529 InkDropState ink_drop_state, | |
530 const ui::CallbackLayerAnimationObserver& observer) { | |
531 FOR_EACH_OBSERVER( | |
532 InkDropAnimationObserver, observers_, | |
533 InkDropAnimationEnded(ink_drop_state, | |
534 observer.aborted_count() | |
sadrul
2015/10/08 01:06:01
Is this the only reason to send the observer back
bruthig
2015/10/08 21:42:55
In the current use case yes, this is the only data
sadrul
2015/10/09 20:36:26
Simplicity. It's not complex as it is now, so that
| |
535 ? InkDropAnimationObserver::PRE_EMPTED | |
536 : InkDropAnimationObserver::SUCCESS)); | |
537 return true; | |
538 } | |
539 | |
476 } // namespace views | 540 } // namespace views |
OLD | NEW |