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" |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 original_opacity_(window->GetTargetOpacity()), | 264 original_opacity_(window->GetTargetOpacity()), |
265 weak_ptr_factory_(this) {} | 265 weak_ptr_factory_(this) {} |
266 | 266 |
267 ScopedTransformOverviewWindow::~ScopedTransformOverviewWindow() {} | 267 ScopedTransformOverviewWindow::~ScopedTransformOverviewWindow() {} |
268 | 268 |
269 void ScopedTransformOverviewWindow::RestoreWindow() { | 269 void ScopedTransformOverviewWindow::RestoreWindow() { |
270 ScopedAnimationSettings animation_settings_list; | 270 ScopedAnimationSettings animation_settings_list; |
271 BeginScopedAnimation(OverviewAnimationType::OVERVIEW_ANIMATION_RESTORE_WINDOW, | 271 BeginScopedAnimation(OverviewAnimationType::OVERVIEW_ANIMATION_RESTORE_WINDOW, |
272 &animation_settings_list); | 272 &animation_settings_list); |
273 SetTransform(window()->GetRootWindow(), original_transform_, | 273 SetTransform(window()->GetRootWindow(), original_transform_, |
274 false /* use_mask */, false /* use_shape */, 0); | 274 false /* use_mask */); |
| 275 set_overview_transform(original_transform_); |
275 | 276 |
276 std::unique_ptr<ScopedOverviewAnimationSettings> animation_settings = | 277 std::unique_ptr<ScopedOverviewAnimationSettings> animation_settings = |
277 CreateScopedOverviewAnimationSettings( | 278 CreateScopedOverviewAnimationSettings( |
278 OverviewAnimationType::OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS, | 279 OverviewAnimationType::OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS, |
279 window_); | 280 window_); |
280 gfx::Transform transform; | 281 gfx::Transform transform; |
281 if ((original_visibility_ == ORIGINALLY_MINIMIZED && | 282 if ((original_visibility_ == ORIGINALLY_MINIMIZED && |
282 window_->GetShowState() != ui::SHOW_STATE_MINIMIZED) || | 283 window_->GetShowState() != ui::SHOW_STATE_MINIMIZED) || |
283 (original_visibility_ == ORIGINALLY_DOCKED_MINIMIZED && | 284 (original_visibility_ == ORIGINALLY_DOCKED_MINIMIZED && |
284 window_->GetWindowState()->GetStateType() != | 285 window_->GetWindowState()->GetStateType() != |
285 wm::WINDOW_STATE_TYPE_DOCKED_MINIMIZED)) { | 286 wm::WINDOW_STATE_TYPE_DOCKED_MINIMIZED)) { |
286 // Setting opacity 0 and visible false ensures that the property change | 287 // Setting opacity 0 and visible false ensures that the property change |
287 // to SHOW_STATE_MINIMIZED will not animate the window from its original | 288 // to SHOW_STATE_MINIMIZED will not animate the window from its original |
288 // bounds to the minimized position. | 289 // bounds to the minimized position. |
289 // Hiding the window needs to be done before the target opacity is 0, | 290 // Hiding the window needs to be done before the target opacity is 0, |
290 // otherwise the layer's visibility will not be updated | 291 // otherwise the layer's visibility will not be updated |
291 // (See VisibilityController::UpdateLayerVisibility). | 292 // (See VisibilityController::UpdateLayerVisibility). |
292 window_->Hide(); | 293 window_->Hide(); |
293 window_->SetOpacity(0); | 294 window_->SetOpacity(0); |
294 window_->SetShowState(ui::SHOW_STATE_MINIMIZED); | 295 window_->SetShowState(ui::SHOW_STATE_MINIMIZED); |
295 } | 296 } |
296 window_->GetWindowState()->set_ignored_by_shelf(ignored_by_shelf_); | 297 window_->GetWindowState()->set_ignored_by_shelf(ignored_by_shelf_); |
297 SetOpacity(original_opacity_); | 298 SetOpacity(original_opacity_); |
298 | 299 |
299 if (ash::MaterialDesignController::IsOverviewMaterial()) { | 300 if (ash::MaterialDesignController::IsOverviewMaterial()) |
300 ui::Layer* layer = window()->GetLayer(); | 301 ShowHeaderAndResetShape(); |
301 layer->SetMaskLayer(nullptr); | |
302 mask_.reset(); | |
303 | |
304 if (original_window_shape_) { | |
305 layer->SetAlphaShape( | |
306 base::MakeUnique<SkRegion>(*original_window_shape_.get())); | |
307 } else { | |
308 layer->SetAlphaShape(nullptr); | |
309 } | |
310 window()->SetMasksToBounds(false); | |
311 } | |
312 } | 302 } |
313 | 303 |
314 void ScopedTransformOverviewWindow::BeginScopedAnimation( | 304 void ScopedTransformOverviewWindow::BeginScopedAnimation( |
315 OverviewAnimationType animation_type, | 305 OverviewAnimationType animation_type, |
316 ScopedAnimationSettings* animation_settings) { | 306 ScopedAnimationSettings* animation_settings) { |
317 for (auto* window : GetTransientTreeIterator(window_)) { | 307 for (auto* window : GetTransientTreeIterator(window_)) { |
318 animation_settings->push_back( | 308 animation_settings->push_back( |
319 CreateScopedOverviewAnimationSettings(animation_type, window)); | 309 CreateScopedOverviewAnimationSettings(animation_type, window)); |
320 } | 310 } |
321 } | 311 } |
(...skipping 16 matching lines...) Expand all Loading... |
338 continue; | 328 continue; |
339 } | 329 } |
340 bounds.Union( | 330 bounds.Union( |
341 window->GetParent()->ConvertRectToScreen(window->GetTargetBounds())); | 331 window->GetParent()->ConvertRectToScreen(window->GetTargetBounds())); |
342 } | 332 } |
343 return bounds; | 333 return bounds; |
344 } | 334 } |
345 | 335 |
346 gfx::Rect ScopedTransformOverviewWindow::GetTransformedBounds( | 336 gfx::Rect ScopedTransformOverviewWindow::GetTransformedBounds( |
347 bool hide_header) const { | 337 bool hide_header) const { |
| 338 if (window_->GetWindowState()->IsMinimized()) |
| 339 return window_->GetMinimizeAnimationTargetBoundsInScreen(); |
| 340 |
348 const bool material = ash::MaterialDesignController::IsOverviewMaterial(); | 341 const bool material = ash::MaterialDesignController::IsOverviewMaterial(); |
349 const int top_inset = hide_header ? GetTopInset() : 0; | 342 const int top_inset = hide_header ? GetTopInset() : 0; |
350 gfx::Rect bounds; | 343 gfx::Rect bounds; |
351 for (auto* window : GetTransientTreeIterator(window_)) { | 344 for (auto* window : GetTransientTreeIterator(window_)) { |
352 // Ignore other window types when computing bounding box of window | 345 // Ignore other window types when computing bounding box of window |
353 // selector target item. | 346 // selector target item. |
354 if (window != window_ && | 347 if (window != window_ && |
355 (!material || (window->GetType() != ui::wm::WINDOW_TYPE_NORMAL && | 348 (!material || (window->GetType() != ui::wm::WINDOW_TYPE_NORMAL && |
356 window->GetType() != ui::wm::WINDOW_TYPE_PANEL))) { | 349 window->GetType() != ui::wm::WINDOW_TYPE_PANEL))) { |
357 continue; | 350 continue; |
(...skipping 12 matching lines...) Expand all Loading... |
370 header_bounds.set_height(top_inset); | 363 header_bounds.set_height(top_inset); |
371 new_transform.TransformRect(&header_bounds); | 364 new_transform.TransformRect(&header_bounds); |
372 window_bounds.Inset(0, gfx::ToCeiledInt(header_bounds.height()), 0, 0); | 365 window_bounds.Inset(0, gfx::ToCeiledInt(header_bounds.height()), 0, 0); |
373 } | 366 } |
374 bounds.Union(window->GetParent()->ConvertRectToScreen( | 367 bounds.Union(window->GetParent()->ConvertRectToScreen( |
375 ToEnclosingRect(window_bounds))); | 368 ToEnclosingRect(window_bounds))); |
376 } | 369 } |
377 return bounds; | 370 return bounds; |
378 } | 371 } |
379 | 372 |
| 373 SkColor ScopedTransformOverviewWindow::GetTopColor() const { |
| 374 for (auto* window : GetTransientTreeIterator(window_)) { |
| 375 // If there are regular windows in the transient ancestor tree, all those |
| 376 // windows are shown in the same overview item and the header is not masked. |
| 377 if (window != window_ && (window->GetType() == ui::wm::WINDOW_TYPE_NORMAL || |
| 378 window->GetType() == ui::wm::WINDOW_TYPE_PANEL)) { |
| 379 return SK_ColorTRANSPARENT; |
| 380 } |
| 381 } |
| 382 return window_->GetColorProperty(WmWindowProperty::TOP_VIEW_COLOR); |
| 383 } |
| 384 |
380 int ScopedTransformOverviewWindow::GetTopInset() const { | 385 int ScopedTransformOverviewWindow::GetTopInset() const { |
381 for (auto* window : GetTransientTreeIterator(window_)) { | 386 for (auto* window : GetTransientTreeIterator(window_)) { |
382 // If there are regular windows in the transient ancestor tree, all those | 387 // If there are regular windows in the transient ancestor tree, all those |
383 // windows are shown in the same overview item and the header is not masked. | 388 // windows are shown in the same overview item and the header is not masked. |
384 if (window != window_ && (window->GetType() == ui::wm::WINDOW_TYPE_NORMAL || | 389 if (window != window_ && (window->GetType() == ui::wm::WINDOW_TYPE_NORMAL || |
385 window->GetType() == ui::wm::WINDOW_TYPE_PANEL)) { | 390 window->GetType() == ui::wm::WINDOW_TYPE_PANEL)) { |
386 return 0; | 391 return 0; |
387 } | 392 } |
388 } | 393 } |
389 return window_->GetIntProperty(WmWindowProperty::TOP_VIEW_INSET); | 394 return window_->GetIntProperty(WmWindowProperty::TOP_VIEW_INSET); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 gfx::Transform transform; | 464 gfx::Transform transform; |
460 transform.Translate(dst_rect.x() - src_rect.x(), dst_rect.y() - src_rect.y()); | 465 transform.Translate(dst_rect.x() - src_rect.x(), dst_rect.y() - src_rect.y()); |
461 transform.Scale(static_cast<float>(dst_rect.width()) / src_rect.width(), | 466 transform.Scale(static_cast<float>(dst_rect.width()) / src_rect.width(), |
462 static_cast<float>(dst_rect.height()) / src_rect.height()); | 467 static_cast<float>(dst_rect.height()) / src_rect.height()); |
463 return transform; | 468 return transform; |
464 } | 469 } |
465 | 470 |
466 void ScopedTransformOverviewWindow::SetTransform( | 471 void ScopedTransformOverviewWindow::SetTransform( |
467 WmWindow* root_window, | 472 WmWindow* root_window, |
468 const gfx::Transform& transform, | 473 const gfx::Transform& transform, |
469 bool use_mask, | 474 bool use_mask) { |
470 bool use_shape, | |
471 float radius) { | |
472 DCHECK(overview_started_); | 475 DCHECK(overview_started_); |
473 | 476 |
474 if (ash::MaterialDesignController::IsOverviewMaterial() && | 477 if (ash::MaterialDesignController::IsOverviewMaterial() && |
475 &transform != &original_transform_) { | 478 &transform != &original_transform_) { |
476 if (use_mask && !mask_) { | 479 if (use_mask && !mask_) { |
477 mask_.reset(new OverviewContentMask()); | 480 mask_.reset(new OverviewContentMask()); |
478 mask_->layer()->SetFillsBoundsOpaquely(false); | 481 mask_->layer()->SetFillsBoundsOpaquely(false); |
479 window()->GetLayer()->SetMaskLayer(mask_->layer()); | 482 window()->GetLayer()->SetMaskLayer(mask_->layer()); |
480 } | 483 } |
481 if (!determined_original_window_shape_) { | 484 if (!determined_original_window_shape_) { |
482 determined_original_window_shape_ = true; | 485 determined_original_window_shape_ = true; |
483 SkRegion* window_shape = window()->GetLayer()->alpha_shape(); | 486 SkRegion* window_shape = window()->GetLayer()->alpha_shape(); |
484 if (!original_window_shape_ && window_shape) | 487 if (!original_window_shape_ && window_shape) |
485 original_window_shape_.reset(new SkRegion(*window_shape)); | 488 original_window_shape_.reset(new SkRegion(*window_shape)); |
486 } | 489 } |
487 gfx::Rect bounds(GetTargetBoundsInScreen().size()); | |
488 const int inset = (use_mask || use_shape) ? GetTopInset() : 0; | |
489 if (mask_) { | |
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 } | 490 } |
508 | 491 |
509 gfx::Point target_origin(GetTargetBoundsInScreen().origin()); | 492 gfx::Point target_origin(GetTargetBoundsInScreen().origin()); |
510 | 493 |
511 for (auto* window : GetTransientTreeIterator(window_)) { | 494 for (auto* window : GetTransientTreeIterator(window_)) { |
512 WmWindow* parent_window = window->GetParent(); | 495 WmWindow* parent_window = window->GetParent(); |
513 gfx::Point original_origin = | 496 gfx::Point original_origin = |
514 parent_window->ConvertRectToScreen(window->GetTargetBounds()).origin(); | 497 parent_window->ConvertRectToScreen(window->GetTargetBounds()).origin(); |
515 gfx::Transform new_transform = | 498 gfx::Transform new_transform = |
516 TransformAboutPivot(gfx::Point(target_origin.x() - original_origin.x(), | 499 TransformAboutPivot(gfx::Point(target_origin.x() - original_origin.x(), |
517 target_origin.y() - original_origin.y()), | 500 target_origin.y() - original_origin.y()), |
518 transform); | 501 transform); |
519 window->SetTransform(new_transform); | 502 window->SetTransform(new_transform); |
520 } | 503 } |
521 } | 504 } |
522 | 505 |
523 void ScopedTransformOverviewWindow::SetOpacity(float opacity) { | 506 void ScopedTransformOverviewWindow::SetOpacity(float opacity) { |
524 for (auto* window : GetTransientTreeIterator(window_)) { | 507 for (auto* window : GetTransientTreeIterator(window_)) { |
525 window->SetOpacity(opacity); | 508 window->SetOpacity(opacity); |
526 } | 509 } |
527 } | 510 } |
528 | 511 |
| 512 void ScopedTransformOverviewWindow::HideHeaderAndSetShape(bool use_mask, |
| 513 bool use_shape, |
| 514 int radius) { |
| 515 gfx::Rect bounds(GetTargetBoundsInScreen().size()); |
| 516 const int inset = (use_mask || use_shape) ? GetTopInset() : 0; |
| 517 if (mask_) { |
| 518 // Mask layer is used both to hide the window header and to use rounded |
| 519 // corners. Its layout needs to be updated when setting a transform. |
| 520 mask_->layer()->SetBounds(bounds); |
| 521 mask_->set_inset(inset); |
| 522 mask_->set_radius(radius); |
| 523 window()->GetLayer()->SchedulePaint(bounds); |
| 524 } else if (inset > 0) { |
| 525 // Alpha shape is only used to hide the window header and only when not |
| 526 // using a mask layer. |
| 527 bounds.Inset(0, inset, 0, 0); |
| 528 std::unique_ptr<SkRegion> region(new SkRegion); |
| 529 region->setRect(RectToSkIRect(bounds)); |
| 530 if (original_window_shape_) |
| 531 region->op(*original_window_shape_, SkRegion::kIntersect_Op); |
| 532 window()->GetLayer()->SetAlphaShape(std::move(region)); |
| 533 window()->SetMasksToBounds(true); |
| 534 } |
| 535 } |
| 536 |
| 537 void ScopedTransformOverviewWindow::ShowHeaderAndResetShape() { |
| 538 ui::Layer* layer = window()->GetLayer(); |
| 539 layer->SetMaskLayer(nullptr); |
| 540 mask_.reset(); |
| 541 |
| 542 if (original_window_shape_) { |
| 543 layer->SetAlphaShape( |
| 544 base::MakeUnique<SkRegion>(*original_window_shape_.get())); |
| 545 } else { |
| 546 layer->SetAlphaShape(nullptr); |
| 547 } |
| 548 window()->SetMasksToBounds(false); |
| 549 } |
| 550 |
529 void ScopedTransformOverviewWindow::Close() { | 551 void ScopedTransformOverviewWindow::Close() { |
530 if (immediate_close_for_tests || | 552 if (immediate_close_for_tests || |
531 !ash::MaterialDesignController::IsOverviewMaterial()) { | 553 !ash::MaterialDesignController::IsOverviewMaterial()) { |
532 CloseWidget(); | 554 CloseWidget(); |
533 return; | 555 return; |
534 } | 556 } |
535 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 557 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
536 FROM_HERE, base::Bind(&ScopedTransformOverviewWindow::CloseWidget, | 558 FROM_HERE, base::Bind(&ScopedTransformOverviewWindow::CloseWidget, |
537 weak_ptr_factory_.GetWeakPtr()), | 559 weak_ptr_factory_.GetWeakPtr()), |
538 base::TimeDelta::FromMilliseconds(kCloseWindowDelayInMilliseconds)); | 560 base::TimeDelta::FromMilliseconds(kCloseWindowDelayInMilliseconds)); |
(...skipping 11 matching lines...) Expand all Loading... |
550 if (parent_window) | 572 if (parent_window) |
551 parent_window->CloseWidget(); | 573 parent_window->CloseWidget(); |
552 } | 574 } |
553 | 575 |
554 // static | 576 // static |
555 void ScopedTransformOverviewWindow::SetImmediateCloseForTests() { | 577 void ScopedTransformOverviewWindow::SetImmediateCloseForTests() { |
556 immediate_close_for_tests = true; | 578 immediate_close_for_tests = true; |
557 } | 579 } |
558 | 580 |
559 } // namespace ash | 581 } // namespace ash |
OLD | NEW |