OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/common/wm/overview/scoped_transform_overview_window.h" | 5 #include "ash/common/wm/overview/scoped_transform_overview_window.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "ash/common/material_design/material_design_controller.h" | 10 #include "ash/common/material_design/material_design_controller.h" |
11 #include "ash/common/wm/overview/scoped_overview_animation_settings.h" | 11 #include "ash/common/wm/overview/scoped_overview_animation_settings.h" |
12 #include "ash/common/wm/overview/scoped_overview_animation_settings_factory.h" | 12 #include "ash/common/wm/overview/scoped_overview_animation_settings_factory.h" |
13 #include "ash/common/wm/overview/window_selector_item.h" | 13 #include "ash/common/wm/overview/window_selector_item.h" |
14 #include "ash/common/wm/window_state.h" | 14 #include "ash/common/wm/window_state.h" |
15 #include "ash/common/wm_window.h" | 15 #include "ash/common/wm_window.h" |
16 #include "ash/common/wm_window_property.h" | 16 #include "ash/common/wm_window_property.h" |
17 #include "base/macros.h" | 17 #include "base/macros.h" |
18 #include "base/single_thread_task_runner.h" | 18 #include "base/single_thread_task_runner.h" |
19 #include "base/threading/thread_task_runner_handle.h" | 19 #include "base/threading/thread_task_runner_handle.h" |
20 #include "third_party/skia/include/core/SkPaint.h" | 20 #include "third_party/skia/include/core/SkPaint.h" |
21 #include "third_party/skia/include/core/SkPath.h" | 21 #include "third_party/skia/include/core/SkPath.h" |
22 #include "third_party/skia/include/core/SkRect.h" | 22 #include "third_party/skia/include/core/SkRect.h" |
23 #include "ui/compositor/layer.h" | 23 #include "ui/compositor/layer.h" |
24 #include "ui/compositor/layer_animation_observer.h" | |
24 #include "ui/compositor/layer_delegate.h" | 25 #include "ui/compositor/layer_delegate.h" |
25 #include "ui/compositor/paint_recorder.h" | 26 #include "ui/compositor/paint_recorder.h" |
26 #include "ui/gfx/geometry/rect.h" | 27 #include "ui/gfx/geometry/rect.h" |
27 #include "ui/gfx/geometry/safe_integer_conversions.h" | 28 #include "ui/gfx/geometry/safe_integer_conversions.h" |
28 #include "ui/gfx/transform_util.h" | 29 #include "ui/gfx/transform_util.h" |
29 | 30 |
30 using WmWindows = std::vector<ash::WmWindow*>; | 31 using WmWindows = std::vector<ash::WmWindow*>; |
31 | 32 |
32 namespace ash { | 33 namespace ash { |
33 | 34 |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
241 void ScopedTransformOverviewWindow::OverviewContentMask:: | 242 void ScopedTransformOverviewWindow::OverviewContentMask:: |
242 OnDeviceScaleFactorChanged(float device_scale_factor) { | 243 OnDeviceScaleFactorChanged(float device_scale_factor) { |
243 // Redrawing will take care of scale factor change. | 244 // Redrawing will take care of scale factor change. |
244 } | 245 } |
245 | 246 |
246 base::Closure ScopedTransformOverviewWindow::OverviewContentMask:: | 247 base::Closure ScopedTransformOverviewWindow::OverviewContentMask:: |
247 PrepareForLayerBoundsChange() { | 248 PrepareForLayerBoundsChange() { |
248 return base::Closure(); | 249 return base::Closure(); |
249 } | 250 } |
250 | 251 |
252 // A class that hides the original window's header and optionally sets a mask | |
253 // or a shape on the target to make the corners rounded. The header is hidden | |
254 // once the animations complete. When not animating, the changes are done | |
255 // immediately upon construction. | |
256 class ScopedTransformOverviewWindow::OverviewWindowAnimationObserver | |
257 : public ui::LayerAnimationObserver { | |
258 public: | |
259 OverviewWindowAnimationObserver( | |
260 ScopedTransformOverviewWindow* window, | |
261 bool animate, | |
262 bool use_mask, | |
263 bool use_shape, | |
264 int radius, | |
265 ScopedTransformOverviewWindow::OverviewContentMask* mask, | |
266 SkRegion* original_window_shape) | |
267 : window_(window), | |
268 animate_(animate), | |
269 use_mask_(use_mask), | |
270 use_shape_(use_shape), | |
271 radius_(radius), | |
272 mask_(mask), | |
273 original_window_shape_(original_window_shape) { | |
274 if (animate_) { | |
275 window_->window()->GetLayer()->GetAnimator()->AddObserver(this); | |
276 return; | |
277 } | |
278 HideHeaderAndSetShape(); | |
279 } | |
280 | |
281 ~OverviewWindowAnimationObserver() override { | |
282 if (animate_) | |
283 window_->window()->GetLayer()->GetAnimator()->RemoveObserver(this); | |
284 } | |
285 | |
286 // ui::LayerAnimationObserver: | |
287 void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override { | |
288 window_->window()->GetLayer()->GetAnimator()->RemoveObserver(this); | |
289 HideHeaderAndSetShape(); | |
290 } | |
291 | |
292 void OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) override {} | |
293 | |
294 void OnLayerAnimationScheduled( | |
295 ui::LayerAnimationSequence* sequence) override {} | |
296 | |
297 private: | |
298 void HideHeaderAndSetShape() { | |
299 gfx::Rect bounds(window_->GetTargetBoundsInScreen().size()); | |
300 const int inset = (use_mask_ || use_shape_) ? window_->GetTopInset() : 0; | |
301 if (mask_) { | |
302 // Mask layer is used both to hide the window header and to use rounded | |
303 // corners. Its layout needs to be update when setting a transform. | |
bruthig
2016/08/30 17:57:32
spelling-nit: update->updated
| |
304 mask_->layer()->SetBounds(bounds); | |
305 mask_->set_inset(inset); | |
306 mask_->set_radius(radius_); | |
307 window_->window()->GetLayer()->SchedulePaint(bounds); | |
308 } else if (inset > 0) { | |
309 // 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"
| |
310 // not using a mask layer. | |
311 bounds.Inset(0, inset, 0, 0); | |
312 SkRegion* region = new SkRegion; | |
313 region->setRect(RectToSkIRect(bounds)); | |
314 if (original_window_shape_) | |
315 region->op(*original_window_shape_, SkRegion::kIntersect_Op); | |
316 window_->window()->GetLayer()->SetAlphaShape(base::WrapUnique(region)); | |
317 window_->window()->SetMasksToBounds(true); | |
318 } | |
319 } | |
320 | |
321 ScopedTransformOverviewWindow* window_; | |
322 bool animate_; | |
323 bool use_mask_; | |
324 bool use_shape_; | |
325 int radius_; | |
326 ScopedTransformOverviewWindow::OverviewContentMask* mask_; | |
327 SkRegion* original_window_shape_; | |
328 | |
329 DISALLOW_COPY_AND_ASSIGN(OverviewWindowAnimationObserver); | |
330 }; | |
331 | |
251 ScopedTransformOverviewWindow::ScopedTransformOverviewWindow(WmWindow* window) | 332 ScopedTransformOverviewWindow::ScopedTransformOverviewWindow(WmWindow* window) |
252 : window_(window), | 333 : window_(window), |
253 determined_original_window_shape_(false), | 334 determined_original_window_shape_(false), |
254 original_visibility_( | 335 original_visibility_( |
255 window->GetWindowState()->GetStateType() == | 336 window->GetWindowState()->GetStateType() == |
256 wm::WINDOW_STATE_TYPE_DOCKED_MINIMIZED | 337 wm::WINDOW_STATE_TYPE_DOCKED_MINIMIZED |
257 ? ORIGINALLY_DOCKED_MINIMIZED | 338 ? ORIGINALLY_DOCKED_MINIMIZED |
258 : (window->GetShowState() == ui::SHOW_STATE_MINIMIZED | 339 : (window->GetShowState() == ui::SHOW_STATE_MINIMIZED |
259 ? ORIGINALLY_MINIMIZED | 340 ? ORIGINALLY_MINIMIZED |
260 : ORIGINALLY_VISIBLE)), | 341 : ORIGINALLY_VISIBLE)), |
261 ignored_by_shelf_(window->GetWindowState()->ignored_by_shelf()), | 342 ignored_by_shelf_(window->GetWindowState()->ignored_by_shelf()), |
262 overview_started_(false), | 343 overview_started_(false), |
263 original_transform_(window->GetTargetTransform()), | 344 original_transform_(window->GetTargetTransform()), |
264 original_opacity_(window->GetTargetOpacity()), | 345 original_opacity_(window->GetTargetOpacity()), |
265 weak_ptr_factory_(this) {} | 346 weak_ptr_factory_(this) {} |
266 | 347 |
267 ScopedTransformOverviewWindow::~ScopedTransformOverviewWindow() {} | 348 ScopedTransformOverviewWindow::~ScopedTransformOverviewWindow() {} |
268 | 349 |
269 void ScopedTransformOverviewWindow::RestoreWindow() { | 350 void ScopedTransformOverviewWindow::RestoreWindow() { |
270 ScopedAnimationSettings animation_settings_list; | 351 ScopedAnimationSettings animation_settings_list; |
271 BeginScopedAnimation(OverviewAnimationType::OVERVIEW_ANIMATION_RESTORE_WINDOW, | 352 BeginScopedAnimation(OverviewAnimationType::OVERVIEW_ANIMATION_RESTORE_WINDOW, |
272 &animation_settings_list); | 353 &animation_settings_list); |
273 SetTransform(window()->GetRootWindow(), original_transform_, | 354 SetTransform(window()->GetRootWindow(), original_transform_, |
274 false /* use_mask */, false /* use_shape */, 0); | 355 false /* use_mask */, false /* use_shape */, 0, |
356 true /* animate */); | |
275 | 357 |
276 std::unique_ptr<ScopedOverviewAnimationSettings> animation_settings = | 358 std::unique_ptr<ScopedOverviewAnimationSettings> animation_settings = |
277 CreateScopedOverviewAnimationSettings( | 359 CreateScopedOverviewAnimationSettings( |
278 OverviewAnimationType::OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS, | 360 OverviewAnimationType::OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS, |
279 window_); | 361 window_); |
280 gfx::Transform transform; | 362 gfx::Transform transform; |
281 if ((original_visibility_ == ORIGINALLY_MINIMIZED && | 363 if ((original_visibility_ == ORIGINALLY_MINIMIZED && |
282 window_->GetShowState() != ui::SHOW_STATE_MINIMIZED) || | 364 window_->GetShowState() != ui::SHOW_STATE_MINIMIZED) || |
283 (original_visibility_ == ORIGINALLY_DOCKED_MINIMIZED && | 365 (original_visibility_ == ORIGINALLY_DOCKED_MINIMIZED && |
284 window_->GetWindowState()->GetStateType() != | 366 window_->GetWindowState()->GetStateType() != |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
338 continue; | 420 continue; |
339 } | 421 } |
340 bounds.Union( | 422 bounds.Union( |
341 window->GetParent()->ConvertRectToScreen(window->GetTargetBounds())); | 423 window->GetParent()->ConvertRectToScreen(window->GetTargetBounds())); |
342 } | 424 } |
343 return bounds; | 425 return bounds; |
344 } | 426 } |
345 | 427 |
346 gfx::Rect ScopedTransformOverviewWindow::GetTransformedBounds( | 428 gfx::Rect ScopedTransformOverviewWindow::GetTransformedBounds( |
347 bool hide_header) const { | 429 bool hide_header) const { |
430 if (window_->GetWindowState()->IsMinimized()) | |
431 return window_->GetMinimizeAnimationTargetBoundsInScreen(); | |
432 | |
348 const bool material = ash::MaterialDesignController::IsOverviewMaterial(); | 433 const bool material = ash::MaterialDesignController::IsOverviewMaterial(); |
349 const int top_inset = hide_header ? GetTopInset() : 0; | 434 const int top_inset = hide_header ? GetTopInset() : 0; |
350 gfx::Rect bounds; | 435 gfx::Rect bounds; |
351 for (auto* window : GetTransientTreeIterator(window_)) { | 436 for (auto* window : GetTransientTreeIterator(window_)) { |
352 // Ignore other window types when computing bounding box of window | 437 // Ignore other window types when computing bounding box of window |
353 // selector target item. | 438 // selector target item. |
354 if (window != window_ && | 439 if (window != window_ && |
355 (!material || (window->GetType() != ui::wm::WINDOW_TYPE_NORMAL && | 440 (!material || (window->GetType() != ui::wm::WINDOW_TYPE_NORMAL && |
356 window->GetType() != ui::wm::WINDOW_TYPE_PANEL))) { | 441 window->GetType() != ui::wm::WINDOW_TYPE_PANEL))) { |
357 continue; | 442 continue; |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
461 transform.Scale(static_cast<float>(dst_rect.width()) / src_rect.width(), | 546 transform.Scale(static_cast<float>(dst_rect.width()) / src_rect.width(), |
462 static_cast<float>(dst_rect.height()) / src_rect.height()); | 547 static_cast<float>(dst_rect.height()) / src_rect.height()); |
463 return transform; | 548 return transform; |
464 } | 549 } |
465 | 550 |
466 void ScopedTransformOverviewWindow::SetTransform( | 551 void ScopedTransformOverviewWindow::SetTransform( |
467 WmWindow* root_window, | 552 WmWindow* root_window, |
468 const gfx::Transform& transform, | 553 const gfx::Transform& transform, |
469 bool use_mask, | 554 bool use_mask, |
470 bool use_shape, | 555 bool use_shape, |
471 float radius) { | 556 float radius, |
557 bool animate) { | |
472 DCHECK(overview_started_); | 558 DCHECK(overview_started_); |
473 | 559 |
474 if (ash::MaterialDesignController::IsOverviewMaterial() && | 560 if (ash::MaterialDesignController::IsOverviewMaterial() && |
475 &transform != &original_transform_) { | 561 &transform != &original_transform_) { |
476 if (use_mask && !mask_) { | 562 if (use_mask && !mask_) { |
477 mask_.reset(new OverviewContentMask()); | 563 mask_.reset(new OverviewContentMask()); |
478 mask_->layer()->SetFillsBoundsOpaquely(false); | 564 mask_->layer()->SetFillsBoundsOpaquely(false); |
479 window()->GetLayer()->SetMaskLayer(mask_->layer()); | 565 window()->GetLayer()->SetMaskLayer(mask_->layer()); |
480 } | 566 } |
481 if (!determined_original_window_shape_) { | 567 if (!determined_original_window_shape_) { |
482 determined_original_window_shape_ = true; | 568 determined_original_window_shape_ = true; |
483 SkRegion* window_shape = window()->GetLayer()->alpha_shape(); | 569 SkRegion* window_shape = window()->GetLayer()->alpha_shape(); |
484 if (!original_window_shape_ && window_shape) | 570 if (!original_window_shape_ && window_shape) |
485 original_window_shape_.reset(new SkRegion(*window_shape)); | 571 original_window_shape_.reset(new SkRegion(*window_shape)); |
486 } | 572 } |
487 gfx::Rect bounds(GetTargetBoundsInScreen().size()); | 573 animation_observer_.reset(new OverviewWindowAnimationObserver( |
488 const int inset = (use_mask || use_shape) ? GetTopInset() : 0; | 574 this, animate, use_mask, use_shape, radius, mask_.get(), |
489 if (mask_) { | 575 original_window_shape_.get())); |
490 // Mask layer is used both to hide the window header and to use rounded | |
491 // corners. Its layout needs to be update when setting a transform. | |
492 mask_->layer()->SetBounds(bounds); | |
493 mask_->set_inset(inset); | |
494 mask_->set_radius(radius); | |
495 window()->GetLayer()->SchedulePaint(bounds); | |
496 } else if (inset > 0) { | |
497 // Alpha shape is only used to to hide the window header and only when | |
498 // not using a mask layer. | |
499 bounds.Inset(0, inset, 0, 0); | |
500 SkRegion* region = new SkRegion; | |
501 region->setRect(RectToSkIRect(bounds)); | |
502 if (original_window_shape_) | |
503 region->op(*original_window_shape_, SkRegion::kIntersect_Op); | |
504 window()->GetLayer()->SetAlphaShape(base::WrapUnique(region)); | |
505 window()->SetMasksToBounds(true); | |
506 } | |
507 } | 576 } |
508 | 577 |
509 gfx::Point target_origin(GetTargetBoundsInScreen().origin()); | 578 gfx::Point target_origin(GetTargetBoundsInScreen().origin()); |
510 | 579 |
511 for (auto* window : GetTransientTreeIterator(window_)) { | 580 for (auto* window : GetTransientTreeIterator(window_)) { |
512 WmWindow* parent_window = window->GetParent(); | 581 WmWindow* parent_window = window->GetParent(); |
513 gfx::Point original_origin = | 582 gfx::Point original_origin = |
514 parent_window->ConvertRectToScreen(window->GetTargetBounds()).origin(); | 583 parent_window->ConvertRectToScreen(window->GetTargetBounds()).origin(); |
515 gfx::Transform new_transform = | 584 gfx::Transform new_transform = |
516 TransformAboutPivot(gfx::Point(target_origin.x() - original_origin.x(), | 585 TransformAboutPivot(gfx::Point(target_origin.x() - original_origin.x(), |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
550 if (parent_window) | 619 if (parent_window) |
551 parent_window->CloseWidget(); | 620 parent_window->CloseWidget(); |
552 } | 621 } |
553 | 622 |
554 // static | 623 // static |
555 void ScopedTransformOverviewWindow::SetImmediateCloseForTests() { | 624 void ScopedTransformOverviewWindow::SetImmediateCloseForTests() { |
556 immediate_close_for_tests = true; | 625 immediate_close_for_tests = true; |
557 } | 626 } |
558 | 627 |
559 } // namespace ash | 628 } // namespace ash |
OLD | NEW |