Commit ec6ba949 authored by Andrew Xu's avatar Andrew Xu Committed by Commit Bot

Fix shelf icon animation issue

When adding an icon to shelf, two animations occur in sequence: first,
icons which are already pinned are moved to leave the space for the
new icon; second, the new icon fades in. Now bounds animator
is used for both animations through ShelfView::AnimateToIdealBounds.
However, ShelfView::AnimateToIdealBounds actually updates the bounds
of all icons. As a result, first animation may be interrupted by
the second animation.

Note that in the second animation, only the opacity of the new
icon changes. This CL replaces the bounds animator with layer animation
for the second animation. In addition, thanks to the recent change in
bounds animator (https://crrev.com/c/2079607), calling SchedulePaint
during fade out animation should be unnecessary. Hence this CL also
removes that.

Bug: 1061984
Change-Id: Ide80042db99ba9ec40e824eb38ed37eb754715f4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2114579
Commit-Queue: Andrew Xu <andrewxu@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#752506}
parent 61318202
......@@ -49,6 +49,7 @@
#include "ui/base/models/simple_menu_model.h"
#include "ui/base/ui_base_features.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_animation_observer.h"
#include "ui/compositor/layer_animator.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
#include "ui/events/event_utils.h"
......@@ -196,34 +197,21 @@ bool ShelfButtonIsInDrag(const ShelfItemType item_type,
} // namespace
// AnimationDelegate used when inserting a new item. This steadily increases the
// opacity of the layer as the animation progress.
class ShelfView::FadeInAnimationDelegate : public gfx::AnimationDelegate {
// ImplicitAnimationObserver used when adding an item.
class ShelfView::FadeInAnimationDelegate
: public ui::ImplicitAnimationObserver {
public:
explicit FadeInAnimationDelegate(ShelfView* host, views::View* view)
: shelf_view_(host), view_(view) {}
~FadeInAnimationDelegate() override = default;
explicit FadeInAnimationDelegate(ShelfView* shelf_view)
: shelf_view_(shelf_view) {}
~FadeInAnimationDelegate() override { StopObservingImplicitAnimations(); }
// AnimationDelegate overrides:
void AnimationProgressed(const Animation* animation) override {
view_->layer()->SetOpacity(animation->GetCurrentValue());
view_->layer()->ScheduleDraw();
}
void AnimationEnded(const Animation* animation) override {
view_->layer()->SetOpacity(1.0f);
view_->layer()->ScheduleDraw();
private:
// ui::ImplicitAnimationObserver:
void OnImplicitAnimationsCompleted() override {
shelf_view_->OnFadeInAnimationEnded();
}
void AnimationCanceled(const Animation* animation) override {
view_->layer()->SetOpacity(1.0f);
view_->layer()->ScheduleDraw();
}
private:
ShelfView* shelf_view_ = nullptr;
views::View* view_;
DISALLOW_COPY_AND_ASSIGN(FadeInAnimationDelegate);
};
// AnimationDelegate used when deleting an item. This steadily decreased the
......@@ -237,7 +225,6 @@ class ShelfView::FadeOutAnimationDelegate : public gfx::AnimationDelegate {
// AnimationDelegate overrides:
void AnimationProgressed(const Animation* animation) override {
view_->layer()->SetOpacity(1 - animation->GetCurrentValue());
view_->layer()->ScheduleDraw();
}
void AnimationEnded(const Animation* animation) override {
// Ensures that |view| is not used after destruction.
......@@ -350,6 +337,8 @@ void ShelfView::Init() {
AddChildViewAt(child, index);
}
fade_in_animation_delegate_ = std::make_unique<FadeInAnimationDelegate>(this);
// We'll layout when our bounds change.
}
......@@ -1223,10 +1212,14 @@ void ShelfView::AnimateToIdealBounds() {
void ShelfView::FadeIn(views::View* view) {
view->SetVisible(true);
view->layer()->SetOpacity(0);
AnimateToIdealBounds();
bounds_animator_->SetAnimationDelegate(
view, std::unique_ptr<gfx::AnimationDelegate>(
new FadeInAnimationDelegate(this, view)));
ui::ScopedLayerAnimationSettings fade_in_animation_settings(
view->layer()->GetAnimator());
fade_in_animation_settings.SetTweenType(gfx::Tween::EASE_OUT);
fade_in_animation_settings.SetPreemptionStrategy(
ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET);
fade_in_animation_settings.AddObserver(fade_in_animation_delegate_.get());
view->layer()->SetOpacity(1.f);
}
void ShelfView::PrepareForDrag(Pointer pointer, const ui::LocatedEvent& event) {
......
......@@ -637,6 +637,8 @@ class ASH_EXPORT ShelfView : public views::AccessiblePaneView,
// be ScrollableShelfView.
ShelfButtonDelegate* shelf_button_delegate_ = nullptr;
std::unique_ptr<FadeInAnimationDelegate> fade_in_animation_delegate_;
base::WeakPtrFactory<ShelfView> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(ShelfView);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment