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