15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/window_animations.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <math.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/screen_util.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/shelf/shelf.h" 14ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ash/shelf/shelf_layout_manager.h" 15ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ash/shelf/shelf_widget.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/window_util.h" 18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ash/wm/workspace_controller.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/message_loop/message_loop.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/client/aura_constants.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window_observer.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window_property.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/compositor_observer.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer_animation_observer.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer_animation_sequence.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer_animator.h" 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/compositor/layer_tree_owner.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/scoped_layer_animation_settings.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/interpolated_transform.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen.h" 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/vector3d_f.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/view.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h" 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/window_util.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kLayerAnimationsForMinimizeDurationMS = 200; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Durations for the cross-fade animation, in milliseconds. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const float kCrossFadeDurationMinMs = 200.f; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const float kCrossFadeDurationMaxMs = 400.f; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Durations for the brightness/grayscale fade animation, in milliseconds. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kBrightnessGrayscaleFadeDurationMs = 1000; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Brightness/grayscale values for hide/show window animations. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const float kWindowAnimation_HideBrightnessGrayscale = 1.f; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const float kWindowAnimation_ShowBrightnessGrayscale = 0.f; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const float kWindowAnimation_HideOpacity = 0.f; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const float kWindowAnimation_ShowOpacity = 1.f; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Scales for AshWindow above/below current workspace. 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const float kLayerScaleAboveSize = 1.1f; 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const float kLayerScaleBelowSize = .9f; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 Round64(float f) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<int64>(f + 0.5f); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)base::TimeDelta GetCrossFadeDuration(aura::Window* window, 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const gfx::Rect& old_bounds, 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const gfx::Rect& new_bounds) { 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (::wm::WindowAnimationsDisabled(window)) 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return base::TimeDelta(); 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int old_area = old_bounds.width() * old_bounds.height(); 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int new_area = new_bounds.width() * new_bounds.height(); 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int max_area = std::max(old_area, new_area); 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Avoid divide by zero. 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (max_area == 0) 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return base::TimeDelta::FromMilliseconds(kCrossFadeDurationMS); 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int delta_area = std::abs(old_area - new_area); 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // If the area didn't change, the animation is instantaneous. 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (delta_area == 0) 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return base::TimeDelta::FromMilliseconds(kCrossFadeDurationMS); 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) float factor = 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static_cast<float>(delta_area) / static_cast<float>(max_area); 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const float kRange = kCrossFadeDurationMaxMs - kCrossFadeDurationMinMs; 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return base::TimeDelta::FromMilliseconds( 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Round64(kCrossFadeDurationMinMs + (factor * kRange))); 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst int kCrossFadeDurationMS = 200; 972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddLayerAnimationsForMinimize(aura::Window* window, bool show) { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Recalculate the transform at restore time since the launcher item may have 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // moved while the window was minimized. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect bounds = window->bounds(); 102ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch gfx::Rect target_bounds = GetMinimizeAnimationTargetBoundsInScreen(window); 103ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch target_bounds = 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScreenUtil::ConvertRectFromScreen(window->parent(), target_bounds); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 106ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch float scale_x = static_cast<float>(target_bounds.width()) / bounds.width(); 107ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch float scale_y = static_cast<float>(target_bounds.height()) / bounds.height(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ui::InterpolatedTransform> scale( 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ui::InterpolatedScale(gfx::Point3F(1, 1, 1), 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Point3F(scale_x, scale_y, 1))); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ui::InterpolatedTransform> translation( 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ui::InterpolatedTranslation( 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Point(), 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Point(target_bounds.x() - bounds.x(), 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_bounds.y() - bounds.y()))); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scale->SetChild(translation.release()); 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scale->SetReversed(show); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::TimeDelta duration = window->layer()->GetAnimator()-> 123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) GetTransitionDuration(); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ui::LayerAnimationElement> transition( 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::LayerAnimationElement::CreateInterpolatedTransformElement( 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scale.release(), duration)); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transition->set_tween_type( 130d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) show ? gfx::Tween::EASE_IN : gfx::Tween::EASE_IN_OUT); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window->layer()->GetAnimator()->ScheduleAnimation( 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ui::LayerAnimationSequence(transition.release())); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When hiding a window, turn off blending until the animation is 3 / 4 done 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to save bandwidth and reduce jank. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!show) { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window->layer()->GetAnimator()->SchedulePauseForProperties( 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (duration * 3) / 4, ui::LayerAnimationElement::OPACITY); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Fade in and out quickly when the window is small to reduce jank. 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float opacity = show ? 1.0f : 0.0f; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window->layer()->GetAnimator()->ScheduleAnimation( 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ui::LayerAnimationSequence( 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::LayerAnimationElement::CreateOpacityElement( 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opacity, duration / 4))); 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Reset the transform to identity when the minimize animation is completed. 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window->layer()->GetAnimator()->ScheduleAnimation( 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new ui::LayerAnimationSequence( 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::LayerAnimationElement::CreateTransformElement( 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Transform(), 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TimeDelta()))); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AnimateShowWindow_Minimize(aura::Window* window) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window->layer()->SetOpacity(kWindowAnimation_HideOpacity); 159a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); 160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::TimeDelta duration = base::TimeDelta::FromMilliseconds( 161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) kLayerAnimationsForMinimizeDurationMS); 162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) settings.SetTransitionDuration(duration); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddLayerAnimationsForMinimize(window, true); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now that the window has been restored, we need to clear its animation style 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to default so that normal animation applies. 167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ::wm::SetWindowVisibilityAnimationType( 168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window, ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_DEFAULT); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AnimateHideWindow_Minimize(aura::Window* window) { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Property sets within this scope will be implicitly animated. 17323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ::wm::ScopedHidingAnimationSettings hiding_settings(window); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta duration = base::TimeDelta::FromMilliseconds( 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kLayerAnimationsForMinimizeDurationMS); 17623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) hiding_settings.layer_animation_settings()->SetTransitionDuration(duration); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window->layer()->SetVisible(false); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddLayerAnimationsForMinimize(window, false); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AnimateShowHideWindowCommon_BrightnessGrayscale(aura::Window* window, 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool show) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float start_value, end_value; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (show) { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_value = kWindowAnimation_HideBrightnessGrayscale; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end_value = kWindowAnimation_ShowBrightnessGrayscale; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_value = kWindowAnimation_ShowBrightnessGrayscale; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end_value = kWindowAnimation_HideBrightnessGrayscale; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window->layer()->SetLayerBrightness(start_value); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window->layer()->SetLayerGrayscale(start_value); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (show) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window->layer()->SetOpacity(kWindowAnimation_ShowOpacity); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window->layer()->SetVisible(true); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta duration = 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta::FromMilliseconds(kBrightnessGrayscaleFadeDurationMs); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (show) { 20423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); 20523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) window->layer()->GetAnimator()-> 20623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ScheduleTogether( 20723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) CreateBrightnessGrayscaleAnimationSequence(end_value, duration)); 20823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } else { 20923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ::wm::ScopedHidingAnimationSettings hiding_settings(window); 21023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) window->layer()->GetAnimator()-> 21123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ScheduleTogether( 21223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) CreateBrightnessGrayscaleAnimationSequence(end_value, duration)); 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window->layer()->SetOpacity(kWindowAnimation_HideOpacity); 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window->layer()->SetVisible(false); 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AnimateShowWindow_BrightnessGrayscale(aura::Window* window) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AnimateShowHideWindowCommon_BrightnessGrayscale(window, true); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AnimateHideWindow_BrightnessGrayscale(aura::Window* window) { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AnimateShowHideWindowCommon_BrightnessGrayscale(window, false); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AnimateShowWindow(aura::Window* window) { 227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!::wm::HasWindowVisibilityAnimationTransition( 228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window, ::wm::ANIMATE_SHOW)) { 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) switch (::wm::GetWindowVisibilityAnimationType(window)) { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE: 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AnimateShowWindow_Minimize(window); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WINDOW_VISIBILITY_ANIMATION_TYPE_BRIGHTNESS_GRAYSCALE: 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AnimateShowWindow_BrightnessGrayscale(window); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AnimateHideWindow(aura::Window* window) { 246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!::wm::HasWindowVisibilityAnimationTransition( 247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window, ::wm::ANIMATE_HIDE)) { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) switch (::wm::GetWindowVisibilityAnimationType(window)) { 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE: 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AnimateHideWindow_Minimize(window); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WINDOW_VISIBILITY_ANIMATION_TYPE_BRIGHTNESS_GRAYSCALE: 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AnimateHideWindow_BrightnessGrayscale(window); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Observer for a window cross-fade animation. If either the window closes or 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the layer's animation completes or compositing is aborted due to GPU crash, 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it deletes the layer and removes itself as an observer. 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CrossFadeObserver : public ui::CompositorObserver, 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public aura::WindowObserver, 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public ui::ImplicitAnimationObserver { 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Observes |window| for destruction, but does not take ownership. 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Takes ownership of |layer| and its child layers. 273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CrossFadeObserver(aura::Window* window, 274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<ui::LayerTreeOwner> layer_owner) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : window_(window), 276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) layer_owner_(layer_owner.Pass()) { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_->AddObserver(this); 278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) layer_owner_->root()->GetCompositor()->AddObserver(this); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~CrossFadeObserver() { 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_->RemoveObserver(this); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_ = NULL; 283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) layer_owner_->root()->GetCompositor()->RemoveObserver(this); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ui::CompositorObserver overrides: 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnCompositingDidCommit(ui::Compositor* compositor) OVERRIDE { 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnCompositingStarted(ui::Compositor* compositor, 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks start_time) OVERRIDE { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnCompositingEnded(ui::Compositor* compositor) OVERRIDE { 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnCompositingAborted(ui::Compositor* compositor) OVERRIDE { 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Triggers OnImplicitAnimationsCompleted() to be called and deletes us. 296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) layer_owner_->root()->GetAnimator()->StopAnimating(); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnCompositingLockStateChanged( 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::Compositor* compositor) OVERRIDE { 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // aura::WindowObserver overrides: 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Triggers OnImplicitAnimationsCompleted() to be called and deletes us. 305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) layer_owner_->root()->GetAnimator()->StopAnimating(); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 307effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch virtual void OnWindowRemovingFromRootWindow(aura::Window* window, 308effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch aura::Window* new_root) OVERRIDE { 309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) layer_owner_->root()->GetAnimator()->StopAnimating(); 310424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ui::ImplicitAnimationObserver overrides: 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnImplicitAnimationsCompleted() OVERRIDE { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete this; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::Window* window_; // not owned 319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<ui::LayerTreeOwner> layer_owner_; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(CrossFadeObserver); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)base::TimeDelta CrossFadeAnimation( 325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) aura::Window* window, 326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<ui::LayerTreeOwner> old_layer_owner, 327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Tween::Type tween_type) { 328a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(old_layer_owner->root()); 329a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const gfx::Rect old_bounds(old_layer_owner->root()->bounds()); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect new_bounds(window->bounds()); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool old_on_top = (old_bounds.width() > new_bounds.width()); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Shorten the animation if there's not much visual movement. 334a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::TimeDelta duration = GetCrossFadeDuration(window, 335a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) old_bounds, new_bounds); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Scale up the old layer while translating to new position. 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::Layer* old_layer = old_layer_owner->root(); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_layer->GetAnimator()->StopAnimating(); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::ScopedLayerAnimationSettings settings(old_layer->GetAnimator()); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Animation observer owns the old layer and deletes itself. 344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) settings.AddObserver(new CrossFadeObserver(window, old_layer_owner.Pass())); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settings.SetTransitionDuration(duration); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settings.SetTweenType(tween_type); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Transform out_transform; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float scale_x = static_cast<float>(new_bounds.width()) / 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<float>(old_bounds.width()); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float scale_y = static_cast<float>(new_bounds.height()) / 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<float>(old_bounds.height()); 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) out_transform.Translate(new_bounds.x() - old_bounds.x(), 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_bounds.y() - old_bounds.y()); 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) out_transform.Scale(scale_x, scale_y); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_layer->SetTransform(out_transform); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (old_on_top) { 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The old layer is on top, and should fade out. The new layer below will 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // stay opaque to block the desktop. 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) old_layer->SetOpacity(kWindowAnimation_HideOpacity); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In tests |old_layer| is deleted here, as animations have zero duration. 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_layer = NULL; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the new layer's current transform, such that the user sees a scaled 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // version of the window with the original bounds at the original position. 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Transform in_transform; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const float scale_x = static_cast<float>(old_bounds.width()) / 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<float>(new_bounds.width()); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const float scale_y = static_cast<float>(old_bounds.height()) / 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<float>(new_bounds.height()); 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) in_transform.Translate(old_bounds.x() - new_bounds.x(), 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_bounds.y() - new_bounds.y()); 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) in_transform.Scale(scale_x, scale_y); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window->layer()->SetTransform(in_transform); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!old_on_top) { 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The new layer is on top and should fade in. The old layer below will 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // stay opaque and block the desktop. 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window->layer()->SetOpacity(kWindowAnimation_HideOpacity); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Animate the new layer to the identity transform, so the window goes to 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // its newly set bounds. 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settings.SetTransitionDuration(duration); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settings.SetTweenType(tween_type); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window->layer()->SetTransform(gfx::Transform()); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!old_on_top) { 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // New layer is on top, fade it in. 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window->layer()->SetOpacity(kWindowAnimation_ShowOpacity); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return duration; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AnimateOnChildWindowVisibilityChanged(aura::Window* window, bool visible) { 397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (::wm::WindowAnimationsDisabled(window)) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Attempt to run CoreWm supplied animation types. 401a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (::wm::AnimateOnChildWindowVisibilityChanged(window, visible)) 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Otherwise try to run an Ash-specific animation. 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (visible) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AnimateShowWindow(window); 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Don't start hiding the window again if it's already being hidden. 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return window->layer()->GetTargetOpacity() != 0.0f && 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AnimateHideWindow(window); 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::vector<ui::LayerAnimationSequence*> 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CreateBrightnessGrayscaleAnimationSequence(float target_value, 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta duration) { 415d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) gfx::Tween::Type animation_type = gfx::Tween::EASE_OUT; 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ui::LayerAnimationSequence> brightness_sequence( 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new ui::LayerAnimationSequence()); 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ui::LayerAnimationSequence> grayscale_sequence( 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new ui::LayerAnimationSequence()); 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ui::LayerAnimationElement> brightness_element( 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::LayerAnimationElement::CreateBrightnessElement( 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target_value, duration)); 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) brightness_element->set_tween_type(animation_type); 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) brightness_sequence->AddElement(brightness_element.release()); 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ui::LayerAnimationElement> grayscale_element( 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::LayerAnimationElement::CreateGrayscaleElement( 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target_value, duration)); 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grayscale_element->set_tween_type(animation_type); 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grayscale_sequence->AddElement(grayscale_element.release()); 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<ui::LayerAnimationSequence*> animations; 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) animations.push_back(brightness_sequence.release()); 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) animations.push_back(grayscale_sequence.release()); 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return animations; 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns scale related to the specified AshWindowScaleType. 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SetTransformForScaleAnimation(ui::Layer* layer, 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerScaleAnimationDirection type) { 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const float scale = 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) type == LAYER_SCALE_ANIMATION_ABOVE ? kLayerScaleAboveSize : 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kLayerScaleBelowSize; 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Transform transform; 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) transform.Translate(-layer->bounds().width() * (scale - 1.0f) / 2, 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) -layer->bounds().height() * (scale - 1.0f) / 2); 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) transform.Scale(scale, scale); 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) layer->SetTransform(transform); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 453ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochgfx::Rect GetMinimizeAnimationTargetBoundsInScreen(aura::Window* window) { 4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Shelf* shelf = Shelf::ForWindow(window); 455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Shelf is created lazily and can be NULL. 4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!shelf) 457ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return gfx::Rect(); 4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Rect item_rect = shelf->GetScreenBoundsOfItemIconForWindow(window); 459ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 460ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // The launcher item is visible and has an icon. 461ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!item_rect.IsEmpty()) 462ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return item_rect; 463ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 464ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // If both the icon width and height are 0, then there is no icon in the 465cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // launcher for |window|. If the launcher is auto hidden, one of the height or 466cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // width will be 0 but the position in the launcher and the major dimension 467cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // are still reported correctly and the window can be animated to the launcher 468cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // item's light bar. 469cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ShelfLayoutManager* layout_manager = ShelfLayoutManager::ForShelf(window); 470ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (item_rect.width() != 0 || item_rect.height() != 0) { 471ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (layout_manager->visibility_state() == SHELF_AUTO_HIDE) { 4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Rect shelf_bounds = shelf->shelf_widget()->GetWindowBoundsInScreen(); 473ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch switch (layout_manager->GetAlignment()) { 474ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case SHELF_ALIGNMENT_BOTTOM: 475ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch item_rect.set_y(shelf_bounds.y()); 476ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 477ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case SHELF_ALIGNMENT_LEFT: 478ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch item_rect.set_x(shelf_bounds.right()); 479ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 480ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case SHELF_ALIGNMENT_RIGHT: 481ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch item_rect.set_x(shelf_bounds.x()); 482ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 483ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case SHELF_ALIGNMENT_TOP: 484ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch item_rect.set_y(shelf_bounds.bottom()); 485ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 486ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 487ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return item_rect; 488ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 489ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 490ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 491cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Coming here, there is no visible icon of that shelf item and we zoom back 492cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // to the location of the application launcher (which is fixed as first item 493cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // of the shelf). 494ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch gfx::Rect work_area = 495ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch Shell::GetScreen()->GetDisplayNearestWindow(window).work_area(); 496cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int ltr_adjusted_x = base::i18n::IsRTL() ? work_area.right() : work_area.x(); 497cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) switch (layout_manager->GetAlignment()) { 498cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SHELF_ALIGNMENT_BOTTOM: 499cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return gfx::Rect(ltr_adjusted_x, work_area.bottom(), 0, 0); 500cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SHELF_ALIGNMENT_TOP: 501cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return gfx::Rect(ltr_adjusted_x, work_area.y(), 0, 0); 502cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SHELF_ALIGNMENT_LEFT: 503cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return gfx::Rect(work_area.x(), work_area.y(), 0, 0); 504cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SHELF_ALIGNMENT_RIGHT: 505cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return gfx::Rect(work_area.right(), work_area.y(), 0, 0); 506cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 507cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NOTREACHED(); 508cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return gfx::Rect(); 509ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 510ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ash 512