Chromium Code Reviews| Index: ui/views/corewm/window_animations.cc |
| diff --git a/ui/views/corewm/window_animations.cc b/ui/views/corewm/window_animations.cc |
| index c7c86913b3e0e729039a1461cfaf9f94c8deca2a..7c2ebe6002a7c284dd539a58652f9d137b619c48 100644 |
| --- a/ui/views/corewm/window_animations.cc |
| +++ b/ui/views/corewm/window_animations.cc |
| @@ -17,6 +17,7 @@ |
| #include "base/time.h" |
| #include "ui/aura/client/aura_constants.h" |
| #include "ui/aura/window.h" |
| +#include "ui/aura/window_delegate.h" |
| #include "ui/aura/window_observer.h" |
| #include "ui/aura/window_property.h" |
| #include "ui/compositor/compositor_observer.h" |
| @@ -26,6 +27,7 @@ |
| #include "ui/compositor/layer_animator.h" |
| #include "ui/compositor/scoped_layer_animation_settings.h" |
| #include "ui/gfx/interpolated_transform.h" |
| +#include "ui/gfx/rect_conversions.h" |
| #include "ui/gfx/screen.h" |
| #include "ui/gfx/vector3d_f.h" |
| #include "ui/views/corewm/corewm_switches.h" |
| @@ -130,8 +132,11 @@ class HidingWindowAnimationObserver : public ui::ImplicitAnimationObserver, |
| // Overridden from ui::ImplicitAnimationObserver: |
| virtual void OnImplicitAnimationsCompleted() OVERRIDE { |
| // Window may have been destroyed by this point. |
| - if (window_) |
| + if (window_) { |
| + if (window_->delegate()) |
| + window_->delegate()->OnWindowHidingAnimationCompleted(); |
|
sky
2013/03/14 20:06:37
Add a test for coverage of this.
scottmg
2013/03/14 22:51:53
ui/views/corewm/window_animations_unittest.cc wasn
|
| window_->RemoveObserver(this); |
| + } |
| delete this; |
| } |
| @@ -179,6 +184,50 @@ class HidingWindowAnimationObserver : public ui::ImplicitAnimationObserver, |
| DISALLOW_COPY_AND_ASSIGN(HidingWindowAnimationObserver); |
| }; |
| +void GetTransformRelativeToRoot(ui::Layer* layer, gfx::Transform* transform) { |
| + const Layer* p = layer; |
|
sky
2013/03/14 20:06:37
This use Layer::GetTargetTransformRelativeTo (that
scottmg
2013/03/14 22:51:53
Done.
|
| + for (; p->parent(); p = p->parent()) { |
| + gfx::Transform translation; |
| + translation.Translate(static_cast<float>(p->bounds().x()), |
| + static_cast<float>(p->bounds().y())); |
| + // Use target transform so that result will be correct once animation is |
| + // finished. |
| + if (!p->GetTargetTransform().IsIdentity()) |
| + transform->ConcatTransform(p->GetTargetTransform()); |
| + transform->ConcatTransform(translation); |
| + } |
| +} |
| +gfx::Rect GetLayerWorldBoundsAfterTransform(ui::Layer* layer, |
|
sky
2013/03/14 20:06:37
nit: newline between 199/200.
scottmg
2013/03/14 22:51:53
Done.
|
| + const gfx::Transform& transform) { |
| + gfx::Transform in_world = transform; |
| + GetTransformRelativeToRoot(layer, &in_world); |
| + |
| + gfx::RectF transformed = layer->bounds(); |
| + transform.TransformRect(&transformed); |
| + |
| + return gfx::ToEnclosingRect(transformed); |
| +} |
| + |
| +// Augment the host window so that the enclosing bounds of the full |
| +// animation will fit inside of it. |
| +void AugmentWindowSize(aura::Window* window, |
| + const gfx::Transform& start_transform, |
| + const gfx::Transform& end_transform) { |
| + gfx::Rect world_at_start = |
| + GetLayerWorldBoundsAfterTransform(window->layer(), start_transform); |
| + gfx::Rect world_at_end = |
| + GetLayerWorldBoundsAfterTransform(window->layer(), end_transform); |
| + gfx::Rect union_in_window_space = |
| + gfx::UnionRects(world_at_start, world_at_end); |
| + gfx::Rect current_bounds = window->bounds(); |
| + gfx::Rect result(union_in_window_space.x() - current_bounds.x(), |
| + union_in_window_space.y() - current_bounds.y(), |
| + union_in_window_space.width() - current_bounds.width(), |
| + union_in_window_space.height() - current_bounds.height()); |
| + if (window->delegate()) |
| + window->delegate()->SetHostTransitionBounds(result); |
| +} |
| + |
| // Shows a window using an animation, animating its opacity from 0.f to 1.f, |
| // its visibility to true, and its transform from |start_transform| to |
| // |end_transform|. |
| @@ -186,6 +235,9 @@ void AnimateShowWindowCommon(aura::Window* window, |
| const gfx::Transform& start_transform, |
| const gfx::Transform& end_transform) { |
| window->layer()->set_delegate(window); |
| + |
| + AugmentWindowSize(window, start_transform, end_transform); |
|
sky
2013/03/14 20:06:37
Don't we only need to do this for some windows? Fo
scottmg
2013/03/14 22:51:53
That's right. It's ignored by the delegate in thos
|
| + |
| window->layer()->SetOpacity(kWindowAnimation_HideOpacity); |
| window->layer()->SetTransform(start_transform); |
| window->layer()->SetVisible(true); |
| @@ -196,7 +248,6 @@ void AnimateShowWindowCommon(aura::Window* window, |
| base::TimeDelta duration = GetWindowVisibilityAnimationDuration(window); |
| if (duration.ToInternalValue() > 0) |
| settings.SetTransitionDuration(duration); |
| - |
| window->layer()->SetTransform(end_transform); |
| window->layer()->SetOpacity(kWindowAnimation_ShowOpacity); |
| } |
| @@ -206,6 +257,7 @@ void AnimateShowWindowCommon(aura::Window* window, |
| // its visibility to false, and its transform to |end_transform|. |
| void AnimateHideWindowCommon(aura::Window* window, |
| const gfx::Transform& end_transform) { |
| + AugmentWindowSize(window, gfx::Transform(), end_transform); |
| window->layer()->set_delegate(NULL); |
| // Property sets within this scope will be implicitly animated. |
| @@ -215,7 +267,6 @@ void AnimateHideWindowCommon(aura::Window* window, |
| base::TimeDelta duration = GetWindowVisibilityAnimationDuration(window); |
| if (duration.ToInternalValue() > 0) |
| settings.SetTransitionDuration(duration); |
| - |
| window->layer()->SetOpacity(kWindowAnimation_HideOpacity); |
| window->layer()->SetTransform(end_transform); |
| window->layer()->SetVisible(false); |