summaryrefslogtreecommitdiffstats
path: root/ash/system/tray
diff options
context:
space:
mode:
authorjonross@chromium.org <jonross@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-26 15:49:48 +0000
committerjonross@chromium.org <jonross@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-26 15:49:48 +0000
commit1d6eeeaba9dd6226de93f368b3db0b7f2e3db239 (patch)
tree735e9b368187dddf43ac3219243276f453ba6566 /ash/system/tray
parent23a135902b17b8d20e1e7c0bac68b6b71aab9c21 (diff)
downloadchromium_src-1d6eeeaba9dd6226de93f368b3db0b7f2e3db239.zip
chromium_src-1d6eeeaba9dd6226de93f368b3db0b7f2e3db239.tar.gz
chromium_src-1d6eeeaba9dd6226de93f368b3db0b7f2e3db239.tar.bz2
Overview Button Tray Animation accounting for startup
Reapply the animation of TrayBackgroundView. Update to account for visibility changes that occur during animations. Added a test for to cover state changes during animations. Original review: https://codereview.chromium.org/251193004/ Revert review: https://codereview.chromium.org/281793002/ This reverts commit 399aa22e04f289f496f60ad23379a098e389d6a1 TEST=SystemTrayTest BUG=372285,363714 Review URL: https://codereview.chromium.org/289743002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@272829 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash/system/tray')
-rw-r--r--ash/system/tray/system_tray_unittest.cc22
-rw-r--r--ash/system/tray/tray_background_view.cc93
-rw-r--r--ash/system/tray/tray_background_view.h24
3 files changed, 130 insertions, 9 deletions
diff --git a/ash/system/tray/system_tray_unittest.cc b/ash/system/tray/system_tray_unittest.cc
index fbf2859..c798e78 100644
--- a/ash/system/tray/system_tray_unittest.cc
+++ b/ash/system/tray/system_tray_unittest.cc
@@ -21,6 +21,7 @@
#include "ui/aura/test/event_generator.h"
#include "ui/aura/window.h"
#include "ui/base/ui_base_types.h"
+#include "ui/compositor/scoped_animation_duration_scale_mode.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/fill_layout.h"
@@ -483,5 +484,26 @@ TEST_F(SystemTrayTest, MAYBE_WithSystemModal) {
EXPECT_TRUE(settings->visible());
}
+// Tests that if SetVisible(true) is called while animating to hidden that the
+// tray becomes visible, and stops animating to hidden.
+TEST_F(SystemTrayTest, SetVisibleDuringHideAnimation) {
+ SystemTray* tray = GetSystemTray();
+ ASSERT_TRUE(tray->visible());
+
+ scoped_ptr<ui::ScopedAnimationDurationScaleMode> animation_duration;
+ animation_duration.reset(
+ new ui::ScopedAnimationDurationScaleMode(
+ ui::ScopedAnimationDurationScaleMode::SLOW_DURATION));
+ tray->SetVisible(false);
+ EXPECT_TRUE(tray->visible());
+ EXPECT_EQ(0.0f, tray->layer()->GetTargetOpacity());
+
+ tray->SetVisible(true);
+ animation_duration.reset();
+ tray->layer()->GetAnimator()->StopAnimating();
+ EXPECT_TRUE(tray->visible());
+ EXPECT_EQ(1.0f, tray->layer()->GetTargetOpacity());
+}
+
} // namespace test
} // namespace ash
diff --git a/ash/system/tray/tray_background_view.cc b/ash/system/tray/tray_background_view.cc
index b6d06da..a166da3 100644
--- a/ash/system/tray/tray_background_view.cc
+++ b/ash/system/tray/tray_background_view.cc
@@ -22,12 +22,17 @@
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/base/resource/resource_bundle.h"
+#include "ui/compositor/layer.h"
+#include "ui/compositor/layer_animation_element.h"
+#include "ui/compositor/scoped_layer_animation_settings.h"
+#include "ui/gfx/animation/tween.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_operations.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/screen.h"
#include "ui/gfx/skia_util.h"
+#include "ui/gfx/transform.h"
#include "ui/views/background.h"
#include "ui/views/layout/box_layout.h"
@@ -37,7 +42,15 @@ const int kTrayBackgroundAlpha = 100;
const int kTrayBackgroundHoverAlpha = 150;
const SkColor kTrayBackgroundPressedColor = SkColorSetRGB(66, 129, 244);
-const int kAnimationDurationForPopupMS = 200;
+const int kAnimationDurationForPopupMs = 200;
+
+// Duration of opacity animation for visibility changes.
+const int kAnimationDurationForVisibilityMs = 250;
+
+// When becoming visible delay the animation so that StatusAreaWidgetDelegate
+// can animate sibling views out of the position to be occuped by the
+// TrayBackgroundView.
+const int kShowAnimationDelayMs = 100;
} // namespace
@@ -307,6 +320,9 @@ TrayBackgroundView::TrayBackgroundView(StatusAreaWidget* status_area_widget)
tray_container_ = new TrayContainer(shelf_alignment_);
SetContents(tray_container_);
tray_event_filter_.reset(new TrayEventFilter);
+
+ SetPaintToLayer(true);
+ SetFillsBoundsOpaquely(false);
}
TrayBackgroundView::~TrayBackgroundView() {
@@ -319,6 +335,56 @@ void TrayBackgroundView::Initialize() {
SetTrayBorder();
}
+void TrayBackgroundView::SetVisible(bool visible) {
+ if (visible == layer()->GetTargetVisibility())
+ return;
+
+ if (visible) {
+ // The alignment of the shelf can change while the TrayBackgroundView is
+ // hidden. Reset the offscreen transform so that the animation to becoming
+ // visible reflects the current layout.
+ HideTransformation();
+ // SetVisible(false) is defered until the animation for hiding is done.
+ // Otherwise the view is immediately hidden and the animation does not
+ // render.
+ views::View::SetVisible(true);
+ // If SetVisible(true) is called while animating to not visible, then
+ // views::View::SetVisible(true) is a no-op. When the previous animation
+ // ends layer->SetVisible(false) is called. To prevent this
+ // layer->SetVisible(true) immediately interrupts the animation of this
+ // property, and keeps the layer visible.
+ layer()->SetVisible(true);
+ }
+
+ ui::ScopedLayerAnimationSettings animation(layer()->GetAnimator());
+ animation.SetTransitionDuration(base::TimeDelta::FromMilliseconds(
+ kAnimationDurationForVisibilityMs));
+ animation.SetPreemptionStrategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+
+ if (visible) {
+ animation.SetTweenType(gfx::Tween::EASE_OUT);
+ // Show is delayed so as to allow time for other children of
+ // StatusAreaWidget to begin animating to their new positions.
+ layer()->GetAnimator()->SchedulePauseForProperties(
+ base::TimeDelta::FromMilliseconds(kShowAnimationDelayMs),
+ ui::LayerAnimationElement::OPACITY |
+ ui::LayerAnimationElement::TRANSFORM);
+ layer()->SetOpacity(1.0f);
+ gfx::Transform transform;
+ transform.Translate(0.0f, 0.0f);
+ layer()->SetTransform(transform);
+ } else {
+ // Listen only to the hide animation. As we cannot turn off visibility
+ // until the animation is over.
+ animation.AddObserver(this);
+ animation.SetTweenType(gfx::Tween::EASE_IN);
+ layer()->SetOpacity(0.0f);
+ layer()->SetVisible(false);
+ HideTransformation();
+ }
+}
+
const char* TrayBackgroundView::GetClassName() const {
return kViewClassName;
}
@@ -420,6 +486,29 @@ void TrayBackgroundView::SetTrayBorder() {
top_edge, left_edge, bottom_edge, right_edge));
}
+void TrayBackgroundView::OnImplicitAnimationsCompleted() {
+ // If there is another animation in the queue, the reverse animation was
+ // triggered before the completion of animating to invisible. Do not turn off
+ // the visibility so that the next animation may render. The value of
+ // layer()->GetTargetVisibility() can be incorrect if the hide animation was
+ // aborted to schedule an animation to become visible. As the new animation
+ // is not yet added to the queue. crbug.com/374236
+ if(layer()->GetAnimator()->is_animating() ||
+ layer()->GetTargetVisibility())
+ return;
+ views::View::SetVisible(false);
+}
+
+void TrayBackgroundView::HideTransformation() {
+ gfx::Transform transform;
+ if (shelf_alignment_ == SHELF_ALIGNMENT_BOTTOM ||
+ shelf_alignment_ == SHELF_ALIGNMENT_TOP)
+ transform.Translate(width(), 0.0f);
+ else
+ transform.Translate(0.0f, height());
+ layer()->SetTransform(transform);
+}
+
void TrayBackgroundView::InitializeBubbleAnimations(
views::Widget* bubble_widget) {
wm::SetWindowVisibilityAnimationType(
@@ -430,7 +519,7 @@ void TrayBackgroundView::InitializeBubbleAnimations(
wm::ANIMATE_HIDE);
wm::SetWindowVisibilityAnimationDuration(
bubble_widget->GetNativeWindow(),
- base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMS));
+ base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMs));
}
aura::Window* TrayBackgroundView::GetBubbleWindowContainer() const {
diff --git a/ash/system/tray/tray_background_view.h b/ash/system/tray/tray_background_view.h
index c76fd87..da4eaf5 100644
--- a/ash/system/tray/tray_background_view.h
+++ b/ash/system/tray/tray_background_view.h
@@ -9,6 +9,7 @@
#include "ash/shelf/background_animator.h"
#include "ash/shelf/shelf_types.h"
#include "ash/system/tray/actionable_view.h"
+#include "ui/compositor/layer_animation_observer.h"
#include "ui/views/bubble/tray_bubble_view.h"
namespace ash {
@@ -18,12 +19,13 @@ class TrayEventFilter;
class TrayBackground;
// Base class for children of StatusAreaWidget: SystemTray, WebNotificationTray,
-// LogoutButtonTray.
+// LogoutButtonTray, OverviewButtonTray.
// This class handles setting and animating the background when the Launcher
// his shown/hidden. It also inherits from ActionableView so that the tray
// items can override PerformAction when clicked on.
class ASH_EXPORT TrayBackgroundView : public ActionableView,
- public BackgroundAnimatorDelegate {
+ public BackgroundAnimatorDelegate,
+ public ui::ImplicitAnimationObserver {
public:
static const char kViewClassName[];
@@ -38,11 +40,11 @@ class ASH_EXPORT TrayBackgroundView : public ActionableView,
void set_size(const gfx::Size& size) { size_ = size; }
- // Overridden from views::View.
+ // views::View:
virtual gfx::Size GetPreferredSize() const OVERRIDE;
protected:
- // Overridden from views::View.
+ // views::View:
virtual void ChildPreferredSizeChanged(views::View* child) OVERRIDE;
virtual void ChildVisibilityChanged(View* child) OVERRIDE;
virtual void ViewHierarchyChanged(
@@ -63,7 +65,8 @@ class ASH_EXPORT TrayBackgroundView : public ActionableView,
// Called after the tray has been added to the widget containing it.
virtual void Initialize();
- // Overridden from views::View.
+ // views::View:
+ virtual void SetVisible(bool visible) OVERRIDE;
virtual const char* GetClassName() const OVERRIDE;
virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE;
virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE;
@@ -71,11 +74,11 @@ class ASH_EXPORT TrayBackgroundView : public ActionableView,
virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE;
virtual void AboutToRequestFocusFromTabTraversal(bool reverse) OVERRIDE;
- // Overridden from ActionableView.
+ // ActionableView:
virtual bool PerformAction(const ui::Event& event) OVERRIDE;
virtual gfx::Rect GetFocusBounds() OVERRIDE;
- // Overridden from BackgroundAnimatorDelegate.
+ // BackgroundAnimatorDelegate:
virtual void UpdateBackground(int alpha) OVERRIDE;
// Called whenever the shelf alignment changes.
@@ -152,6 +155,13 @@ class ASH_EXPORT TrayBackgroundView : public ActionableView,
// Sets the border based on the position of the view.
void SetTrayBorder();
+ // ui::ImplicitAnimationObserver:
+ virtual void OnImplicitAnimationsCompleted() OVERRIDE;
+
+ // Applies transformations to the |layer()| to animate the view when
+ // SetVisible(false) is called.
+ void HideTransformation();
+
// Unowned pointer to parent widget.
StatusAreaWidget* status_area_widget_;