diff options
author | jamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-07 01:19:20 +0000 |
---|---|---|
committer | jamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-07 01:19:20 +0000 |
commit | f5e713b5b6154f002bcaf7b1ee3d4fece3faaae1 (patch) | |
tree | 0a084f1b4320783d07afbc9134ca5638433ac1d2 | |
parent | 4223f8d3d82ed7794ffce1ac174a91e62e8795ad (diff) | |
download | chromium_src-f5e713b5b6154f002bcaf7b1ee3d4fece3faaae1.zip chromium_src-f5e713b5b6154f002bcaf7b1ee3d4fece3faaae1.tar.gz chromium_src-f5e713b5b6154f002bcaf7b1ee3d4fece3faaae1.tar.bz2 |
ash: Adjust maximize/restore animation timing based on window size
In particular, make the animation faster if the window almost fills the screen and is being maximized. This is a common case for freshly created windows. At the default 400 ms timing this feels too slow, so this patch scales the time between 200 and 400 ms.
BUG=131016
TEST=added
Review URL: https://chromiumcodereview.appspot.com/10537029
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@140918 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ash/wm/window_animations.cc | 32 | ||||
-rw-r--r-- | ash/wm/window_animations.h | 5 | ||||
-rw-r--r-- | ash/wm/window_animations_unittest.cc | 31 |
3 files changed, 62 insertions, 6 deletions
diff --git a/ash/wm/window_animations.cc b/ash/wm/window_animations.cc index 70e7d07..f33243a 100644 --- a/ash/wm/window_animations.cc +++ b/ash/wm/window_animations.cc @@ -58,8 +58,9 @@ namespace { const int kDefaultAnimationDurationForMenuMS = 150; -// TODO(jamescook): Shorten the duration if the window doesn't move much. -const int kCrossFadeAnimationDurationMs = 400; +// Durations for the cross-fade animation, in milliseconds. +const float kCrossFadeDurationMinMs = 200.f; +const float kCrossFadeDurationMaxMs = 400.f; const float kWindowAnimation_HideOpacity = 0.f; const float kWindowAnimation_ShowOpacity = 1.f; @@ -661,13 +662,14 @@ void CrossFadeToBounds(aura::Window* window, const gfx::Rect& new_bounds) { // Tween types for transform animations must match to keep the window edges // aligned during the animation. const ui::Tween::Type kTransformTween = ui::Tween::EASE_OUT; + // Shorten the animation if there's not much visual movement. + TimeDelta duration = GetCrossFadeDuration(old_bounds, new_bounds); { // Scale up the old layer while translating to new position. ui::ScopedLayerAnimationSettings settings(old_layer->GetAnimator()); // Animation observer owns the old layer and deletes itself. settings.AddObserver(new CrossFadeObserver(window, old_layer)); - settings.SetTransitionDuration( - TimeDelta::FromMilliseconds(kCrossFadeAnimationDurationMs)); + settings.SetTransitionDuration(duration); settings.SetTweenType(kTransformTween); ui::Transform out_transform; float scale_x = static_cast<float>(new_bounds.width()) / @@ -709,8 +711,7 @@ void CrossFadeToBounds(aura::Window* window, const gfx::Rect& new_bounds) { // Animate the new layer to the identity transform, so the window goes to // its newly set bounds. ui::ScopedLayerAnimationSettings settings(new_layer->GetAnimator()); - settings.SetTransitionDuration( - TimeDelta::FromMilliseconds(kCrossFadeAnimationDurationMs)); + settings.SetTransitionDuration(duration); settings.SetTweenType(kTransformTween); new_layer->SetTransform(ui::Transform()); if (!old_on_top) { @@ -720,6 +721,25 @@ void CrossFadeToBounds(aura::Window* window, const gfx::Rect& new_bounds) { } } +TimeDelta GetCrossFadeDuration(const gfx::Rect& old_bounds, + const gfx::Rect& new_bounds) { + int max_width = std::max(old_bounds.width(), new_bounds.width()); + // Avoid divide by zero. + if (max_width == 0) + return TimeDelta(); + + int delta_width = std::abs(old_bounds.width() - new_bounds.width()); + // If the width didn't change, the animation is instantaneous. + if (delta_width == 0) + return TimeDelta(); + + float factor = + static_cast<float>(delta_width) / static_cast<float>(max_width); + const float kRange = kCrossFadeDurationMaxMs - kCrossFadeDurationMinMs; + return TimeDelta::FromMilliseconds( + roundf(kCrossFadeDurationMinMs + (factor * kRange))); +} + bool AnimateOnChildWindowVisibilityChanged(aura::Window* window, bool visible) { if (window->GetProperty(aura::client::kAnimationsDisabledKey) || CommandLine::ForCurrentProcess()->HasSwitch( diff --git a/ash/wm/window_animations.h b/ash/wm/window_animations.h index 29083d3..1d1a9f7 100644 --- a/ash/wm/window_animations.h +++ b/ash/wm/window_animations.h @@ -80,6 +80,11 @@ namespace internal { ASH_EXPORT void CrossFadeToBounds(aura::Window* window, const gfx::Rect& new_bounds); +// Returns the duration of the cross-fade animation based on the |old_bounds| +// and |new_bounds| of the window. +ASH_EXPORT base::TimeDelta GetCrossFadeDuration(const gfx::Rect& old_bounds, + const gfx::Rect& new_bounds); + // Returns false if the |window| didn't animate. ASH_EXPORT bool AnimateOnChildWindowVisibilityChanged( aura::Window* window, bool visible); diff --git a/ash/wm/window_animations_unittest.cc b/ash/wm/window_animations_unittest.cc index 0b1b377..9628db2 100644 --- a/ash/wm/window_animations_unittest.cc +++ b/ash/wm/window_animations_unittest.cc @@ -6,6 +6,7 @@ #include "ash/shell_window_ids.h" #include "ash/test/ash_test_base.h" +#include "base/time.h" #include "ui/aura/test/test_windows.h" #include "ui/aura/window.h" #include "ui/base/animation/animation_container_element.h" @@ -159,5 +160,35 @@ TEST_F(WindowAnimationsTest, CrossFadeToBounds) { RunAllPendingInMessageLoop(); } +TEST_F(WindowAnimationsTest, GetCrossFadeDuration) { + gfx::Rect empty; + gfx::Rect screen(0, 0, 1000, 500); + + // No change takes no time. + EXPECT_EQ(0, GetCrossFadeDuration(empty, empty).InMilliseconds()); + EXPECT_EQ(0, GetCrossFadeDuration(screen, screen).InMilliseconds()); + + // Small changes are fast. + gfx::Rect almost_screen(10, 10, 900, 400); + EXPECT_EQ(220, GetCrossFadeDuration(almost_screen, screen).InMilliseconds()); + EXPECT_EQ(220, GetCrossFadeDuration(screen, almost_screen).InMilliseconds()); + + // Large changes are slow. + gfx::Rect small(10, 10, 100, 100); + EXPECT_EQ(380, GetCrossFadeDuration(small, screen).InMilliseconds()); + EXPECT_EQ(380, GetCrossFadeDuration(screen, small).InMilliseconds()); + + // Medium changes take medium time. + gfx::Rect half_screen(10, 10, 500, 250); + EXPECT_EQ(300, GetCrossFadeDuration(half_screen, screen).InMilliseconds()); + EXPECT_EQ(300, GetCrossFadeDuration(screen, half_screen).InMilliseconds()); + + // Change is based on width. + gfx::Rect narrow(10, 10, 100, 500); + gfx::Rect wide(10, 10, 900, 500); + EXPECT_EQ(380, GetCrossFadeDuration(narrow, screen).InMilliseconds()); + EXPECT_EQ(220, GetCrossFadeDuration(wide, screen).InMilliseconds()); +} + } // namespace internal } // namespace ash |