Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Side by Side Diff: ash/common/wm/overview/window_grid.cc

Issue 2141133002: [ash-md] Animates overview shield in and out (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: [ash-md] Completes shield opacity animation after overview closes (nits) Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ash/common/wm/overview/window_grid.h ('k') | ash/common/wm/overview/window_selector.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/window_grid.h" 5 #include "ash/common/wm/overview/window_grid.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <functional> 8 #include <functional>
9 #include <set> 9 #include <set>
10 #include <utility> 10 #include <utility>
11 #include <vector> 11 #include <vector>
12 12
13 #include "ash/common/ash_switches.h" 13 #include "ash/common/ash_switches.h"
14 #include "ash/common/material_design/material_design_controller.h" 14 #include "ash/common/material_design/material_design_controller.h"
15 #include "ash/common/shelf/shelf_types.h"
16 #include "ash/common/shelf/wm_shelf.h"
15 #include "ash/common/shell_window_ids.h" 17 #include "ash/common/shell_window_ids.h"
18 #include "ash/common/wm/overview/cleanup_animation_observer.h"
16 #include "ash/common/wm/overview/scoped_overview_animation_settings.h" 19 #include "ash/common/wm/overview/scoped_overview_animation_settings.h"
17 #include "ash/common/wm/overview/scoped_overview_animation_settings_factory.h" 20 #include "ash/common/wm/overview/scoped_overview_animation_settings_factory.h"
18 #include "ash/common/wm/overview/scoped_transform_overview_window.h" 21 #include "ash/common/wm/overview/scoped_transform_overview_window.h"
19 #include "ash/common/wm/overview/window_selector.h" 22 #include "ash/common/wm/overview/window_selector.h"
23 #include "ash/common/wm/overview/window_selector_delegate.h"
20 #include "ash/common/wm/overview/window_selector_item.h" 24 #include "ash/common/wm/overview/window_selector_item.h"
21 #include "ash/common/wm/window_state.h" 25 #include "ash/common/wm/window_state.h"
22 #include "ash/common/wm/wm_screen_util.h" 26 #include "ash/common/wm/wm_screen_util.h"
23 #include "ash/common/wm_lookup.h" 27 #include "ash/common/wm_lookup.h"
24 #include "ash/common/wm_root_window_controller.h" 28 #include "ash/common/wm_root_window_controller.h"
25 #include "ash/common/wm_window.h" 29 #include "ash/common/wm_window.h"
26 #include "base/command_line.h" 30 #include "base/command_line.h"
27 #include "base/i18n/string_search.h" 31 #include "base/i18n/string_search.h"
28 #include "base/memory/scoped_vector.h" 32 #include "base/memory/scoped_vector.h"
29 #include "third_party/skia/include/core/SkColor.h" 33 #include "third_party/skia/include/core/SkColor.h"
(...skipping 11 matching lines...) Expand all
41 #include "ui/views/view.h" 45 #include "ui/views/view.h"
42 #include "ui/views/widget/widget.h" 46 #include "ui/views/widget/widget.h"
43 #include "ui/wm/core/shadow.h" 47 #include "ui/wm/core/shadow.h"
44 #include "ui/wm/core/window_animations.h" 48 #include "ui/wm/core/window_animations.h"
45 49
46 namespace ash { 50 namespace ash {
47 namespace { 51 namespace {
48 52
49 using Windows = std::vector<WmWindow*>; 53 using Windows = std::vector<WmWindow*>;
50 54
51 // An observer which holds onto the passed widget until the animation is
52 // complete.
53 class CleanupWidgetAfterAnimationObserver
54 : public ui::ImplicitAnimationObserver {
55 public:
56 explicit CleanupWidgetAfterAnimationObserver(
57 std::unique_ptr<views::Widget> widget);
58 ~CleanupWidgetAfterAnimationObserver() override;
59
60 // ui::ImplicitAnimationObserver:
61 void OnImplicitAnimationsCompleted() override;
62
63 private:
64 std::unique_ptr<views::Widget> widget_;
65
66 DISALLOW_COPY_AND_ASSIGN(CleanupWidgetAfterAnimationObserver);
67 };
68
69 CleanupWidgetAfterAnimationObserver::CleanupWidgetAfterAnimationObserver(
70 std::unique_ptr<views::Widget> widget)
71 : widget_(std::move(widget)) {}
72
73 CleanupWidgetAfterAnimationObserver::~CleanupWidgetAfterAnimationObserver() {}
74
75 void CleanupWidgetAfterAnimationObserver::OnImplicitAnimationsCompleted() {
76 delete this;
77 }
78
79 // A comparator for locating a given target window. 55 // A comparator for locating a given target window.
80 struct WindowSelectorItemComparator { 56 struct WindowSelectorItemComparator {
81 explicit WindowSelectorItemComparator(const WmWindow* target_window) 57 explicit WindowSelectorItemComparator(const WmWindow* target_window)
82 : target(target_window) {} 58 : target(target_window) {}
83 59
84 bool operator()(WindowSelectorItem* window) const { 60 bool operator()(WindowSelectorItem* window) const {
85 return window->GetWindow() == target; 61 return window->GetWindow() == target;
86 } 62 }
87 63
88 const WmWindow* target; 64 const WmWindow* target;
89 }; 65 };
90 66
91 // Conceptually the window overview is a table or grid of cells having this 67 // Conceptually the window overview is a table or grid of cells having this
92 // fixed aspect ratio. The number of columns is determined by maximizing the 68 // fixed aspect ratio. The number of columns is determined by maximizing the
93 // area of them based on the number of window_list. 69 // area of them based on the number of window_list.
94 const float kCardAspectRatio = 4.0f / 3.0f; 70 const float kCardAspectRatio = 4.0f / 3.0f;
95 71
96 // The minimum number of cards along the major axis (i.e. horizontally on a 72 // The minimum number of cards along the major axis (i.e. horizontally on a
97 // landscape orientation). 73 // landscape orientation).
98 const int kMinCardsMajor = 3; 74 const int kMinCardsMajor = 3;
99 75
100 const int kOverviewSelectorTransitionMilliseconds = 250; 76 const int kOverviewSelectorTransitionMilliseconds = 250;
101 77
102 // The color and opacity of the screen shield in overview. 78 // The color and opacity of the screen shield in overview.
103 const SkColor kShieldColor = SkColorSetARGB(178, 0, 0, 0); 79 const SkColor kShieldColor = SkColorSetARGB(255, 0, 0, 0);
80 const float kShieldOpacity = 0.7f;
104 81
105 // The color and opacity of the overview selector. 82 // The color and opacity of the overview selector.
106 const SkColor kWindowSelectionColor = SkColorSetARGB(128, 0, 0, 0); 83 const SkColor kWindowSelectionColor = SkColorSetARGB(128, 0, 0, 0);
107 const SkColor kWindowSelectionColorMD = SkColorSetARGB(51, 255, 255, 255); 84 const SkColor kWindowSelectionColorMD = SkColorSetARGB(51, 255, 255, 255);
108 const SkColor kWindowSelectionBorderColor = SkColorSetARGB(38, 255, 255, 255); 85 const SkColor kWindowSelectionBorderColor = SkColorSetARGB(38, 255, 255, 255);
109 const SkColor kWindowSelectionBorderColorMD = SkColorSetARGB(76, 255, 255, 255); 86 const SkColor kWindowSelectionBorderColorMD = SkColorSetARGB(76, 255, 255, 255);
110 87
111 // Border thickness of overview selector. 88 // Border thickness of overview selector.
112 const int kWindowSelectionBorderThickness = 2; 89 const int kWindowSelectionBorderThickness = 2;
113 const int kWindowSelectionBorderThicknessMD = 1; 90 const int kWindowSelectionBorderThicknessMD = 1;
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 } 324 }
348 if (swap_index > i) 325 if (swap_index > i)
349 std::swap((*items)[i], (*items)[swap_index]); 326 std::swap((*items)[i], (*items)[swap_index]);
350 } 327 }
351 } 328 }
352 329
353 // Creates and returns a background translucent widget parented in 330 // Creates and returns a background translucent widget parented in
354 // |root_window|'s default container and having |background_color|. 331 // |root_window|'s default container and having |background_color|.
355 // When |border_thickness| is non-zero, a border is created having 332 // When |border_thickness| is non-zero, a border is created having
356 // |border_color|, otherwise |border_color| parameter is ignored. 333 // |border_color|, otherwise |border_color| parameter is ignored.
334 // The new background widget starts with |initial_opacity| and then fades in.
357 views::Widget* CreateBackgroundWidget(WmWindow* root_window, 335 views::Widget* CreateBackgroundWidget(WmWindow* root_window,
358 SkColor background_color, 336 SkColor background_color,
359 int border_thickness, 337 int border_thickness,
360 int border_radius, 338 int border_radius,
361 SkColor border_color) { 339 SkColor border_color,
340 float initial_opacity) {
362 views::Widget* widget = new views::Widget; 341 views::Widget* widget = new views::Widget;
363 views::Widget::InitParams params; 342 views::Widget::InitParams params;
364 params.type = views::Widget::InitParams::TYPE_POPUP; 343 params.type = views::Widget::InitParams::TYPE_POPUP;
365 params.keep_on_top = false; 344 params.keep_on_top = false;
366 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 345 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
367 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; 346 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
368 params.accept_events = false; 347 params.accept_events = false;
369 widget->set_focus_on_creation(false); 348 widget->set_focus_on_creation(false);
370 // Parenting in kShellWindowId_DesktopBackgroundContainer allows proper 349 // Parenting in kShellWindowId_DesktopBackgroundContainer allows proper
371 // layering of the shield and selection widgets. Since that container is 350 // layering of the shield and selection widgets. Since that container is
(...skipping 17 matching lines...) Expand all
389 content_view->set_background( 368 content_view->set_background(
390 views::Background::CreateSolidBackground(background_color)); 369 views::Background::CreateSolidBackground(background_color));
391 if (border_thickness) { 370 if (border_thickness) {
392 content_view->SetBorder( 371 content_view->SetBorder(
393 views::Border::CreateSolidBorder(border_thickness, border_color)); 372 views::Border::CreateSolidBorder(border_thickness, border_color));
394 } 373 }
395 } 374 }
396 widget->SetContentsView(content_view); 375 widget->SetContentsView(content_view);
397 widget_window->GetParent()->StackChildAtTop(widget_window); 376 widget_window->GetParent()->StackChildAtTop(widget_window);
398 widget->Show(); 377 widget->Show();
399 // New background widget starts with 0 opacity and then fades in. 378 widget_window->SetOpacity(initial_opacity);
400 widget_window->SetOpacity(0.f);
401 return widget; 379 return widget;
402 } 380 }
403 381
404 } // namespace 382 } // namespace
405 383
406 WindowGrid::WindowGrid(WmWindow* root_window, 384 WindowGrid::WindowGrid(WmWindow* root_window,
407 const std::vector<WmWindow*>& windows, 385 const std::vector<WmWindow*>& windows,
408 WindowSelector* window_selector) 386 WindowSelector* window_selector)
409 : root_window_(root_window), 387 : root_window_(root_window),
410 window_selector_(window_selector), 388 window_selector_(window_selector),
(...skipping 18 matching lines...) Expand all
429 observed_windows_.insert(window); 407 observed_windows_.insert(window);
430 window_list_.push_back(new WindowSelectorItem(window, window_selector_)); 408 window_list_.push_back(new WindowSelectorItem(window, window_selector_));
431 } 409 }
432 } 410 }
433 411
434 WindowGrid::~WindowGrid() { 412 WindowGrid::~WindowGrid() {
435 for (WmWindow* window : observed_windows_) 413 for (WmWindow* window : observed_windows_)
436 window->RemoveObserver(this); 414 window->RemoveObserver(this);
437 } 415 }
438 416
417 void WindowGrid::Shutdown() {
418 if (shield_widget_) {
419 // Fade out the shield widget. This animation continues past the lifetime
420 // of |this|.
421 WmWindow* widget_window =
422 WmLookup::Get()->GetWindowForWidget(shield_widget_.get());
423 ui::ScopedLayerAnimationSettings animation_settings(
424 widget_window->GetLayer()->GetAnimator());
425 animation_settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(
426 kOverviewSelectorTransitionMilliseconds));
427 animation_settings.SetTweenType(gfx::Tween::EASE_IN);
428 animation_settings.SetPreemptionStrategy(
429 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
430 // CleanupAnimationObserver will delete itself (and the shield widget) when
431 // the opacity animation is complete.
432 // Ownership over the observer is passed to the window_selector_->delegate()
433 // which has longer lifetime so that animations can continue even after the
434 // overview mode is shut down.
435 views::Widget* shield_widget = shield_widget_.get();
436 std::unique_ptr<CleanupAnimationObserver> observer(
437 new CleanupAnimationObserver(std::move(shield_widget_)));
438 animation_settings.AddObserver(observer.get());
439 window_selector_->delegate()->AddDelayedAnimationObserver(
440 std::move(observer));
441 shield_widget->SetOpacity(0.f);
442 }
443 }
444
439 void WindowGrid::PrepareForOverview() { 445 void WindowGrid::PrepareForOverview() {
440 if (ash::MaterialDesignController::IsOverviewMaterial()) 446 if (ash::MaterialDesignController::IsOverviewMaterial())
441 InitShieldWidget(); 447 InitShieldWidget();
442 for (auto iter = window_list_.begin(); iter != window_list_.end(); ++iter) 448 for (auto iter = window_list_.begin(); iter != window_list_.end(); ++iter)
443 (*iter)->PrepareForOverview(); 449 (*iter)->PrepareForOverview();
444 } 450 }
445 451
446 void WindowGrid::PositionWindowsMD(bool animate) { 452 void WindowGrid::PositionWindowsMD(bool animate) {
447 if (window_list_.empty()) 453 if (window_list_.empty())
448 return; 454 return;
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
787 793
788 if (ash::MaterialDesignController::IsOverviewMaterial()) { 794 if (ash::MaterialDesignController::IsOverviewMaterial()) {
789 PositionWindows(false); 795 PositionWindows(false);
790 return; 796 return;
791 } 797 }
792 // Recompute the transform for the window. 798 // Recompute the transform for the window.
793 (*iter)->RecomputeWindowTransforms(); 799 (*iter)->RecomputeWindowTransforms();
794 } 800 }
795 801
796 void WindowGrid::InitShieldWidget() { 802 void WindowGrid::InitShieldWidget() {
797 shield_widget_.reset(CreateBackgroundWidget(root_window_, kShieldColor, 0, 0, 803 // TODO(varkha): The code assumes that SHELF_BACKGROUND_MAXIMIZED is
798 SK_ColorTRANSPARENT)); 804 // synonymous with a black shelf background. Update this code if that
805 // assumption is no longer valid.
806 const float initial_opacity =
807 (root_window_->GetRootWindowController()
808 ->GetShelf()
809 ->GetBackgroundType() == SHELF_BACKGROUND_MAXIMIZED)
810 ? 1.f
811 : 0.f;
812 shield_widget_.reset(CreateBackgroundWidget(
813 root_window_, kShieldColor, 0, 0, SK_ColorTRANSPARENT, initial_opacity));
799 814
800 WmWindow* widget_window = 815 WmWindow* widget_window =
801 WmLookup::Get()->GetWindowForWidget(shield_widget_.get()); 816 WmLookup::Get()->GetWindowForWidget(shield_widget_.get());
802 const gfx::Rect bounds = widget_window->GetParent()->GetBounds(); 817 const gfx::Rect bounds = widget_window->GetParent()->GetBounds();
803 widget_window->SetBounds(bounds); 818 widget_window->SetBounds(bounds);
804 819
805 ui::ScopedLayerAnimationSettings animation_settings( 820 ui::ScopedLayerAnimationSettings animation_settings(
806 widget_window->GetLayer()->GetAnimator()); 821 widget_window->GetLayer()->GetAnimator());
807 animation_settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds( 822 animation_settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(
808 kOverviewSelectorTransitionMilliseconds)); 823 kOverviewSelectorTransitionMilliseconds));
809 animation_settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN); 824 animation_settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN);
810 animation_settings.SetPreemptionStrategy( 825 animation_settings.SetPreemptionStrategy(
811 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); 826 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
812 shield_widget_->SetOpacity(1.f); 827 shield_widget_->SetOpacity(kShieldOpacity);
813 } 828 }
814 829
815 void WindowGrid::InitSelectionWidget(WindowSelector::Direction direction) { 830 void WindowGrid::InitSelectionWidget(WindowSelector::Direction direction) {
816 const bool material = ash::MaterialDesignController::IsOverviewMaterial(); 831 const bool material = ash::MaterialDesignController::IsOverviewMaterial();
817 const int border_thickness = material ? kWindowSelectionBorderThicknessMD 832 const int border_thickness = material ? kWindowSelectionBorderThicknessMD
818 : kWindowSelectionBorderThickness; 833 : kWindowSelectionBorderThickness;
819 const int border_color = 834 const int border_color =
820 material ? kWindowSelectionBorderColorMD : kWindowSelectionBorderColor; 835 material ? kWindowSelectionBorderColorMD : kWindowSelectionBorderColor;
821 const int selection_color = 836 const int selection_color =
822 material ? kWindowSelectionColorMD : kWindowSelectionColor; 837 material ? kWindowSelectionColorMD : kWindowSelectionColor;
823 const int border_radius = 838 const int border_radius =
824 material ? kWindowSelectionRadiusMD : kWindowSelectionRadius; 839 material ? kWindowSelectionRadiusMD : kWindowSelectionRadius;
825 selection_widget_.reset(CreateBackgroundWidget(root_window_, selection_color, 840 selection_widget_.reset(
826 border_thickness, 841 CreateBackgroundWidget(root_window_, selection_color, border_thickness,
827 border_radius, border_color)); 842 border_radius, border_color, 0.f));
828 WmWindow* widget_window = 843 WmWindow* widget_window =
829 WmLookup::Get()->GetWindowForWidget(selection_widget_.get()); 844 WmLookup::Get()->GetWindowForWidget(selection_widget_.get());
830 const gfx::Rect target_bounds = 845 const gfx::Rect target_bounds =
831 root_window_->ConvertRectFromScreen(SelectedWindow()->target_bounds()); 846 root_window_->ConvertRectFromScreen(SelectedWindow()->target_bounds());
832 gfx::Vector2d fade_out_direction = 847 gfx::Vector2d fade_out_direction =
833 GetSlideVectorForFadeIn(direction, target_bounds); 848 GetSlideVectorForFadeIn(direction, target_bounds);
834 widget_window->SetBounds(target_bounds - fade_out_direction); 849 widget_window->SetBounds(target_bounds - fade_out_direction);
835 850
836 if (material) { 851 if (material) {
837 selector_shadow_.reset(new ::wm::Shadow()); 852 selector_shadow_.reset(new ::wm::Shadow());
(...skipping 19 matching lines...) Expand all
857 gfx::Vector2d fade_out_direction = 872 gfx::Vector2d fade_out_direction =
858 GetSlideVectorForFadeIn(direction, old_selection_window->GetBounds()); 873 GetSlideVectorForFadeIn(direction, old_selection_window->GetBounds());
859 874
860 ui::ScopedLayerAnimationSettings animation_settings( 875 ui::ScopedLayerAnimationSettings animation_settings(
861 old_selection_window->GetLayer()->GetAnimator()); 876 old_selection_window->GetLayer()->GetAnimator());
862 animation_settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds( 877 animation_settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(
863 kOverviewSelectorTransitionMilliseconds)); 878 kOverviewSelectorTransitionMilliseconds));
864 animation_settings.SetPreemptionStrategy( 879 animation_settings.SetPreemptionStrategy(
865 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); 880 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
866 animation_settings.SetTweenType(gfx::Tween::FAST_OUT_LINEAR_IN); 881 animation_settings.SetTweenType(gfx::Tween::FAST_OUT_LINEAR_IN);
867 // CleanupWidgetAfterAnimationObserver will delete itself (and the 882 // CleanupAnimationObserver will delete itself (and the widget) when the
868 // widget) when the movement animation is complete. 883 // motion animation is complete.
869 animation_settings.AddObserver( 884 // Ownership over the observer is passed to the window_selector_->delegate()
870 new CleanupWidgetAfterAnimationObserver(std::move(selection_widget_))); 885 // which has longer lifetime so that animations can continue even after the
886 // overview mode is shut down.
887 std::unique_ptr<CleanupAnimationObserver> observer(
888 new CleanupAnimationObserver(std::move(selection_widget_)));
889 animation_settings.AddObserver(observer.get());
890 window_selector_->delegate()->AddDelayedAnimationObserver(
891 std::move(observer));
871 old_selection->SetOpacity(0.f); 892 old_selection->SetOpacity(0.f);
872 old_selection_window->SetBounds(old_selection_window->GetBounds() + 893 old_selection_window->SetBounds(old_selection_window->GetBounds() +
873 fade_out_direction); 894 fade_out_direction);
874 old_selection->Hide(); 895 old_selection->Hide();
875 } 896 }
876 if (out_of_bounds) 897 if (out_of_bounds)
877 return; 898 return;
878 899
879 if (!selection_widget_) 900 if (!selection_widget_)
880 InitSelectionWidget(direction); 901 InitSelectionWidget(direction);
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 *min_right = left; 1014 *min_right = left;
994 if (*max_right < left) 1015 if (*max_right < left)
995 *max_right = left; 1016 *max_right = left;
996 } 1017 }
997 *max_bottom = top + height; 1018 *max_bottom = top + height;
998 } 1019 }
999 return windows_fit; 1020 return windows_fit;
1000 } 1021 }
1001 1022
1002 } // namespace ash 1023 } // namespace ash
OLDNEW
« no previous file with comments | « ash/common/wm/overview/window_grid.h ('k') | ash/common/wm/overview/window_selector.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698