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

Side by Side Diff: ash/wm/overview/window_selector_item.cc

Issue 872113004: Modified OverviewMode's LabelButton bounds to cover the entire item. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed ignore_border_overlap from label_button as per msw suggestion. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/wm/overview/window_selector_item.h" 5 #include "ash/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/screen_util.h" 10 #include "ash/screen_util.h"
11 #include "ash/shell.h" 11 #include "ash/shell.h"
12 #include "ash/shell_window_ids.h" 12 #include "ash/shell_window_ids.h"
13 #include "ash/wm/overview/overview_animation_type.h" 13 #include "ash/wm/overview/overview_animation_type.h"
14 #include "ash/wm/overview/overview_window_button.h"
15 #include "ash/wm/overview/scoped_overview_animation_settings.h" 14 #include "ash/wm/overview/scoped_overview_animation_settings.h"
16 #include "ash/wm/overview/scoped_transform_overview_window.h" 15 #include "ash/wm/overview/scoped_transform_overview_window.h"
17 #include "ash/wm/overview/window_selector_controller.h" 16 #include "ash/wm/overview/window_selector_controller.h"
17 #include "ash/wm/window_state.h"
18 #include "base/auto_reset.h" 18 #include "base/auto_reset.h"
19 #include "base/strings/string_util.h" 19 #include "base/strings/string_util.h"
20 #include "base/strings/utf_string_conversions.h" 20 #include "base/strings/utf_string_conversions.h"
21 #include "base/time/time.h" 21 #include "base/time/time.h"
22 #include "grit/ash_resources.h" 22 #include "grit/ash_resources.h"
23 #include "grit/ash_strings.h" 23 #include "grit/ash_strings.h"
24 #include "ui/aura/window.h" 24 #include "ui/aura/window.h"
25 #include "ui/base/l10n/l10n_util.h" 25 #include "ui/base/l10n/l10n_util.h"
26 #include "ui/base/resource/resource_bundle.h" 26 #include "ui/base/resource/resource_bundle.h"
27 #include "ui/gfx/geometry/vector2d.h" 27 #include "ui/gfx/geometry/vector2d.h"
28 #include "ui/gfx/transform_util.h" 28 #include "ui/gfx/transform_util.h"
29 #include "ui/strings/grit/ui_strings.h" 29 #include "ui/strings/grit/ui_strings.h"
30 #include "ui/views/border.h"
30 #include "ui/views/controls/button/image_button.h" 31 #include "ui/views/controls/button/image_button.h"
32 #include "ui/views/controls/button/label_button.h"
31 #include "ui/views/layout/box_layout.h" 33 #include "ui/views/layout/box_layout.h"
32 #include "ui/views/widget/widget.h" 34 #include "ui/views/widget/widget.h"
33 #include "ui/wm/core/window_util.h" 35 #include "ui/wm/core/window_util.h"
34 36
35 namespace ash { 37 namespace ash {
36 38
37 namespace { 39 namespace {
38 40
39 // In the conceptual overview table, the window margin is the space reserved 41 // In the conceptual overview table, the window margin is the space reserved
40 // around the window within the cell. This margin does not overlap so the 42 // around the window within the cell. This margin does not overlap so the
41 // closest distance between adjacent windows will be twice this amount. 43 // closest distance between adjacent windows will be twice this amount.
42 static const int kWindowMargin = 30; 44 static const int kWindowMargin = 30;
43 45
46 // Foreground label color.
47 static const SkColor kLabelColor = SK_ColorWHITE;
48
49 // Label shadow color.
50 static const SkColor kLabelShadow = 0xB0000000;
51
52 // Vertical padding for the label, on top of it.
53 static const int kVerticalLabelPadding = 20;
54
55 // Solid shadow length from the label
56 static const int kVerticalShadowOffset = 1;
57
58 // Amount of blur applied to the label shadow
59 static const int kShadowBlur = 10;
60
44 // Opacity for dimmed items. 61 // Opacity for dimmed items.
45 static const float kDimmedItemOpacity = 0.5f; 62 static const float kDimmedItemOpacity = 0.5f;
46 63
64 class OverviewLabelButton : public views::LabelButton {
65 public:
66 OverviewLabelButton(views::ButtonListener* listener,
67 const base::string16& text)
68 : LabelButton(listener, text) {}
69
70 ~OverviewLabelButton() override {}
71
72 protected:
73 gfx::Rect GetChildAreaBounds() override {
74 gfx::Rect bounds = GetLocalBounds();
75 bounds.Inset(GetInsets());
msw 2015/02/06 21:24:26 This will double-apply border insets, instead, her
Nina 2015/02/09 16:35:09 Done.
msw 2015/02/09 23:45:27 Acknowledged.
76 return bounds;
77 }
78 };
79
47 // Calculates the |window| bounds after being transformed to the selector's 80 // Calculates the |window| bounds after being transformed to the selector's
48 // space. The returned Rect is in virtual screen coordinates. 81 // space. The returned Rect is in virtual screen coordinates.
49 gfx::Rect GetTransformedBounds(aura::Window* window) { 82 gfx::Rect GetTransformedBounds(aura::Window* window) {
50 gfx::RectF bounds(ScreenUtil::ConvertRectToScreen(window->GetRootWindow(), 83 gfx::RectF bounds(ScreenUtil::ConvertRectToScreen(window->GetRootWindow(),
51 window->layer()->GetTargetBounds())); 84 window->layer()->GetTargetBounds()));
52 gfx::Transform new_transform = TransformAboutPivot( 85 gfx::Transform new_transform = TransformAboutPivot(
53 gfx::Point(bounds.x(), bounds.y()), 86 gfx::Point(bounds.x(), bounds.y()),
54 window->layer()->GetTargetTransform()); 87 window->layer()->GetTargetTransform());
55 new_transform.TransformRect(&bounds); 88 new_transform.TransformRect(&bounds);
56 return ToEnclosingRect(bounds); 89 return ToEnclosingRect(bounds);
(...skipping 23 matching lines...) Expand all
80 OverviewCloseButton::~OverviewCloseButton() { 113 OverviewCloseButton::~OverviewCloseButton() {
81 } 114 }
82 115
83 } // namespace 116 } // namespace
84 117
85 WindowSelectorItem::WindowSelectorItem(aura::Window* window) 118 WindowSelectorItem::WindowSelectorItem(aura::Window* window)
86 : dimmed_(false), 119 : dimmed_(false),
87 root_window_(window->GetRootWindow()), 120 root_window_(window->GetRootWindow()),
88 transform_window_(window), 121 transform_window_(window),
89 in_bounds_update_(false), 122 in_bounds_update_(false),
90 close_button_(new OverviewCloseButton(this)), 123 window_label_button_view_(nullptr),
91 overview_window_button_(new OverviewWindowButton(window)) { 124 close_button_(new OverviewCloseButton(this)) {
125 CreateWindowLabel(window->title());
92 views::Widget::InitParams params; 126 views::Widget::InitParams params;
93 params.type = views::Widget::InitParams::TYPE_POPUP; 127 params.type = views::Widget::InitParams::TYPE_POPUP;
94 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 128 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
95 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; 129 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
96 params.parent = Shell::GetContainer(root_window_, 130 params.parent = Shell::GetContainer(root_window_,
97 kShellWindowId_OverlayContainer); 131 kShellWindowId_OverlayContainer);
98 close_button_widget_.set_focus_on_creation(false); 132 close_button_widget_.set_focus_on_creation(false);
99 close_button_widget_.Init(params); 133 close_button_widget_.Init(params);
100 close_button_->SetVisible(false); 134 close_button_->SetVisible(false);
101 close_button_widget_.SetContentsView(close_button_); 135 close_button_widget_.SetContentsView(close_button_);
102 close_button_widget_.SetSize(close_button_->GetPreferredSize()); 136 close_button_widget_.SetSize(close_button_->GetPreferredSize());
103 close_button_widget_.Show(); 137 close_button_widget_.Show();
104 138
105 gfx::Rect close_button_rect(close_button_widget_.GetNativeWindow()->bounds()); 139 gfx::Rect close_button_rect(close_button_widget_.GetNativeWindow()->bounds());
106 // Align the center of the button with position (0, 0) so that the 140 // Align the center of the button with position (0, 0) so that the
107 // translate transform does not need to take the button dimensions into 141 // translate transform does not need to take the button dimensions into
108 // account. 142 // account.
109 close_button_rect.set_x(-close_button_rect.width() / 2); 143 close_button_rect.set_x(-close_button_rect.width() / 2);
110 close_button_rect.set_y(-close_button_rect.height() / 2); 144 close_button_rect.set_y(-close_button_rect.height() / 2);
111 close_button_widget_.GetNativeWindow()->SetBounds(close_button_rect); 145 close_button_widget_.GetNativeWindow()->SetBounds(close_button_rect);
112 146
113 GetWindow()->AddObserver(this); 147 GetWindow()->AddObserver(this);
114
115 UpdateCloseButtonAccessibilityName();
116 } 148 }
117 149
118 WindowSelectorItem::~WindowSelectorItem() { 150 WindowSelectorItem::~WindowSelectorItem() {
119 GetWindow()->RemoveObserver(this); 151 GetWindow()->RemoveObserver(this);
120 } 152 }
121 153
122 aura::Window* WindowSelectorItem::GetWindow() { 154 aura::Window* WindowSelectorItem::GetWindow() {
123 return transform_window_.window(); 155 return transform_window_.window();
124 } 156 }
125 157
(...skipping 13 matching lines...) Expand all
139 return transform_window_.Contains(target); 171 return transform_window_.Contains(target);
140 } 172 }
141 173
142 void WindowSelectorItem::SetBounds(const gfx::Rect& target_bounds, 174 void WindowSelectorItem::SetBounds(const gfx::Rect& target_bounds,
143 OverviewAnimationType animation_type) { 175 OverviewAnimationType animation_type) {
144 if (in_bounds_update_) 176 if (in_bounds_update_)
145 return; 177 return;
146 base::AutoReset<bool> auto_reset_in_bounds_update(&in_bounds_update_, true); 178 base::AutoReset<bool> auto_reset_in_bounds_update(&in_bounds_update_, true);
147 target_bounds_ = target_bounds; 179 target_bounds_ = target_bounds;
148 180
149 overview_window_button_->SetBounds(target_bounds, animation_type);
150
151 gfx::Rect inset_bounds(target_bounds); 181 gfx::Rect inset_bounds(target_bounds);
152 inset_bounds.Inset(kWindowMargin, kWindowMargin); 182 inset_bounds.Inset(kWindowMargin, kWindowMargin);
153 SetItemBounds(inset_bounds, animation_type); 183 SetItemBounds(inset_bounds, animation_type);
154 184
155 // SetItemBounds is called before UpdateCloseButtonLayout so the close button 185 // SetItemBounds is called before UpdateCloseButtonLayout so the close button
156 // can properly use the updated windows bounds. 186 // can properly use the updated windows bounds.
157 UpdateCloseButtonLayout(animation_type); 187 UpdateCloseButtonLayout(animation_type);
188 UpdateWindowLabel(target_bounds, animation_type);
158 } 189 }
159 190
160 void WindowSelectorItem::RecomputeWindowTransforms() { 191 void WindowSelectorItem::RecomputeWindowTransforms() {
161 if (in_bounds_update_ || target_bounds_.IsEmpty()) 192 if (in_bounds_update_ || target_bounds_.IsEmpty())
162 return; 193 return;
163 base::AutoReset<bool> auto_reset_in_bounds_update(&in_bounds_update_, true); 194 base::AutoReset<bool> auto_reset_in_bounds_update(&in_bounds_update_, true);
164 gfx::Rect inset_bounds(target_bounds_); 195 gfx::Rect inset_bounds(target_bounds_);
165 inset_bounds.Inset(kWindowMargin, kWindowMargin); 196 inset_bounds.Inset(kWindowMargin, kWindowMargin);
166 SetItemBounds(inset_bounds, OverviewAnimationType::OVERVIEW_ANIMATION_NONE); 197 SetItemBounds(inset_bounds, OverviewAnimationType::OVERVIEW_ANIMATION_NONE);
167 UpdateCloseButtonLayout(OverviewAnimationType::OVERVIEW_ANIMATION_NONE); 198 UpdateCloseButtonLayout(OverviewAnimationType::OVERVIEW_ANIMATION_NONE);
168 } 199 }
169 200
170 void WindowSelectorItem::SendFocusAlert() const { 201 void WindowSelectorItem::SendFocusAlert() const {
171 overview_window_button_->SendFocusAlert(); 202 window_label_button_view_->NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, true);
172 } 203 }
173 204
174 void WindowSelectorItem::SetDimmed(bool dimmed) { 205 void WindowSelectorItem::SetDimmed(bool dimmed) {
175 dimmed_ = dimmed; 206 dimmed_ = dimmed;
176 SetOpacity(dimmed ? kDimmedItemOpacity : 1.0f); 207 SetOpacity(dimmed ? kDimmedItemOpacity : 1.0f);
177 } 208 }
178 209
179 void WindowSelectorItem::ButtonPressed(views::Button* sender, 210 void WindowSelectorItem::ButtonPressed(views::Button* sender,
180 const ui::Event& event) { 211 const ui::Event& event) {
181 transform_window_.Close(); 212 if (sender == close_button_) {
213 transform_window_.Close();
214 return;
215 }
216 CHECK(sender == window_label_button_view_);
217 wm::GetWindowState(transform_window_.window())->Activate();
182 } 218 }
183 219
184 void WindowSelectorItem::OnWindowDestroying(aura::Window* window) { 220 void WindowSelectorItem::OnWindowDestroying(aura::Window* window) {
185 window->RemoveObserver(this); 221 window->RemoveObserver(this);
186 transform_window_.OnWindowDestroyed(); 222 transform_window_.OnWindowDestroyed();
187 } 223 }
188 224
189 void WindowSelectorItem::OnWindowTitleChanged(aura::Window* window) { 225 void WindowSelectorItem::OnWindowTitleChanged(aura::Window* window) {
190 // TODO(flackr): Maybe add the new title to a vector of titles so that we can 226 // TODO(flackr): Maybe add the new title to a vector of titles so that we can
191 // filter any of the titles the window had while in the overview session. 227 // filter any of the titles the window had while in the overview session.
192 overview_window_button_->SetLabelText(window->title()); 228 window_label_button_view_->SetText(window->title());
193 UpdateCloseButtonAccessibilityName(); 229 UpdateCloseButtonAccessibilityName();
194 } 230 }
195 231
196 void WindowSelectorItem::SetItemBounds(const gfx::Rect& target_bounds, 232 void WindowSelectorItem::SetItemBounds(const gfx::Rect& target_bounds,
197 OverviewAnimationType animation_type) { 233 OverviewAnimationType animation_type) {
198 DCHECK(root_window_ == GetWindow()->GetRootWindow()); 234 DCHECK(root_window_ == GetWindow()->GetRootWindow());
199 gfx::Rect screen_bounds = transform_window_.GetTargetBoundsInScreen(); 235 gfx::Rect screen_bounds = transform_window_.GetTargetBoundsInScreen();
200 gfx::Rect selector_item_bounds = 236 gfx::Rect selector_item_bounds =
201 ScopedTransformOverviewWindow::ShrinkRectToFitPreservingAspectRatio( 237 ScopedTransformOverviewWindow::ShrinkRectToFitPreservingAspectRatio(
202 screen_bounds, target_bounds); 238 screen_bounds, target_bounds);
203 gfx::Transform transform = 239 gfx::Transform transform =
204 ScopedTransformOverviewWindow::GetTransformForRect(screen_bounds, 240 ScopedTransformOverviewWindow::GetTransformForRect(screen_bounds,
205 selector_item_bounds); 241 selector_item_bounds);
206 ScopedTransformOverviewWindow::ScopedAnimationSettings animation_settings; 242 ScopedTransformOverviewWindow::ScopedAnimationSettings animation_settings;
207 transform_window_.BeginScopedAnimation(animation_type, &animation_settings); 243 transform_window_.BeginScopedAnimation(animation_type, &animation_settings);
208 transform_window_.SetTransform(root_window_, transform); 244 transform_window_.SetTransform(root_window_, transform);
209 transform_window_.set_overview_transform(transform); 245 transform_window_.set_overview_transform(transform);
210 } 246 }
211 247
212 void WindowSelectorItem::SetOpacity(float opacity) { 248 void WindowSelectorItem::SetOpacity(float opacity) {
213 overview_window_button_->SetOpacity(opacity); 249 window_label_->GetNativeWindow()->layer()->SetOpacity(opacity);
214 close_button_widget_.GetNativeWindow()->layer()->SetOpacity(opacity); 250 close_button_widget_.GetNativeWindow()->layer()->SetOpacity(opacity);
215 251
216 transform_window_.SetOpacity(opacity); 252 transform_window_.SetOpacity(opacity);
217 } 253 }
218 254
255 void WindowSelectorItem::UpdateWindowLabel(
256 const gfx::Rect& window_bounds,
257 OverviewAnimationType animation_type) {
258 // If the root window has changed, force the window label to be recreated
259 // and faded in on the new root window.
260 DCHECK(!window_label_ ||
261 window_label_->GetNativeWindow()->GetRootWindow() == root_window_);
262
263 if (!window_label_->IsVisible()) {
264 window_label_->Show();
265 ScopedOverviewAnimationSettings::SetupFadeInAfterLayout(
266 window_label_->GetNativeWindow());
267 }
268
269 gfx::Rect converted_bounds =
270 ScreenUtil::ConvertRectFromScreen(root_window_, window_bounds);
271 gfx::Rect label_bounds(converted_bounds.x(), converted_bounds.y(),
272 converted_bounds.width(), converted_bounds.height());
273 window_label_button_view_->SetBorder(views::Border::CreateEmptyBorder(
274 label_bounds.height() - kVerticalLabelPadding, 0, 0, 0));
275 ScopedOverviewAnimationSettings animation_settings(
276 animation_type, window_label_->GetNativeWindow());
277
278 window_label_->GetNativeWindow()->SetBounds(label_bounds);
279 }
280
281 void WindowSelectorItem::CreateWindowLabel(const base::string16& title) {
282 window_label_.reset(new views::Widget);
283 views::Widget::InitParams params;
284 params.type = views::Widget::InitParams::TYPE_POPUP;
285 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
286 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
287 params.parent =
288 Shell::GetContainer(root_window_, kShellWindowId_OverlayContainer);
289 params.visible_on_all_workspaces = true;
290 window_label_->set_focus_on_creation(false);
291 window_label_->Init(params);
292 window_label_button_view_ = new OverviewLabelButton(this, title);
293 window_label_button_view_->SetTextColor(views::LabelButton::STATE_NORMAL,
294 kLabelColor);
295 window_label_button_view_->SetTextColor(views::LabelButton::STATE_HOVERED,
msw 2015/02/06 21:24:26 I don't think you need to explicitly set the text
Nina 2015/02/09 16:35:09 It seems they don't - removing the lines makes the
msw 2015/02/09 23:45:27 Acknowledged. Sorry, it probably should behave as
296 kLabelColor);
297 window_label_button_view_->SetTextColor(views::LabelButton::STATE_PRESSED,
298 kLabelColor);
299 window_label_button_view_->set_animate_on_state_change(false);
300 window_label_button_view_->SetHorizontalAlignment(gfx::ALIGN_CENTER);
301 window_label_button_view_->SetTextShadows(gfx::ShadowValues(
302 1, gfx::ShadowValue(gfx::Point(0, kVerticalShadowOffset), kShadowBlur,
303 kLabelShadow)));
304 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
305 window_label_button_view_->SetFontList(
306 bundle.GetFontList(ui::ResourceBundle::BoldFont));
307 window_label_->SetContentsView(window_label_button_view_);
308 }
309
219 void WindowSelectorItem::UpdateCloseButtonLayout( 310 void WindowSelectorItem::UpdateCloseButtonLayout(
220 OverviewAnimationType animation_type) { 311 OverviewAnimationType animation_type) {
221 if (!close_button_->visible()) { 312 if (!close_button_->visible()) {
222 close_button_->SetVisible(true); 313 close_button_->SetVisible(true);
223 ScopedOverviewAnimationSettings::SetupFadeInAfterLayout( 314 ScopedOverviewAnimationSettings::SetupFadeInAfterLayout(
224 close_button_widget_.GetNativeWindow()); 315 close_button_widget_.GetNativeWindow());
225 } 316 }
226 ScopedOverviewAnimationSettings animation_settings(animation_type, 317 ScopedOverviewAnimationSettings animation_settings(animation_type,
227 close_button_widget_.GetNativeWindow()); 318 close_button_widget_.GetNativeWindow());
228 319
229 gfx::Rect transformed_window_bounds = ScreenUtil::ConvertRectFromScreen( 320 gfx::Rect transformed_window_bounds = ScreenUtil::ConvertRectFromScreen(
230 close_button_widget_.GetNativeWindow()->GetRootWindow(), 321 close_button_widget_.GetNativeWindow()->GetRootWindow(),
231 GetTransformedBounds(GetWindow())); 322 GetTransformedBounds(GetWindow()));
232 323
233 gfx::Transform close_button_transform; 324 gfx::Transform close_button_transform;
234 close_button_transform.Translate(transformed_window_bounds.right(), 325 close_button_transform.Translate(transformed_window_bounds.right(),
235 transformed_window_bounds.y()); 326 transformed_window_bounds.y());
236 close_button_widget_.GetNativeWindow()->SetTransform( 327 close_button_widget_.GetNativeWindow()->SetTransform(
237 close_button_transform); 328 close_button_transform);
238 } 329 }
239 330
240 void WindowSelectorItem::UpdateCloseButtonAccessibilityName() { 331 void WindowSelectorItem::UpdateCloseButtonAccessibilityName() {
241 close_button_->SetAccessibleName(l10n_util::GetStringFUTF16( 332 close_button_->SetAccessibleName(l10n_util::GetStringFUTF16(
242 IDS_ASH_OVERVIEW_CLOSE_ITEM_BUTTON_ACCESSIBLE_NAME, 333 IDS_ASH_OVERVIEW_CLOSE_ITEM_BUTTON_ACCESSIBLE_NAME,
243 GetWindow()->title())); 334 GetWindow()->title()));
244 } 335 }
245 336
246 } // namespace ash 337 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698