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