diff options
author | jonross@chromium.org <jonross@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-26 15:49:48 +0000 |
---|---|---|
committer | jonross@chromium.org <jonross@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-26 15:49:48 +0000 |
commit | 1d6eeeaba9dd6226de93f368b3db0b7f2e3db239 (patch) | |
tree | 735e9b368187dddf43ac3219243276f453ba6566 /ash/system/tray | |
parent | 23a135902b17b8d20e1e7c0bac68b6b71aab9c21 (diff) | |
download | chromium_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.cc | 22 | ||||
-rw-r--r-- | ash/system/tray/tray_background_view.cc | 93 | ||||
-rw-r--r-- | ash/system/tray/tray_background_view.h | 24 |
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_; |