Chromium Code Reviews| Index: ash/common/wm/overview/scoped_transform_overview_window.cc |
| diff --git a/ash/common/wm/overview/scoped_transform_overview_window.cc b/ash/common/wm/overview/scoped_transform_overview_window.cc |
| index 2c1b83e03db1ceca913f50dbcaf4c28b796baa39..9e735d7a1b28eb55bd4e70ac1529a2ef2831ad0c 100644 |
| --- a/ash/common/wm/overview/scoped_transform_overview_window.cc |
| +++ b/ash/common/wm/overview/scoped_transform_overview_window.cc |
| @@ -21,6 +21,7 @@ |
| #include "third_party/skia/include/core/SkPath.h" |
| #include "third_party/skia/include/core/SkRect.h" |
| #include "ui/compositor/layer.h" |
| +#include "ui/compositor/layer_animation_observer.h" |
| #include "ui/compositor/layer_delegate.h" |
| #include "ui/compositor/paint_recorder.h" |
| #include "ui/gfx/geometry/rect.h" |
| @@ -248,6 +249,86 @@ base::Closure ScopedTransformOverviewWindow::OverviewContentMask:: |
| return base::Closure(); |
| } |
| +// A class that hides the original window's header and optionally sets a mask |
| +// or a shape on the target to make the corners rounded. The header is hidden |
| +// once the animations complete. When not animating, the changes are done |
| +// immediately upon construction. |
| +class ScopedTransformOverviewWindow::OverviewWindowAnimationObserver |
| + : public ui::LayerAnimationObserver { |
| + public: |
| + OverviewWindowAnimationObserver( |
| + ScopedTransformOverviewWindow* window, |
| + bool animate, |
| + bool use_mask, |
| + bool use_shape, |
| + int radius, |
| + ScopedTransformOverviewWindow::OverviewContentMask* mask, |
| + SkRegion* original_window_shape) |
| + : window_(window), |
| + animate_(animate), |
| + use_mask_(use_mask), |
| + use_shape_(use_shape), |
| + radius_(radius), |
| + mask_(mask), |
| + original_window_shape_(original_window_shape) { |
| + if (animate_) { |
| + window_->window()->GetLayer()->GetAnimator()->AddObserver(this); |
| + return; |
| + } |
| + HideHeaderAndSetShape(); |
| + } |
| + |
| + ~OverviewWindowAnimationObserver() override { |
| + if (animate_) |
| + window_->window()->GetLayer()->GetAnimator()->RemoveObserver(this); |
| + } |
| + |
| + // ui::LayerAnimationObserver: |
| + void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override { |
| + window_->window()->GetLayer()->GetAnimator()->RemoveObserver(this); |
| + HideHeaderAndSetShape(); |
| + } |
| + |
| + void OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) override {} |
| + |
| + void OnLayerAnimationScheduled( |
| + ui::LayerAnimationSequence* sequence) override {} |
| + |
| + private: |
| + void HideHeaderAndSetShape() { |
| + gfx::Rect bounds(window_->GetTargetBoundsInScreen().size()); |
| + const int inset = (use_mask_ || use_shape_) ? window_->GetTopInset() : 0; |
| + if (mask_) { |
| + // Mask layer is used both to hide the window header and to use rounded |
| + // corners. Its layout needs to be update when setting a transform. |
|
bruthig
2016/08/30 17:57:32
spelling-nit: update->updated
|
| + mask_->layer()->SetBounds(bounds); |
| + mask_->set_inset(inset); |
| + mask_->set_radius(radius_); |
| + window_->window()->GetLayer()->SchedulePaint(bounds); |
| + } else if (inset > 0) { |
| + // Alpha shape is only used to to hide the window header and only when |
|
bruthig
2016/08/30 17:57:33
spelling-nit: "to to" -> "to"
|
| + // not using a mask layer. |
| + bounds.Inset(0, inset, 0, 0); |
| + SkRegion* region = new SkRegion; |
| + region->setRect(RectToSkIRect(bounds)); |
| + if (original_window_shape_) |
| + region->op(*original_window_shape_, SkRegion::kIntersect_Op); |
| + window_->window()->GetLayer()->SetAlphaShape(base::WrapUnique(region)); |
| + window_->window()->SetMasksToBounds(true); |
| + } |
| + } |
| + |
| + ScopedTransformOverviewWindow* window_; |
| + bool animate_; |
| + bool use_mask_; |
| + bool use_shape_; |
| + int radius_; |
| + ScopedTransformOverviewWindow::OverviewContentMask* mask_; |
| + SkRegion* original_window_shape_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(OverviewWindowAnimationObserver); |
| +}; |
| + |
| ScopedTransformOverviewWindow::ScopedTransformOverviewWindow(WmWindow* window) |
| : window_(window), |
| determined_original_window_shape_(false), |
| @@ -271,7 +352,8 @@ void ScopedTransformOverviewWindow::RestoreWindow() { |
| BeginScopedAnimation(OverviewAnimationType::OVERVIEW_ANIMATION_RESTORE_WINDOW, |
| &animation_settings_list); |
| SetTransform(window()->GetRootWindow(), original_transform_, |
| - false /* use_mask */, false /* use_shape */, 0); |
| + false /* use_mask */, false /* use_shape */, 0, |
| + true /* animate */); |
| std::unique_ptr<ScopedOverviewAnimationSettings> animation_settings = |
| CreateScopedOverviewAnimationSettings( |
| @@ -345,6 +427,9 @@ gfx::Rect ScopedTransformOverviewWindow::GetTargetBoundsInScreen() const { |
| gfx::Rect ScopedTransformOverviewWindow::GetTransformedBounds( |
| bool hide_header) const { |
| + if (window_->GetWindowState()->IsMinimized()) |
| + return window_->GetMinimizeAnimationTargetBoundsInScreen(); |
| + |
| const bool material = ash::MaterialDesignController::IsOverviewMaterial(); |
| const int top_inset = hide_header ? GetTopInset() : 0; |
| gfx::Rect bounds; |
| @@ -468,7 +553,8 @@ void ScopedTransformOverviewWindow::SetTransform( |
| const gfx::Transform& transform, |
| bool use_mask, |
| bool use_shape, |
| - float radius) { |
| + float radius, |
| + bool animate) { |
| DCHECK(overview_started_); |
| if (ash::MaterialDesignController::IsOverviewMaterial() && |
| @@ -484,26 +570,9 @@ void ScopedTransformOverviewWindow::SetTransform( |
| if (!original_window_shape_ && window_shape) |
| original_window_shape_.reset(new SkRegion(*window_shape)); |
| } |
| - gfx::Rect bounds(GetTargetBoundsInScreen().size()); |
| - const int inset = (use_mask || use_shape) ? GetTopInset() : 0; |
| - if (mask_) { |
| - // Mask layer is used both to hide the window header and to use rounded |
| - // corners. Its layout needs to be update when setting a transform. |
| - mask_->layer()->SetBounds(bounds); |
| - mask_->set_inset(inset); |
| - mask_->set_radius(radius); |
| - window()->GetLayer()->SchedulePaint(bounds); |
| - } else if (inset > 0) { |
| - // Alpha shape is only used to to hide the window header and only when |
| - // not using a mask layer. |
| - bounds.Inset(0, inset, 0, 0); |
| - SkRegion* region = new SkRegion; |
| - region->setRect(RectToSkIRect(bounds)); |
| - if (original_window_shape_) |
| - region->op(*original_window_shape_, SkRegion::kIntersect_Op); |
| - window()->GetLayer()->SetAlphaShape(base::WrapUnique(region)); |
| - window()->SetMasksToBounds(true); |
| - } |
| + animation_observer_.reset(new OverviewWindowAnimationObserver( |
| + this, animate, use_mask, use_shape, radius, mask_.get(), |
| + original_window_shape_.get())); |
| } |
| gfx::Point target_origin(GetTargetBoundsInScreen().origin()); |