OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/wm/window_animations.h" | 5 #include "ash/wm/window_animations.h" |
6 | 6 |
7 #include <math.h> | 7 #include <math.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <vector> | 10 #include <vector> |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 | 60 |
61 // Scales for AshWindow above/below current workspace. | 61 // Scales for AshWindow above/below current workspace. |
62 const float kLayerScaleAboveSize = 1.1f; | 62 const float kLayerScaleAboveSize = 1.1f; |
63 const float kLayerScaleBelowSize = .9f; | 63 const float kLayerScaleBelowSize = .9f; |
64 | 64 |
65 int64 Round64(float f) { | 65 int64 Round64(float f) { |
66 return static_cast<int64>(f + 0.5f); | 66 return static_cast<int64>(f + 0.5f); |
67 } | 67 } |
68 | 68 |
69 base::TimeDelta GetCrossFadeDuration(aura::Window* window, | 69 base::TimeDelta GetCrossFadeDuration(aura::Window* window, |
70 const gfx::Rect& old_bounds, | 70 const gfx::RectF& old_bounds, |
71 const gfx::Rect& new_bounds) { | 71 const gfx::Rect& new_bounds) { |
72 if (::wm::WindowAnimationsDisabled(window)) | 72 if (::wm::WindowAnimationsDisabled(window)) |
73 return base::TimeDelta(); | 73 return base::TimeDelta(); |
74 | 74 |
75 int old_area = old_bounds.width() * old_bounds.height(); | 75 int old_area = static_cast<int>(old_bounds.width() * old_bounds.height()); |
76 int new_area = new_bounds.width() * new_bounds.height(); | 76 int new_area = new_bounds.width() * new_bounds.height(); |
77 int max_area = std::max(old_area, new_area); | 77 int max_area = std::max(old_area, new_area); |
78 // Avoid divide by zero. | 78 // Avoid divide by zero. |
79 if (max_area == 0) | 79 if (max_area == 0) |
80 return base::TimeDelta::FromMilliseconds(kCrossFadeDurationMS); | 80 return base::TimeDelta::FromMilliseconds(kCrossFadeDurationMS); |
81 | 81 |
82 int delta_area = std::abs(old_area - new_area); | 82 int delta_area = std::abs(old_area - new_area); |
83 // If the area didn't change, the animation is instantaneous. | 83 // If the area didn't change, the animation is instantaneous. |
84 if (delta_area == 0) | 84 if (delta_area == 0) |
85 return base::TimeDelta::FromMilliseconds(kCrossFadeDurationMS); | 85 return base::TimeDelta::FromMilliseconds(kCrossFadeDurationMS); |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 | 320 |
321 DISALLOW_COPY_AND_ASSIGN(CrossFadeObserver); | 321 DISALLOW_COPY_AND_ASSIGN(CrossFadeObserver); |
322 }; | 322 }; |
323 | 323 |
324 base::TimeDelta CrossFadeAnimation( | 324 base::TimeDelta CrossFadeAnimation( |
325 aura::Window* window, | 325 aura::Window* window, |
326 scoped_ptr<ui::LayerTreeOwner> old_layer_owner, | 326 scoped_ptr<ui::LayerTreeOwner> old_layer_owner, |
327 gfx::Tween::Type tween_type) { | 327 gfx::Tween::Type tween_type) { |
328 DCHECK(old_layer_owner->root()); | 328 DCHECK(old_layer_owner->root()); |
329 const gfx::Rect old_bounds(old_layer_owner->root()->bounds()); | 329 const gfx::Rect old_bounds(old_layer_owner->root()->bounds()); |
| 330 gfx::RectF old_transformed_bounds(old_bounds); |
| 331 gfx::Transform old_transform(old_layer_owner->root()->transform()); |
| 332 gfx::Transform old_transform_in_root; |
| 333 old_transform_in_root.Translate(old_bounds.x(), old_bounds.y()); |
| 334 old_transform_in_root.PreconcatTransform(old_transform); |
| 335 old_transform_in_root.Translate(-old_bounds.x(), -old_bounds.y()); |
| 336 old_transform_in_root.TransformRect(&old_transformed_bounds); |
330 const gfx::Rect new_bounds(window->bounds()); | 337 const gfx::Rect new_bounds(window->bounds()); |
331 const bool old_on_top = (old_bounds.width() > new_bounds.width()); | 338 const bool old_on_top = (old_bounds.width() > new_bounds.width()); |
332 | 339 |
333 // Shorten the animation if there's not much visual movement. | 340 // Shorten the animation if there's not much visual movement. |
334 const base::TimeDelta duration = GetCrossFadeDuration(window, | 341 const base::TimeDelta duration = GetCrossFadeDuration(window, |
335 old_bounds, new_bounds); | 342 old_transformed_bounds, new_bounds); |
336 | 343 |
337 // Scale up the old layer while translating to new position. | 344 // Scale up the old layer while translating to new position. |
338 { | 345 { |
339 ui::Layer* old_layer = old_layer_owner->root(); | 346 ui::Layer* old_layer = old_layer_owner->root(); |
340 old_layer->GetAnimator()->StopAnimating(); | 347 old_layer->GetAnimator()->StopAnimating(); |
| 348 old_layer->SetTransform(old_transform); |
341 ui::ScopedLayerAnimationSettings settings(old_layer->GetAnimator()); | 349 ui::ScopedLayerAnimationSettings settings(old_layer->GetAnimator()); |
342 | 350 |
343 // Animation observer owns the old layer and deletes itself. | 351 // Animation observer owns the old layer and deletes itself. |
344 settings.AddObserver(new CrossFadeObserver(window, old_layer_owner.Pass())); | 352 settings.AddObserver(new CrossFadeObserver(window, old_layer_owner.Pass())); |
345 settings.SetTransitionDuration(duration); | 353 settings.SetTransitionDuration(duration); |
346 settings.SetTweenType(tween_type); | 354 settings.SetTweenType(tween_type); |
347 gfx::Transform out_transform; | 355 gfx::Transform out_transform; |
348 float scale_x = static_cast<float>(new_bounds.width()) / | 356 float scale_x = static_cast<float>(new_bounds.width()) / |
349 static_cast<float>(old_bounds.width()); | 357 static_cast<float>(old_bounds.width()); |
350 float scale_y = static_cast<float>(new_bounds.height()) / | 358 float scale_y = static_cast<float>(new_bounds.height()) / |
351 static_cast<float>(old_bounds.height()); | 359 static_cast<float>(old_bounds.height()); |
352 out_transform.Translate(new_bounds.x() - old_bounds.x(), | 360 out_transform.Translate(new_bounds.x() - old_bounds.x(), |
353 new_bounds.y() - old_bounds.y()); | 361 new_bounds.y() - old_bounds.y()); |
354 out_transform.Scale(scale_x, scale_y); | 362 out_transform.Scale(scale_x, scale_y); |
355 old_layer->SetTransform(out_transform); | 363 old_layer->SetTransform(out_transform); |
356 if (old_on_top) { | 364 if (old_on_top) { |
357 // The old layer is on top, and should fade out. The new layer below will | 365 // The old layer is on top, and should fade out. The new layer below will |
358 // stay opaque to block the desktop. | 366 // stay opaque to block the desktop. |
359 old_layer->SetOpacity(kWindowAnimation_HideOpacity); | 367 old_layer->SetOpacity(kWindowAnimation_HideOpacity); |
360 } | 368 } |
361 // In tests |old_layer| is deleted here, as animations have zero duration. | 369 // In tests |old_layer| is deleted here, as animations have zero duration. |
362 old_layer = NULL; | 370 old_layer = NULL; |
363 } | 371 } |
364 | 372 |
365 // Set the new layer's current transform, such that the user sees a scaled | 373 // Set the new layer's current transform, such that the user sees a scaled |
366 // version of the window with the original bounds at the original position. | 374 // version of the window with the original bounds at the original position. |
367 gfx::Transform in_transform; | 375 gfx::Transform in_transform; |
368 const float scale_x = static_cast<float>(old_bounds.width()) / | 376 const float scale_x = old_transformed_bounds.width() / |
369 static_cast<float>(new_bounds.width()); | 377 static_cast<float>(new_bounds.width()); |
370 const float scale_y = static_cast<float>(old_bounds.height()) / | 378 const float scale_y = old_transformed_bounds.height() / |
371 static_cast<float>(new_bounds.height()); | 379 static_cast<float>(new_bounds.height()); |
372 in_transform.Translate(old_bounds.x() - new_bounds.x(), | 380 in_transform.Translate(old_transformed_bounds.x() - new_bounds.x(), |
373 old_bounds.y() - new_bounds.y()); | 381 old_transformed_bounds.y() - new_bounds.y()); |
374 in_transform.Scale(scale_x, scale_y); | 382 in_transform.Scale(scale_x, scale_y); |
375 window->layer()->SetTransform(in_transform); | 383 window->layer()->SetTransform(in_transform); |
376 if (!old_on_top) { | 384 if (!old_on_top) { |
377 // The new layer is on top and should fade in. The old layer below will | 385 // The new layer is on top and should fade in. The old layer below will |
378 // stay opaque and block the desktop. | 386 // stay opaque and block the desktop. |
379 window->layer()->SetOpacity(kWindowAnimation_HideOpacity); | 387 window->layer()->SetOpacity(kWindowAnimation_HideOpacity); |
380 } | 388 } |
381 { | 389 { |
382 // Animate the new layer to the identity transform, so the window goes to | 390 // Animate the new layer to the identity transform, so the window goes to |
383 // its newly set bounds. | 391 // its newly set bounds. |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 case SHELF_ALIGNMENT_LEFT: | 510 case SHELF_ALIGNMENT_LEFT: |
503 return gfx::Rect(work_area.x(), work_area.y(), 0, 0); | 511 return gfx::Rect(work_area.x(), work_area.y(), 0, 0); |
504 case SHELF_ALIGNMENT_RIGHT: | 512 case SHELF_ALIGNMENT_RIGHT: |
505 return gfx::Rect(work_area.right(), work_area.y(), 0, 0); | 513 return gfx::Rect(work_area.right(), work_area.y(), 0, 0); |
506 } | 514 } |
507 NOTREACHED(); | 515 NOTREACHED(); |
508 return gfx::Rect(); | 516 return gfx::Rect(); |
509 } | 517 } |
510 | 518 |
511 } // namespace ash | 519 } // namespace ash |
OLD | NEW |