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

Unified Diff: ui/views/animation/ink_drop_animation.cc

Issue 1373983002: Enhanced the InkDropRippleImpl to create/destroy InkDropAnimations as needed. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Based diff delta on dependant branch. Created 5 years, 2 months 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 side-by-side diff with in-line comments
Download patch
Index: ui/views/animation/ink_drop_animation.cc
diff --git a/ui/views/animation/ink_drop_animation.cc b/ui/views/animation/ink_drop_animation.cc
index d5ce3ca9d524b6984d00343092ef49a3c44e566c..0b5e65e88afc3691eda2d8d80e924d1d362e8f7f 100644
--- a/ui/views/animation/ink_drop_animation.cc
+++ b/ui/views/animation/ink_drop_animation.cc
@@ -11,13 +11,14 @@
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "ui/base/ui_base_switches.h"
+#include "ui/compositor/callback_layer_animation_observer.h"
#include "ui/compositor/layer.h"
-#include "ui/compositor/layer_animation_observer.h"
#include "ui/compositor/layer_animation_sequence.h"
#include "ui/compositor/paint_recorder.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/transform_util.h"
+#include "ui/views/animation/ink_drop_animation_observer.h"
#include "ui/views/view.h"
namespace {
@@ -253,75 +254,103 @@ InkDropAnimation::InkDropAnimation(const gfx::Size& large_size,
root_layer_->SetMasksToBounds(false);
root_layer_->SetBounds(gfx::Rect(large_size_));
- ResetTransformsToMinSize();
+ SetStateToHidden();
+}
- SetOpacity(kHiddenOpacity);
+InkDropAnimation::~InkDropAnimation() {
+ // Explicitly aborting all the animations ensures all callbacks are invoked
+ // while this instance still exists.
+ AbortAllAnimations();
}
-InkDropAnimation::~InkDropAnimation() {}
+void InkDropAnimation::AddObserver(InkDropAnimationObserver* observer) {
+ 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
+ observers_.AddObserver(observer);
+}
+
+void InkDropAnimation::RemoveObserver(InkDropAnimationObserver* observer) {
+ observers_.RemoveObserver(observer);
+}
void InkDropAnimation::AnimateToState(InkDropState ink_drop_state) {
- if (ink_drop_state_ == ink_drop_state)
- return;
+ // |animation_observer| will be deleted when AnimationEndedCallback() returns
+ // true.
+ ui::CallbackLayerAnimationObserver* animation_observer =
+ new ui::CallbackLayerAnimationObserver(
+ base::Bind(&InkDropAnimation::AnimationStartedCallback,
+ base::Unretained(this), ink_drop_state),
+ base::Bind(&InkDropAnimation::AnimationEndedCallback,
+ base::Unretained(this), ink_drop_state));
+ AnimateToStateInternal(ink_drop_state, animation_observer);
+ animation_observer->SetActive();
+}
+
+void InkDropAnimation::AnimateToStateInternal(
+ InkDropState ink_drop_state,
+ ui::LayerAnimationObserver* animation_observer) {
+ ink_drop_state_ = ink_drop_state;
if (ink_drop_state_ == InkDropState::HIDDEN) {
- ResetTransformsToMinSize();
- SetOpacity(kVisibleOpacity);
+ // Animating to the HIDDEN state doesn't actually use any
+ // LayerAnimationSequences so we need to explicitly abort any running ones
+ // so that observers receive an InkDropAnimationEnded() event for the
+ // running animation prior to receiving an InkDropAnimationStarted() event
+ // for the HIDDEN 'animation'.
+ AbortAllAnimations();
+ root_layer_->SetVisible(false);
+ SetStateToHidden();
+ return;
}
InkDropTransforms transforms;
-
- // Must set the |ink_drop_state_| before handling the state change because
- // some state changes make recursive calls to AnimateToState() and the last
- // call should 'win'.
- ink_drop_state_ = ink_drop_state;
+ root_layer_->SetVisible(true);
switch (ink_drop_state_) {
case InkDropState::HIDDEN:
- GetCurrentTansforms(&transforms);
- AnimateToTransforms(transforms, kHiddenOpacity,
- GetAnimationDuration(InkDropState::HIDDEN),
- ui::LayerAnimator::ENQUEUE_NEW_ANIMATION);
+ // This case is handled above in a short circuit return.
break;
case InkDropState::ACTION_PENDING:
CalculateCircleTransforms(large_size_, &transforms);
AnimateToTransforms(transforms, kVisibleOpacity,
GetAnimationDuration(InkDropState::ACTION_PENDING),
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
+ animation_observer);
break;
case InkDropState::QUICK_ACTION:
CalculateCircleTransforms(large_size_, &transforms);
AnimateToTransforms(transforms, kHiddenOpacity,
GetAnimationDuration(InkDropState::QUICK_ACTION),
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
- AnimateToState(InkDropState::HIDDEN);
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
+ animation_observer);
break;
case InkDropState::SLOW_ACTION_PENDING:
CalculateRectTransforms(small_size_, small_corner_radius_, &transforms);
AnimateToTransforms(
transforms, kVisibleOpacity,
GetAnimationDuration(InkDropState::SLOW_ACTION_PENDING),
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
+ animation_observer);
break;
case InkDropState::SLOW_ACTION:
CalculateRectTransforms(large_size_, large_corner_radius_, &transforms);
AnimateToTransforms(transforms, kHiddenOpacity,
GetAnimationDuration(InkDropState::SLOW_ACTION),
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
- AnimateToState(InkDropState::HIDDEN);
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
+ animation_observer);
break;
case InkDropState::ACTIVATED:
CalculateRectTransforms(small_size_, small_corner_radius_, &transforms);
AnimateToTransforms(transforms, kVisibleOpacity,
GetAnimationDuration(InkDropState::ACTIVATED),
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
+ animation_observer);
break;
case InkDropState::DEACTIVATED:
CalculateRectTransforms(large_size_, large_corner_radius_, &transforms);
AnimateToTransforms(transforms, kHiddenOpacity,
GetAnimationDuration(InkDropState::DEACTIVATED),
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
- AnimateToState(InkDropState::HIDDEN);
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
+ animation_observer);
break;
}
}
@@ -330,7 +359,8 @@ void InkDropAnimation::AnimateToTransforms(
const InkDropTransforms transforms,
float opacity,
base::TimeDelta duration,
- ui::LayerAnimator::PreemptionStrategy preemption_strategy) {
+ ui::LayerAnimator::PreemptionStrategy preemption_strategy,
+ ui::LayerAnimationObserver* animation_observer) {
ui::LayerAnimator* root_animator = root_layer_->GetAnimator();
ui::ScopedLayerAnimationSettings root_animation(root_animator);
root_animation.SetPreemptionStrategy(preemption_strategy);
@@ -338,6 +368,10 @@ void InkDropAnimation::AnimateToTransforms(
ui::LayerAnimationElement::CreateOpacityElement(opacity, duration);
ui::LayerAnimationSequence* root_sequence =
new ui::LayerAnimationSequence(root_element);
+
+ if (animation_observer)
+ root_sequence->AddObserver(animation_observer);
+
root_animator->StartAnimation(root_sequence);
for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) {
@@ -349,15 +383,20 @@ void InkDropAnimation::AnimateToTransforms(
duration);
ui::LayerAnimationSequence* sequence =
new ui::LayerAnimationSequence(element);
+
+ if (animation_observer)
+ sequence->AddObserver(animation_observer);
+
animator->StartAnimation(sequence);
}
}
-void InkDropAnimation::ResetTransformsToMinSize() {
+void InkDropAnimation::SetStateToHidden() {
InkDropTransforms transforms;
// Using a size of 0x0 creates visual anomalies.
CalculateCircleTransforms(gfx::Size(1, 1), &transforms);
SetTransforms(transforms);
+ SetOpacity(kHiddenOpacity);
}
void InkDropAnimation::SetTransforms(const InkDropTransforms transforms) {
@@ -473,4 +512,29 @@ void InkDropAnimation::AddPaintLayer(PaintedShape painted_shape) {
painted_layers_[painted_shape].reset(layer);
}
+void InkDropAnimation::AbortAllAnimations() {
+ root_layer_->GetAnimator()->AbortAllAnimations();
+ 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
+ painted_layers_[i]->GetAnimator()->AbortAllAnimations();
+}
+
+void InkDropAnimation::AnimationStartedCallback(
+ InkDropState ink_drop_state,
+ const ui::CallbackLayerAnimationObserver& observer) {
+ FOR_EACH_OBSERVER(InkDropAnimationObserver, observers_,
+ InkDropAnimationStarted(ink_drop_state));
+}
+
+bool InkDropAnimation::AnimationEndedCallback(
+ InkDropState ink_drop_state,
+ const ui::CallbackLayerAnimationObserver& observer) {
+ FOR_EACH_OBSERVER(
+ InkDropAnimationObserver, observers_,
+ InkDropAnimationEnded(ink_drop_state,
+ 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
+ ? InkDropAnimationObserver::PRE_EMPTED
+ : InkDropAnimationObserver::SUCCESS));
+ return true;
+}
+
} // namespace views

Powered by Google App Engine
This is Rietveld 408576698