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/window_selector_item.h" | 5 #include "ash/common/wm/overview/window_selector_item.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/metrics/user_metrics_action.h" | 11 #include "ash/common/metrics/user_metrics_action.h" |
12 #include "ash/common/shell_window_ids.h" | 12 #include "ash/common/shell_window_ids.h" |
| 13 #include "ash/common/wm/overview/cleanup_animation_observer.h" |
13 #include "ash/common/wm/overview/overview_animation_type.h" | 14 #include "ash/common/wm/overview/overview_animation_type.h" |
14 #include "ash/common/wm/overview/scoped_overview_animation_settings.h" | 15 #include "ash/common/wm/overview/scoped_overview_animation_settings.h" |
15 #include "ash/common/wm/overview/scoped_overview_animation_settings_factory.h" | 16 #include "ash/common/wm/overview/scoped_overview_animation_settings_factory.h" |
16 #include "ash/common/wm/overview/scoped_transform_overview_window.h" | 17 #include "ash/common/wm/overview/scoped_transform_overview_window.h" |
17 #include "ash/common/wm/overview/window_selector.h" | 18 #include "ash/common/wm/overview/window_selector.h" |
18 #include "ash/common/wm/overview/window_selector_controller.h" | 19 #include "ash/common/wm/overview/window_selector_controller.h" |
19 #include "ash/common/wm/window_state.h" | 20 #include "ash/common/wm/window_state.h" |
20 #include "ash/common/wm_lookup.h" | 21 #include "ash/common/wm_lookup.h" |
21 #include "ash/common/wm_root_window_controller.h" | 22 #include "ash/common/wm_root_window_controller.h" |
22 #include "ash/common/wm_shell.h" | 23 #include "ash/common/wm_shell.h" |
23 #include "ash/common/wm_window.h" | 24 #include "ash/common/wm_window.h" |
24 #include "ash/common/wm_window_property.h" | 25 #include "ash/common/wm_window_property.h" |
25 #include "base/auto_reset.h" | 26 #include "base/auto_reset.h" |
26 #include "base/strings/string_util.h" | 27 #include "base/strings/string_util.h" |
27 #include "base/strings/utf_string_conversions.h" | 28 #include "base/strings/utf_string_conversions.h" |
28 #include "base/time/time.h" | 29 #include "base/time/time.h" |
29 #include "grit/ash_resources.h" | 30 #include "grit/ash_resources.h" |
30 #include "grit/ash_strings.h" | 31 #include "grit/ash_strings.h" |
31 #include "ui/base/l10n/l10n_util.h" | 32 #include "ui/base/l10n/l10n_util.h" |
32 #include "ui/base/resource/resource_bundle.h" | 33 #include "ui/base/resource/resource_bundle.h" |
| 34 #include "ui/compositor/layer_animation_sequence.h" |
| 35 #include "ui/compositor/scoped_animation_duration_scale_mode.h" |
33 #include "ui/gfx/canvas.h" | 36 #include "ui/gfx/canvas.h" |
| 37 #include "ui/gfx/color_utils.h" |
34 #include "ui/gfx/geometry/safe_integer_conversions.h" | 38 #include "ui/gfx/geometry/safe_integer_conversions.h" |
35 #include "ui/gfx/geometry/vector2d.h" | 39 #include "ui/gfx/geometry/vector2d.h" |
36 #include "ui/gfx/paint_vector_icon.h" | 40 #include "ui/gfx/paint_vector_icon.h" |
37 #include "ui/gfx/transform_util.h" | 41 #include "ui/gfx/transform_util.h" |
38 #include "ui/gfx/vector_icons_public.h" | 42 #include "ui/gfx/vector_icons_public.h" |
39 #include "ui/strings/grit/ui_strings.h" | 43 #include "ui/strings/grit/ui_strings.h" |
40 #include "ui/views/background.h" | 44 #include "ui/views/background.h" |
41 #include "ui/views/border.h" | 45 #include "ui/views/border.h" |
42 #include "ui/views/controls/button/image_button.h" | |
43 #include "ui/views/layout/box_layout.h" | 46 #include "ui/views/layout/box_layout.h" |
44 #include "ui/views/window/non_client_view.h" | 47 #include "ui/views/window/non_client_view.h" |
45 #include "ui/wm/core/shadow.h" | 48 #include "ui/wm/core/shadow.h" |
46 #include "ui/wm/core/window_util.h" | 49 #include "ui/wm/core/window_util.h" |
47 | 50 |
48 namespace ash { | 51 namespace ash { |
49 | 52 |
50 namespace { | 53 namespace { |
51 | 54 |
52 // In the conceptual overview table, the window margin is the space reserved | 55 // In the conceptual overview table, the window margin is the space reserved |
53 // around the window within the cell. This margin does not overlap so the | 56 // around the window within the cell. This margin does not overlap so the |
54 // closest distance between adjacent windows will be twice this amount. | 57 // closest distance between adjacent windows will be twice this amount. |
55 static const int kWindowMargin = 30; | 58 static const int kWindowMargin = 30; |
56 static const int kWindowMarginMD = 5; | 59 static const int kWindowMarginMD = 5; |
57 | 60 |
58 // Cover the transformed window including the gaps between the windows with a | 61 // Cover the transformed window including the gaps between the windows with a |
59 // transparent shield to block the input events from reaching the transformed | 62 // transparent shield to block the input events from reaching the transformed |
60 // window while in overview. | 63 // window while in overview. |
61 static const int kWindowSelectorMargin = kWindowMarginMD * 2; | 64 static const int kWindowSelectorMargin = kWindowMarginMD * 2; |
62 | 65 |
63 // Foreground label color. | 66 // Foreground label color. |
64 static const SkColor kLabelColor = SK_ColorWHITE; | 67 static const SkColor kLabelColor = SK_ColorWHITE; |
65 | 68 |
66 // TODO(tdanderson): Move this to a central location. | 69 // TODO(tdanderson): Move this to a central location. |
67 static const SkColor kCloseButtonColor = SK_ColorWHITE; | 70 static const SkColor kCloseButtonColor = SK_ColorWHITE; |
68 | 71 |
69 // Label background color used with Material Design. | 72 // Label background color used with Material Design once in overview mode. |
70 // TODO(varkha): Make background color conform to window header. | |
71 static const SkColor kLabelBackgroundColor = SkColorSetARGB(25, 255, 255, 255); | 73 static const SkColor kLabelBackgroundColor = SkColorSetARGB(25, 255, 255, 255); |
72 | 74 |
| 75 // Label background color used with Material Design when exiting overview mode. |
| 76 static const SkColor kLabelExitColor = SkColorSetARGB(255, 90, 90, 90); |
| 77 |
73 // Corner radius for the selection tiles used with Material Design. | 78 // Corner radius for the selection tiles used with Material Design. |
74 static int kLabelBackgroundRadius = 2; | 79 static int kLabelBackgroundRadius = 2; |
75 | 80 |
76 // Label shadow color. | 81 // Label shadow color. |
77 static const SkColor kLabelShadow = SkColorSetARGB(176, 0, 0, 0); | 82 static const SkColor kLabelShadow = SkColorSetARGB(176, 0, 0, 0); |
78 | 83 |
79 // Vertical padding for the label, on top of it. | 84 // Vertical padding for the label, on top of it. |
80 static const int kVerticalLabelPadding = 20; | 85 static const int kVerticalLabelPadding = 20; |
81 | 86 |
82 // Horizontal padding for the label, on both sides. Used with Material Design. | 87 // Horizontal padding for the label, on both sides. Used with Material Design. |
83 static const int kHorizontalLabelPaddingMD = 8; | 88 static const int kHorizontalLabelPaddingMD = 8; |
84 | 89 |
85 // Solid shadow length from the label | 90 // Solid shadow length from the label |
86 static const int kVerticalShadowOffset = 1; | 91 static const int kVerticalShadowOffset = 1; |
87 | 92 |
88 // Amount of blur applied to the label shadow | 93 // Amount of blur applied to the label shadow |
89 static const int kShadowBlur = 10; | 94 static const int kShadowBlur = 10; |
90 | 95 |
91 // Height of an item header in Material Design. | 96 // Height of an item header in Material Design. |
92 static const int kHeaderHeight = 32; | 97 static const int kHeaderHeight = 32; |
93 | 98 |
94 // Opacity for dimmed items. | 99 // Opacity for dimmed items. |
95 static const float kDimmedItemOpacity = 0.5f; | 100 static const float kDimmedItemOpacity = 0.5f; |
96 | 101 |
97 // Opacity for fading out during closing a window. | 102 // Opacity for fading out during closing a window. |
98 static const float kClosingItemOpacity = 0.8f; | 103 static const float kClosingItemOpacity = 0.8f; |
99 | 104 |
| 105 // Opacity for the item header. |
| 106 static const float kHeaderOpacity = |
| 107 (SkColorGetA(kLabelBackgroundColor) / 255.f); |
| 108 |
| 109 // Duration it takes for the header to shift from opaque header color to |
| 110 // |kLabelBackgroundColor|. |
| 111 static const int kSelectorColorSlideMilliseconds = 240; |
| 112 |
100 // Duration of background opacity transition for the selected label. | 113 // Duration of background opacity transition for the selected label. |
101 static const int kSelectorFadeInMilliseconds = 350; | 114 static const int kSelectorFadeInMilliseconds = 350; |
102 | 115 |
| 116 // Duration of background opacity transition when exiting overview mode. |
| 117 static const int kExitFadeInMilliseconds = 30; |
| 118 |
103 // Before closing a window animate both the window and the caption to shrink by | 119 // Before closing a window animate both the window and the caption to shrink by |
104 // this fraction of size. | 120 // this fraction of size. |
105 static const float kPreCloseScale = 0.02f; | 121 static const float kPreCloseScale = 0.02f; |
106 | 122 |
107 // Convenience method to fade in a Window with predefined animation settings. | 123 // Convenience method to fade in a Window with predefined animation settings. |
108 // Note: The fade in animation will occur after a delay where the delay is how | 124 // Note: The fade in animation will occur after a delay where the delay is how |
109 // long the lay out animations take. | 125 // long the lay out animations take. |
110 void SetupFadeInAfterLayout(views::Widget* widget) { | 126 void SetupFadeInAfterLayout(views::Widget* widget) { |
111 WmWindow* window = WmLookup::Get()->GetWindowForWidget(widget); | 127 WmWindow* window = WmLookup::Get()->GetWindowForWidget(widget); |
112 window->SetOpacity(0.0f); | 128 window->SetOpacity(0.0f); |
113 std::unique_ptr<ScopedOverviewAnimationSettings> | 129 std::unique_ptr<ScopedOverviewAnimationSettings> |
114 scoped_overview_animation_settings = | 130 scoped_overview_animation_settings = |
115 ScopedOverviewAnimationSettingsFactory::Get() | 131 ScopedOverviewAnimationSettingsFactory::Get() |
116 ->CreateOverviewAnimationSettings( | 132 ->CreateOverviewAnimationSettings( |
117 OverviewAnimationType:: | 133 OverviewAnimationType:: |
118 OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_IN, | 134 OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_IN, |
119 window); | 135 window); |
120 window->SetOpacity(1.0f); | 136 window->SetOpacity(1.0f); |
121 } | 137 } |
122 | 138 |
123 // An image button with a close window icon. | 139 } // namespace |
124 class OverviewCloseButton : public views::ImageButton { | |
125 public: | |
126 explicit OverviewCloseButton(views::ButtonListener* listener); | |
127 ~OverviewCloseButton() override; | |
128 | 140 |
129 private: | 141 WindowSelectorItem::OverviewCloseButton::OverviewCloseButton( |
130 gfx::ImageSkia icon_image_; | 142 views::ButtonListener* listener) |
131 | |
132 DISALLOW_COPY_AND_ASSIGN(OverviewCloseButton); | |
133 }; | |
134 | |
135 OverviewCloseButton::OverviewCloseButton(views::ButtonListener* listener) | |
136 : views::ImageButton(listener) { | 143 : views::ImageButton(listener) { |
137 if (ash::MaterialDesignController::IsOverviewMaterial()) { | 144 if (ash::MaterialDesignController::IsOverviewMaterial()) { |
138 icon_image_ = gfx::CreateVectorIcon(gfx::VectorIconId::WINDOW_CONTROL_CLOSE, | 145 icon_image_ = gfx::CreateVectorIcon(gfx::VectorIconId::WINDOW_CONTROL_CLOSE, |
139 kCloseButtonColor); | 146 kCloseButtonColor); |
140 SetImage(views::CustomButton::STATE_NORMAL, &icon_image_); | 147 SetImage(views::CustomButton::STATE_NORMAL, &icon_image_); |
141 SetImage(views::CustomButton::STATE_HOVERED, &icon_image_); | 148 SetImage(views::CustomButton::STATE_HOVERED, &icon_image_); |
142 SetImage(views::CustomButton::STATE_PRESSED, &icon_image_); | 149 SetImage(views::CustomButton::STATE_PRESSED, &icon_image_); |
143 SetImageAlignment(views::ImageButton::ALIGN_CENTER, | 150 SetImageAlignment(views::ImageButton::ALIGN_CENTER, |
144 views::ImageButton::ALIGN_MIDDLE); | 151 views::ImageButton::ALIGN_MIDDLE); |
145 SetMinimumImageSize(gfx::Size(kHeaderHeight, kHeaderHeight)); | 152 SetMinimumImageSize(gfx::Size(kHeaderHeight, kHeaderHeight)); |
146 } else { | 153 } else { |
147 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 154 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
148 SetImage(views::CustomButton::STATE_NORMAL, | 155 SetImage(views::CustomButton::STATE_NORMAL, |
149 rb.GetImageSkiaNamed(IDR_AURA_WINDOW_OVERVIEW_CLOSE)); | 156 rb.GetImageSkiaNamed(IDR_AURA_WINDOW_OVERVIEW_CLOSE)); |
150 SetImage(views::CustomButton::STATE_HOVERED, | 157 SetImage(views::CustomButton::STATE_HOVERED, |
151 rb.GetImageSkiaNamed(IDR_AURA_WINDOW_OVERVIEW_CLOSE_H)); | 158 rb.GetImageSkiaNamed(IDR_AURA_WINDOW_OVERVIEW_CLOSE_H)); |
152 SetImage(views::CustomButton::STATE_PRESSED, | 159 SetImage(views::CustomButton::STATE_PRESSED, |
153 rb.GetImageSkiaNamed(IDR_AURA_WINDOW_OVERVIEW_CLOSE_P)); | 160 rb.GetImageSkiaNamed(IDR_AURA_WINDOW_OVERVIEW_CLOSE_P)); |
154 } | 161 } |
155 } | 162 } |
156 | 163 |
157 OverviewCloseButton::~OverviewCloseButton() {} | 164 WindowSelectorItem::OverviewCloseButton::~OverviewCloseButton() {} |
158 | 165 |
159 // A View having rounded corners and a specified background color which is | 166 // A View having rounded top corners and a specified background color which is |
160 // only painted within the bounds defined by the rounded corners. | 167 // only painted within the bounds defined by the rounded corners. |
161 // TODO(varkha): This duplicates code from RoundedImageView. Refactor these | 168 // This class coordinates the transitions of the overview mode header when |
162 // classes and move into ui/views. | 169 // entering the overview mode. Those animations are: |
163 class RoundedContainerView : public views::View { | 170 // - Opacity animation. The header is initially same color as the original |
| 171 // window's header. It starts as transparent and is faded in. When the full |
| 172 // opacity is reached the original header is hidden (which is nearly |
| 173 // imperceptable because this view obscures the original header) and a color |
| 174 // animation starts. |
| 175 // - Color animation is used to change the color from the opaque color of the |
| 176 // original window's header to semi-transparent color of the overview mode |
| 177 // header (on entry to overview). It is also used on exit from overview to |
| 178 // quickly change the color to a close opaque color in parallel with an |
| 179 // opacity transition to mask the original header reappearing. |
| 180 class WindowSelectorItem::RoundedContainerView |
| 181 : public views::View, |
| 182 public gfx::AnimationDelegate, |
| 183 public ui::LayerAnimationObserver { |
164 public: | 184 public: |
165 RoundedContainerView(int corner_radius, SkColor background) | 185 RoundedContainerView(WindowSelectorItem* item, |
166 : corner_radius_(corner_radius), background_(background) {} | 186 WmWindow* item_window, |
| 187 int corner_radius, |
| 188 SkColor background) |
| 189 : item_(item), |
| 190 item_window_(item_window), |
| 191 corner_radius_(corner_radius), |
| 192 initial_color_(background), |
| 193 target_color_(background), |
| 194 current_value_(0), |
| 195 layer_(nullptr), |
| 196 animation_(new gfx::SlideAnimation(this)) {} |
167 | 197 |
168 ~RoundedContainerView() override {} | 198 ~RoundedContainerView() override { StopObservingLayerAnimations(); } |
169 | 199 |
| 200 void OnItemRestored() { item_ = nullptr; } |
| 201 |
| 202 // Starts observing layer animations so that actions can be taken when |
| 203 // particular animations (opacity) complete. It should only be called once |
| 204 // when the initial fade in animation is started. |
| 205 void ObserveLayerAnimations(ui::Layer* layer) { |
| 206 DCHECK(!layer_); |
| 207 layer_ = layer; |
| 208 layer_->GetAnimator()->AddObserver(this); |
| 209 } |
| 210 |
| 211 // Stops observing layer animations |
| 212 void StopObservingLayerAnimations() { |
| 213 if (!layer_) |
| 214 return; |
| 215 layer_->GetAnimator()->RemoveObserver(this); |
| 216 layer_ = nullptr; |
| 217 } |
| 218 |
| 219 void set_color(SkColor target_color) { target_color_ = target_color; } |
| 220 |
| 221 // Starts a color animation using |tween_type|. The animation will change the |
| 222 // color from |initial_color_| to |target_color_| over |duration| specified |
| 223 // in milliseconds. |
| 224 // This animation can start once the implicit layer fade-in opacity animation |
| 225 // is completed. It is used to transition color from the opaque original |
| 226 // window header color to |kLabelBackgroundColor| on entry into overview mode |
| 227 // and from |kLabelBackgroundColor| back to the original window header color |
| 228 // on exit from the overview mode. |
| 229 void AnimateColor(gfx::Tween::Type tween_type, int duration) { |
| 230 DCHECK(!layer_); // layer animations should be completed. |
| 231 animation_->SetSlideDuration(duration); |
| 232 animation_->SetTweenType(tween_type); |
| 233 animation_->Reset(0); |
| 234 animation_->Show(); |
| 235 |
| 236 // Tests complete animations immediately. Emulate by invoking the callback. |
| 237 if (ui::ScopedAnimationDurationScaleMode::duration_scale_mode() == |
| 238 ui::ScopedAnimationDurationScaleMode::ZERO_DURATION) { |
| 239 AnimationEnded(animation_.get()); |
| 240 } |
| 241 } |
| 242 |
| 243 // Changes the view opacity by animating its background color. The animation |
| 244 // will change the alpha value in |target_color_| from its current value to |
| 245 // |opacity| * 255 but preserve the RGB values. |
| 246 void AnimateBackgroundOpacity(float opacity) { |
| 247 animation_->SetSlideDuration(kSelectorFadeInMilliseconds); |
| 248 animation_->SetTweenType(gfx::Tween::EASE_OUT); |
| 249 animation_->Reset(0); |
| 250 animation_->Show(); |
| 251 target_color_ = SkColorSetA(target_color_, opacity * 255); |
| 252 } |
| 253 |
| 254 // views::View: |
170 void OnPaint(gfx::Canvas* canvas) override { | 255 void OnPaint(gfx::Canvas* canvas) override { |
171 views::View::OnPaint(canvas); | 256 views::View::OnPaint(canvas); |
172 | |
173 SkScalar radius = SkIntToScalar(corner_radius_); | 257 SkScalar radius = SkIntToScalar(corner_radius_); |
174 const SkScalar kRadius[8] = {radius, radius, radius, radius, | 258 const SkScalar kRadius[8] = {radius, radius, radius, radius, 0, 0, 0, 0}; |
175 radius, radius, radius, radius}; | |
176 SkPath path; | 259 SkPath path; |
177 gfx::Rect bounds(size()); | 260 gfx::Rect bounds(size()); |
178 bounds.set_height(bounds.height() + radius); | |
179 path.addRoundRect(gfx::RectToSkRect(bounds), kRadius); | 261 path.addRoundRect(gfx::RectToSkRect(bounds), kRadius); |
180 | 262 |
181 SkPaint paint; | 263 SkPaint paint; |
182 paint.setAntiAlias(true); | 264 paint.setAntiAlias(true); |
183 canvas->ClipPath(path, true); | 265 canvas->ClipPath(path, true); |
184 canvas->DrawColor(background_); | 266 |
| 267 SkColor target_color = initial_color_; |
| 268 if (target_color_ != target_color) { |
| 269 target_color = color_utils::AlphaBlend(target_color_, initial_color_, |
| 270 current_value_); |
| 271 } |
| 272 canvas->DrawColor(target_color); |
185 } | 273 } |
186 | 274 |
187 private: | 275 private: |
| 276 // gfx::AnimationDelegate: |
| 277 void AnimationEnded(const gfx::Animation* animation) override { |
| 278 initial_color_ = target_color_; |
| 279 // Tabbed browser windows show the overview mode header behind the window |
| 280 // during the initial animation. Once the initial fade-in completes and the |
| 281 // overview header is fully exposed update stacking to keep the label above |
| 282 // the item which prevents input events from reaching the window. |
| 283 WmWindow* label_window = WmLookup::Get()->GetWindowForWidget(GetWidget()); |
| 284 if (label_window && item_window_) |
| 285 label_window->GetParent()->StackChildAbove(label_window, item_window_); |
| 286 item_window_ = nullptr; |
| 287 } |
| 288 |
| 289 void AnimationProgressed(const gfx::Animation* animation) override { |
| 290 current_value_ = animation_->CurrentValueBetween(0, 255); |
| 291 SchedulePaint(); |
| 292 } |
| 293 |
| 294 void AnimationCanceled(const gfx::Animation* animation) override { |
| 295 item_window_ = nullptr; |
| 296 initial_color_ = target_color_; |
| 297 current_value_ = 255; |
| 298 SchedulePaint(); |
| 299 } |
| 300 |
| 301 // ui::LayerAnimationObserver: |
| 302 void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override { |
| 303 if (0 != (sequence->properties() & |
| 304 ui::LayerAnimationElement::AnimatableProperty::OPACITY)) { |
| 305 if (item_) |
| 306 item_->HideHeaderAndSetShape(0); |
| 307 StopObservingLayerAnimations(); |
| 308 AnimateColor(gfx::Tween::EASE_IN, kSelectorColorSlideMilliseconds); |
| 309 } |
| 310 } |
| 311 |
| 312 void OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) override { |
| 313 if (0 != (sequence->properties() & |
| 314 ui::LayerAnimationElement::AnimatableProperty::OPACITY)) { |
| 315 StopObservingLayerAnimations(); |
| 316 } |
| 317 } |
| 318 |
| 319 void OnLayerAnimationScheduled( |
| 320 ui::LayerAnimationSequence* sequence) override {} |
| 321 |
| 322 WindowSelectorItem* item_; |
| 323 WmWindow* item_window_; |
188 int corner_radius_; | 324 int corner_radius_; |
189 SkColor background_; | 325 SkColor initial_color_; |
| 326 SkColor target_color_; |
| 327 int current_value_; |
| 328 ui::Layer* layer_; |
| 329 std::unique_ptr<gfx::SlideAnimation> animation_; |
190 | 330 |
191 DISALLOW_COPY_AND_ASSIGN(RoundedContainerView); | 331 DISALLOW_COPY_AND_ASSIGN(RoundedContainerView); |
192 }; | 332 }; |
193 | 333 |
194 } // namespace | |
195 | |
196 bool WindowSelectorItem::use_mask_ = false; | 334 bool WindowSelectorItem::use_mask_ = false; |
197 bool WindowSelectorItem::use_shape_ = false; | 335 bool WindowSelectorItem::use_shape_ = false; |
198 | 336 |
199 WindowSelectorItem::OverviewLabelButton::OverviewLabelButton( | 337 WindowSelectorItem::OverviewLabelButton::OverviewLabelButton( |
200 views::ButtonListener* listener, | 338 views::ButtonListener* listener, |
201 const base::string16& text) | 339 const base::string16& text) |
202 : LabelButton(listener, text) {} | 340 : LabelButton(listener, text) {} |
203 | 341 |
204 WindowSelectorItem::OverviewLabelButton::~OverviewLabelButton() {} | 342 WindowSelectorItem::OverviewLabelButton::~OverviewLabelButton() {} |
205 | 343 |
(...skipping 10 matching lines...) Expand all Loading... |
216 bounds.Inset(padding_); | 354 bounds.Inset(padding_); |
217 if (ash::MaterialDesignController::IsOverviewMaterial()) | 355 if (ash::MaterialDesignController::IsOverviewMaterial()) |
218 bounds.Inset(kHorizontalLabelPaddingMD, 0, kHorizontalLabelPaddingMD, 0); | 356 bounds.Inset(kHorizontalLabelPaddingMD, 0, kHorizontalLabelPaddingMD, 0); |
219 return bounds; | 357 return bounds; |
220 } | 358 } |
221 | 359 |
222 // Container View that has an item label and a close button as children. | 360 // Container View that has an item label and a close button as children. |
223 class WindowSelectorItem::CaptionContainerView : public views::View { | 361 class WindowSelectorItem::CaptionContainerView : public views::View { |
224 public: | 362 public: |
225 CaptionContainerView(WindowSelectorItem::OverviewLabelButton* label, | 363 CaptionContainerView(WindowSelectorItem::OverviewLabelButton* label, |
226 views::ImageButton* close_button) | 364 views::ImageButton* close_button, |
227 : label_(label), close_button_(close_button) { | 365 WindowSelectorItem::RoundedContainerView* background) |
| 366 : label_(label), close_button_(close_button), background_(background) { |
| 367 AddChildView(background_); |
228 AddChildView(label_); | 368 AddChildView(label_); |
229 AddChildView(close_button_); | 369 AddChildView(close_button_); |
230 } | 370 } |
231 | 371 |
232 protected: | 372 protected: |
233 // views::View: | 373 // views::View: |
234 void Layout() override { | 374 void Layout() override { |
235 // Position close button in the top right corner sized to its icon size and | 375 // Position close button in the top right corner sized to its icon size and |
236 // the label in the top left corner as tall as the button and extending to | 376 // the label in the top left corner as tall as the button and extending to |
237 // the button's left edge. | 377 // the button's left edge. |
238 // The rest of this container view serves as a shield to prevent input | 378 // The rest of this container view serves as a shield to prevent input |
239 // events from reaching the transformed window in overview. | 379 // events from reaching the transformed window in overview. |
240 gfx::Rect bounds(GetLocalBounds()); | 380 gfx::Rect bounds(GetLocalBounds()); |
241 bounds.Inset(kWindowSelectorMargin, kWindowSelectorMargin); | 381 bounds.Inset(kWindowSelectorMargin, kWindowSelectorMargin); |
| 382 gfx::Rect background_bounds(bounds); |
| 383 background_bounds.set_height(close_button_->GetPreferredSize().height()); |
| 384 background_->SetBoundsRect(background_bounds); |
| 385 |
242 const int visible_height = close_button_->GetPreferredSize().height(); | 386 const int visible_height = close_button_->GetPreferredSize().height(); |
243 gfx::Insets label_padding(0, 0, bounds.height() - visible_height, | 387 gfx::Insets label_padding(0, 0, bounds.height() - visible_height, |
244 visible_height); | 388 visible_height); |
245 label_->set_padding(label_padding); | 389 label_->set_padding(label_padding); |
246 label_->SetBoundsRect(bounds); | 390 label_->SetBoundsRect(bounds); |
247 bounds.set_x(bounds.right() - visible_height); | 391 bounds.set_x(bounds.right() - visible_height); |
248 bounds.set_width(visible_height); | 392 bounds.set_width(visible_height); |
249 bounds.set_height(visible_height); | 393 bounds.set_height(visible_height); |
250 close_button_->SetBoundsRect(bounds); | 394 close_button_->SetBoundsRect(bounds); |
251 } | 395 } |
252 | 396 |
253 void OnBoundsChanged(const gfx::Rect& previous_bounds) override { Layout(); } | |
254 | |
255 private: | 397 private: |
256 WindowSelectorItem::OverviewLabelButton* label_; | 398 WindowSelectorItem::OverviewLabelButton* label_; |
257 views::ImageButton* close_button_; | 399 views::ImageButton* close_button_; |
| 400 WindowSelectorItem::RoundedContainerView* background_; |
258 | 401 |
259 DISALLOW_COPY_AND_ASSIGN(CaptionContainerView); | 402 DISALLOW_COPY_AND_ASSIGN(CaptionContainerView); |
260 }; | 403 }; |
261 | 404 |
262 WindowSelectorItem::WindowSelectorItem(WmWindow* window, | 405 WindowSelectorItem::WindowSelectorItem(WmWindow* window, |
263 WindowSelector* window_selector) | 406 WindowSelector* window_selector) |
264 : dimmed_(false), | 407 : dimmed_(false), |
265 root_window_(window->GetRootWindow()), | 408 root_window_(window->GetRootWindow()), |
266 transform_window_(window), | 409 transform_window_(window), |
267 in_bounds_update_(false), | 410 in_bounds_update_(false), |
| 411 selected_(false), |
268 caption_container_view_(nullptr), | 412 caption_container_view_(nullptr), |
269 window_label_button_view_(nullptr), | 413 window_label_button_view_(nullptr), |
270 close_button_(new OverviewCloseButton(this)), | 414 close_button_(new OverviewCloseButton(this)), |
271 window_selector_(window_selector) { | 415 window_selector_(window_selector), |
| 416 background_view_(nullptr) { |
272 CreateWindowLabel(window->GetTitle()); | 417 CreateWindowLabel(window->GetTitle()); |
273 if (!ash::MaterialDesignController::IsOverviewMaterial()) { | 418 if (!ash::MaterialDesignController::IsOverviewMaterial()) { |
274 views::Widget::InitParams params; | 419 views::Widget::InitParams params; |
275 params.type = views::Widget::InitParams::TYPE_POPUP; | 420 params.type = views::Widget::InitParams::TYPE_POPUP; |
276 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 421 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
277 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; | 422 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; |
278 params.name = "OverviewModeCloseButton"; | 423 params.name = "OverviewModeCloseButton"; |
279 close_button_widget_.reset(new views::Widget); | 424 close_button_widget_.reset(new views::Widget); |
280 close_button_widget_->set_focus_on_creation(false); | 425 close_button_widget_->set_focus_on_creation(false); |
281 window->GetRootWindowController()->ConfigureWidgetInitParamsForContainer( | 426 window->GetRootWindowController()->ConfigureWidgetInitParamsForContainer( |
(...skipping 11 matching lines...) Expand all Loading... |
293 close_button_rect.set_x(-close_button_rect.width() / 2); | 438 close_button_rect.set_x(-close_button_rect.width() / 2); |
294 close_button_rect.set_y(-close_button_rect.height() / 2); | 439 close_button_rect.set_y(-close_button_rect.height() / 2); |
295 WmLookup::Get() | 440 WmLookup::Get() |
296 ->GetWindowForWidget(close_button_widget_.get()) | 441 ->GetWindowForWidget(close_button_widget_.get()) |
297 ->SetBounds(close_button_rect); | 442 ->SetBounds(close_button_rect); |
298 } | 443 } |
299 GetWindow()->AddObserver(this); | 444 GetWindow()->AddObserver(this); |
300 } | 445 } |
301 | 446 |
302 WindowSelectorItem::~WindowSelectorItem() { | 447 WindowSelectorItem::~WindowSelectorItem() { |
| 448 if (background_view_) |
| 449 background_view_->OnItemRestored(); |
303 GetWindow()->RemoveObserver(this); | 450 GetWindow()->RemoveObserver(this); |
304 } | 451 } |
305 | 452 |
306 WmWindow* WindowSelectorItem::GetWindow() { | 453 WmWindow* WindowSelectorItem::GetWindow() { |
307 return transform_window_.window(); | 454 return transform_window_.window(); |
308 } | 455 } |
309 | 456 |
310 void WindowSelectorItem::RestoreWindow() { | 457 void WindowSelectorItem::RestoreWindow() { |
| 458 window_label_button_view_->ResetListener(); |
| 459 close_button_->ResetListener(); |
311 transform_window_.RestoreWindow(); | 460 transform_window_.RestoreWindow(); |
| 461 if (background_view_) |
| 462 background_view_->OnItemRestored(); |
| 463 UpdateHeaderLayout( |
| 464 HeaderFadeInMode::EXIT, |
| 465 OverviewAnimationType::OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS); |
| 466 } |
| 467 |
| 468 void WindowSelectorItem::Shutdown() { |
| 469 if (transform_window_.GetTopInset()) { |
| 470 // Activating a window (even when it is the window that was active before |
| 471 // overview) results in stacking it at the top. Maintain the label window |
| 472 // stacking position above the item to make the header transformation more |
| 473 // gradual upon exiting the overview mode. |
| 474 WmWindow* label_window = |
| 475 WmLookup::Get()->GetWindowForWidget(window_label_.get()); |
| 476 label_window->GetParent()->StackChildAbove(label_window, |
| 477 transform_window_.window()); |
| 478 } |
| 479 FadeOut(std::move(window_label_)); |
312 } | 480 } |
313 | 481 |
314 void WindowSelectorItem::ShowWindowOnExit() { | 482 void WindowSelectorItem::ShowWindowOnExit() { |
315 transform_window_.ShowWindowOnExit(); | 483 transform_window_.ShowWindowOnExit(); |
316 } | 484 } |
317 | 485 |
318 void WindowSelectorItem::PrepareForOverview() { | 486 void WindowSelectorItem::PrepareForOverview() { |
319 transform_window_.PrepareForOverview(); | 487 transform_window_.PrepareForOverview(); |
320 } | 488 } |
321 | 489 |
(...skipping 10 matching lines...) Expand all Loading... |
332 | 500 |
333 gfx::Rect inset_bounds(target_bounds); | 501 gfx::Rect inset_bounds(target_bounds); |
334 if (ash::MaterialDesignController::IsOverviewMaterial()) | 502 if (ash::MaterialDesignController::IsOverviewMaterial()) |
335 inset_bounds.Inset(kWindowMarginMD, kWindowMarginMD); | 503 inset_bounds.Inset(kWindowMarginMD, kWindowMarginMD); |
336 else | 504 else |
337 inset_bounds.Inset(kWindowMargin, kWindowMargin); | 505 inset_bounds.Inset(kWindowMargin, kWindowMargin); |
338 SetItemBounds(inset_bounds, animation_type); | 506 SetItemBounds(inset_bounds, animation_type); |
339 | 507 |
340 // SetItemBounds is called before UpdateHeaderLayout so the header can | 508 // SetItemBounds is called before UpdateHeaderLayout so the header can |
341 // properly use the updated windows bounds. | 509 // properly use the updated windows bounds. |
342 UpdateHeaderLayout(animation_type); | 510 UpdateHeaderLayout(HeaderFadeInMode::UPDATE, animation_type); |
343 if (!ash::MaterialDesignController::IsOverviewMaterial()) | 511 if (!ash::MaterialDesignController::IsOverviewMaterial()) |
344 UpdateWindowLabel(target_bounds, animation_type); | 512 UpdateWindowLabel(target_bounds, animation_type); |
345 } | 513 } |
346 | 514 |
347 void WindowSelectorItem::SetSelected(bool selected) { | 515 void WindowSelectorItem::SetSelected(bool selected) { |
348 if (!ash::MaterialDesignController::IsOverviewMaterial()) | 516 if (!ash::MaterialDesignController::IsOverviewMaterial()) |
349 return; | 517 return; |
350 WmWindow* window = | 518 selected_ = selected; |
351 WmLookup::Get()->GetWindowForWidget(window_label_selector_.get()); | 519 background_view_->AnimateBackgroundOpacity(selected ? 0.f : kHeaderOpacity); |
352 ui::ScopedLayerAnimationSettings animation_settings( | |
353 window->GetLayer()->GetAnimator()); | |
354 animation_settings.SetTransitionDuration( | |
355 base::TimeDelta::FromMilliseconds(kSelectorFadeInMilliseconds)); | |
356 animation_settings.SetTweenType(selected ? gfx::Tween::FAST_OUT_LINEAR_IN | |
357 : gfx::Tween::LINEAR_OUT_SLOW_IN); | |
358 animation_settings.SetPreemptionStrategy( | |
359 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | |
360 window->SetOpacity(selected ? 0.0f : 1.0f); | |
361 | 520 |
362 ui::ScopedLayerAnimationSettings animation_settings_shadow( | 521 if (shadow_) { |
363 shadow_->shadow_layer()->GetAnimator()); | 522 ui::ScopedLayerAnimationSettings animation_settings_shadow( |
364 animation_settings_shadow.SetTransitionDuration( | 523 shadow_->shadow_layer()->GetAnimator()); |
365 base::TimeDelta::FromMilliseconds(kSelectorFadeInMilliseconds)); | 524 animation_settings_shadow.SetTransitionDuration( |
366 animation_settings_shadow.SetTweenType(selected | 525 base::TimeDelta::FromMilliseconds(kSelectorFadeInMilliseconds)); |
367 ? gfx::Tween::FAST_OUT_LINEAR_IN | 526 animation_settings_shadow.SetTweenType( |
368 : gfx::Tween::LINEAR_OUT_SLOW_IN); | 527 selected ? gfx::Tween::FAST_OUT_LINEAR_IN |
369 animation_settings_shadow.SetPreemptionStrategy( | 528 : gfx::Tween::LINEAR_OUT_SLOW_IN); |
370 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 529 animation_settings_shadow.SetPreemptionStrategy( |
371 shadow_->shadow_layer()->SetOpacity(selected ? 0.0f : 1.0f); | 530 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 531 shadow_->shadow_layer()->SetOpacity(selected ? 0.0f : 1.0f); |
| 532 } |
372 } | 533 } |
373 | 534 |
374 void WindowSelectorItem::RecomputeWindowTransforms() { | 535 void WindowSelectorItem::RecomputeWindowTransforms() { |
375 if (in_bounds_update_ || target_bounds_.IsEmpty()) | 536 if (in_bounds_update_ || target_bounds_.IsEmpty()) |
376 return; | 537 return; |
377 base::AutoReset<bool> auto_reset_in_bounds_update(&in_bounds_update_, true); | 538 base::AutoReset<bool> auto_reset_in_bounds_update(&in_bounds_update_, true); |
378 gfx::Rect inset_bounds(target_bounds_); | 539 gfx::Rect inset_bounds(target_bounds_); |
379 if (ash::MaterialDesignController::IsOverviewMaterial()) | 540 if (ash::MaterialDesignController::IsOverviewMaterial()) |
380 inset_bounds.Inset(kWindowMarginMD, kWindowMarginMD); | 541 inset_bounds.Inset(kWindowMarginMD, kWindowMarginMD); |
381 else | 542 else |
382 inset_bounds.Inset(kWindowMargin, kWindowMargin); | 543 inset_bounds.Inset(kWindowMargin, kWindowMargin); |
383 SetItemBounds(inset_bounds, OverviewAnimationType::OVERVIEW_ANIMATION_NONE); | 544 SetItemBounds(inset_bounds, OverviewAnimationType::OVERVIEW_ANIMATION_NONE); |
384 UpdateHeaderLayout(OverviewAnimationType::OVERVIEW_ANIMATION_NONE); | 545 UpdateHeaderLayout(HeaderFadeInMode::UPDATE, |
| 546 OverviewAnimationType::OVERVIEW_ANIMATION_NONE); |
385 } | 547 } |
386 | 548 |
387 void WindowSelectorItem::SendAccessibleSelectionEvent() { | 549 void WindowSelectorItem::SendAccessibleSelectionEvent() { |
388 window_label_button_view_->NotifyAccessibilityEvent(ui::AX_EVENT_SELECTION, | 550 window_label_button_view_->NotifyAccessibilityEvent(ui::AX_EVENT_SELECTION, |
389 true); | 551 true); |
390 } | 552 } |
391 | 553 |
392 void WindowSelectorItem::CloseWindow() { | 554 void WindowSelectorItem::CloseWindow() { |
393 if (ash::MaterialDesignController::IsOverviewMaterial()) { | 555 if (ash::MaterialDesignController::IsOverviewMaterial()) { |
394 gfx::Rect inset_bounds(target_bounds_); | 556 gfx::Rect inset_bounds(target_bounds_); |
395 inset_bounds.Inset(target_bounds_.width() * kPreCloseScale, | 557 inset_bounds.Inset(target_bounds_.width() * kPreCloseScale, |
396 target_bounds_.height() * kPreCloseScale); | 558 target_bounds_.height() * kPreCloseScale); |
397 OverviewAnimationType animation_type = | 559 OverviewAnimationType animation_type = |
398 OverviewAnimationType::OVERVIEW_ANIMATION_CLOSING_SELECTOR_ITEM; | 560 OverviewAnimationType::OVERVIEW_ANIMATION_CLOSING_SELECTOR_ITEM; |
399 // Scale down both the window and label. | 561 // Scale down both the window and label. |
400 SetBounds(inset_bounds, animation_type); | 562 SetBounds(inset_bounds, animation_type); |
401 // First animate opacity to an intermediate value concurrently with the | 563 // First animate opacity to an intermediate value concurrently with the |
402 // scaling animation. | 564 // scaling animation. |
403 AnimateOpacity(kClosingItemOpacity, animation_type); | 565 AnimateOpacity(kClosingItemOpacity, animation_type); |
404 | 566 |
405 // Fade out the window and the label, effectively hiding them. | 567 // Fade out the window and the label, effectively hiding them. |
406 AnimateOpacity( | 568 AnimateOpacity( |
407 0.0, OverviewAnimationType::OVERVIEW_ANIMATION_CLOSE_SELECTOR_ITEM); | 569 0.0, OverviewAnimationType::OVERVIEW_ANIMATION_CLOSE_SELECTOR_ITEM); |
408 } | 570 } |
409 transform_window_.Close(); | 571 transform_window_.Close(); |
410 } | 572 } |
411 | 573 |
| 574 void WindowSelectorItem::HideHeaderAndSetShape(int radius) { |
| 575 transform_window_.HideHeaderAndSetShape(use_mask_, use_shape_, radius); |
| 576 } |
| 577 |
412 void WindowSelectorItem::SetDimmed(bool dimmed) { | 578 void WindowSelectorItem::SetDimmed(bool dimmed) { |
413 dimmed_ = dimmed; | 579 dimmed_ = dimmed; |
414 SetOpacity(dimmed ? kDimmedItemOpacity : 1.0f); | 580 SetOpacity(dimmed ? kDimmedItemOpacity : 1.0f); |
415 } | 581 } |
416 | 582 |
417 void WindowSelectorItem::ButtonPressed(views::Button* sender, | 583 void WindowSelectorItem::ButtonPressed(views::Button* sender, |
418 const ui::Event& event) { | 584 const ui::Event& event) { |
419 if (sender == close_button_) { | 585 if (sender == close_button_) { |
420 WmShell::Get()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW_CLOSE_BUTTON); | 586 WmShell::Get()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW_CLOSE_BUTTON); |
421 CloseWindow(); | 587 CloseWindow(); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 top_view_inset = transform_window_.GetTopInset(); | 632 top_view_inset = transform_window_.GetTopInset(); |
467 title_height = close_button_->GetPreferredSize().height(); | 633 title_height = close_button_->GetPreferredSize().height(); |
468 } | 634 } |
469 gfx::Rect selector_item_bounds = | 635 gfx::Rect selector_item_bounds = |
470 ScopedTransformOverviewWindow::ShrinkRectToFitPreservingAspectRatio( | 636 ScopedTransformOverviewWindow::ShrinkRectToFitPreservingAspectRatio( |
471 screen_rect, target_bounds, top_view_inset, title_height); | 637 screen_rect, target_bounds, top_view_inset, title_height); |
472 gfx::Transform transform = ScopedTransformOverviewWindow::GetTransformForRect( | 638 gfx::Transform transform = ScopedTransformOverviewWindow::GetTransformForRect( |
473 screen_rect, selector_item_bounds); | 639 screen_rect, selector_item_bounds); |
474 ScopedTransformOverviewWindow::ScopedAnimationSettings animation_settings; | 640 ScopedTransformOverviewWindow::ScopedAnimationSettings animation_settings; |
475 transform_window_.BeginScopedAnimation(animation_type, &animation_settings); | 641 transform_window_.BeginScopedAnimation(animation_type, &animation_settings); |
476 // Rounded corners are achieved by using a mask layer on the original window | 642 transform_window_.SetTransform(root_window_, transform, use_mask_); |
477 // before the transform. Dividing by scale factor obtains the corner radius | |
478 // which when scaled will yield |kLabelBackgroundRadius|. | |
479 transform_window_.SetTransform( | |
480 root_window_, transform, use_mask_, use_shape_, | |
481 (kLabelBackgroundRadius / GetItemScale(target_bounds.size()))); | |
482 transform_window_.set_overview_transform(transform); | 643 transform_window_.set_overview_transform(transform); |
483 } | 644 } |
484 | 645 |
485 void WindowSelectorItem::SetOpacity(float opacity) { | 646 void WindowSelectorItem::SetOpacity(float opacity) { |
486 window_label_->SetOpacity(opacity); | 647 window_label_->SetOpacity(opacity); |
| 648 if (background_view_) { |
| 649 background_view_->AnimateBackgroundOpacity( |
| 650 selected_ ? 0.f : kHeaderOpacity * opacity); |
| 651 } |
| 652 |
487 if (!ash::MaterialDesignController::IsOverviewMaterial()) | 653 if (!ash::MaterialDesignController::IsOverviewMaterial()) |
488 close_button_widget_->SetOpacity(opacity); | 654 close_button_widget_->SetOpacity(opacity); |
489 | 655 |
490 transform_window_.SetOpacity(opacity); | 656 transform_window_.SetOpacity(opacity); |
491 } | 657 } |
492 | 658 |
493 void WindowSelectorItem::UpdateWindowLabel( | 659 void WindowSelectorItem::UpdateWindowLabel( |
494 const gfx::Rect& window_bounds, | 660 const gfx::Rect& window_bounds, |
495 OverviewAnimationType animation_type) { | 661 OverviewAnimationType animation_type) { |
496 if (!window_label_->IsVisible()) { | 662 if (!window_label_->IsVisible()) { |
(...skipping 10 matching lines...) Expand all Loading... |
507 animation_type, | 673 animation_type, |
508 WmLookup::Get()->GetWindowForWidget(window_label_.get())); | 674 WmLookup::Get()->GetWindowForWidget(window_label_.get())); |
509 | 675 |
510 WmWindow* window_label_window = | 676 WmWindow* window_label_window = |
511 WmLookup::Get()->GetWindowForWidget(window_label_.get()); | 677 WmLookup::Get()->GetWindowForWidget(window_label_.get()); |
512 window_label_window->SetBounds(label_bounds); | 678 window_label_window->SetBounds(label_bounds); |
513 } | 679 } |
514 | 680 |
515 void WindowSelectorItem::CreateWindowLabel(const base::string16& title) { | 681 void WindowSelectorItem::CreateWindowLabel(const base::string16& title) { |
516 const bool material = ash::MaterialDesignController::IsOverviewMaterial(); | 682 const bool material = ash::MaterialDesignController::IsOverviewMaterial(); |
517 window_label_.reset(new views::Widget); | 683 if (material) { |
518 views::Widget::InitParams params; | 684 background_view_ = new RoundedContainerView( |
519 params.type = views::Widget::InitParams::TYPE_POPUP; | 685 this, transform_window_.window(), kLabelBackgroundRadius, |
520 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 686 transform_window_.GetTopColor()); |
521 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; | 687 // |background_view_| will get added as a child to CaptionContainerView. |
522 params.visible_on_all_workspaces = true; | 688 } |
523 params.name = "OverviewModeLabel"; | 689 views::Widget::InitParams params_label; |
524 window_label_->set_focus_on_creation(false); | 690 params_label.type = views::Widget::InitParams::TYPE_POPUP; |
| 691 params_label.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 692 params_label.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; |
| 693 params_label.visible_on_all_workspaces = true; |
| 694 params_label.name = "OverviewModeLabel"; |
| 695 params_label.activatable = |
| 696 views::Widget::InitParams::Activatable::ACTIVATABLE_DEFAULT; |
| 697 params_label.accept_events = true; |
525 root_window_->GetRootWindowController() | 698 root_window_->GetRootWindowController() |
526 ->ConfigureWidgetInitParamsForContainer( | 699 ->ConfigureWidgetInitParamsForContainer( |
527 window_label_.get(), kShellWindowId_StatusContainer, ¶ms); | 700 window_label_.get(), |
528 window_label_->Init(params); | 701 transform_window_.window()->GetParent()->GetShellWindowId(), |
| 702 ¶ms_label); |
| 703 window_label_.reset(new views::Widget); |
| 704 window_label_->set_focus_on_creation(false); |
| 705 window_label_->Init(params_label); |
529 window_label_button_view_ = new OverviewLabelButton(this, title); | 706 window_label_button_view_ = new OverviewLabelButton(this, title); |
530 window_label_button_view_->SetBorder(views::Border::NullBorder()); | 707 window_label_button_view_->SetBorder(views::Border::NullBorder()); |
531 window_label_button_view_->SetEnabledTextColors(kLabelColor); | 708 window_label_button_view_->SetEnabledTextColors(kLabelColor); |
532 window_label_button_view_->set_animate_on_state_change(false); | 709 window_label_button_view_->set_animate_on_state_change(false); |
533 if (material) { | 710 if (material) { |
| 711 WmWindow* label_window = |
| 712 WmLookup::Get()->GetWindowForWidget(window_label_.get()); |
| 713 if (transform_window_.GetTopInset()) { |
| 714 // For windows with headers the overview header fades in above the |
| 715 // original window header. |
| 716 label_window->GetParent()->StackChildAbove(label_window, |
| 717 transform_window_.window()); |
| 718 } else { |
| 719 // For tabbed windows the overview header slides from behind. The stacking |
| 720 // is then corrected when the animation completes. |
| 721 label_window->GetParent()->StackChildBelow(label_window, |
| 722 transform_window_.window()); |
| 723 } |
534 window_label_button_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 724 window_label_button_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
535 } else { | 725 } else { |
536 window_label_button_view_->SetHorizontalAlignment(gfx::ALIGN_CENTER); | 726 window_label_button_view_->SetHorizontalAlignment(gfx::ALIGN_CENTER); |
537 window_label_button_view_->SetTextShadows(gfx::ShadowValues( | 727 window_label_button_view_->SetTextShadows(gfx::ShadowValues( |
538 1, gfx::ShadowValue(gfx::Vector2d(0, kVerticalShadowOffset), | 728 1, gfx::ShadowValue(gfx::Vector2d(0, kVerticalShadowOffset), |
539 kShadowBlur, kLabelShadow))); | 729 kShadowBlur, kLabelShadow))); |
540 } | 730 } |
541 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); | 731 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); |
542 window_label_button_view_->SetFontList(bundle.GetFontList( | 732 window_label_button_view_->SetFontList(bundle.GetFontList( |
543 material ? ui::ResourceBundle::BaseFont : ui::ResourceBundle::BoldFont)); | 733 material ? ui::ResourceBundle::BaseFont : ui::ResourceBundle::BoldFont)); |
544 if (material) { | 734 if (material) { |
545 // Hint at the background color that the label will be drawn onto (for | 735 // Hint at the background color that the label will be drawn onto (for |
546 // subpixel antialiasing). Does not actually set the background color. | 736 // subpixel antialiasing). Does not actually set the background color. |
547 window_label_button_view_->SetBackgroundColorHint(kLabelBackgroundColor); | 737 window_label_button_view_->SetBackgroundColorHint(kLabelBackgroundColor); |
548 caption_container_view_ = | 738 caption_container_view_ = new CaptionContainerView( |
549 new CaptionContainerView(window_label_button_view_, close_button_); | 739 window_label_button_view_, close_button_, background_view_); |
550 window_label_->SetContentsView(caption_container_view_); | 740 window_label_->SetContentsView(caption_container_view_); |
551 window_label_button_view_->SetVisible(false); | 741 window_label_button_view_->SetVisible(false); |
| 742 window_label_->SetOpacity(0); |
552 window_label_->Show(); | 743 window_label_->Show(); |
553 | 744 |
554 shadow_.reset(new ::wm::Shadow()); | 745 // TODO(varkha): Restore shadows when programmatic shadows exist. |
555 shadow_->Init(::wm::Shadow::STYLE_INACTIVE); | 746 // Note: current shadow implementation does not allow proper animation when |
556 shadow_->layer()->SetVisible(true); | 747 // the parent layer bounds change during the animation since |
557 window_label_->GetLayer()->Add(shadow_->layer()); | 748 // Shadow::UpdateLayerBounds() only happens before the animation starts. |
| 749 if (ash::MaterialDesignController::GetMode() == |
| 750 ash::MaterialDesignController::Mode::MATERIAL_EXPERIMENTAL) { |
| 751 shadow_.reset(new ::wm::Shadow()); |
| 752 shadow_->Init(::wm::Shadow::STYLE_INACTIVE); |
| 753 shadow_->layer()->SetVisible(true); |
| 754 window_label_->GetLayer()->Add(shadow_->layer()); |
| 755 } |
558 window_label_->GetLayer()->SetMasksToBounds(false); | 756 window_label_->GetLayer()->SetMasksToBounds(false); |
559 | 757 UpdateHeaderLayout(HeaderFadeInMode::ENTER, |
560 views::View* background_view = | 758 OverviewAnimationType::OVERVIEW_ANIMATION_NONE); |
561 new RoundedContainerView(kLabelBackgroundRadius, kLabelBackgroundColor); | |
562 window_label_selector_.reset(new views::Widget); | |
563 params.activatable = views::Widget::InitParams::Activatable::ACTIVATABLE_NO; | |
564 params.accept_events = false; | |
565 params.name = "OverviewModeLabelSelector"; | |
566 window_label_selector_->Init(params); | |
567 window_label_selector_->set_focus_on_creation(false); | |
568 window_label_selector_->SetContentsView(background_view); | |
569 window_label_selector_->Show(); | |
570 } else { | 759 } else { |
571 // Indicate that the label will be drawn onto a transparent background | 760 // Indicate that the label will be drawn onto a transparent background |
572 // (disables subpixel antialiasing). | 761 // (disables subpixel antialiasing). |
573 window_label_button_view_->SetBackgroundColorHint(SK_ColorTRANSPARENT); | 762 window_label_button_view_->SetBackgroundColorHint(SK_ColorTRANSPARENT); |
574 window_label_->SetContentsView(window_label_button_view_); | 763 window_label_->SetContentsView(window_label_button_view_); |
575 } | 764 } |
576 } | 765 } |
577 | 766 |
578 void WindowSelectorItem::UpdateHeaderLayout( | 767 void WindowSelectorItem::UpdateHeaderLayout( |
| 768 HeaderFadeInMode mode, |
579 OverviewAnimationType animation_type) { | 769 OverviewAnimationType animation_type) { |
580 gfx::Rect transformed_window_bounds = root_window_->ConvertRectFromScreen( | 770 gfx::Rect transformed_window_bounds = root_window_->ConvertRectFromScreen( |
581 transform_window_.GetTransformedBounds(hide_header())); | 771 transform_window_.GetTransformedBounds(hide_header())); |
582 | 772 |
583 if (ash::MaterialDesignController::IsOverviewMaterial()) { | 773 if (ash::MaterialDesignController::IsOverviewMaterial()) { |
584 gfx::Rect label_rect(close_button_->GetPreferredSize()); | 774 gfx::Rect label_rect(close_button_->GetPreferredSize()); |
585 label_rect.set_y(-label_rect.height()); | |
586 label_rect.set_width(transformed_window_bounds.width()); | 775 label_rect.set_width(transformed_window_bounds.width()); |
587 | 776 // For tabbed windows the initial bounds of the caption are set such that it |
| 777 // appears to be "growing" up from the window content area. |
| 778 label_rect.set_y( |
| 779 (mode != HeaderFadeInMode::ENTER || transform_window_.GetTopInset()) |
| 780 ? -label_rect.height() |
| 781 : 0); |
| 782 if (background_view_) { |
| 783 if (mode == HeaderFadeInMode::ENTER) { |
| 784 background_view_->ObserveLayerAnimations(window_label_->GetLayer()); |
| 785 background_view_->set_color(kLabelBackgroundColor); |
| 786 // The color will be animated only once the label widget is faded in. |
| 787 } else if (mode == HeaderFadeInMode::EXIT) { |
| 788 // Normally the observer is disconnected when the fade-in animations |
| 789 // complete but some tests invoke animations with |NON_ZERO_DURATION| |
| 790 // without waiting for completion so do it here. |
| 791 background_view_->StopObservingLayerAnimations(); |
| 792 // Make the header visible above the window. It will be faded out when |
| 793 // the Shutdown() is called. |
| 794 background_view_->AnimateColor(gfx::Tween::EASE_OUT, |
| 795 kExitFadeInMilliseconds); |
| 796 background_view_->set_color(kLabelExitColor); |
| 797 } |
| 798 } |
588 if (!window_label_button_view_->visible()) { | 799 if (!window_label_button_view_->visible()) { |
589 window_label_button_view_->SetVisible(true); | 800 window_label_button_view_->SetVisible(true); |
590 SetupFadeInAfterLayout(window_label_.get()); | 801 SetupFadeInAfterLayout(window_label_.get()); |
591 SetupFadeInAfterLayout(window_label_selector_.get()); | |
592 } | 802 } |
593 WmWindow* window_label_window = | 803 WmWindow* window_label_window = |
594 WmLookup::Get()->GetWindowForWidget(window_label_.get()); | 804 WmLookup::Get()->GetWindowForWidget(window_label_.get()); |
595 WmWindow* window_label_selector_window = | |
596 WmLookup::Get()->GetWindowForWidget(window_label_selector_.get()); | |
597 std::unique_ptr<ScopedOverviewAnimationSettings> animation_settings = | 805 std::unique_ptr<ScopedOverviewAnimationSettings> animation_settings = |
598 ScopedOverviewAnimationSettingsFactory::Get() | 806 ScopedOverviewAnimationSettingsFactory::Get() |
599 ->CreateOverviewAnimationSettings(animation_type, | 807 ->CreateOverviewAnimationSettings(animation_type, |
600 window_label_window); | 808 window_label_window); |
601 std::unique_ptr<ScopedOverviewAnimationSettings> | |
602 animation_settings_selector = | |
603 ScopedOverviewAnimationSettingsFactory::Get() | |
604 ->CreateOverviewAnimationSettings(animation_type, | |
605 window_label_selector_window); | |
606 window_label_selector_window->SetBounds(label_rect); | |
607 // |window_label_window| covers both the transformed window and the header | 809 // |window_label_window| covers both the transformed window and the header |
608 // as well as the gap between the windows to prevent events from reaching | 810 // as well as the gap between the windows to prevent events from reaching |
609 // the window including its sizing borders. | 811 // the window including its sizing borders. |
610 label_rect.set_height(label_rect.height() + | 812 if (mode != HeaderFadeInMode::ENTER) { |
611 transformed_window_bounds.height()); | 813 label_rect.set_height(close_button_->GetPreferredSize().height() + |
612 gfx::Rect shadow_bounds(label_rect.size()); | 814 transformed_window_bounds.height()); |
| 815 } |
613 label_rect.Inset(-kWindowSelectorMargin, -kWindowSelectorMargin); | 816 label_rect.Inset(-kWindowSelectorMargin, -kWindowSelectorMargin); |
614 window_label_window->SetBounds(label_rect); | 817 window_label_window->SetBounds(label_rect); |
615 gfx::Transform label_transform; | 818 gfx::Transform label_transform; |
616 label_transform.Translate(transformed_window_bounds.x(), | 819 label_transform.Translate(transformed_window_bounds.x(), |
617 transformed_window_bounds.y()); | 820 transformed_window_bounds.y()); |
618 window_label_window->SetTransform(label_transform); | 821 window_label_window->SetTransform(label_transform); |
619 window_label_selector_window->SetTransform(label_transform); | |
620 | 822 |
621 shadow_bounds.Offset(kWindowSelectorMargin, kWindowSelectorMargin); | 823 gfx::Rect shadow_bounds(label_rect.size()); |
622 shadow_->SetContentBounds(shadow_bounds); | 824 shadow_bounds.Inset(kWindowSelectorMargin, kWindowSelectorMargin); |
| 825 if (shadow_) |
| 826 shadow_->SetContentBounds(shadow_bounds); |
623 } else { | 827 } else { |
624 if (!close_button_->visible()) { | 828 if (!close_button_->visible()) { |
625 close_button_->SetVisible(true); | 829 close_button_->SetVisible(true); |
626 SetupFadeInAfterLayout(close_button_widget_.get()); | 830 SetupFadeInAfterLayout(close_button_widget_.get()); |
627 } | 831 } |
628 WmWindow* close_button_widget_window = | 832 WmWindow* close_button_widget_window = |
629 WmLookup::Get()->GetWindowForWidget(close_button_widget_.get()); | 833 WmLookup::Get()->GetWindowForWidget(close_button_widget_.get()); |
630 std::unique_ptr<ScopedOverviewAnimationSettings> animation_settings = | 834 std::unique_ptr<ScopedOverviewAnimationSettings> animation_settings = |
631 ScopedOverviewAnimationSettingsFactory::Get() | 835 ScopedOverviewAnimationSettingsFactory::Get() |
632 ->CreateOverviewAnimationSettings(animation_type, | 836 ->CreateOverviewAnimationSettings(animation_type, |
633 close_button_widget_window); | 837 close_button_widget_window); |
634 | 838 |
635 gfx::Transform close_button_transform; | 839 gfx::Transform close_button_transform; |
636 close_button_transform.Translate(transformed_window_bounds.right(), | 840 close_button_transform.Translate(transformed_window_bounds.right(), |
637 transformed_window_bounds.y()); | 841 transformed_window_bounds.y()); |
638 close_button_widget_window->SetTransform(close_button_transform); | 842 close_button_widget_window->SetTransform(close_button_transform); |
639 } | 843 } |
640 } | 844 } |
641 | 845 |
642 void WindowSelectorItem::AnimateOpacity(float opacity, | 846 void WindowSelectorItem::AnimateOpacity(float opacity, |
643 OverviewAnimationType animation_type) { | 847 OverviewAnimationType animation_type) { |
644 DCHECK_GE(opacity, 0.f); | 848 DCHECK_GE(opacity, 0.f); |
645 DCHECK_LE(opacity, 1.f); | 849 DCHECK_LE(opacity, 1.f); |
646 ScopedTransformOverviewWindow::ScopedAnimationSettings animation_settings; | 850 ScopedTransformOverviewWindow::ScopedAnimationSettings animation_settings; |
647 transform_window_.BeginScopedAnimation(animation_type, &animation_settings); | 851 transform_window_.BeginScopedAnimation(animation_type, &animation_settings); |
648 transform_window_.SetOpacity(opacity); | 852 transform_window_.SetOpacity(opacity); |
649 | 853 |
| 854 const float header_opacity = selected_ ? 0.f : kHeaderOpacity * opacity; |
650 WmWindow* window_label_window = | 855 WmWindow* window_label_window = |
651 WmLookup::Get()->GetWindowForWidget(window_label_.get()); | 856 WmLookup::Get()->GetWindowForWidget(window_label_.get()); |
652 std::unique_ptr<ScopedOverviewAnimationSettings> animation_settings_label = | 857 std::unique_ptr<ScopedOverviewAnimationSettings> animation_settings_label = |
653 ScopedOverviewAnimationSettingsFactory::Get() | 858 ScopedOverviewAnimationSettingsFactory::Get() |
654 ->CreateOverviewAnimationSettings(animation_type, | 859 ->CreateOverviewAnimationSettings(animation_type, |
655 window_label_window); | 860 window_label_window); |
656 window_label_window->SetOpacity(opacity); | 861 window_label_window->SetOpacity(header_opacity); |
657 | |
658 WmWindow* window_label_selector_window = | |
659 WmLookup::Get()->GetWindowForWidget(window_label_selector_.get()); | |
660 std::unique_ptr<ScopedOverviewAnimationSettings> animation_settings_selector = | |
661 ScopedOverviewAnimationSettingsFactory::Get() | |
662 ->CreateOverviewAnimationSettings(animation_type, | |
663 window_label_selector_window); | |
664 window_label_selector_window->SetOpacity(opacity); | |
665 } | 862 } |
666 | 863 |
667 void WindowSelectorItem::UpdateCloseButtonAccessibilityName() { | 864 void WindowSelectorItem::UpdateCloseButtonAccessibilityName() { |
668 close_button_->SetAccessibleName(l10n_util::GetStringFUTF16( | 865 close_button_->SetAccessibleName(l10n_util::GetStringFUTF16( |
669 IDS_ASH_OVERVIEW_CLOSE_ITEM_BUTTON_ACCESSIBLE_NAME, | 866 IDS_ASH_OVERVIEW_CLOSE_ITEM_BUTTON_ACCESSIBLE_NAME, |
670 GetWindow()->GetTitle())); | 867 GetWindow()->GetTitle())); |
671 } | 868 } |
672 | 869 |
| 870 void WindowSelectorItem::FadeOut(std::unique_ptr<views::Widget> widget) { |
| 871 widget->SetOpacity(1.f); |
| 872 |
| 873 // Fade out the widget. This animation continues past the lifetime of |this|. |
| 874 WmWindow* widget_window = WmLookup::Get()->GetWindowForWidget(widget.get()); |
| 875 std::unique_ptr<ScopedOverviewAnimationSettings> animation_settings = |
| 876 ScopedOverviewAnimationSettingsFactory::Get() |
| 877 ->CreateOverviewAnimationSettings( |
| 878 OverviewAnimationType:: |
| 879 OVERVIEW_ANIMATION_EXIT_OVERVIEW_MODE_FADE_OUT, |
| 880 widget_window); |
| 881 // CleanupAnimationObserver will delete itself (and the widget) when the |
| 882 // opacity animation is complete. |
| 883 // Ownership over the observer is passed to the window_selector_->delegate() |
| 884 // which has longer lifetime so that animations can continue even after the |
| 885 // overview mode is shut down. |
| 886 views::Widget* widget_ptr = widget.get(); |
| 887 std::unique_ptr<CleanupAnimationObserver> observer( |
| 888 new CleanupAnimationObserver(std::move(widget))); |
| 889 animation_settings->AddObserver(observer.get()); |
| 890 window_selector_->delegate()->AddDelayedAnimationObserver( |
| 891 std::move(observer)); |
| 892 widget_ptr->SetOpacity(0.f); |
| 893 } |
| 894 |
673 } // namespace ash | 895 } // namespace ash |
OLD | NEW |