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); |
}; |