summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-07 01:19:20 +0000
committerjamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-07 01:19:20 +0000
commitf5e713b5b6154f002bcaf7b1ee3d4fece3faaae1 (patch)
tree0a084f1b4320783d07afbc9134ca5638433ac1d2
parent4223f8d3d82ed7794ffce1ac174a91e62e8795ad (diff)
downloadchromium_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.cc32
-rw-r--r--ash/wm/window_animations.h5
-rw-r--r--ash/wm/window_animations_unittest.cc31
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