Chromium Code Reviews| 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 |