| 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 observers_.AddObserver(observer); |
| 268 } |
| 269 |
| 270 void InkDropAnimation::RemoveObserver(InkDropAnimationObserver* observer) { |
| 271 observers_.RemoveObserver(observer); |
| 272 } |
| 262 | 273 |
| 263 void InkDropAnimation::AnimateToState(InkDropState ink_drop_state) { | 274 void InkDropAnimation::AnimateToState(InkDropState ink_drop_state) { |
| 264 if (ink_drop_state_ == ink_drop_state) | 275 // |animation_observer| will be deleted when AnimationEndedCallback() returns |
| 265 return; | 276 // true. |
| 277 ui::CallbackLayerAnimationObserver* animation_observer = |
| 278 new ui::CallbackLayerAnimationObserver( |
| 279 base::Bind(&InkDropAnimation::AnimationStartedCallback, |
| 280 base::Unretained(this), ink_drop_state), |
| 281 base::Bind(&InkDropAnimation::AnimationEndedCallback, |
| 282 base::Unretained(this), ink_drop_state)); |
| 283 AnimateToStateInternal(ink_drop_state, animation_observer); |
| 284 animation_observer->SetActive(); |
| 285 } |
| 286 |
| 287 void InkDropAnimation::SetCenterPoint(const gfx::Point& center_point) { |
| 288 gfx::Transform transform; |
| 289 transform.Translate(center_point.x(), center_point.y()); |
| 290 root_layer_->SetTransform(transform); |
| 291 } |
| 292 |
| 293 void InkDropAnimation::AnimateToStateInternal( |
| 294 InkDropState ink_drop_state, |
| 295 ui::LayerAnimationObserver* animation_observer) { |
| 296 ink_drop_state_ = ink_drop_state; |
| 266 | 297 |
| 267 if (ink_drop_state_ == InkDropState::HIDDEN) { | 298 if (ink_drop_state_ == InkDropState::HIDDEN) { |
| 268 ResetTransformsToMinSize(); | 299 // Animating to the HIDDEN state doesn't actually use any |
| 269 SetOpacity(kVisibleOpacity); | 300 // LayerAnimationSequences so we need to explicitly abort any running ones |
| 301 // so that observers receive an InkDropAnimationEnded() event for the |
| 302 // running animation prior to receiving an InkDropAnimationStarted() event |
| 303 // for the HIDDEN 'animation'. |
| 304 AbortAllAnimations(); |
| 305 root_layer_->SetVisible(false); |
| 306 SetStateToHidden(); |
| 307 return; |
| 270 } | 308 } |
| 271 | 309 |
| 272 InkDropTransforms transforms; | 310 InkDropTransforms transforms; |
| 273 | 311 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 | 312 |
| 279 switch (ink_drop_state_) { | 313 switch (ink_drop_state_) { |
| 280 case InkDropState::HIDDEN: | 314 case InkDropState::HIDDEN: |
| 281 GetCurrentTansforms(&transforms); | 315 // 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; | 316 break; |
| 286 case InkDropState::ACTION_PENDING: | 317 case InkDropState::ACTION_PENDING: |
| 287 CalculateCircleTransforms(large_size_, &transforms); | 318 CalculateCircleTransforms(large_size_, &transforms); |
| 288 AnimateToTransforms(transforms, kVisibleOpacity, | 319 AnimateToTransforms(transforms, kVisibleOpacity, |
| 289 GetAnimationDuration(InkDropState::ACTION_PENDING), | 320 GetAnimationDuration(InkDropState::ACTION_PENDING), |
| 290 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 321 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, |
| 322 animation_observer); |
| 291 break; | 323 break; |
| 292 case InkDropState::QUICK_ACTION: | 324 case InkDropState::QUICK_ACTION: |
| 293 CalculateCircleTransforms(large_size_, &transforms); | 325 CalculateCircleTransforms(large_size_, &transforms); |
| 294 AnimateToTransforms(transforms, kHiddenOpacity, | 326 AnimateToTransforms(transforms, kHiddenOpacity, |
| 295 GetAnimationDuration(InkDropState::QUICK_ACTION), | 327 GetAnimationDuration(InkDropState::QUICK_ACTION), |
| 296 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 328 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, |
| 297 AnimateToState(InkDropState::HIDDEN); | 329 animation_observer); |
| 298 break; | 330 break; |
| 299 case InkDropState::SLOW_ACTION_PENDING: | 331 case InkDropState::SLOW_ACTION_PENDING: |
| 300 CalculateRectTransforms(small_size_, small_corner_radius_, &transforms); | 332 CalculateRectTransforms(small_size_, small_corner_radius_, &transforms); |
| 301 AnimateToTransforms( | 333 AnimateToTransforms( |
| 302 transforms, kVisibleOpacity, | 334 transforms, kVisibleOpacity, |
| 303 GetAnimationDuration(InkDropState::SLOW_ACTION_PENDING), | 335 GetAnimationDuration(InkDropState::SLOW_ACTION_PENDING), |
| 304 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 336 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, |
| 337 animation_observer); |
| 305 break; | 338 break; |
| 306 case InkDropState::SLOW_ACTION: | 339 case InkDropState::SLOW_ACTION: |
| 307 CalculateRectTransforms(large_size_, large_corner_radius_, &transforms); | 340 CalculateRectTransforms(large_size_, large_corner_radius_, &transforms); |
| 308 AnimateToTransforms(transforms, kHiddenOpacity, | 341 AnimateToTransforms(transforms, kHiddenOpacity, |
| 309 GetAnimationDuration(InkDropState::SLOW_ACTION), | 342 GetAnimationDuration(InkDropState::SLOW_ACTION), |
| 310 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 343 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, |
| 311 AnimateToState(InkDropState::HIDDEN); | 344 animation_observer); |
| 312 break; | 345 break; |
| 313 case InkDropState::ACTIVATED: | 346 case InkDropState::ACTIVATED: |
| 314 CalculateRectTransforms(small_size_, small_corner_radius_, &transforms); | 347 CalculateRectTransforms(small_size_, small_corner_radius_, &transforms); |
| 315 AnimateToTransforms(transforms, kVisibleOpacity, | 348 AnimateToTransforms(transforms, kVisibleOpacity, |
| 316 GetAnimationDuration(InkDropState::ACTIVATED), | 349 GetAnimationDuration(InkDropState::ACTIVATED), |
| 317 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 350 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, |
| 351 animation_observer); |
| 318 break; | 352 break; |
| 319 case InkDropState::DEACTIVATED: | 353 case InkDropState::DEACTIVATED: |
| 320 CalculateRectTransforms(large_size_, large_corner_radius_, &transforms); | 354 CalculateRectTransforms(large_size_, large_corner_radius_, &transforms); |
| 321 AnimateToTransforms(transforms, kHiddenOpacity, | 355 AnimateToTransforms(transforms, kHiddenOpacity, |
| 322 GetAnimationDuration(InkDropState::DEACTIVATED), | 356 GetAnimationDuration(InkDropState::DEACTIVATED), |
| 323 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 357 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, |
| 324 AnimateToState(InkDropState::HIDDEN); | 358 animation_observer); |
| 325 break; | 359 break; |
| 326 } | 360 } |
| 327 } | 361 } |
| 328 | 362 |
| 329 void InkDropAnimation::AnimateToTransforms( | 363 void InkDropAnimation::AnimateToTransforms( |
| 330 const InkDropTransforms transforms, | 364 const InkDropTransforms transforms, |
| 331 float opacity, | 365 float opacity, |
| 332 base::TimeDelta duration, | 366 base::TimeDelta duration, |
| 333 ui::LayerAnimator::PreemptionStrategy preemption_strategy) { | 367 ui::LayerAnimator::PreemptionStrategy preemption_strategy, |
| 368 ui::LayerAnimationObserver* animation_observer) { |
| 334 ui::LayerAnimator* root_animator = root_layer_->GetAnimator(); | 369 ui::LayerAnimator* root_animator = root_layer_->GetAnimator(); |
| 335 ui::ScopedLayerAnimationSettings root_animation(root_animator); | 370 ui::ScopedLayerAnimationSettings root_animation(root_animator); |
| 336 root_animation.SetPreemptionStrategy(preemption_strategy); | 371 root_animation.SetPreemptionStrategy(preemption_strategy); |
| 337 ui::LayerAnimationElement* root_element = | 372 ui::LayerAnimationElement* root_element = |
| 338 ui::LayerAnimationElement::CreateOpacityElement(opacity, duration); | 373 ui::LayerAnimationElement::CreateOpacityElement(opacity, duration); |
| 339 ui::LayerAnimationSequence* root_sequence = | 374 ui::LayerAnimationSequence* root_sequence = |
| 340 new ui::LayerAnimationSequence(root_element); | 375 new ui::LayerAnimationSequence(root_element); |
| 376 |
| 377 if (animation_observer) |
| 378 root_sequence->AddObserver(animation_observer); |
| 379 |
| 341 root_animator->StartAnimation(root_sequence); | 380 root_animator->StartAnimation(root_sequence); |
| 342 | 381 |
| 343 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) { | 382 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) { |
| 344 ui::LayerAnimator* animator = painted_layers_[i]->GetAnimator(); | 383 ui::LayerAnimator* animator = painted_layers_[i]->GetAnimator(); |
| 345 ui::ScopedLayerAnimationSettings animation(animator); | 384 ui::ScopedLayerAnimationSettings animation(animator); |
| 346 animation.SetPreemptionStrategy(preemption_strategy); | 385 animation.SetPreemptionStrategy(preemption_strategy); |
| 347 ui::LayerAnimationElement* element = | 386 ui::LayerAnimationElement* element = |
| 348 ui::LayerAnimationElement::CreateTransformElement(transforms[i], | 387 ui::LayerAnimationElement::CreateTransformElement(transforms[i], |
| 349 duration); | 388 duration); |
| 350 ui::LayerAnimationSequence* sequence = | 389 ui::LayerAnimationSequence* sequence = |
| 351 new ui::LayerAnimationSequence(element); | 390 new ui::LayerAnimationSequence(element); |
| 391 |
| 392 if (animation_observer) |
| 393 sequence->AddObserver(animation_observer); |
| 394 |
| 352 animator->StartAnimation(sequence); | 395 animator->StartAnimation(sequence); |
| 353 } | 396 } |
| 354 } | 397 } |
| 355 | 398 |
| 356 void InkDropAnimation::ResetTransformsToMinSize() { | 399 void InkDropAnimation::SetStateToHidden() { |
| 357 InkDropTransforms transforms; | 400 InkDropTransforms transforms; |
| 358 // Using a size of 0x0 creates visual anomalies. | 401 // Using a size of 0x0 creates visual anomalies. |
| 359 CalculateCircleTransforms(gfx::Size(1, 1), &transforms); | 402 CalculateCircleTransforms(gfx::Size(1, 1), &transforms); |
| 360 SetTransforms(transforms); | 403 SetTransforms(transforms); |
| 404 SetOpacity(kHiddenOpacity); |
| 361 } | 405 } |
| 362 | 406 |
| 363 void InkDropAnimation::SetTransforms(const InkDropTransforms transforms) { | 407 void InkDropAnimation::SetTransforms(const InkDropTransforms transforms) { |
| 364 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) | 408 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) |
| 365 painted_layers_[i]->SetTransform(transforms[i]); | 409 painted_layers_[i]->SetTransform(transforms[i]); |
| 366 } | 410 } |
| 367 | 411 |
| 368 void InkDropAnimation::SetOpacity(float opacity) { | 412 void InkDropAnimation::SetOpacity(float opacity) { |
| 369 root_layer_->SetOpacity(opacity); | 413 root_layer_->SetOpacity(opacity); |
| 370 } | 414 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 (size.width() - 2.0f * corner_radius) / rect_delegate_width), | 473 (size.width() - 2.0f * corner_radius) / rect_delegate_width), |
| 430 std::max(kMinimumRectScale, size.height() / rect_delegate_height)); | 474 std::max(kMinimumRectScale, size.height() / rect_delegate_height)); |
| 431 } | 475 } |
| 432 | 476 |
| 433 void InkDropAnimation::GetCurrentTansforms( | 477 void InkDropAnimation::GetCurrentTansforms( |
| 434 InkDropTransforms* transforms_out) const { | 478 InkDropTransforms* transforms_out) const { |
| 435 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) | 479 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) |
| 436 (*transforms_out)[i] = painted_layers_[i]->GetTargetTransform(); | 480 (*transforms_out)[i] = painted_layers_[i]->GetTargetTransform(); |
| 437 } | 481 } |
| 438 | 482 |
| 439 void InkDropAnimation::SetCenterPoint(const gfx::Point& center_point) { | |
| 440 gfx::Transform transform; | |
| 441 transform.Translate(center_point.x(), center_point.y()); | |
| 442 root_layer_->SetTransform(transform); | |
| 443 } | |
| 444 | |
| 445 void InkDropAnimation::AddPaintLayer(PaintedShape painted_shape) { | 483 void InkDropAnimation::AddPaintLayer(PaintedShape painted_shape) { |
| 446 ui::LayerDelegate* delegate = nullptr; | 484 ui::LayerDelegate* delegate = nullptr; |
| 447 switch (painted_shape) { | 485 switch (painted_shape) { |
| 448 case TOP_LEFT_CIRCLE: | 486 case TOP_LEFT_CIRCLE: |
| 449 case TOP_RIGHT_CIRCLE: | 487 case TOP_RIGHT_CIRCLE: |
| 450 case BOTTOM_RIGHT_CIRCLE: | 488 case BOTTOM_RIGHT_CIRCLE: |
| 451 case BOTTOM_LEFT_CIRCLE: | 489 case BOTTOM_LEFT_CIRCLE: |
| 452 delegate = circle_layer_delegate_.get(); | 490 delegate = circle_layer_delegate_.get(); |
| 453 break; | 491 break; |
| 454 case HORIZONTAL_RECT: | 492 case HORIZONTAL_RECT: |
| (...skipping 11 matching lines...) Expand all Loading... |
| 466 layer->SetBounds(gfx::Rect(large_size_)); | 504 layer->SetBounds(gfx::Rect(large_size_)); |
| 467 layer->SetFillsBoundsOpaquely(false); | 505 layer->SetFillsBoundsOpaquely(false); |
| 468 layer->set_delegate(delegate); | 506 layer->set_delegate(delegate); |
| 469 layer->SetVisible(true); | 507 layer->SetVisible(true); |
| 470 layer->SetOpacity(1.0); | 508 layer->SetOpacity(1.0); |
| 471 layer->SetMasksToBounds(false); | 509 layer->SetMasksToBounds(false); |
| 472 | 510 |
| 473 painted_layers_[painted_shape].reset(layer); | 511 painted_layers_[painted_shape].reset(layer); |
| 474 } | 512 } |
| 475 | 513 |
| 514 void InkDropAnimation::AbortAllAnimations() { |
| 515 root_layer_->GetAnimator()->AbortAllAnimations(); |
| 516 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) |
| 517 painted_layers_[i]->GetAnimator()->AbortAllAnimations(); |
| 518 } |
| 519 |
| 520 void InkDropAnimation::AnimationStartedCallback( |
| 521 InkDropState ink_drop_state, |
| 522 const ui::CallbackLayerAnimationObserver& observer) { |
| 523 FOR_EACH_OBSERVER(InkDropAnimationObserver, observers_, |
| 524 InkDropAnimationStarted(ink_drop_state)); |
| 525 } |
| 526 |
| 527 bool InkDropAnimation::AnimationEndedCallback( |
| 528 InkDropState ink_drop_state, |
| 529 const ui::CallbackLayerAnimationObserver& observer) { |
| 530 FOR_EACH_OBSERVER( |
| 531 InkDropAnimationObserver, observers_, |
| 532 InkDropAnimationEnded(ink_drop_state, |
| 533 observer.aborted_count() |
| 534 ? InkDropAnimationObserver::PRE_EMPTED |
| 535 : InkDropAnimationObserver::SUCCESS)); |
| 536 return true; |
| 537 } |
| 538 |
| 476 } // namespace views | 539 } // namespace views |
| OLD | NEW |