Chromium Code Reviews| Index: ash/system/tray/system_tray.cc |
| diff --git a/ash/system/tray/system_tray.cc b/ash/system/tray/system_tray.cc |
| index ed64a7e2e9dc44f78a42a7656ffb13e71a722a74..3852d322d144293e8b125f0b5c9c0671a8def890 100644 |
| --- a/ash/system/tray/system_tray.cc |
| +++ b/ash/system/tray/system_tray.cc |
| @@ -28,6 +28,7 @@ |
| #include "ui/base/accessibility/accessible_view_state.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/gfx/canvas.h" |
| +#include "ui/gfx/compositor/layer.h" |
| #include "ui/gfx/skia_util.h" |
| #include "ui/views/border.h" |
| #include "ui/views/bubble/bubble_delegate.h" |
| @@ -45,6 +46,7 @@ const int kPaddingFromRightEdgeOfScreen = 15; |
| const int kPaddingFromBottomOfScreen = 10; |
| const int kAnimationDurationForPopupMS = 200; |
| +const int kTrayItemAnimationDurationMS = 200; |
| const int kArrowHeight = 10; |
| const int kArrowWidth = 20; |
| @@ -65,12 +67,17 @@ const SkColor kTrayBackgroundHoverAlpha = 150; |
| // Container for items in the tray. It makes sure the widget is updated |
| // correctly when the visibility/size of the tray item changes. |
| -// TODO: setup animation. |
| -class TrayItemContainer : public views::View { |
| +class TrayItemContainer : public views::View, |
| + public ui::AnimationDelegate { |
| public: |
| - explicit TrayItemContainer(views::View* view) : child_(view) { |
| + explicit TrayItemContainer(views::View* view) |
| + : child_(view), |
| + processing_(false) { |
| AddChildView(child_); |
| SetVisible(child_->visible()); |
| + |
| + child_->SetPaintToLayer(true); |
| + child_->SetFillsBoundsOpaquely(false); |
| } |
| virtual ~TrayItemContainer() {} |
| @@ -79,8 +86,8 @@ class TrayItemContainer : public views::View { |
| // Makes sure the widget relayouts after the size/visibility of the view |
| // changes. |
| void ApplyChange() { |
| - // Forcing the widget to the new size is sufficient. The positing is taken |
| - // care of by the layout manager (ShelfLayoutManager). |
| + // Forcing the widget to the new size is sufficient. The positioning is |
| + // taken care of by the layout manager (ShelfLayoutManager). |
| GetWidget()->SetSize(GetWidget()->GetContentsView()->GetPreferredSize()); |
| } |
| @@ -90,7 +97,11 @@ class TrayItemContainer : public views::View { |
| } |
| virtual gfx::Size GetPreferredSize() OVERRIDE { |
| + if (!animation_.get() || !animation_->is_animating()) |
| + return child_->GetPreferredSize(); |
| gfx::Size size = child_->GetPreferredSize(); |
| + size.set_width(std::max(1, |
| + static_cast<int>(size.width() * animation_->GetCurrentValue()))); |
| size.set_height(kTrayIconHeight); |
| return size; |
| } |
| @@ -100,13 +111,59 @@ class TrayItemContainer : public views::View { |
| } |
| virtual void ChildVisibilityChanged(views::View* child) OVERRIDE { |
| - if (visible() == child_->visible()) |
| + if (processing_) |
| return; |
| - SetVisible(child_->visible()); |
| + processing_ = true; |
| + if (!animation_.get()) { |
| + animation_.reset(new ui::SlideAnimation(this)); |
| + animation_->SetSlideDuration(kTrayItemAnimationDurationMS); |
| + animation_->SetTweenType(ui::Tween::LINEAR); |
| + } |
| + |
| + if (!child_->visible()) { |
| + // child_ is hiding. To animate nicely, it is necessary to redisplay the |
| + // child view during animation. |
| + child_->SetVisible(true); |
|
sadrul
2012/04/02 20:41:12
This is a bit hacky. This can cause a bug if the i
|
| + animation_->Hide(); |
| + AnimationProgressed(animation_.get()); |
| + } else { |
| + SetVisible(true); |
| + animation_->Show(); |
| + AnimationProgressed(animation_.get()); |
| + } |
| + processing_ = false; |
| + } |
| + |
| + // Overridden from ui::AnimationDelegate. |
| + virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE { |
| + ui::Transform transform; |
| + transform.SetScale(animation->GetCurrentValue(), |
| + animation->GetCurrentValue()); |
| + transform.ConcatTranslate(0, animation->CurrentValueBetween( |
| + static_cast<double>(height()) / 2, 0.)); |
| + child_->layer()->SetTransform(transform); |
| ApplyChange(); |
| } |
| + virtual void AnimationEnded(const ui::Animation* animation) OVERRIDE { |
| + processing_ = true; |
| + if (animation->GetCurrentValue() < 0.1) { |
| + child_->SetVisible(false); |
| + SetVisible(false); |
| + } else { |
| + child_->SetVisible(true); |
| + SetVisible(true); |
| + } |
| + processing_ = false; |
| + } |
| + |
| + virtual void AnimationCanceled(const ui::Animation* animation) OVERRIDE { |
| + AnimationEnded(animation); |
| + } |
| + |
| views::View* child_; |
| + bool processing_; |
| + scoped_ptr<ui::SlideAnimation> animation_; |
| DISALLOW_COPY_AND_ASSIGN(TrayItemContainer); |
| }; |