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

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

Issue 844763006: Change overview mode to so that docked panel windows are not grouped together. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Polished after a self-review. Created 5 years, 11 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"
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 rb.GetImageSkiaNamed(IDR_AURA_WINDOW_OVERVIEW_CLOSE_H)); 106 rb.GetImageSkiaNamed(IDR_AURA_WINDOW_OVERVIEW_CLOSE_H));
107 SetImage(views::CustomButton::STATE_PRESSED, 107 SetImage(views::CustomButton::STATE_PRESSED,
108 rb.GetImageSkiaNamed(IDR_AURA_WINDOW_OVERVIEW_CLOSE_P)); 108 rb.GetImageSkiaNamed(IDR_AURA_WINDOW_OVERVIEW_CLOSE_P));
109 } 109 }
110 110
111 OverviewCloseButton::~OverviewCloseButton() { 111 OverviewCloseButton::~OverviewCloseButton() {
112 } 112 }
113 113
114 } // namespace 114 } // namespace
115 115
116 WindowSelectorItem::WindowSelectorItem(aura::Window* root_window) 116 WindowSelectorItem::WindowSelectorItem(aura::Window* root_window,
117 aura::Window* window)
117 : dimmed_(false), 118 : dimmed_(false),
118 root_window_(root_window), 119 root_window_(root_window),
120 transform_window_(window),
119 in_bounds_update_(false), 121 in_bounds_update_(false),
120 window_label_view_(nullptr), 122 window_label_view_(nullptr),
121 close_button_(new OverviewCloseButton(this)), 123 close_button_(new OverviewCloseButton(this)),
122 selector_item_activate_window_button_( 124 selector_item_activate_window_button_(
123 new TransparentActivateWindowButton(root_window, this)) { 125 new TransparentActivateWindowButton(root_window, this)) {
124 views::Widget::InitParams params; 126 views::Widget::InitParams params;
125 params.type = views::Widget::InitParams::TYPE_POPUP; 127 params.type = views::Widget::InitParams::TYPE_POPUP;
126 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 128 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
127 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; 129 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
128 params.parent = Shell::GetContainer(root_window, 130 params.parent = Shell::GetContainer(root_window,
129 kShellWindowId_OverlayContainer); 131 kShellWindowId_OverlayContainer);
130 close_button_widget_.set_focus_on_creation(false); 132 close_button_widget_.set_focus_on_creation(false);
131 close_button_widget_.Init(params); 133 close_button_widget_.Init(params);
132 close_button_->SetVisible(false); 134 close_button_->SetVisible(false);
133 close_button_widget_.SetContentsView(close_button_); 135 close_button_widget_.SetContentsView(close_button_);
134 close_button_widget_.SetSize(close_button_->GetPreferredSize()); 136 close_button_widget_.SetSize(close_button_->GetPreferredSize());
135 close_button_widget_.Show(); 137 close_button_widget_.Show();
136 138
137 gfx::Rect close_button_rect(close_button_widget_.GetNativeWindow()->bounds()); 139 gfx::Rect close_button_rect(close_button_widget_.GetNativeWindow()->bounds());
138 // 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
139 // translate transform does not need to take the button dimensions into 141 // translate transform does not need to take the button dimensions into
140 // account. 142 // account.
141 close_button_rect.set_x(-close_button_rect.width() / 2); 143 close_button_rect.set_x(-close_button_rect.width() / 2);
142 close_button_rect.set_y(-close_button_rect.height() / 2); 144 close_button_rect.set_y(-close_button_rect.height() / 2);
143 close_button_widget_.GetNativeWindow()->SetBounds(close_button_rect); 145 close_button_widget_.GetNativeWindow()->SetBounds(close_button_rect);
146
147
148 window->AddObserver(this);
149
150 UpdateCloseButtonAccessibilityName();
144 } 151 }
145 152
146 WindowSelectorItem::~WindowSelectorItem() { 153 WindowSelectorItem::~WindowSelectorItem() {
147 for (auto* transform_window : transform_windows_) { 154 aura::Window* window = GetWindow();
148 transform_window->window()->RemoveObserver(this); 155 if (window)
156 window->RemoveObserver(this);
157 }
158
159 aura::Window* WindowSelectorItem::GetWindow() const {
160 return transform_window_.window();
161 }
162
163 void WindowSelectorItem::RestoreWindowOnExit(aura::Window* window) {
164 if (transform_window_.Contains(window)) {
165 transform_window_.RestoreWindowOnExit();
149 } 166 }
150 } 167 }
151 168
152 void WindowSelectorItem::AddWindow(aura::Window* window) { 169 void WindowSelectorItem::PrepareForOverview() {
153 DCHECK(window->GetRootWindow() == root_window_); 170 transform_window_.PrepareForOverview();
154 window->AddObserver(this);
155 ScopedTransformOverviewWindow* transform_window =
156 new ScopedTransformOverviewWindow(window);
157 transform_windows_.push_back(transform_window);
158 // The transparent overlays are added at the front of the z-order when
159 // created so make sure the selector item's transparent overlay is behind the
160 // overlay for the window that was just added.
161 transform_window->activate_button()->StackAbove(
162 selector_item_activate_window_button_.get());
163
164 UpdateSelectorButtons();
165 UpdateCloseButtonAccessibilityName();
166 }
167
168 bool WindowSelectorItem::HasSelectableWindow(const aura::Window* window) const {
169 for (auto* transform_window : transform_windows_) {
170 if (transform_window->window() == window)
171 return true;
172 }
173 return false;
174 } 171 }
175 172
176 bool WindowSelectorItem::Contains(const aura::Window* target) const { 173 bool WindowSelectorItem::Contains(const aura::Window* target) const {
177 for (auto* transform_window : transform_windows_) { 174 return transform_window_.Contains(target);
178 if (transform_window->Contains(target))
179 return true;
180 }
181 return false;
182 } 175 }
183 176
184 void WindowSelectorItem::RestoreWindowOnExit(aura::Window* window) { 177 void WindowSelectorItem::SetBounds(const gfx::Rect& target_bounds,
185 for (auto* transform_window : transform_windows_) {
186 if (transform_window->Contains(window)) {
187 transform_window->RestoreWindowOnExit();
188 break;
189 }
190 }
191 }
192
193 aura::Window* WindowSelectorItem::SelectionWindow() const {
194 return SelectionTransformWindow()->window();
195 }
196
197 void WindowSelectorItem::RemoveWindow(const aura::Window* window) {
198 bool window_found = false;
199
200 for (TransformWindows::iterator iter = transform_windows_.begin();
201 iter != transform_windows_.end();
202 ++iter) {
203 ScopedTransformOverviewWindow* transform_window = *iter;
204
205 if (transform_window->window() == window) {
206 transform_window->window()->RemoveObserver(this);
207 transform_window->OnWindowDestroyed();
208 transform_windows_.erase(iter);
209 window_found = true;
210 break;
211 }
212 }
213 CHECK(window_found);
214
215
216 // If empty WindowSelectorItem will be destroyed immediately after this by
217 // its owner.
218 if (empty())
219 return;
220
221 UpdateCloseButtonAccessibilityName();
222 window_label_.reset();
223 UpdateWindowLabels(target_bounds_,
224 OverviewAnimationType::OVERVIEW_ANIMATION_NONE);
225 UpdateCloseButtonLayout(OverviewAnimationType::OVERVIEW_ANIMATION_NONE);
226 UpdateSelectorButtons();
227 }
228
229 bool WindowSelectorItem::empty() const {
230 return transform_windows_.empty();
231 }
232
233 void WindowSelectorItem::PrepareForOverview() {
234 for (auto* transform_window : transform_windows_)
235 transform_window->PrepareForOverview();
236 }
237
238 void WindowSelectorItem::SetBounds(aura::Window* root_window,
239 const gfx::Rect& target_bounds,
240 OverviewAnimationType animation_type) { 178 OverviewAnimationType animation_type) {
241 if (in_bounds_update_) 179 if (in_bounds_update_)
242 return; 180 return;
243 base::AutoReset<bool> auto_reset_in_bounds_update(&in_bounds_update_, true); 181 base::AutoReset<bool> auto_reset_in_bounds_update(&in_bounds_update_, true);
244 target_bounds_ = target_bounds; 182 target_bounds_ = target_bounds;
245 183
246 UpdateWindowLabels(target_bounds, animation_type); 184 UpdateWindowLabels(target_bounds, animation_type);
247 185
248 gfx::Rect inset_bounds(target_bounds); 186 gfx::Rect inset_bounds(target_bounds);
249 inset_bounds.Inset(kWindowMargin, kWindowMargin); 187 inset_bounds.Inset(kWindowMargin, kWindowMargin);
250 SetItemBounds(root_window, inset_bounds, animation_type); 188 SetItemBounds(inset_bounds, animation_type);
251 189
252 // SetItemBounds is called before UpdateCloseButtonLayout so the close button 190 // SetItemBounds is called before UpdateCloseButtonLayout so the close button
253 // can properly use the updated windows bounds. 191 // can properly use the updated windows bounds.
254 UpdateCloseButtonLayout(animation_type); 192 UpdateCloseButtonLayout(animation_type);
255 UpdateSelectorButtons(); 193 UpdateSelectorButtons();
256 } 194 }
257 195
258 void WindowSelectorItem::RecomputeWindowTransforms() { 196 void WindowSelectorItem::RecomputeWindowTransforms() {
259 if (in_bounds_update_ || target_bounds_.IsEmpty()) 197 if (in_bounds_update_ || target_bounds_.IsEmpty())
260 return; 198 return;
261 DCHECK(root_window_);
262 base::AutoReset<bool> auto_reset_in_bounds_update(&in_bounds_update_, true); 199 base::AutoReset<bool> auto_reset_in_bounds_update(&in_bounds_update_, true);
263 gfx::Rect inset_bounds(target_bounds_); 200 gfx::Rect inset_bounds(target_bounds_);
264 inset_bounds.Inset(kWindowMargin, kWindowMargin); 201 inset_bounds.Inset(kWindowMargin, kWindowMargin);
265 SetItemBounds(root_window_, inset_bounds, 202 SetItemBounds(inset_bounds, OverviewAnimationType::OVERVIEW_ANIMATION_NONE);
266 OverviewAnimationType::OVERVIEW_ANIMATION_NONE);
267 203
268 UpdateCloseButtonLayout(OverviewAnimationType::OVERVIEW_ANIMATION_NONE); 204 UpdateCloseButtonLayout(OverviewAnimationType::OVERVIEW_ANIMATION_NONE);
269 UpdateSelectorButtons(); 205 UpdateSelectorButtons();
270 } 206 }
271 207
272 void WindowSelectorItem::SendFocusAlert() const { 208 void WindowSelectorItem::SendFocusAlert() const {
273 selector_item_activate_window_button_->SendFocusAlert(); 209 selector_item_activate_window_button_->SendFocusAlert();
274 } 210 }
275 211
276 void WindowSelectorItem::SetDimmed(bool dimmed) { 212 void WindowSelectorItem::SetDimmed(bool dimmed) {
277 dimmed_ = dimmed; 213 dimmed_ = dimmed;
278 SetOpacity(dimmed ? kDimmedItemOpacity : 1.0f); 214 SetOpacity(dimmed ? kDimmedItemOpacity : 1.0f);
279 } 215 }
280 216
217 void WindowSelectorItem::OnWindowDestroyed() {
218 CHECK(GetWindow());
219 GetWindow()->RemoveObserver(this);
220 transform_window_.OnWindowDestroyed();
221 }
222
281 void WindowSelectorItem::ButtonPressed(views::Button* sender, 223 void WindowSelectorItem::ButtonPressed(views::Button* sender,
282 const ui::Event& event) { 224 const ui::Event& event) {
283 CHECK(!transform_windows_.empty()); 225 transform_window_.Close();
284 SelectionTransformWindow()->Close();
285 } 226 }
286 227
287 void WindowSelectorItem::OnWindowTitleChanged(aura::Window* window) { 228 void WindowSelectorItem::OnWindowTitleChanged(aura::Window* window) {
288 // TODO(flackr): Maybe add the new title to a vector of titles so that we can 229 // TODO(flackr): Maybe add the new title to a vector of titles so that we can
289 // filter any of the titles the window had while in the overview session. 230 // filter any of the titles the window had while in the overview session.
290 if (window == SelectionWindow()) { 231 if (window == GetWindow()) {
291 window_label_view_->SetText(window->title()); 232 window_label_view_->SetText(window->title());
292 UpdateCloseButtonAccessibilityName(); 233 UpdateCloseButtonAccessibilityName();
293 } 234 }
294 UpdateCloseButtonLayout(OverviewAnimationType::OVERVIEW_ANIMATION_NONE); 235 UpdateCloseButtonLayout(OverviewAnimationType::OVERVIEW_ANIMATION_NONE);
295 UpdateSelectorButtons(); 236 UpdateSelectorButtons();
296 } 237 }
297 238
298 void WindowSelectorItem::Select() { 239 void WindowSelectorItem::Select() {
299 aura::Window* selection_window = SelectionWindow(); 240 aura::Window* selection_window = GetWindow();
300 if (selection_window) 241 if (selection_window)
301 wm::GetWindowState(selection_window)->Activate(); 242 wm::GetWindowState(selection_window)->Activate();
302 } 243 }
303 244
304 void WindowSelectorItem::SetItemBounds(aura::Window* root_window, 245 void WindowSelectorItem::SetItemBounds(const gfx::Rect& target_bounds,
305 const gfx::Rect& target_bounds,
306 OverviewAnimationType animation_type) { 246 OverviewAnimationType animation_type) {
307 gfx::Rect bounding_rect; 247 gfx::Rect screen_bounds = transform_window_.GetTargetBoundsInScreen();
308 for (auto* transform_window : transform_windows_) { 248 gfx::Rect selector_item_bounds =
309 bounding_rect.Union(
310 transform_window->GetTargetBoundsInScreen());
311 }
312 gfx::Rect bounds =
313 ScopedTransformOverviewWindow::ShrinkRectToFitPreservingAspectRatio( 249 ScopedTransformOverviewWindow::ShrinkRectToFitPreservingAspectRatio(
314 bounding_rect, target_bounds); 250 screen_bounds, target_bounds);
315 gfx::Transform bounding_transform = 251 gfx::Transform transform =
316 ScopedTransformOverviewWindow::GetTransformForRect(bounding_rect, bounds); 252 ScopedTransformOverviewWindow::GetTransformForRect(screen_bounds,
317 for (auto* transform_window : transform_windows_) { 253 selector_item_bounds);
318 gfx::Rect target_bounds = transform_window->GetTargetBoundsInScreen(); 254 ScopedTransformOverviewWindow::ScopedAnimationSettings animation_settings;
319 gfx::Transform transform = TransformAboutPivot( 255 transform_window_.BeginScopedAnimation(animation_type, &animation_settings);
320 gfx::Point(bounding_rect.x() - target_bounds.x(), 256 transform_window_.SetTransform(root_window_, transform);
321 bounding_rect.y() - target_bounds.y()), 257 transform_window_.set_overview_transform(transform);
322 bounding_transform);
323
324 ScopedTransformOverviewWindow::ScopedAnimationSettings animation_settings;
325 transform_window->BeginScopedAnimation(animation_type, &animation_settings);
326 transform_window->SetTransform(root_window, transform);
327 transform_window->set_overview_transform(transform);
328 }
329 } 258 }
330 259
331 void WindowSelectorItem::SetOpacity(float opacity) { 260 void WindowSelectorItem::SetOpacity(float opacity) {
332 window_label_->GetNativeWindow()->layer()->SetOpacity(opacity); 261 window_label_->GetNativeWindow()->layer()->SetOpacity(opacity);
333 close_button_widget_.GetNativeWindow()->layer()->SetOpacity(opacity); 262 close_button_widget_.GetNativeWindow()->layer()->SetOpacity(opacity);
334 263
335 // TODO(flackr): find a way to make panels that are hidden behind other panels 264 transform_window_.SetOpacity(opacity);
336 // look nice.
337 for (auto* transform_window : transform_windows_) {
338 transform_window->SetOpacity(opacity);
339 }
340 } 265 }
341 266
342 void WindowSelectorItem::UpdateWindowLabels( 267 void WindowSelectorItem::UpdateWindowLabels(
343 const gfx::Rect& window_bounds, 268 const gfx::Rect& window_bounds,
344 OverviewAnimationType animation_type) { 269 OverviewAnimationType animation_type) {
345 // If the root window has changed, force the window label to be recreated
346 // and faded in on the new root window.
347 DCHECK(!window_label_ || 270 DCHECK(!window_label_ ||
348 window_label_->GetNativeWindow()->GetRootWindow() == root_window_); 271 window_label_->GetNativeWindow()->GetRootWindow() == root_window_);
349 272
350 if (!window_label_) { 273 if (!window_label_) {
351 CreateWindowLabel(SelectionWindow()->title()); 274 CreateWindowLabel(GetWindow()->title());
352 SetupFadeInAfterLayout(window_label_->GetNativeWindow()); 275 SetupFadeInAfterLayout(window_label_->GetNativeWindow());
353 } 276 }
354 277
355 gfx::Rect converted_bounds = ScreenUtil::ConvertRectFromScreen(root_window_, 278 gfx::Rect converted_bounds = ScreenUtil::ConvertRectFromScreen(root_window_,
356 window_bounds); 279 window_bounds);
357 gfx::Rect label_bounds(converted_bounds.x(), 280 gfx::Rect label_bounds(converted_bounds.x(),
358 converted_bounds.bottom(), 281 converted_bounds.bottom(),
359 converted_bounds.width(), 282 converted_bounds.width(),
360 0); 283 0);
361 label_bounds.set_height(window_label_->GetContentsView()-> 284 label_bounds.set_height(window_label_->GetContentsView()->
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 views::BoxLayout* layout = new views::BoxLayout(views::BoxLayout::kVertical, 318 views::BoxLayout* layout = new views::BoxLayout(views::BoxLayout::kVertical,
396 0, 319 0,
397 kVerticalLabelPadding, 320 kVerticalLabelPadding,
398 0); 321 0);
399 window_label_view_->SetLayoutManager(layout); 322 window_label_view_->SetLayoutManager(layout);
400 window_label_->SetContentsView(window_label_view_); 323 window_label_->SetContentsView(window_label_view_);
401 window_label_->Show(); 324 window_label_->Show();
402 } 325 }
403 326
404 void WindowSelectorItem::UpdateSelectorButtons() { 327 void WindowSelectorItem::UpdateSelectorButtons() {
405 CHECK(!transform_windows_.empty()); 328 aura::Window* window = GetWindow();
329 CHECK(window);
406 330
407 selector_item_activate_window_button_->SetBounds(target_bounds()); 331 selector_item_activate_window_button_->SetBounds(target_bounds());
408 selector_item_activate_window_button_->SetAccessibleName( 332 selector_item_activate_window_button_->SetAccessibleName(window->title());
409 transform_windows_.front()->window()->title());
410 333
411 for (auto* transform_window : transform_windows_) { 334 TransparentActivateWindowButton* activate_button =
412 TransparentActivateWindowButton* activate_button = 335 transform_window_.activate_button();
413 transform_window->activate_button(); 336 activate_button->SetBounds(target_bounds());
414 337 activate_button->SetAccessibleName(window->title());
415 // If there is only one window in this, then expand the transparent overlay
416 // so that touch exploration in ChromVox only provides spoken feedback once
417 // within |this| selector item's bounds.
418 gfx::Rect bounds = transform_windows_.size() == 1
419 ? target_bounds() : GetTransformedBounds(transform_window->window());
420 activate_button->SetBounds(bounds);
421 activate_button->SetAccessibleName(transform_window->window()->title());
422 }
423 } 338 }
424 339
425 void WindowSelectorItem::UpdateCloseButtonLayout( 340 void WindowSelectorItem::UpdateCloseButtonLayout(
426 OverviewAnimationType animation_type) { 341 OverviewAnimationType animation_type) {
427 if (!close_button_->visible()) { 342 if (!close_button_->visible()) {
428 close_button_->SetVisible(true); 343 close_button_->SetVisible(true);
429 SetupFadeInAfterLayout(close_button_widget_.GetNativeWindow()); 344 SetupFadeInAfterLayout(close_button_widget_.GetNativeWindow());
430 } 345 }
431 ScopedOverviewAnimationSettings animation_settings(animation_type, 346 ScopedOverviewAnimationSettings animation_settings(animation_type,
432 close_button_widget_.GetNativeWindow()); 347 close_button_widget_.GetNativeWindow());
433 348
434 gfx::Rect transformed_window_bounds = ScreenUtil::ConvertRectFromScreen( 349 gfx::Rect transformed_window_bounds = ScreenUtil::ConvertRectFromScreen(
435 close_button_widget_.GetNativeWindow()->GetRootWindow(), 350 close_button_widget_.GetNativeWindow()->GetRootWindow(),
436 GetTransformedBounds(SelectionWindow())); 351 GetTransformedBounds(GetWindow()));
437 352
438 gfx::Transform close_button_transform; 353 gfx::Transform close_button_transform;
439 close_button_transform.Translate(transformed_window_bounds.right(), 354 close_button_transform.Translate(transformed_window_bounds.right(),
440 transformed_window_bounds.y()); 355 transformed_window_bounds.y());
441 close_button_widget_.GetNativeWindow()->SetTransform( 356 close_button_widget_.GetNativeWindow()->SetTransform(
442 close_button_transform); 357 close_button_transform);
443 } 358 }
444 359
445 void WindowSelectorItem::UpdateCloseButtonAccessibilityName() { 360 void WindowSelectorItem::UpdateCloseButtonAccessibilityName() {
446 close_button_->SetAccessibleName(l10n_util::GetStringFUTF16( 361 close_button_->SetAccessibleName(l10n_util::GetStringFUTF16(
447 IDS_ASH_OVERVIEW_CLOSE_ITEM_BUTTON_ACCESSIBLE_NAME, 362 IDS_ASH_OVERVIEW_CLOSE_ITEM_BUTTON_ACCESSIBLE_NAME,
448 SelectionWindow()->title())); 363 GetWindow()->title()));
449 }
450
451 ScopedTransformOverviewWindow*
452 WindowSelectorItem::SelectionTransformWindow() const {
453 CHECK(!transform_windows_.empty());
454 return transform_windows_.front();
455 } 364 }
456 365
457 } // namespace ash 366 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698