12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/window_animations.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <math.h> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <algorithm> 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector> 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/compiler_specific.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 15ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h" 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/client/aura_constants.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/window.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/window_delegate.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/window_observer.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/window_property.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/compositor_observer.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/layer.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/layer_animation_observer.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/layer_animation_sequence.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/layer_animator.h" 2823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/compositor/layer_tree_owner.h" 295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/compositor/scoped_animation_duration_scale_mode.h" 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/scoped_layer_animation_settings.h" 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/animation/animation.h" 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/interpolated_transform.h" 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/rect_conversions.h" 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/screen.h" 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/gfx/vector2d.h" 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/vector3d_f.h" 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/window_util.h" 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/wm_core_switches.h" 39effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ui/wm/public/animation_host.h" 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DECLARE_WINDOW_PROPERTY_TYPE(int) 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)DECLARE_WINDOW_PROPERTY_TYPE(wm::WindowVisibilityAnimationType) 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)DECLARE_WINDOW_PROPERTY_TYPE(wm::WindowVisibilityAnimationTransition) 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DECLARE_WINDOW_PROPERTY_TYPE(float) 450529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochDECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(WM_EXPORT, bool) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace wm { 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const float kWindowAnimation_Vertical_TranslateY = 15.f; 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// A base class for hiding animation observer which has two roles: 5223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// 1) Notifies AnimationHost at the end of hiding animation. 5323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// 2) Detaches the window's layers for hiding animation and deletes 5423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// them upon completion of the animation. This is necessary to a) 5523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// ensure that the animation continues in the event of the window being 5623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// deleted, and b) to ensure that the animation is visible even if the 5723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// window gets restacked below other windows when focus or activation 5823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// changes. 59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// The subclass will determine when the animation is completed. 60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class HidingWindowAnimationObserverBase : public aura::WindowObserver { 6123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) public: 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch explicit HidingWindowAnimationObserverBase(aura::Window* window) 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : window_(window) { 64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) window_->AddObserver(this); 65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) virtual ~HidingWindowAnimationObserverBase() { 67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (window_) 68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) window_->RemoveObserver(this); 69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 7023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 7123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // aura::WindowObserver: 72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { 73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_EQ(window, window_); 74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) WindowInvalid(); 75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE { 78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_EQ(window, window_); 79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) WindowInvalid(); 80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 8123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 8223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Detach the current layers and create new layers for |window_|. 8323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Stack the original layers above |window_| and its transient 8423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // children. If the window has transient children, the original 8523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // layers will be moved above the top most transient child so that 8623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // activation change does not put the window above the animating 8723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // layer. 88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) void DetachAndRecreateLayers() { 89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) layer_owner_ = RecreateLayers(window_); 90010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (window_->parent()) { 91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const aura::Window::Windows& transient_children = 92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GetTransientChildren(window_); 93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) aura::Window::Windows::const_iterator iter = 94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::find(window_->parent()->children().begin(), 95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) window_->parent()->children().end(), 96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) window_); 97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(iter != window_->parent()->children().end()); 98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) aura::Window* topmost_transient_child = NULL; 99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (++iter; iter != window_->parent()->children().end(); ++iter) { 100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (std::find(transient_children.begin(), 101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) transient_children.end(), 102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) *iter) != transient_children.end()) { 103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) topmost_transient_child = *iter; 104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 106010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (topmost_transient_child) { 107010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) window_->parent()->layer()->StackAbove( 108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) layer_owner_->root(), topmost_transient_child->layer()); 109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 110010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) protected: 114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Invoked when the hiding animation is completed. It will delete 115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // 'this', and no operation should be made on this object after this 116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // point. 117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) void OnAnimationCompleted() { 118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Window may have been destroyed by this point. 119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (window_) { 120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) aura::client::AnimationHost* animation_host = 121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) aura::client::GetAnimationHost(window_); 122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (animation_host) 123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) animation_host->OnWindowHidingAnimationCompleted(); 124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) window_->RemoveObserver(this); 125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) delete this; 127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 12823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 12923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) private: 130e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Invoked when the window is destroyed (or destroying). 131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) void WindowInvalid() { 132010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) layer_owner_->root()->SuppressPaint(); 133010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 134010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) window_->RemoveObserver(this); 135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) window_ = NULL; 136010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 137e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 13823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) aura::Window* window_; 13923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 14023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // The owner of detached layers. 14123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_ptr<ui::LayerTreeOwner> layer_owner_; 14223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 143010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(HidingWindowAnimationObserverBase); 144010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}; 145010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 146010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} // namespace 147010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 148010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)DEFINE_WINDOW_PROPERTY_KEY(int, 149010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) kWindowVisibilityAnimationTypeKey, 150010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) WINDOW_VISIBILITY_ANIMATION_TYPE_DEFAULT); 151010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)DEFINE_WINDOW_PROPERTY_KEY(int, kWindowVisibilityAnimationDurationKey, 0); 152010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)DEFINE_WINDOW_PROPERTY_KEY(WindowVisibilityAnimationTransition, 153010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) kWindowVisibilityAnimationTransitionKey, 154010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ANIMATE_BOTH); 155010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)DEFINE_WINDOW_PROPERTY_KEY(float, 156010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) kWindowVisibilityAnimationVerticalPositionKey, 157010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) kWindowAnimation_Vertical_TranslateY); 158010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 159010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// A HidingWindowAnimationObserver that deletes observer and detached 160010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// layers upon the completion of the implicit animation. 161010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class ImplicitHidingWindowAnimationObserver 162010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : public HidingWindowAnimationObserverBase, 163010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) public ui::ImplicitAnimationObserver { 164010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) public: 165010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ImplicitHidingWindowAnimationObserver( 166010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) aura::Window* window, 167010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::ScopedLayerAnimationSettings* settings); 168010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) virtual ~ImplicitHidingWindowAnimationObserver() {} 169010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 170010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // ui::ImplicitAnimationObserver: 171010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) virtual void OnImplicitAnimationsCompleted() OVERRIDE; 172010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 173010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private: 174010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ImplicitHidingWindowAnimationObserver); 17523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}; 17623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kDefaultAnimationDurationForMenuMS = 150; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const float kWindowAnimation_HideOpacity = 0.f; 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const float kWindowAnimation_ShowOpacity = 1.f; 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const float kWindowAnimation_TranslateFactor = 0.5f; 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const float kWindowAnimation_ScaleFactor = .95f; 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kWindowAnimation_Rotate_DurationMS = 180; 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kWindowAnimation_Rotate_OpacityDurationPercent = 90; 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const float kWindowAnimation_Rotate_TranslateY = -20.f; 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const float kWindowAnimation_Rotate_PerspectiveDepth = 500.f; 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const float kWindowAnimation_Rotate_DegreesX = 5.f; 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const float kWindowAnimation_Rotate_ScaleFactor = .99f; 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const float kWindowAnimation_Bounce_Scale = 1.02f; 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kWindowAnimation_Bounce_DurationMS = 180; 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kWindowAnimation_Bounce_GrowShrinkDurationPercent = 40; 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::TimeDelta GetWindowVisibilityAnimationDuration( 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const aura::Window& window) { 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int duration = 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) window.GetProperty(kWindowVisibilityAnimationDurationKey); 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (duration == 0 && window.type() == ui::wm::WINDOW_TYPE_MENU) { 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::TimeDelta::FromMilliseconds( 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kDefaultAnimationDurationForMenuMS); 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 20523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return base::TimeDelta::FromInternalValue(duration); 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Gets/sets the WindowVisibilityAnimationType associated with a window. 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(beng): redundant/fold into method on public api? 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int GetWindowVisibilityAnimationType(aura::Window* window) { 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int type = window->GetProperty(kWindowVisibilityAnimationTypeKey); 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (type == WINDOW_VISIBILITY_ANIMATION_TYPE_DEFAULT) { 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return (window->type() == ui::wm::WINDOW_TYPE_MENU || 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) window->type() == ui::wm::WINDOW_TYPE_TOOLTIP) 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ? WINDOW_VISIBILITY_ANIMATION_TYPE_FADE 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : WINDOW_VISIBILITY_ANIMATION_TYPE_DROP; 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return type; 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GetTransformRelativeToRoot(ui::Layer* layer, gfx::Transform* transform) { 22223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const ui::Layer* root = layer; 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (root->parent()) 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root = root->parent(); 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) layer->GetTargetTransformRelativeTo(root, transform); 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Rect GetLayerWorldBoundsAfterTransform(ui::Layer* layer, 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Transform& transform) { 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Transform in_world = transform; 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetTransformRelativeToRoot(layer, &in_world); 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::RectF transformed = layer->bounds(); 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) in_world.TransformRect(&transformed); 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return gfx::ToEnclosingRect(transformed); 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Augment the host window so that the enclosing bounds of the full 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// animation will fit inside of it. 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AugmentWindowSize(aura::Window* window, 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Transform& end_transform) { 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::client::AnimationHost* animation_host = 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::client::GetAnimationHost(window); 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!animation_host) 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const gfx::Rect& world_at_start = window->bounds(); 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect world_at_end = 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetLayerWorldBoundsAfterTransform(window->layer(), end_transform); 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect union_in_window_space = 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::UnionRects(world_at_start, world_at_end); 2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Calculate the top left and bottom right deltas to be added to the window 2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // bounds. 2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) gfx::Vector2d top_left_delta(world_at_start.x() - union_in_window_space.x(), 2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) world_at_start.y() - union_in_window_space.y()); 2584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) gfx::Vector2d bottom_right_delta( 2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) union_in_window_space.x() + union_in_window_space.width() - 2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) (world_at_start.x() + world_at_start.width()), 2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) union_in_window_space.y() + union_in_window_space.height() - 2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) (world_at_start.y() + world_at_start.height())); 2644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(top_left_delta.x() >= 0 && top_left_delta.y() >= 0 && 2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bottom_right_delta.x() >= 0 && bottom_right_delta.y() >= 0); 2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) animation_host->SetHostTransitionOffsets(top_left_delta, bottom_right_delta); 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Shows a window using an animation, animating its opacity from 0.f to 1.f, 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// its visibility to true, and its transform from |start_transform| to 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |end_transform|. 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AnimateShowWindowCommon(aura::Window* window, 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Transform& start_transform, 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Transform& end_transform) { 2774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AugmentWindowSize(window, end_transform); 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window->layer()->SetOpacity(kWindowAnimation_HideOpacity); 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window->layer()->SetTransform(start_transform); 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window->layer()->SetVisible(true); 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Property sets within this scope will be implicitly animated. 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta duration = GetWindowVisibilityAnimationDuration(*window); 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (duration.ToInternalValue() > 0) 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) settings.SetTransitionDuration(duration); 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window->layer()->SetTransform(end_transform); 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window->layer()->SetOpacity(kWindowAnimation_ShowOpacity); 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Hides a window using an animation, animating its opacity from 1.f to 0.f, 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// its visibility to false, and its transform to |end_transform|. 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AnimateHideWindowCommon(aura::Window* window, 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Transform& end_transform) { 2994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AugmentWindowSize(window, end_transform); 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Property sets within this scope will be implicitly animated. 30223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ScopedHidingAnimationSettings hiding_settings(window); 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta duration = GetWindowVisibilityAnimationDuration(*window); 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (duration.ToInternalValue() > 0) 30523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) hiding_settings.layer_animation_settings()->SetTransitionDuration(duration); 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window->layer()->SetOpacity(kWindowAnimation_HideOpacity); 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window->layer()->SetTransform(end_transform); 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window->layer()->SetVisible(false); 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static gfx::Transform GetScaleForWindow(aura::Window* window) { 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect bounds = window->bounds(); 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Transform scale = gfx::GetScaleTransform( 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Point(kWindowAnimation_TranslateFactor * bounds.width(), 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kWindowAnimation_TranslateFactor * bounds.height()), 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kWindowAnimation_ScaleFactor); 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return scale; 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Show/Hide windows using a shrink animation. 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AnimateShowWindow_Drop(aura::Window* window) { 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AnimateShowWindowCommon(window, GetScaleForWindow(window), gfx::Transform()); 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AnimateHideWindow_Drop(aura::Window* window) { 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AnimateHideWindowCommon(window, GetScaleForWindow(window)); 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Show/Hide windows using a vertical Glenimation. 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AnimateShowWindow_Vertical(aura::Window* window) { 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Transform transform; 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) transform.Translate(0, window->GetProperty( 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kWindowVisibilityAnimationVerticalPositionKey)); 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AnimateShowWindowCommon(window, transform, gfx::Transform()); 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AnimateHideWindow_Vertical(aura::Window* window) { 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Transform transform; 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) transform.Translate(0, window->GetProperty( 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kWindowVisibilityAnimationVerticalPositionKey)); 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AnimateHideWindowCommon(window, transform); 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Show/Hide windows using a fade. 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AnimateShowWindow_Fade(aura::Window* window) { 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AnimateShowWindowCommon(window, gfx::Transform(), gfx::Transform()); 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AnimateHideWindow_Fade(aura::Window* window) { 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AnimateHideWindowCommon(window, gfx::Transform()); 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ui::LayerAnimationElement* CreateGrowShrinkElement( 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::Window* window, bool grow) { 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ui::InterpolatedTransform> scale(new ui::InterpolatedScale( 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Point3F(kWindowAnimation_Bounce_Scale, 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kWindowAnimation_Bounce_Scale, 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1), 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Point3F(1, 1, 1))); 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ui::InterpolatedTransform> scale_about_pivot( 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new ui::InterpolatedTransformAboutPivot( 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Point(window->bounds().width() * 0.5, 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window->bounds().height() * 0.5), 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scale.release())); 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scale_about_pivot->SetReversed(grow); 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ui::LayerAnimationElement> transition( 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::LayerAnimationElement::CreateInterpolatedTransformElement( 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scale_about_pivot.release(), 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta::FromMilliseconds( 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kWindowAnimation_Bounce_DurationMS * 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kWindowAnimation_Bounce_GrowShrinkDurationPercent / 100))); 373d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) transition->set_tween_type(grow ? gfx::Tween::EASE_OUT : gfx::Tween::EASE_IN); 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return transition.release(); 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AnimateBounce(aura::Window* window) { 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::ScopedLayerAnimationSettings scoped_settings( 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window->layer()->GetAnimator()); 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_settings.SetPreemptionStrategy( 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS); 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ui::LayerAnimationSequence> sequence( 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new ui::LayerAnimationSequence); 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sequence->AddElement(CreateGrowShrinkElement(window, true)); 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sequence->AddElement(ui::LayerAnimationElement::CreatePauseElement( 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui::LayerAnimationElement::BOUNDS, 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta::FromMilliseconds( 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kWindowAnimation_Bounce_DurationMS * 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (100 - 2 * kWindowAnimation_Bounce_GrowShrinkDurationPercent) / 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 100))); 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sequence->AddElement(CreateGrowShrinkElement(window, false)); 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window->layer()->GetAnimator()->StartAnimation(sequence.release()); 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 395010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// A HidingWindowAnimationObserver that deletes observer and detached 396010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// layers when the last_sequence has been completed or aborted. 397010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class RotateHidingWindowAnimationObserver 398010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : public HidingWindowAnimationObserverBase, 399010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) public ui::LayerAnimationObserver { 400010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) public: 401116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch explicit RotateHidingWindowAnimationObserver(aura::Window* window) 402116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : HidingWindowAnimationObserverBase(window) {} 403010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) virtual ~RotateHidingWindowAnimationObserver() {} 404010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 405116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Destroys itself after |last_sequence| ends or is aborted. Does not take 406116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // ownership of |last_sequence|, which should not be NULL. 407116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void SetLastSequence(ui::LayerAnimationSequence* last_sequence) { 408116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch last_sequence->AddObserver(this); 409010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 410010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 411010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // ui::LayerAnimationObserver: 412010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) virtual void OnLayerAnimationEnded( 413010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::LayerAnimationSequence* sequence) OVERRIDE { 414116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch OnAnimationCompleted(); 415010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 416010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) virtual void OnLayerAnimationAborted( 417010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::LayerAnimationSequence* sequence) OVERRIDE { 418116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch OnAnimationCompleted(); 419010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 420010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) virtual void OnLayerAnimationScheduled( 421010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::LayerAnimationSequence* sequence) OVERRIDE {} 422010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 423010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private: 424010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(RotateHidingWindowAnimationObserver); 425010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}; 426010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AddLayerAnimationsForRotate(aura::Window* window, bool show) { 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (show) 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window->layer()->SetOpacity(kWindowAnimation_HideOpacity); 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta duration = base::TimeDelta::FromMilliseconds( 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kWindowAnimation_Rotate_DurationMS); 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 434010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RotateHidingWindowAnimationObserver* observer = NULL; 43523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!show) { 437010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) observer = new RotateHidingWindowAnimationObserver(window); 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window->layer()->GetAnimator()->SchedulePauseForProperties( 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) duration * (100 - kWindowAnimation_Rotate_OpacityDurationPercent) / 100, 4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui::LayerAnimationElement::OPACITY); 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ui::LayerAnimationElement> opacity( 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::LayerAnimationElement::CreateOpacityElement( 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) show ? kWindowAnimation_ShowOpacity : kWindowAnimation_HideOpacity, 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) duration * kWindowAnimation_Rotate_OpacityDurationPercent / 100)); 446d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) opacity->set_tween_type(gfx::Tween::EASE_IN_OUT); 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window->layer()->GetAnimator()->ScheduleAnimation( 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new ui::LayerAnimationSequence(opacity.release())); 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) float xcenter = window->bounds().width() * 0.5; 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Transform transform; 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) transform.Translate(xcenter, 0); 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) transform.ApplyPerspectiveDepth(kWindowAnimation_Rotate_PerspectiveDepth); 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) transform.Translate(-xcenter, 0); 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ui::InterpolatedTransform> perspective( 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new ui::InterpolatedConstantTransform(transform)); 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ui::InterpolatedTransform> scale( 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new ui::InterpolatedScale(1, kWindowAnimation_Rotate_ScaleFactor)); 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ui::InterpolatedTransform> scale_about_pivot( 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new ui::InterpolatedTransformAboutPivot( 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Point(xcenter, kWindowAnimation_Rotate_TranslateY), 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scale.release())); 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ui::InterpolatedTransform> translation( 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new ui::InterpolatedTranslation(gfx::Point(), gfx::Point( 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 0, kWindowAnimation_Rotate_TranslateY))); 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ui::InterpolatedTransform> rotation( 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new ui::InterpolatedAxisAngleRotation( 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector3dF(1, 0, 0), 0, kWindowAnimation_Rotate_DegreesX)); 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scale_about_pivot->SetChild(perspective.release()); 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) translation->SetChild(scale_about_pivot.release()); 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rotation->SetChild(translation.release()); 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rotation->SetReversed(show); 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ui::LayerAnimationElement> transition( 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::LayerAnimationElement::CreateInterpolatedTransformElement( 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rotation.release(), duration)); 482010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::LayerAnimationSequence* last_sequence = 483010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) new ui::LayerAnimationSequence(transition.release()); 484010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) window->layer()->GetAnimator()->ScheduleAnimation(last_sequence); 485116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 486010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (observer) { 487116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch observer->SetLastSequence(last_sequence); 48823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) observer->DetachAndRecreateLayers(); 489010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AnimateShowWindow_Rotate(aura::Window* window) { 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddLayerAnimationsForRotate(window, true); 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AnimateHideWindow_Rotate(aura::Window* window) { 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddLayerAnimationsForRotate(window, false); 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool AnimateShowWindow(aura::Window* window) { 50190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!HasWindowVisibilityAnimationTransition(window, ANIMATE_SHOW)) { 50290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (HasWindowVisibilityAnimationTransition(window, ANIMATE_HIDE)) { 50390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Since hide animation may have changed opacity and transform, 50490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // reset them to show the window. 50590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) window->layer()->SetOpacity(kWindowAnimation_ShowOpacity); 50690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) window->layer()->SetTransform(gfx::Transform()); 50790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 50990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (GetWindowVisibilityAnimationType(window)) { 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WINDOW_VISIBILITY_ANIMATION_TYPE_DROP: 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AnimateShowWindow_Drop(window); 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL: 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AnimateShowWindow_Vertical(window); 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WINDOW_VISIBILITY_ANIMATION_TYPE_FADE: 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AnimateShowWindow_Fade(window); 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WINDOW_VISIBILITY_ANIMATION_TYPE_ROTATE: 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AnimateShowWindow_Rotate(window); 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool AnimateHideWindow(aura::Window* window) { 53090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!HasWindowVisibilityAnimationTransition(window, ANIMATE_HIDE)) { 53190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (HasWindowVisibilityAnimationTransition(window, ANIMATE_SHOW)) { 53290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Since show animation may have changed opacity and transform, 53390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // reset them, though the change should be hidden. 53490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) window->layer()->SetOpacity(kWindowAnimation_HideOpacity); 53590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) window->layer()->SetTransform(gfx::Transform()); 53690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 53890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (GetWindowVisibilityAnimationType(window)) { 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WINDOW_VISIBILITY_ANIMATION_TYPE_DROP: 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AnimateHideWindow_Drop(window); 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL: 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AnimateHideWindow_Vertical(window); 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WINDOW_VISIBILITY_ANIMATION_TYPE_FADE: 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AnimateHideWindow_Fade(window); 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WINDOW_VISIBILITY_ANIMATION_TYPE_ROTATE: 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AnimateHideWindow_Rotate(window); 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 561010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// ImplicitHidingWindowAnimationObserver 56223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 563010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ImplicitHidingWindowAnimationObserver::ImplicitHidingWindowAnimationObserver( 56423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) aura::Window* window, 56523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ui::ScopedLayerAnimationSettings* settings) 566010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : HidingWindowAnimationObserverBase(window) { 567010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) settings->AddObserver(this); 56823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 56923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 570010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ImplicitHidingWindowAnimationObserver::OnImplicitAnimationsCompleted() { 571010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) OnAnimationCompleted(); 572e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 573e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 57423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 57523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// ScopedHidingAnimationSettings 57623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 57723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)ScopedHidingAnimationSettings::ScopedHidingAnimationSettings( 57823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) aura::Window* window) 57923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) : layer_animation_settings_(window->layer()->GetAnimator()), 580010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) observer_(new ImplicitHidingWindowAnimationObserver( 581010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) window, 582010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) &layer_animation_settings_)) { 58323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 58423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 58523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)ScopedHidingAnimationSettings::~ScopedHidingAnimationSettings() { 58623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) observer_->DetachAndRecreateLayers(); 58723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 58823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 58923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// External interface 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SetWindowVisibilityAnimationType(aura::Window* window, int type) { 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window->SetProperty(kWindowVisibilityAnimationTypeKey, type); 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int GetWindowVisibilityAnimationType(aura::Window* window) { 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return window->GetProperty(kWindowVisibilityAnimationTypeKey); 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SetWindowVisibilityAnimationTransition( 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::Window* window, 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WindowVisibilityAnimationTransition transition) { 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window->SetProperty(kWindowVisibilityAnimationTransitionKey, transition); 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool HasWindowVisibilityAnimationTransition( 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::Window* window, 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WindowVisibilityAnimationTransition transition) { 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WindowVisibilityAnimationTransition prop = window->GetProperty( 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kWindowVisibilityAnimationTransitionKey); 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (prop & transition) != 0; 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SetWindowVisibilityAnimationDuration(aura::Window* window, 61523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const base::TimeDelta& duration) { 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window->SetProperty(kWindowVisibilityAnimationDurationKey, 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<int>(duration.ToInternalValue())); 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::TimeDelta GetWindowVisibilityAnimationDuration( 6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const aura::Window& window) { 6225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return base::TimeDelta::FromInternalValue( 6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) window.GetProperty(kWindowVisibilityAnimationDurationKey)); 6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 6255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SetWindowVisibilityAnimationVerticalPosition(aura::Window* window, 6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) float position) { 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window->SetProperty(kWindowVisibilityAnimationVerticalPositionKey, position); 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool AnimateOnChildWindowVisibilityChanged(aura::Window* window, bool visible) { 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (WindowAnimationsDisabled(window)) 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (visible) 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return AnimateShowWindow(window); 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Don't start hiding the window again if it's already being hidden. 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return window->layer()->GetTargetOpacity() != 0.0f && 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AnimateHideWindow(window); 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool AnimateWindow(aura::Window* window, WindowAnimationType type) { 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (type) { 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WINDOW_ANIMATION_TYPE_BOUNCE: 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AnimateBounce(window); 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool WindowAnimationsDisabled(aura::Window* window) { 6535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Individual windows can choose to skip animations. 6545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (window && window->GetProperty(aura::client::kAnimationsDisabledKey)) 6555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return true; 6565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 6575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Animations can be disabled globally for testing. 6585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (CommandLine::ForCurrentProcess()->HasSwitch( 6595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) switches::kWindowAnimationsDisabled)) 6605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return true; 6615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 6625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Tests of animations themselves should still run even if the machine is 6635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // being accessed via Remote Desktop. 6645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (ui::ScopedAnimationDurationScaleMode::duration_scale_mode() == 6655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION) 6665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 6675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 6685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Let the user decide whether or not to play the animation. 6695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return !gfx::Animation::ShouldRenderRichAnimation(); 6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 672a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace wm 673