Chromium Code Reviews| Index: ui/aura_shell/launcher/launcher_view.cc |
| diff --git a/ui/aura_shell/launcher/launcher_view.cc b/ui/aura_shell/launcher/launcher_view.cc |
| index f1805009bf99ed526cdfe12c1731fdd4f9e8ea8c..41faa43407181354ec51f3f9188d7d4b4a4ebf9f 100644 |
| --- a/ui/aura_shell/launcher/launcher_view.cc |
| +++ b/ui/aura_shell/launcher/launcher_view.cc |
| @@ -13,12 +13,15 @@ |
| #include "ui/aura_shell/launcher/view_model_utils.h" |
| #include "ui/aura_shell/shell.h" |
| #include "ui/aura_shell/shell_delegate.h" |
| +#include "ui/base/animation/animation.h" |
| #include "ui/base/resource/resource_bundle.h" |
| +#include "ui/gfx/compositor/layer.h" |
| #include "ui/gfx/image/image.h" |
| #include "views/animation/bounds_animator.h" |
| #include "views/controls/button/image_button.h" |
| #include "views/widget/widget.h" |
| +using ui::Animation; |
| using views::View; |
| namespace aura_shell { |
| @@ -45,7 +48,7 @@ namespace { |
| class DeleteViewAnimationDelegate : |
| public views::BoundsAnimator::OwnedAnimationDelegate { |
| public: |
| - DeleteViewAnimationDelegate(views::View* view) : view_(view) {} |
| + explicit DeleteViewAnimationDelegate(views::View* view) : view_(view) {} |
| virtual ~DeleteViewAnimationDelegate() {} |
| private: |
| @@ -54,8 +57,92 @@ class DeleteViewAnimationDelegate : |
| DISALLOW_COPY_AND_ASSIGN(DeleteViewAnimationDelegate); |
| }; |
| +// AnimationDelegate used when inserting a new item. This steadily increases the |
| +// opacity of the layer as the animation progress. |
| +class FadeInAnimationDelegate : |
| + public views::BoundsAnimator::OwnedAnimationDelegate { |
| + public: |
| + explicit FadeInAnimationDelegate(views::View* view) : view_(view) {} |
| + virtual ~FadeInAnimationDelegate() {} |
| + |
| + // AnimationDelegate overrides: |
| + virtual void AnimationProgressed(const Animation* animation) OVERRIDE { |
| + view_->layer()->SetOpacity(animation->GetCurrentValue()); |
| + view_->layer()->ScheduleDraw(); |
| + } |
| + virtual void AnimationEnded(const Animation* animation) OVERRIDE { |
| + view_->layer()->SetOpacity(1.0f); |
| + view_->layer()->ScheduleDraw(); |
| + } |
| + virtual void AnimationCanceled(const Animation* animation) OVERRIDE { |
| + view_->layer()->SetOpacity(1.0f); |
| + view_->layer()->ScheduleDraw(); |
|
Ben Goodger (Google)
2011/10/21 23:03:49
I think the default impl of this function calls An
|
| + } |
| + |
| + private: |
| + views::View* view_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(FadeInAnimationDelegate); |
| +}; |
| + |
| } // namespace |
| +// AnimationDelegate used when inserting a new item. This steadily decreased the |
| +// opacity of the layer as the animation progress. |
| +class LauncherView::FadeOutAnimationDelegate : |
| + public views::BoundsAnimator::OwnedAnimationDelegate { |
| + public: |
| + FadeOutAnimationDelegate(LauncherView* host, views::View* view) |
| + : launcher_view_(host), |
| + view_(view) {} |
| + virtual ~FadeOutAnimationDelegate() {} |
| + |
| + // AnimationDelegate overrides: |
| + virtual void AnimationProgressed(const Animation* animation) OVERRIDE { |
| + view_->layer()->SetOpacity(1 - animation->GetCurrentValue()); |
| + view_->layer()->ScheduleDraw(); |
| + } |
| + virtual void AnimationEnded(const Animation* animation) OVERRIDE { |
| + launcher_view_->AnimateToIdealBounds(); |
| + } |
| + virtual void AnimationCanceled(const Animation* animation) OVERRIDE { |
| + } |
| + |
| + private: |
| + LauncherView* launcher_view_; |
| + scoped_ptr<views::View> view_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(FadeOutAnimationDelegate); |
| +}; |
| + |
| +// AnimationDelegate used to trigger fading an element in. When an item is |
| +// inserted this delegate is attached to the animation that expands the size of |
| +// the item. When done it kicks off another animation to fade the item in. |
| +class LauncherView::StartFadeAnimationDelegate : |
| + public views::BoundsAnimator::OwnedAnimationDelegate { |
| + public: |
| + StartFadeAnimationDelegate(LauncherView* host, |
| + views::View* view) |
| + : launcher_view_(host), |
| + view_(view) {} |
| + virtual ~StartFadeAnimationDelegate() {} |
| + |
| + // AnimationDelegate overrides: |
| + virtual void AnimationEnded(const Animation* animation) OVERRIDE { |
| + view_->SetVisible(true); |
| + launcher_view_->FadeIn(view_); |
| + } |
| + virtual void AnimationCanceled(const Animation* animation) OVERRIDE { |
| + view_->SetVisible(true); |
| + } |
| + |
| + private: |
| + LauncherView* launcher_view_; |
| + views::View* view_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(StartFadeAnimationDelegate); |
| +}; |
| + |
| LauncherView::LauncherView(LauncherModel* model) |
| : model_(model), |
| view_model_(new ViewModel), |
| @@ -85,6 +172,7 @@ void LauncherView::Init() { |
| const LauncherItems& items(model_->items()); |
| for (LauncherItems::const_iterator i = items.begin(); i != items.end(); ++i) { |
| views::View* child = CreateViewForItem(*i); |
| + child->SetPaintToLayer(true); |
| view_model_->Add(child, static_cast<int>(i - items.begin())); |
| AddChildView(child); |
| } |
| @@ -145,22 +233,27 @@ void LauncherView::AnimateToIdealBounds() { |
| } |
| views::View* LauncherView::CreateViewForItem(const LauncherItem& item) { |
| + views::View* view = NULL; |
| if (item.type == TYPE_TABBED) { |
| TabbedLauncherButton* button = new TabbedLauncherButton(this, this); |
| button->SetImages(item.tab_images); |
| - return button; |
| + view = button; |
| + } else { |
| + DCHECK_EQ(TYPE_APP, item.type); |
| + AppLauncherButton* button = new AppLauncherButton(this, this); |
| + button->SetAppImage(item.app_image); |
| + view = button; |
| } |
| - AppLauncherButton* button = new AppLauncherButton(this, this); |
| - button->SetAppImage(item.app_image); |
| - return button; |
| + view->SetPaintToLayer(true); |
| + return view; |
| } |
| -void LauncherView::Resize() { |
| - // TODO: we may want to force the width to a specific size. |
| - int y = GetWidget()->GetClientAreaScreenBounds().y(); |
| - gfx::Size pref(GetPreferredSize()); |
| - GetWidget()->SetBounds(gfx::Rect(0, y, pref.width(), pref.height())); |
| - Layout(); |
| +void LauncherView::FadeIn(views::View* view) { |
| + view->SetVisible(true); |
| + view->layer()->SetOpacity(0); |
| + AnimateToIdealBounds(); |
| + bounds_animator_->SetAnimationDelegate( |
| + view, new FadeInAnimationDelegate(view), true); |
| } |
| void LauncherView::PrepareForDrag(const views::MouseEvent& event) { |
| @@ -234,32 +327,27 @@ void LauncherView::LauncherItemAdded(int model_index) { |
| views::View* view = CreateViewForItem(model_->items()[model_index]); |
| AddChildView(view); |
| + // Hide the view, it'll be made visible when the animation is done. |
| + view->SetVisible(false); |
| view_model_->Add(view, model_index); |
| - // Update the bounds and reset the bounds of the newly created view to 0 width |
| - // so that it appears to animate open. |
| - IdealBounds ideal_bounds; |
| - CalculateIdealBounds(&ideal_bounds); |
| - gfx::Rect bounds = view_model_->ideal_bounds(model_index); |
| - bounds.set_width(0); |
| - view->SetBoundsRect(bounds); |
| - |
| - // Resize and animate all the views. |
| - Resize(); |
| + // The first animation moves all the views to their target position. |view| is |
| + // hidden, so it visually appears as though we are providing space for |
| + // it. When done we'll fade the view in. |
| AnimateToIdealBounds(); |
| + bounds_animator_->SetAnimationDelegate( |
| + view, new StartFadeAnimationDelegate(this, view), true); |
| } |
| void LauncherView::LauncherItemRemoved(int model_index) { |
| views::View* view = view_model_->view_at(model_index); |
| CancelDrag(view); |
| view_model_->Remove(model_index); |
| - Resize(); |
| - AnimateToIdealBounds(); |
| - gfx::Rect target_bounds = view->bounds(); |
| - target_bounds.set_width(0); |
| - bounds_animator_->AnimateViewTo(view, target_bounds); |
| + // The first animation fades out the view. When done we'll animate the rest of |
| + // the views to their target location. |
| + bounds_animator_->AnimateViewTo(view, view->bounds()); |
| bounds_animator_->SetAnimationDelegate( |
| - view, new DeleteViewAnimationDelegate(view), true); |
| + view, new FadeOutAnimationDelegate(this, view), true); |
| } |
| void LauncherView::LauncherItemImagesChanged(int model_index) { |
| @@ -269,12 +357,10 @@ void LauncherView::LauncherItemImagesChanged(int model_index) { |
| TabbedLauncherButton* button = static_cast<TabbedLauncherButton*>(view); |
| gfx::Size pref = button->GetPreferredSize(); |
| button->SetImages(item.tab_images); |
| - if (pref != button->GetPreferredSize()) { |
| - Resize(); |
| + if (pref != button->GetPreferredSize()) |
| AnimateToIdealBounds(); |
| - } else { |
| + else |
| button->SchedulePaint(); |
| - } |
| } else { |
| DCHECK_EQ(TYPE_APP, item.type); |
| AppLauncherButton* button = static_cast<AppLauncherButton*>(view); |