| 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> |
| 11 | 11 |
| 12 #include "ash/ash_switches.h" | 12 #include "ash/ash_switches.h" |
| 13 #include "ash/launcher/launcher.h" | 13 #include "ash/launcher/launcher.h" |
| 14 #include "ash/screen_ash.h" | 14 #include "ash/screen_ash.h" |
| 15 #include "ash/shell.h" | 15 #include "ash/shell.h" |
| 16 #include "ash/wm/window_util.h" | 16 #include "ash/wm/window_util.h" |
| 17 #include "ash/wm/workspace_controller.h" | 17 #include "ash/wm/workspace_controller.h" |
| 18 #include "ash/wm/workspace/workspace_animations.h" |
| 18 #include "base/command_line.h" | 19 #include "base/command_line.h" |
| 19 #include "base/compiler_specific.h" | 20 #include "base/compiler_specific.h" |
| 20 #include "base/logging.h" | 21 #include "base/logging.h" |
| 21 #include "base/message_loop.h" | 22 #include "base/message_loop.h" |
| 22 #include "base/stl_util.h" | 23 #include "base/stl_util.h" |
| 23 #include "base/time.h" | 24 #include "base/time.h" |
| 24 #include "ui/aura/client/aura_constants.h" | 25 #include "ui/aura/client/aura_constants.h" |
| 25 #include "ui/aura/window.h" | 26 #include "ui/aura/window.h" |
| 26 #include "ui/aura/window_observer.h" | 27 #include "ui/aura/window_observer.h" |
| 27 #include "ui/aura/window_property.h" | 28 #include "ui/aura/window_property.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 43 | 44 |
| 44 using aura::Window; | 45 using aura::Window; |
| 45 using base::TimeDelta; | 46 using base::TimeDelta; |
| 46 using ui::Layer; | 47 using ui::Layer; |
| 47 | 48 |
| 48 namespace ash { | 49 namespace ash { |
| 49 namespace internal { | 50 namespace internal { |
| 50 namespace { | 51 namespace { |
| 51 const float kWindowAnimation_Vertical_TranslateY = 15.f; | 52 const float kWindowAnimation_Vertical_TranslateY = 15.f; |
| 52 | 53 |
| 53 } | 54 } // namespace |
| 54 | 55 |
| 55 DEFINE_WINDOW_PROPERTY_KEY(WindowVisibilityAnimationType, | 56 DEFINE_WINDOW_PROPERTY_KEY(WindowVisibilityAnimationType, |
| 56 kWindowVisibilityAnimationTypeKey, | 57 kWindowVisibilityAnimationTypeKey, |
| 57 WINDOW_VISIBILITY_ANIMATION_TYPE_DEFAULT); | 58 WINDOW_VISIBILITY_ANIMATION_TYPE_DEFAULT); |
| 58 DEFINE_WINDOW_PROPERTY_KEY(int, kWindowVisibilityAnimationDurationKey, 0); | 59 DEFINE_WINDOW_PROPERTY_KEY(int, kWindowVisibilityAnimationDurationKey, 0); |
| 59 DEFINE_WINDOW_PROPERTY_KEY(WindowVisibilityAnimationTransition, | 60 DEFINE_WINDOW_PROPERTY_KEY(WindowVisibilityAnimationTransition, |
| 60 kWindowVisibilityAnimationTransitionKey, | 61 kWindowVisibilityAnimationTransitionKey, |
| 61 ANIMATE_BOTH); | 62 ANIMATE_BOTH); |
| 62 DEFINE_WINDOW_PROPERTY_KEY(float, | 63 DEFINE_WINDOW_PROPERTY_KEY(float, |
| 63 kWindowVisibilityAnimationVerticalPositionKey, | 64 kWindowVisibilityAnimationVerticalPositionKey, |
| 64 kWindowAnimation_Vertical_TranslateY); | 65 kWindowAnimation_Vertical_TranslateY); |
| 65 | 66 |
| 66 namespace { | 67 namespace { |
| 67 | 68 |
| 68 const int kDefaultAnimationDurationForMenuMS = 150; | 69 const int kDefaultAnimationDurationForMenuMS = 150; |
| 69 const int kLayerAnimationsForMinimizeDurationMS = 200; | 70 const int kLayerAnimationsForMinimizeDurationMS = 200; |
| 70 | 71 |
| 71 // Durations for the cross-fade animation, in milliseconds. | 72 // Durations for the cross-fade animation, in milliseconds. |
| 72 const float kCrossFadeDurationMinMs = 100.f; | 73 const float kCrossFadeDurationMinMs = 200.f; |
| 73 const float kCrossFadeDurationMaxMs = 400.f; | 74 const float kCrossFadeDurationMaxMs = 400.f; |
| 74 | 75 |
| 75 // Durations for the brightness/grayscale fade animation, in milliseconds. | 76 // Durations for the brightness/grayscale fade animation, in milliseconds. |
| 76 const int kBrightnessGrayscaleFadeDurationMs = 1000; | 77 const int kBrightnessGrayscaleFadeDurationMs = 1000; |
| 77 | 78 |
| 78 // Brightness/grayscale values for hide/show window animations. | 79 // Brightness/grayscale values for hide/show window animations. |
| 79 const float kWindowAnimation_HideBrightnessGrayscale = 1.f; | 80 const float kWindowAnimation_HideBrightnessGrayscale = 1.f; |
| 80 const float kWindowAnimation_ShowBrightnessGrayscale = 0.f; | 81 const float kWindowAnimation_ShowBrightnessGrayscale = 0.f; |
| 81 | 82 |
| 82 const float kWindowAnimation_HideOpacity = 0.f; | 83 const float kWindowAnimation_HideOpacity = 0.f; |
| 83 const float kWindowAnimation_ShowOpacity = 1.f; | 84 const float kWindowAnimation_ShowOpacity = 1.f; |
| 84 const float kWindowAnimation_TranslateFactor = 0.025f; | 85 const float kWindowAnimation_TranslateFactor = 0.025f; |
| 85 const float kWindowAnimation_ScaleFactor = .95f; | 86 const float kWindowAnimation_ScaleFactor = .95f; |
| 86 // TODO(sky): if we end up sticking with 0, nuke the code doing the rotation. | 87 // TODO(sky): if we end up sticking with 0, nuke the code doing the rotation. |
| 87 const float kWindowAnimation_MinimizeRotate = 0.f; | 88 const float kWindowAnimation_MinimizeRotate = 0.f; |
| 88 | 89 |
| 89 // Amount windows are scaled during workspace animations. | 90 // Amount windows are scaled during workspace animations. |
| 90 const float kWorkspaceScale = .95f; | 91 const float kWorkspaceScale = .95f; |
| 91 | 92 |
| 93 // Tween type when cross fading a workspace window. |
| 94 const ui::Tween::Type kCrossFadeTweenType = ui::Tween::EASE_IN_OUT; |
| 95 |
| 92 int64 Round64(float f) { | 96 int64 Round64(float f) { |
| 93 return static_cast<int64>(f + 0.5f); | 97 return static_cast<int64>(f + 0.5f); |
| 94 } | 98 } |
| 95 | 99 |
| 96 base::TimeDelta GetWindowVisibilityAnimationDuration(aura::Window* window) { | 100 base::TimeDelta GetWindowVisibilityAnimationDuration(aura::Window* window) { |
| 97 int duration = | 101 int duration = |
| 98 window->GetProperty(kWindowVisibilityAnimationDurationKey); | 102 window->GetProperty(kWindowVisibilityAnimationDurationKey); |
| 99 if (duration == 0 && window->type() == aura::client::WINDOW_TYPE_MENU) { | 103 if (duration == 0 && window->type() == aura::client::WINDOW_TYPE_MENU) { |
| 100 return base::TimeDelta::FromMilliseconds( | 104 return base::TimeDelta::FromMilliseconds( |
| 101 kDefaultAnimationDurationForMenuMS); | 105 kDefaultAnimationDurationForMenuMS); |
| (...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 578 case WINDOW_VISIBILITY_ANIMATION_TYPE_FADE: | 582 case WINDOW_VISIBILITY_ANIMATION_TYPE_FADE: |
| 579 AnimateShowWindow_Fade(window); | 583 AnimateShowWindow_Fade(window); |
| 580 return true; | 584 return true; |
| 581 case WINDOW_VISIBILITY_ANIMATION_TYPE_WORKSPACE_SHOW: | 585 case WINDOW_VISIBILITY_ANIMATION_TYPE_WORKSPACE_SHOW: |
| 582 AnimateShowWindow_Workspace(window); | 586 AnimateShowWindow_Workspace(window); |
| 583 return true; | 587 return true; |
| 584 case WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE: | 588 case WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE: |
| 585 AnimateShowWindow_Minimize(window); | 589 AnimateShowWindow_Minimize(window); |
| 586 return true; | 590 return true; |
| 587 case WINDOW_VISIBILITY_ANIMATION_TYPE_BRIGHTNESS_GRAYSCALE: | 591 case WINDOW_VISIBILITY_ANIMATION_TYPE_BRIGHTNESS_GRAYSCALE: |
| 588 AnimateShowWindow_BrightnessGrayscale(window); | 592 AnimateShowWindow_BrightnessGrayscale(window); |
| 589 return true; | 593 return true; |
| 590 default: | 594 default: |
| 591 NOTREACHED(); | 595 NOTREACHED(); |
| 592 return false; | 596 return false; |
| 593 } | 597 } |
| 594 } | 598 } |
| 595 | 599 |
| 596 bool AnimateHideWindow(aura::Window* window) { | 600 bool AnimateHideWindow(aura::Window* window) { |
| 597 if (!HasWindowVisibilityAnimationTransition(window, ANIMATE_HIDE)) | 601 if (!HasWindowVisibilityAnimationTransition(window, ANIMATE_HIDE)) |
| 598 return false; | 602 return false; |
| 599 | 603 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 675 Layer* layer_; // owned | 679 Layer* layer_; // owned |
| 676 | 680 |
| 677 DISALLOW_COPY_AND_ASSIGN(CrossFadeObserver); | 681 DISALLOW_COPY_AND_ASSIGN(CrossFadeObserver); |
| 678 }; | 682 }; |
| 679 | 683 |
| 680 } // namespace | 684 } // namespace |
| 681 } // namespace internal | 685 } // namespace internal |
| 682 | 686 |
| 683 namespace { | 687 namespace { |
| 684 | 688 |
| 685 // Scales for workspaces above/below current workspace. | |
| 686 const float kWorkspaceScaleAbove = 1.1f; | |
| 687 const float kWorkspaceScaleBelow = .9f; | |
| 688 | |
| 689 // Amount of time to pause before animating anything. Only used during initial | |
| 690 // animation (when logging in). | |
| 691 const int kWorkspaceInitialPauseTimeMS = 750; | |
| 692 | |
| 693 // TODO: leaving in for now since Nicholas wants to play with this, remove if we | |
| 694 // leave it at 0. | |
| 695 const int kPauseTimeMS = 0; | |
| 696 | |
| 697 } // namespace | |
| 698 | |
| 699 // Amount of time for animating a workspace in or out. | |
| 700 const int kWorkspaceSwitchTimeMS = 200 + kPauseTimeMS; | |
| 701 | |
| 702 namespace { | |
| 703 | |
| 704 // Brightness for the non-active workspace. | |
| 705 // TODO(sky): ideally this would be -.33f, but it slows down animations by a | |
| 706 // factor of 2. Figure out why. | |
| 707 const float kWorkspaceBrightness = 0.0f; | |
| 708 | |
| 709 enum WorkspaceScaleType { | |
| 710 WORKSPACE_SCALE_ABOVE, | |
| 711 WORKSPACE_SCALE_BELOW, | |
| 712 }; | |
| 713 | |
| 714 // Used to identify what should animate in AnimateWorkspaceIn/Out. | |
| 715 enum WorkspaceAnimateTypes { | |
| 716 WORKSPACE_ANIMATE_OPACITY = 1 << 0, | |
| 717 WORKSPACE_ANIMATE_BRIGHTNESS = 1 << 1, | |
| 718 }; | |
| 719 | |
| 720 void ApplyWorkspaceScale(ui::Layer* layer, WorkspaceScaleType type) { | |
| 721 const float scale = type == WORKSPACE_SCALE_ABOVE ? kWorkspaceScaleAbove : | |
| 722 kWorkspaceScaleBelow; | |
| 723 ui::Transform transform; | |
| 724 transform.ConcatScale(scale, scale); | |
| 725 transform.ConcatTranslate( | |
| 726 -layer->bounds().width() * (scale - 1.0f) / 2, | |
| 727 -layer->bounds().height() * (scale - 1.0f) / 2); | |
| 728 layer->SetTransform(transform); | |
| 729 } | |
| 730 | |
| 731 // Implementation of cross fading. Window is the window being cross faded. It | 689 // Implementation of cross fading. Window is the window being cross faded. It |
| 732 // should be at the target bounds. |old_layer| the previous layer from |window|. | 690 // should be at the target bounds. |old_layer| the previous layer from |window|. |
| 733 // This takes ownership of |old_layer| and deletes when the animation is done. | 691 // This takes ownership of |old_layer| and deletes when the animation is done. |
| 734 // |pause_duration| is the duration to pause at the current bounds before | 692 // |pause_duration| is the duration to pause at the current bounds before |
| 735 // animating. Returns the duration of the fade. | 693 // animating. Returns the duration of the fade. |
| 736 TimeDelta CrossFadeImpl(aura::Window* window, | 694 TimeDelta CrossFadeImpl(aura::Window* window, |
| 737 ui::Layer* old_layer, | 695 ui::Layer* old_layer, |
| 738 ui::Tween::Type tween_type, | 696 ui::Tween::Type tween_type) { |
| 739 base::TimeDelta pause_duration) { | |
| 740 const gfx::Rect old_bounds(old_layer->bounds()); | 697 const gfx::Rect old_bounds(old_layer->bounds()); |
| 741 const gfx::Rect new_bounds(window->bounds()); | 698 const gfx::Rect new_bounds(window->bounds()); |
| 742 const bool old_on_top = (old_bounds.width() > new_bounds.width()); | 699 const bool old_on_top = (old_bounds.width() > new_bounds.width()); |
| 743 | 700 |
| 744 // Shorten the animation if there's not much visual movement. | 701 // Shorten the animation if there's not much visual movement. |
| 745 const TimeDelta duration = GetCrossFadeDuration(old_bounds, new_bounds); | 702 const TimeDelta duration = GetCrossFadeDuration(old_bounds, new_bounds); |
| 746 | 703 |
| 747 // Scale up the old layer while translating to new position. | 704 // Scale up the old layer while translating to new position. |
| 748 { | 705 { |
| 749 old_layer->GetAnimator()->StopAnimating(); | 706 old_layer->GetAnimator()->StopAnimating(); |
| 750 ui::ScopedLayerAnimationSettings settings(old_layer->GetAnimator()); | 707 ui::ScopedLayerAnimationSettings settings(old_layer->GetAnimator()); |
| 751 settings.SetPreemptionStrategy(ui::LayerAnimator::ENQUEUE_NEW_ANIMATION); | |
| 752 old_layer->GetAnimator()->SchedulePauseForProperties( | |
| 753 pause_duration, ui::LayerAnimationElement::TRANSFORM, | |
| 754 ui::LayerAnimationElement::OPACITY, -1); | |
| 755 | 708 |
| 756 // Animation observer owns the old layer and deletes itself. | 709 // Animation observer owns the old layer and deletes itself. |
| 757 settings.AddObserver(new internal::CrossFadeObserver(window, old_layer)); | 710 settings.AddObserver(new internal::CrossFadeObserver(window, old_layer)); |
| 758 settings.SetTransitionDuration(duration); | 711 settings.SetTransitionDuration(duration); |
| 759 settings.SetTweenType(tween_type); | 712 settings.SetTweenType(tween_type); |
| 760 ui::Transform out_transform; | 713 ui::Transform out_transform; |
| 761 float scale_x = static_cast<float>(new_bounds.width()) / | 714 float scale_x = static_cast<float>(new_bounds.width()) / |
| 762 static_cast<float>(old_bounds.width()); | 715 static_cast<float>(old_bounds.width()); |
| 763 float scale_y = static_cast<float>(new_bounds.height()) / | 716 float scale_y = static_cast<float>(new_bounds.height()) / |
| 764 static_cast<float>(old_bounds.height()); | 717 static_cast<float>(old_bounds.height()); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 788 window->layer()->SetTransform(in_transform); | 741 window->layer()->SetTransform(in_transform); |
| 789 if (!old_on_top) { | 742 if (!old_on_top) { |
| 790 // The new layer is on top and should fade in. The old layer below will | 743 // The new layer is on top and should fade in. The old layer below will |
| 791 // stay opaque and block the desktop. | 744 // stay opaque and block the desktop. |
| 792 window->layer()->SetOpacity(0.f); | 745 window->layer()->SetOpacity(0.f); |
| 793 } | 746 } |
| 794 { | 747 { |
| 795 // Animate the new layer to the identity transform, so the window goes to | 748 // Animate the new layer to the identity transform, so the window goes to |
| 796 // its newly set bounds. | 749 // its newly set bounds. |
| 797 ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); | 750 ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); |
| 798 settings.SetPreemptionStrategy(ui::LayerAnimator::ENQUEUE_NEW_ANIMATION); | |
| 799 window->layer()->GetAnimator()->SchedulePauseForProperties( | |
| 800 pause_duration, ui::LayerAnimationElement::TRANSFORM, | |
| 801 ui::LayerAnimationElement::OPACITY, -1); | |
| 802 settings.SetTransitionDuration(duration); | 751 settings.SetTransitionDuration(duration); |
| 803 settings.SetTweenType(tween_type); | 752 settings.SetTweenType(tween_type); |
| 804 window->layer()->SetTransform(ui::Transform()); | 753 window->layer()->SetTransform(ui::Transform()); |
| 805 if (!old_on_top) { | 754 if (!old_on_top) { |
| 806 // New layer is on top, fade it in. | 755 // New layer is on top, fade it in. |
| 807 window->layer()->SetOpacity(1.f); | 756 window->layer()->SetOpacity(1.f); |
| 808 } | 757 } |
| 809 } | 758 } |
| 810 return duration; | 759 return duration; |
| 811 } | 760 } |
| 812 | 761 |
| 813 // Returns a TimeDelta from |time_ms|. If animations are disabled this returns | |
| 814 // a TimeDelta of 0 (so the animation completes immediately). | |
| 815 base::TimeDelta AdjustAnimationTime(int time_ms) { | |
| 816 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 817 ash::switches::kAshWindowAnimationsDisabled)) | |
| 818 time_ms = 0; | |
| 819 return base::TimeDelta::FromMilliseconds(time_ms); | |
| 820 } | |
| 821 | |
| 822 // Returns a TimeDelta adjusted for animations. If animations are disabled this | |
| 823 // returns 0. If animations are not disabled and |time_delta| is non-empty, it | |
| 824 // is returned. Otherwise |delta_time_ms| is returned. | |
| 825 base::TimeDelta AdjustAnimationTimeDelta(base::TimeDelta time_delta, | |
| 826 int delta_time_ms) { | |
| 827 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 828 ash::switches::kAshWindowAnimationsDisabled)) | |
| 829 return base::TimeDelta(); | |
| 830 return time_delta == base::TimeDelta() ? | |
| 831 base::TimeDelta::FromMilliseconds(delta_time_ms) : time_delta; | |
| 832 } | |
| 833 | |
| 834 void AnimateWorkspaceInImpl(aura::Window* window, | |
| 835 WorkspaceAnimationDirection direction, | |
| 836 uint32 animate_types, | |
| 837 int pause_time_ms, | |
| 838 ui::Tween::Type tween_type, | |
| 839 base::TimeDelta duration) { | |
| 840 window->layer()->SetOpacity( | |
| 841 (animate_types & WORKSPACE_ANIMATE_OPACITY) ? 0.0f : 1.0f); | |
| 842 window->layer()->SetLayerBrightness( | |
| 843 (animate_types & WORKSPACE_ANIMATE_BRIGHTNESS) ? | |
| 844 kWorkspaceBrightness : 0.0f); | |
| 845 window->Show(); | |
| 846 ApplyWorkspaceScale(window->layer(), | |
| 847 direction == WORKSPACE_ANIMATE_UP ? | |
| 848 WORKSPACE_SCALE_BELOW : WORKSPACE_SCALE_ABOVE); | |
| 849 window->layer()->GetAnimator()->StopAnimating(); | |
| 850 | |
| 851 { | |
| 852 ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); | |
| 853 | |
| 854 if (pause_time_ms > 0) { | |
| 855 settings.SetPreemptionStrategy(ui::LayerAnimator::ENQUEUE_NEW_ANIMATION); | |
| 856 window->layer()->GetAnimator()->SchedulePauseForProperties( | |
| 857 AdjustAnimationTime(pause_time_ms), | |
| 858 ui::LayerAnimationElement::TRANSFORM, | |
| 859 ui::LayerAnimationElement::OPACITY, | |
| 860 ui::LayerAnimationElement::BRIGHTNESS, | |
| 861 ui::LayerAnimationElement::VISIBILITY, | |
| 862 -1); | |
| 863 } | |
| 864 | |
| 865 settings.SetTweenType(tween_type); | |
| 866 settings.SetTransitionDuration(duration); | |
| 867 window->layer()->SetTransform(ui::Transform()); | |
| 868 window->layer()->SetOpacity(1.0f); | |
| 869 window->layer()->SetLayerBrightness(0.0f); | |
| 870 } | |
| 871 } | |
| 872 | |
| 873 void AnimateWorkspaceOutImpl(aura::Window* window, | |
| 874 WorkspaceAnimationDirection direction, | |
| 875 uint32 animate_types, | |
| 876 int pause_time_ms, | |
| 877 ui::Tween::Type tween_type, | |
| 878 TimeDelta duration) { | |
| 879 window->Show(); | |
| 880 window->layer()->SetTransform(ui::Transform()); | |
| 881 window->layer()->SetLayerBrightness(0.0f); | |
| 882 window->layer()->SetOpacity(1.0f); | |
| 883 window->layer()->GetAnimator()->StopAnimating(); | |
| 884 | |
| 885 { | |
| 886 ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); | |
| 887 | |
| 888 if (pause_time_ms > 0) { | |
| 889 settings.SetPreemptionStrategy(ui::LayerAnimator::ENQUEUE_NEW_ANIMATION); | |
| 890 window->layer()->GetAnimator()->SchedulePauseForProperties( | |
| 891 AdjustAnimationTime(pause_time_ms), | |
| 892 ui::LayerAnimationElement::TRANSFORM, | |
| 893 ui::LayerAnimationElement::OPACITY, | |
| 894 ui::LayerAnimationElement::BRIGHTNESS, | |
| 895 ui::LayerAnimationElement::VISIBILITY, | |
| 896 -1); | |
| 897 } | |
| 898 | |
| 899 settings.SetTransitionDuration(duration); | |
| 900 settings.SetTweenType(tween_type); | |
| 901 ApplyWorkspaceScale(window->layer(), | |
| 902 direction == WORKSPACE_ANIMATE_UP ? | |
| 903 WORKSPACE_SCALE_ABOVE : WORKSPACE_SCALE_BELOW); | |
| 904 // NOTE: Hide() must be before SetOpacity(), else | |
| 905 // VisibilityController::UpdateLayerVisibility doesn't pass the false to the | |
| 906 // layer so that the layer and window end up out of sync and confused. | |
| 907 window->Hide(); | |
| 908 if (animate_types & WORKSPACE_ANIMATE_OPACITY) | |
| 909 window->layer()->SetOpacity(0.0f); | |
| 910 if (animate_types & WORKSPACE_ANIMATE_BRIGHTNESS) | |
| 911 window->layer()->SetLayerBrightness(kWorkspaceBrightness); | |
| 912 | |
| 913 // After the animation completes snap the transform back to the identity, | |
| 914 // otherwise any one that asks for screen bounds gets a slightly scaled | |
| 915 // version. | |
| 916 settings.SetPreemptionStrategy(ui::LayerAnimator::ENQUEUE_NEW_ANIMATION); | |
| 917 settings.SetTransitionDuration(base::TimeDelta()); | |
| 918 window->layer()->SetTransform(ui::Transform()); | |
| 919 } | |
| 920 } | |
| 921 | |
| 922 ui::Tween::Type TweenTypeForWorskpaceOut(WorkspaceType type) { | |
| 923 return WORKSPACE_DESKTOP ? ui::Tween::LINEAR : ui::Tween::EASE_OUT; | |
| 924 } | |
| 925 | |
| 926 } // namespace | 762 } // namespace |
| 927 | 763 |
| 928 //////////////////////////////////////////////////////////////////////////////// | 764 //////////////////////////////////////////////////////////////////////////////// |
| 929 // External interface | 765 // External interface |
| 930 | 766 |
| 931 void SetWindowVisibilityAnimationType(aura::Window* window, | 767 void SetWindowVisibilityAnimationType(aura::Window* window, |
| 932 WindowVisibilityAnimationType type) { | 768 WindowVisibilityAnimationType type) { |
| 933 window->SetProperty(internal::kWindowVisibilityAnimationTypeKey, type); | 769 window->SetProperty(internal::kWindowVisibilityAnimationTypeKey, type); |
| 934 } | 770 } |
| 935 | 771 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 975 // Resize the window to the new size, which will force a layout and paint. | 811 // Resize the window to the new size, which will force a layout and paint. |
| 976 window->SetBounds(new_bounds); | 812 window->SetBounds(new_bounds); |
| 977 | 813 |
| 978 // Ensure the higher-resolution layer is on top. | 814 // Ensure the higher-resolution layer is on top. |
| 979 bool old_on_top = (old_bounds.width() > new_bounds.width()); | 815 bool old_on_top = (old_bounds.width() > new_bounds.width()); |
| 980 if (old_on_top) | 816 if (old_on_top) |
| 981 old_layer->parent()->StackBelow(new_layer, old_layer); | 817 old_layer->parent()->StackBelow(new_layer, old_layer); |
| 982 else | 818 else |
| 983 old_layer->parent()->StackAbove(new_layer, old_layer); | 819 old_layer->parent()->StackAbove(new_layer, old_layer); |
| 984 | 820 |
| 985 CrossFadeImpl(window, old_layer, ui::Tween::EASE_OUT, base::TimeDelta()); | 821 CrossFadeImpl(window, old_layer, ui::Tween::EASE_OUT); |
| 986 } | 822 } |
| 987 | 823 |
| 988 void CrossFadeWindowBetweenWorkspaces(aura::Window* old_workspace, | 824 void CrossFadeWindowBetweenWorkspaces(aura::Window* new_workspace, |
| 989 aura::Window* new_workspace, | |
| 990 aura::Window* window, | 825 aura::Window* window, |
| 991 ui::Layer* old_layer) { | 826 ui::Layer* old_layer) { |
| 992 ui::Layer* layer_parent = new_workspace->layer()->parent(); | 827 ui::Layer* layer_parent = new_workspace->layer()->parent(); |
| 993 layer_parent->Add(old_layer); | 828 layer_parent->Add(old_layer); |
| 994 const bool restoring = old_layer->bounds().width() > window->bounds().width(); | 829 const bool restoring = old_layer->bounds().width() > window->bounds().width(); |
| 995 ui::Tween::Type tween_type, workspace_tween_type; | 830 if (restoring) |
| 996 if (restoring) { | |
| 997 layer_parent->StackAbove(old_layer, new_workspace->layer()); | 831 layer_parent->StackAbove(old_layer, new_workspace->layer()); |
| 998 tween_type = ui::Tween::EASE_OUT; | 832 else |
| 999 workspace_tween_type = ui::Tween::EASE_OUT; | |
| 1000 } else { | |
| 1001 layer_parent->StackBelow(old_layer, new_workspace->layer()); | 833 layer_parent->StackBelow(old_layer, new_workspace->layer()); |
| 1002 tween_type = ui::Tween::EASE_IN_2; | |
| 1003 workspace_tween_type = ui::Tween::LINEAR; | |
| 1004 } | |
| 1005 | 834 |
| 1006 const TimeDelta duration = | 835 CrossFadeImpl(window, old_layer, internal::kCrossFadeTweenType); |
| 1007 CrossFadeImpl(window, old_layer, tween_type, | |
| 1008 AdjustAnimationTime(restoring ? 0 : kPauseTimeMS)); | |
| 1009 | |
| 1010 if (restoring) { | |
| 1011 typedef aura::Window::Windows Windows; | |
| 1012 if (old_workspace) | |
| 1013 AnimateWorkspaceOutImpl(old_workspace, WORKSPACE_ANIMATE_UP, | |
| 1014 WORKSPACE_ANIMATE_BRIGHTNESS, | |
| 1015 0, workspace_tween_type, duration); | |
| 1016 | |
| 1017 // Ideally we would use AnimateWorkspaceIn() for |new_workspace|, but that | |
| 1018 // results in |window| animating with the workspace scale. We don't want | |
| 1019 // that, so we explicitly animate each of the children to give the effect of | |
| 1020 // the workspace scaling. | |
| 1021 new_workspace->Show(); | |
| 1022 new_workspace->SetTransform(ui::Transform()); | |
| 1023 new_workspace->layer()->SetOpacity(1.0f); | |
| 1024 new_workspace->layer()->SetLayerBrightness(0.0f); | |
| 1025 const Windows& children(new_workspace->children()); | |
| 1026 for (Windows::const_iterator i = children.begin(); i != children.end(); | |
| 1027 ++i) { | |
| 1028 aura::Window* child = *i; | |
| 1029 if (child == window) | |
| 1030 continue; | |
| 1031 child->SetTransform(ash::internal::BuildWorkspaceSwitchTransform( | |
| 1032 child, kWorkspaceScaleBelow)); | |
| 1033 child->layer()->SetLayerBrightness(kWorkspaceBrightness); | |
| 1034 ui::ScopedLayerAnimationSettings settings(child->layer()->GetAnimator()); | |
| 1035 settings.SetTweenType(ui::Tween::EASE_OUT); | |
| 1036 settings.SetTransitionDuration(duration); | |
| 1037 child->SetTransform(ui::Transform()); | |
| 1038 child->layer()->SetLayerBrightness(0.0f); | |
| 1039 } | |
| 1040 } else { | |
| 1041 if (old_workspace) { | |
| 1042 AnimateWorkspaceOutImpl(old_workspace, WORKSPACE_ANIMATE_DOWN, | |
| 1043 WORKSPACE_ANIMATE_BRIGHTNESS, | |
| 1044 0, workspace_tween_type, duration); | |
| 1045 } | |
| 1046 | |
| 1047 new_workspace->Show(); | |
| 1048 new_workspace->layer()->SetOpacity(1.f); | |
| 1049 new_workspace->layer()->SetTransform(ui::Transform()); | |
| 1050 new_workspace->layer()->SetLayerBrightness(0.0f); | |
| 1051 } | |
| 1052 } | |
| 1053 | |
| 1054 void AnimateBetweenWorkspaces(aura::Window* old_window, | |
| 1055 WorkspaceType old_type, | |
| 1056 bool animate_old, | |
| 1057 aura::Window* new_window, | |
| 1058 WorkspaceType new_type, | |
| 1059 bool is_restoring_maximized_window) { | |
| 1060 uint32 common_animate_types = 0; | |
| 1061 if (animate_old) { | |
| 1062 // When switching to the desktop the old window lifts off. | |
| 1063 uint32 animate_types = 0; | |
| 1064 if (!(new_type == WORKSPACE_MAXIMIZED && old_type == WORKSPACE_MAXIMIZED)) | |
| 1065 animate_types |= WORKSPACE_ANIMATE_BRIGHTNESS; | |
| 1066 if ((new_type == WORKSPACE_DESKTOP || old_type == WORKSPACE_MAXIMIZED) && | |
| 1067 !is_restoring_maximized_window) | |
| 1068 animate_types |= WORKSPACE_ANIMATE_OPACITY; | |
| 1069 AnimateWorkspaceOutImpl( | |
| 1070 old_window, | |
| 1071 new_type == WORKSPACE_DESKTOP ? WORKSPACE_ANIMATE_UP : | |
| 1072 WORKSPACE_ANIMATE_DOWN, | |
| 1073 animate_types, | |
| 1074 0, | |
| 1075 TweenTypeForWorskpaceOut(old_type), | |
| 1076 AdjustAnimationTime(kWorkspaceSwitchTimeMS)); | |
| 1077 } | |
| 1078 | |
| 1079 // Switching from the desktop to a maximized animates down. | |
| 1080 uint32 animate_types = common_animate_types; | |
| 1081 if (!(new_type == WORKSPACE_MAXIMIZED && old_type == WORKSPACE_MAXIMIZED) && | |
| 1082 !is_restoring_maximized_window) | |
| 1083 animate_types |= WORKSPACE_ANIMATE_BRIGHTNESS; | |
| 1084 if (old_type == WORKSPACE_DESKTOP) | |
| 1085 animate_types |= WORKSPACE_ANIMATE_OPACITY; | |
| 1086 AnimateWorkspaceInImpl( | |
| 1087 new_window, | |
| 1088 old_type == WORKSPACE_DESKTOP ? | |
| 1089 WORKSPACE_ANIMATE_DOWN : WORKSPACE_ANIMATE_UP, | |
| 1090 animate_types, | |
| 1091 0, | |
| 1092 ui::Tween::EASE_OUT, | |
| 1093 AdjustAnimationTime(kWorkspaceSwitchTimeMS)); | |
| 1094 } | |
| 1095 | |
| 1096 void AnimateWorkspaceIn(aura::Window* window, | |
| 1097 WorkspaceAnimationDirection direction, | |
| 1098 bool initial_animate, | |
| 1099 base::TimeDelta delta) { | |
| 1100 AnimateWorkspaceInImpl( | |
| 1101 window, direction, | |
| 1102 WORKSPACE_ANIMATE_BRIGHTNESS | | |
| 1103 (initial_animate ? WORKSPACE_ANIMATE_OPACITY : 0), | |
| 1104 initial_animate ? kWorkspaceInitialPauseTimeMS : 0, | |
| 1105 ui::Tween::EASE_OUT, | |
| 1106 AdjustAnimationTimeDelta(delta, kWorkspaceSwitchTimeMS)); | |
| 1107 } | |
| 1108 | |
| 1109 void AnimateWorkspaceOut(aura::Window* window, | |
| 1110 WorkspaceAnimationDirection direction, | |
| 1111 WorkspaceType type, | |
| 1112 bool initial_animate, | |
| 1113 base::TimeDelta delta) { | |
| 1114 AnimateWorkspaceOutImpl(window, direction, WORKSPACE_ANIMATE_BRIGHTNESS, | |
| 1115 initial_animate ? kWorkspaceInitialPauseTimeMS : 0, | |
| 1116 TweenTypeForWorskpaceOut(type), | |
| 1117 AdjustAnimationTimeDelta(delta, | |
| 1118 kWorkspaceSwitchTimeMS)); | |
| 1119 } | |
| 1120 | |
| 1121 base::TimeDelta GetSystemBackgroundDestroyDuration() { | |
| 1122 return base::TimeDelta::FromMilliseconds( | |
| 1123 std::max(static_cast<int>(internal::kCrossFadeDurationMaxMs), | |
| 1124 kWorkspaceSwitchTimeMS)); | |
| 1125 } | 836 } |
| 1126 | 837 |
| 1127 TimeDelta GetCrossFadeDuration(const gfx::Rect& old_bounds, | 838 TimeDelta GetCrossFadeDuration(const gfx::Rect& old_bounds, |
| 1128 const gfx::Rect& new_bounds) { | 839 const gfx::Rect& new_bounds) { |
| 1129 if (CommandLine::ForCurrentProcess()->HasSwitch( | 840 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 1130 ash::switches::kAshWindowAnimationsDisabled)) | 841 ash::switches::kAshWindowAnimationsDisabled)) |
| 1131 return base::TimeDelta(); | 842 return base::TimeDelta(); |
| 1132 | 843 |
| 1133 const int min_time_ms = internal::WorkspaceController::IsWorkspace2Enabled() ? | 844 const int min_time_ms = internal::WorkspaceController::IsWorkspace2Enabled() ? |
| 1134 kWorkspaceSwitchTimeMS : 0; | 845 internal::kWorkspaceSwitchTimeMS : 0; |
| 1135 int old_area = old_bounds.width() * old_bounds.height(); | 846 int old_area = old_bounds.width() * old_bounds.height(); |
| 1136 int new_area = new_bounds.width() * new_bounds.height(); | 847 int new_area = new_bounds.width() * new_bounds.height(); |
| 1137 int max_area = std::max(old_area, new_area); | 848 int max_area = std::max(old_area, new_area); |
| 1138 // Avoid divide by zero. | 849 // Avoid divide by zero. |
| 1139 if (max_area == 0) | 850 if (max_area == 0) |
| 1140 return TimeDelta::FromMilliseconds(min_time_ms); | 851 return TimeDelta::FromMilliseconds(min_time_ms); |
| 1141 | 852 |
| 1142 int delta_area = std::abs(old_area - new_area); | 853 int delta_area = std::abs(old_area - new_area); |
| 1143 // If the area didn't change, the animation is instantaneous. | 854 // If the area didn't change, the animation is instantaneous. |
| 1144 if (delta_area == 0) | 855 if (delta_area == 0) |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1164 return AnimateShowWindow(window); | 875 return AnimateShowWindow(window); |
| 1165 } else { | 876 } else { |
| 1166 // Don't start hiding the window again if it's already being hidden. | 877 // Don't start hiding the window again if it's already being hidden. |
| 1167 return window->layer()->GetTargetOpacity() != 0.0f && | 878 return window->layer()->GetTargetOpacity() != 0.0f && |
| 1168 AnimateHideWindow(window); | 879 AnimateHideWindow(window); |
| 1169 } | 880 } |
| 1170 } | 881 } |
| 1171 | 882 |
| 1172 } // namespace internal | 883 } // namespace internal |
| 1173 } // namespace ash | 884 } // namespace ash |
| OLD | NEW |