OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/common/wm/overview/window_grid.h" | 5 #include "ash/common/wm/overview/window_grid.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <functional> | 8 #include <functional> |
9 #include <set> | 9 #include <set> |
10 #include <utility> | 10 #include <utility> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "ash/common/ash_switches.h" | 13 #include "ash/common/ash_switches.h" |
14 #include "ash/common/material_design/material_design_controller.h" | |
15 #include "ash/common/shelf/wm_shelf.h" | 14 #include "ash/common/shelf/wm_shelf.h" |
16 #include "ash/common/shell_window_ids.h" | 15 #include "ash/common/shell_window_ids.h" |
17 #include "ash/common/wm/overview/cleanup_animation_observer.h" | 16 #include "ash/common/wm/overview/cleanup_animation_observer.h" |
18 #include "ash/common/wm/overview/scoped_overview_animation_settings.h" | 17 #include "ash/common/wm/overview/scoped_overview_animation_settings.h" |
19 #include "ash/common/wm/overview/scoped_overview_animation_settings_factory.h" | 18 #include "ash/common/wm/overview/scoped_overview_animation_settings_factory.h" |
20 #include "ash/common/wm/overview/window_selector.h" | 19 #include "ash/common/wm/overview/window_selector.h" |
21 #include "ash/common/wm/overview/window_selector_delegate.h" | 20 #include "ash/common/wm/overview/window_selector_delegate.h" |
22 #include "ash/common/wm/overview/window_selector_item.h" | 21 #include "ash/common/wm/overview/window_selector_item.h" |
23 #include "ash/common/wm/window_state.h" | 22 #include "ash/common/wm/window_state.h" |
24 #include "ash/common/wm/wm_screen_util.h" | 23 #include "ash/common/wm/wm_screen_util.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 explicit WindowSelectorItemComparator(const WmWindow* target_window) | 56 explicit WindowSelectorItemComparator(const WmWindow* target_window) |
58 : target(target_window) {} | 57 : target(target_window) {} |
59 | 58 |
60 bool operator()(WindowSelectorItem* window) const { | 59 bool operator()(WindowSelectorItem* window) const { |
61 return window->GetWindow() == target; | 60 return window->GetWindow() == target; |
62 } | 61 } |
63 | 62 |
64 const WmWindow* target; | 63 const WmWindow* target; |
65 }; | 64 }; |
66 | 65 |
67 // Conceptually the window overview is a table or grid of cells having this | 66 // Time it takes for the selector widget to move to the next target. The same |
68 // fixed aspect ratio. The number of columns is determined by maximizing the | 67 // time is used for fading out shield widget when the overview mode is opened |
69 // area of them based on the number of window_list. | 68 // or closed. |
70 const float kCardAspectRatio = 4.0f / 3.0f; | |
71 | |
72 // The minimum number of cards along the major axis (i.e. horizontally on a | |
73 // landscape orientation). | |
74 const int kMinCardsMajor = 3; | |
75 | |
76 // Hiding window headers can be resource intensive. Only hide the headers when | |
77 // the number of windows in this grid is less or equal than this number. | |
78 // The default is 0, meaning that mask layers are never used and the bottom | |
79 // corners are not rounded in overview. | |
80 const int kMaxWindowsCountToHideHeaderWithMasks = 0; | |
81 | |
82 const int kOverviewSelectorTransitionMilliseconds = 250; | 69 const int kOverviewSelectorTransitionMilliseconds = 250; |
83 | 70 |
84 // The color and opacity of the screen shield in overview. | 71 // The color and opacity of the screen shield in overview. |
85 const SkColor kShieldColor = SkColorSetARGB(255, 0, 0, 0); | 72 const SkColor kShieldColor = SkColorSetARGB(255, 0, 0, 0); |
86 const float kShieldOpacity = 0.7f; | 73 const float kShieldOpacity = 0.7f; |
87 | 74 |
88 // The color and opacity of the overview selector. | 75 // The color and opacity of the overview selector. |
89 const SkColor kWindowSelectionColor = SkColorSetARGB(128, 0, 0, 0); | 76 const SkColor kWindowSelectionColor = SkColorSetARGB(51, 255, 255, 255); |
90 const SkColor kWindowSelectionColorMD = SkColorSetARGB(51, 255, 255, 255); | 77 const SkColor kWindowSelectionBorderColor = SkColorSetARGB(76, 255, 255, 255); |
91 const SkColor kWindowSelectionBorderColor = SkColorSetARGB(38, 255, 255, 255); | |
92 const SkColor kWindowSelectionBorderColorMD = SkColorSetARGB(76, 255, 255, 255); | |
93 | 78 |
94 // Border thickness of overview selector. | 79 // Border thickness of overview selector. |
95 const int kWindowSelectionBorderThickness = 2; | 80 const int kWindowSelectionBorderThickness = 1; |
96 const int kWindowSelectionBorderThicknessMD = 1; | |
97 | 81 |
98 // Corner radius of the overview selector border. | 82 // Corner radius of the overview selector border. |
99 const int kWindowSelectionRadius = 0; | 83 const int kWindowSelectionRadius = 4; |
100 const int kWindowSelectionRadiusMD = 4; | |
101 | |
102 // The minimum amount of spacing between the bottom of the text filtering | |
103 // text field and the top of the selection widget on the first row of items. | |
104 const int kTextFilterBottomMargin = 5; | |
105 | 84 |
106 // In the conceptual overview table, the window margin is the space reserved | 85 // In the conceptual overview table, the window margin is the space reserved |
107 // around the window within the cell. This margin does not overlap so the | 86 // around the window within the cell. This margin does not overlap so the |
108 // closest distance between adjacent windows will be twice this amount. | 87 // closest distance between adjacent windows will be twice this amount. |
109 const int kWindowMarginMD = 5; | 88 const int kWindowMargin = 5; |
110 | 89 |
111 // Windows are not allowed to get taller than this. | 90 // Windows are not allowed to get taller than this. |
112 const int kMaxHeight = 512; | 91 const int kMaxHeight = 512; |
113 | 92 |
114 // Margins reserved in the overview mode. | 93 // Margins reserved in the overview mode. |
115 const float kOverviewInsetRatio = 0.05f; | 94 const float kOverviewInsetRatio = 0.05f; |
116 | 95 |
117 // Additional vertical inset reserved for windows in overview mode. | 96 // Additional vertical inset reserved for windows in overview mode. |
118 const float kOverviewVerticalInset = 0.1f; | 97 const float kOverviewVerticalInset = 0.1f; |
119 | 98 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 if (border_thickness_ > 0) { | 199 if (border_thickness_ > 0) { |
221 paint.setColor(border_color_); | 200 paint.setColor(border_color_); |
222 canvas->sk_canvas()->drawPath(stroke_path, paint); | 201 canvas->sk_canvas()->drawPath(stroke_path, paint); |
223 } | 202 } |
224 } | 203 } |
225 | 204 |
226 // Returns the vector for the fade in animation. | 205 // Returns the vector for the fade in animation. |
227 gfx::Vector2d GetSlideVectorForFadeIn(WindowSelector::Direction direction, | 206 gfx::Vector2d GetSlideVectorForFadeIn(WindowSelector::Direction direction, |
228 const gfx::Rect& bounds) { | 207 const gfx::Rect& bounds) { |
229 gfx::Vector2d vector; | 208 gfx::Vector2d vector; |
230 const bool material = ash::MaterialDesignController::IsOverviewMaterial(); | |
231 switch (direction) { | 209 switch (direction) { |
232 case WindowSelector::UP: | 210 case WindowSelector::UP: |
233 if (!material) { | |
234 vector.set_y(-bounds.height()); | |
235 break; | |
236 } | |
237 case WindowSelector::LEFT: | 211 case WindowSelector::LEFT: |
238 vector.set_x(-bounds.width()); | 212 vector.set_x(-bounds.width()); |
239 break; | 213 break; |
240 case WindowSelector::DOWN: | 214 case WindowSelector::DOWN: |
241 if (!material) { | |
242 vector.set_y(bounds.height()); | |
243 break; | |
244 } | |
245 case WindowSelector::RIGHT: | 215 case WindowSelector::RIGHT: |
246 vector.set_x(bounds.width()); | 216 vector.set_x(bounds.width()); |
247 break; | 217 break; |
248 } | 218 } |
249 return vector; | 219 return vector; |
250 } | 220 } |
251 | 221 |
252 // Given |root_window|, calculates the item size necessary to fit |items| | |
253 // items in the window selection. |bounding_rect| is set to the centered | |
254 // rectangle containing the grid and |item_size| is set to the size of each | |
255 // individual item. | |
256 void CalculateOverviewSizes(WmWindow* root_window, | |
257 size_t items, | |
258 int text_filter_bottom, | |
259 gfx::Rect* bounding_rect, | |
260 gfx::Size* item_size) { | |
261 gfx::Rect total_bounds = root_window->ConvertRectToScreen( | |
262 wm::GetDisplayWorkAreaBoundsInParent(root_window->GetChildByShellWindowId( | |
263 kShellWindowId_DefaultContainer))); | |
264 | |
265 // Reserve space at the top for the text filtering textbox to appear. | |
266 total_bounds.Inset(0, text_filter_bottom + kTextFilterBottomMargin, 0, 0); | |
267 | |
268 // Find the minimum number of windows per row that will fit all of the | |
269 // windows on screen. | |
270 int num_columns = std::max( | |
271 total_bounds.width() > total_bounds.height() ? kMinCardsMajor : 1, | |
272 static_cast<int>(ceil(sqrt(total_bounds.width() * items / | |
273 (kCardAspectRatio * total_bounds.height()))))); | |
274 int num_rows = ((items + num_columns - 1) / num_columns); | |
275 item_size->set_width(std::min( | |
276 static_cast<int>(total_bounds.width() / num_columns), | |
277 static_cast<int>(total_bounds.height() * kCardAspectRatio / num_rows))); | |
278 item_size->set_height( | |
279 static_cast<int>(item_size->width() / kCardAspectRatio)); | |
280 item_size->SetToMax(gfx::Size(1, 1)); | |
281 | |
282 bounding_rect->set_width(std::min(static_cast<int>(items), num_columns) * | |
283 item_size->width()); | |
284 bounding_rect->set_height(num_rows * item_size->height()); | |
285 // Calculate the X and Y offsets necessary to center the grid. | |
286 bounding_rect->set_x(total_bounds.x() + | |
287 (total_bounds.width() - bounding_rect->width()) / 2); | |
288 bounding_rect->set_y(total_bounds.y() + | |
289 (total_bounds.height() - bounding_rect->height()) / 2); | |
290 } | |
291 | |
292 // Reorders the list of windows |items| in |root_window| in an attempt to | |
293 // minimize the distance each window will travel to enter overview. For | |
294 // equidistant windows preserves a stable order between overview sessions | |
295 // by comparing window pointers. | |
296 void ReorderItemsGreedyLeastMovement(std::vector<WmWindow*>* items, | |
297 WmWindow* root_window, | |
298 int text_filter_bottom) { | |
299 if (items->empty()) | |
300 return; | |
301 gfx::Rect bounding_rect; | |
302 gfx::Size item_size; | |
303 CalculateOverviewSizes(root_window, items->size(), text_filter_bottom, | |
304 &bounding_rect, &item_size); | |
305 int num_columns = std::min(static_cast<int>(items->size()), | |
306 bounding_rect.width() / item_size.width()); | |
307 for (size_t i = 0; i < items->size(); ++i) { | |
308 int column = i % num_columns; | |
309 int row = i / num_columns; | |
310 gfx::Point overview_item_center( | |
311 bounding_rect.x() + column * item_size.width() + item_size.width() / 2, | |
312 bounding_rect.y() + row * item_size.height() + item_size.height() / 2); | |
313 // Find the nearest window for this position. | |
314 size_t swap_index = i; | |
315 int64_t shortest_distance = std::numeric_limits<int64_t>::max(); | |
316 for (size_t j = i; j < items->size(); ++j) { | |
317 WmWindow* window = (*items)[j]; | |
318 const gfx::Rect screen_target_bounds = | |
319 window->ConvertRectToScreen(window->GetTargetBounds()); | |
320 int64_t distance = | |
321 (screen_target_bounds.CenterPoint() - overview_item_center) | |
322 .LengthSquared(); | |
323 // We compare raw pointers to create a stable ordering given two windows | |
324 // with the same center point. | |
325 if (distance < shortest_distance || | |
326 (distance == shortest_distance && window < (*items)[swap_index])) { | |
327 shortest_distance = distance; | |
328 swap_index = j; | |
329 } | |
330 } | |
331 if (swap_index > i) | |
332 std::swap((*items)[i], (*items)[swap_index]); | |
333 } | |
334 } | |
335 | |
336 // Creates and returns a background translucent widget parented in | 222 // Creates and returns a background translucent widget parented in |
337 // |root_window|'s default container and having |background_color|. | 223 // |root_window|'s default container and having |background_color|. |
338 // When |border_thickness| is non-zero, a border is created having | 224 // When |border_thickness| is non-zero, a border is created having |
339 // |border_color|, otherwise |border_color| parameter is ignored. | 225 // |border_color|, otherwise |border_color| parameter is ignored. |
340 // The new background widget starts with |initial_opacity| and then fades in. | 226 // The new background widget starts with |initial_opacity| and then fades in. |
341 views::Widget* CreateBackgroundWidget(WmWindow* root_window, | 227 views::Widget* CreateBackgroundWidget(WmWindow* root_window, |
342 SkColor background_color, | 228 SkColor background_color, |
343 int border_thickness, | 229 int border_thickness, |
344 int border_radius, | 230 int border_radius, |
345 SkColor border_color, | 231 SkColor border_color, |
(...skipping 14 matching lines...) Expand all Loading... |
360 widget, kShellWindowId_WallpaperContainer, ¶ms); | 246 widget, kShellWindowId_WallpaperContainer, ¶ms); |
361 widget->Init(params); | 247 widget->Init(params); |
362 WmWindow* widget_window = WmLookup::Get()->GetWindowForWidget(widget); | 248 WmWindow* widget_window = WmLookup::Get()->GetWindowForWidget(widget); |
363 // Disable the "bounce in" animation when showing the window. | 249 // Disable the "bounce in" animation when showing the window. |
364 widget_window->SetVisibilityAnimationTransition(::wm::ANIMATE_NONE); | 250 widget_window->SetVisibilityAnimationTransition(::wm::ANIMATE_NONE); |
365 // The background widget should not activate the shelf when passing under it. | 251 // The background widget should not activate the shelf when passing under it. |
366 widget_window->GetWindowState()->set_ignored_by_shelf(true); | 252 widget_window->GetWindowState()->set_ignored_by_shelf(true); |
367 | 253 |
368 views::View* content_view = | 254 views::View* content_view = |
369 new RoundedRectView(border_radius, SK_ColorTRANSPARENT); | 255 new RoundedRectView(border_radius, SK_ColorTRANSPARENT); |
370 if (ash::MaterialDesignController::IsOverviewMaterial()) { | 256 content_view->set_background(new BackgroundWith1PxBorder( |
371 content_view->set_background(new BackgroundWith1PxBorder( | 257 background_color, border_color, border_thickness, border_radius)); |
372 background_color, border_color, border_thickness, border_radius)); | |
373 } else { | |
374 content_view->set_background( | |
375 views::Background::CreateSolidBackground(background_color)); | |
376 if (border_thickness) { | |
377 content_view->SetBorder( | |
378 views::Border::CreateSolidBorder(border_thickness, border_color)); | |
379 } | |
380 } | |
381 widget->SetContentsView(content_view); | 258 widget->SetContentsView(content_view); |
382 widget_window->GetParent()->StackChildAtTop(widget_window); | 259 widget_window->GetParent()->StackChildAtTop(widget_window); |
383 widget->Show(); | 260 widget->Show(); |
384 widget_window->SetOpacity(initial_opacity); | 261 widget_window->SetOpacity(initial_opacity); |
385 return widget; | 262 return widget; |
386 } | 263 } |
387 | 264 |
388 } // namespace | 265 } // namespace |
389 | 266 |
390 WindowGrid::WindowGrid(WmWindow* root_window, | 267 WindowGrid::WindowGrid(WmWindow* root_window, |
391 const std::vector<WmWindow*>& windows, | 268 const std::vector<WmWindow*>& windows, |
392 WindowSelector* window_selector) | 269 WindowSelector* window_selector) |
393 : root_window_(root_window), | 270 : root_window_(root_window), |
394 window_selector_(window_selector), | 271 window_selector_(window_selector), |
395 window_observer_(this), | 272 window_observer_(this), |
396 selected_index_(0), | 273 selected_index_(0), |
397 num_columns_(0), | 274 num_columns_(0), |
398 prepared_for_overview_(false) { | 275 prepared_for_overview_(false) { |
399 std::vector<WmWindow*> windows_in_root; | 276 std::vector<WmWindow*> windows_in_root; |
400 for (auto* window : windows) { | 277 for (auto* window : windows) { |
401 if (window->GetRootWindow() == root_window) | 278 if (window->GetRootWindow() == root_window) |
402 windows_in_root.push_back(window); | 279 windows_in_root.push_back(window); |
403 } | 280 } |
404 | 281 |
405 if (!ash::MaterialDesignController::IsOverviewMaterial() && | |
406 base::CommandLine::ForCurrentProcess()->HasSwitch( | |
407 switches::kAshEnableStableOverviewOrder)) { | |
408 // Reorder windows to try to minimize movement to target overview positions. | |
409 // This also creates a stable window ordering. | |
410 ReorderItemsGreedyLeastMovement(&windows_in_root, root_window_, | |
411 window_selector_->text_filter_bottom()); | |
412 } | |
413 PrepareForUsingMasksOrShapes(windows_in_root.size()); | |
414 for (auto* window : windows_in_root) { | 282 for (auto* window : windows_in_root) { |
415 window_observer_.Add(window); | 283 window_observer_.Add(window); |
416 window_list_.push_back(new WindowSelectorItem(window, window_selector_)); | 284 window_list_.push_back(new WindowSelectorItem(window, window_selector_)); |
417 } | 285 } |
418 } | 286 } |
419 | 287 |
420 WindowGrid::~WindowGrid() {} | 288 WindowGrid::~WindowGrid() {} |
421 | 289 |
422 void WindowGrid::Shutdown() { | 290 void WindowGrid::Shutdown() { |
423 for (auto iter = window_list_.begin(); iter != window_list_.end(); ++iter) | 291 for (auto iter = window_list_.begin(); iter != window_list_.end(); ++iter) |
(...skipping 20 matching lines...) Expand all Loading... |
444 std::unique_ptr<CleanupAnimationObserver> observer( | 312 std::unique_ptr<CleanupAnimationObserver> observer( |
445 new CleanupAnimationObserver(std::move(shield_widget_))); | 313 new CleanupAnimationObserver(std::move(shield_widget_))); |
446 animation_settings.AddObserver(observer.get()); | 314 animation_settings.AddObserver(observer.get()); |
447 window_selector_->delegate()->AddDelayedAnimationObserver( | 315 window_selector_->delegate()->AddDelayedAnimationObserver( |
448 std::move(observer)); | 316 std::move(observer)); |
449 shield_widget->SetOpacity(0.f); | 317 shield_widget->SetOpacity(0.f); |
450 } | 318 } |
451 } | 319 } |
452 | 320 |
453 void WindowGrid::PrepareForOverview() { | 321 void WindowGrid::PrepareForOverview() { |
454 if (ash::MaterialDesignController::IsOverviewMaterial()) | 322 InitShieldWidget(); |
455 InitShieldWidget(); | |
456 for (auto iter = window_list_.begin(); iter != window_list_.end(); ++iter) | 323 for (auto iter = window_list_.begin(); iter != window_list_.end(); ++iter) |
457 (*iter)->PrepareForOverview(); | 324 (*iter)->PrepareForOverview(); |
458 prepared_for_overview_ = true; | 325 prepared_for_overview_ = true; |
459 } | 326 } |
460 | 327 |
461 void WindowGrid::PositionWindowsMD(bool animate) { | 328 void WindowGrid::PositionWindows(bool animate) { |
462 if (window_list_.empty()) | 329 if (window_selector_->is_shut_down() || window_list_.empty()) |
463 return; | 330 return; |
464 PrepareForUsingMasksOrShapes(window_list_.size()); | 331 DCHECK(shield_widget_.get()); |
| 332 // Keep the background shield widget covering the whole screen. |
| 333 WmWindow* widget_window = |
| 334 WmLookup::Get()->GetWindowForWidget(shield_widget_.get()); |
| 335 const gfx::Rect bounds = widget_window->GetParent()->GetBounds(); |
| 336 widget_window->SetBounds(bounds); |
465 gfx::Rect total_bounds = | 337 gfx::Rect total_bounds = |
466 root_window_->ConvertRectToScreen(wm::GetDisplayWorkAreaBoundsInParent( | 338 root_window_->ConvertRectToScreen(wm::GetDisplayWorkAreaBoundsInParent( |
467 root_window_->GetChildByShellWindowId( | 339 root_window_->GetChildByShellWindowId( |
468 kShellWindowId_DefaultContainer))); | 340 kShellWindowId_DefaultContainer))); |
469 // Windows occupy vertically centered area with additional vertical insets. | 341 // Windows occupy vertically centered area with additional vertical insets. |
470 int horizontal_inset = | 342 int horizontal_inset = |
471 gfx::ToFlooredInt(std::min(kOverviewInsetRatio * total_bounds.width(), | 343 gfx::ToFlooredInt(std::min(kOverviewInsetRatio * total_bounds.width(), |
472 kOverviewInsetRatio * total_bounds.height())); | 344 kOverviewInsetRatio * total_bounds.height())); |
473 int vertical_inset = | 345 int vertical_inset = |
474 horizontal_inset + | 346 horizontal_inset + |
475 kOverviewVerticalInset * (total_bounds.height() - 2 * horizontal_inset); | 347 kOverviewVerticalInset * (total_bounds.height() - 2 * horizontal_inset); |
476 total_bounds.Inset(std::max(0, horizontal_inset - kWindowMarginMD), | 348 total_bounds.Inset(std::max(0, horizontal_inset - kWindowMargin), |
477 std::max(0, vertical_inset - kWindowMarginMD)); | 349 std::max(0, vertical_inset - kWindowMargin)); |
478 std::vector<gfx::Rect> rects; | 350 std::vector<gfx::Rect> rects; |
479 | 351 |
480 // Keep track of the lowest coordinate. | 352 // Keep track of the lowest coordinate. |
481 int max_bottom = total_bounds.y(); | 353 int max_bottom = total_bounds.y(); |
482 | 354 |
483 // Right bound of the narrowest row. | 355 // Right bound of the narrowest row. |
484 int min_right = total_bounds.right(); | 356 int min_right = total_bounds.right(); |
485 // Right bound of the widest row. | 357 // Right bound of the widest row. |
486 int max_right = total_bounds.x(); | 358 int max_right = total_bounds.x(); |
487 | 359 |
488 // Keep track of the difference between the narrowest and the widest row. | 360 // Keep track of the difference between the narrowest and the widest row. |
489 // Initially this is set to the worst it can ever be assuming the windows fit. | 361 // Initially this is set to the worst it can ever be assuming the windows fit. |
490 int width_diff = total_bounds.width(); | 362 int width_diff = total_bounds.width(); |
491 | 363 |
492 // Initially allow the windows to occupy all available width. Shrink this | 364 // Initially allow the windows to occupy all available width. Shrink this |
493 // available space horizontally to find the breakdown into rows that achieves | 365 // available space horizontally to find the breakdown into rows that achieves |
494 // the minimal |width_diff|. | 366 // the minimal |width_diff|. |
495 int right_bound = total_bounds.right(); | 367 int right_bound = total_bounds.right(); |
496 | 368 |
497 // Determine the optimal height bisecting between |low_height| and | 369 // Determine the optimal height bisecting between |low_height| and |
498 // |high_height|. Once this optimal height is known, |height_fixed| is set to | 370 // |high_height|. Once this optimal height is known, |height_fixed| is set to |
499 // true and the rows are balanced by repeatedly squeezing the widest row to | 371 // true and the rows are balanced by repeatedly squeezing the widest row to |
500 // cause windows to overflow to the subsequent rows. | 372 // cause windows to overflow to the subsequent rows. |
501 int low_height = 2 * kWindowMarginMD; | 373 int low_height = 2 * kWindowMargin; |
502 int high_height = | 374 int high_height = |
503 std::max(low_height, static_cast<int>(total_bounds.height() + 1)); | 375 std::max(low_height, static_cast<int>(total_bounds.height() + 1)); |
504 int height = 0.5 * (low_height + high_height); | 376 int height = 0.5 * (low_height + high_height); |
505 bool height_fixed = false; | 377 bool height_fixed = false; |
506 | 378 |
507 // Repeatedly try to fit the windows |rects| within |right_bound|. | 379 // Repeatedly try to fit the windows |rects| within |right_bound|. |
508 // If a maximum |height| is found such that all window |rects| fit, this | 380 // If a maximum |height| is found such that all window |rects| fit, this |
509 // fitting continues while shrinking the |right_bound| in order to balance the | 381 // fitting continues while shrinking the |right_bound| in order to balance the |
510 // rows. If the windows fit the |right_bound| would have been decremented at | 382 // rows. If the windows fit the |right_bound| would have been decremented at |
511 // least once so it needs to be incremented once before getting out of this | 383 // least once so it needs to be incremented once before getting out of this |
512 // loop and one additional pass made to actually fit the |rects|. | 384 // loop and one additional pass made to actually fit the |rects|. |
513 // If the |rects| cannot fit (e.g. there are too many windows) the bisection | 385 // If the |rects| cannot fit (e.g. there are too many windows) the bisection |
514 // will still finish and we might increment the |right_bound| once pixel extra | 386 // will still finish and we might increment the |right_bound| once pixel extra |
515 // which is acceptable since there is an unused margin on the right. | 387 // which is acceptable since there is an unused margin on the right. |
516 bool make_last_adjustment = false; | 388 bool make_last_adjustment = false; |
517 while (true) { | 389 while (true) { |
518 gfx::Rect overview_bounds(total_bounds); | 390 gfx::Rect overview_bounds(total_bounds); |
519 overview_bounds.set_width(right_bound - total_bounds.x()); | 391 overview_bounds.set_width(right_bound - total_bounds.x()); |
520 bool windows_fit = FitWindowRectsInBounds( | 392 bool windows_fit = FitWindowRectsInBounds( |
521 overview_bounds, std::min(kMaxHeight + 2 * kWindowMarginMD, height), | 393 overview_bounds, std::min(kMaxHeight + 2 * kWindowMargin, height), |
522 &rects, &max_bottom, &min_right, &max_right); | 394 &rects, &max_bottom, &min_right, &max_right); |
523 | 395 |
524 if (height_fixed) { | 396 if (height_fixed) { |
525 if (!windows_fit) { | 397 if (!windows_fit) { |
526 // Revert the previous change to |right_bound| and do one last pass. | 398 // Revert the previous change to |right_bound| and do one last pass. |
527 right_bound++; | 399 right_bound++; |
528 make_last_adjustment = true; | 400 make_last_adjustment = true; |
529 break; | 401 break; |
530 } | 402 } |
531 // Break if all the windows are zero-width at the current scale. | 403 // Break if all the windows are zero-width at the current scale. |
(...skipping 26 matching lines...) Expand all Loading... |
558 break; | 430 break; |
559 } | 431 } |
560 } | 432 } |
561 } | 433 } |
562 // Once the windows in |window_list_| no longer fit, the change to | 434 // Once the windows in |window_list_| no longer fit, the change to |
563 // |right_bound| was reverted. Perform one last pass to position the |rects|. | 435 // |right_bound| was reverted. Perform one last pass to position the |rects|. |
564 if (make_last_adjustment) { | 436 if (make_last_adjustment) { |
565 gfx::Rect overview_bounds(total_bounds); | 437 gfx::Rect overview_bounds(total_bounds); |
566 overview_bounds.set_width(right_bound - total_bounds.x()); | 438 overview_bounds.set_width(right_bound - total_bounds.x()); |
567 FitWindowRectsInBounds(overview_bounds, | 439 FitWindowRectsInBounds(overview_bounds, |
568 std::min(kMaxHeight + 2 * kWindowMarginMD, height), | 440 std::min(kMaxHeight + 2 * kWindowMargin, height), |
569 &rects, &max_bottom, &min_right, &max_right); | 441 &rects, &max_bottom, &min_right, &max_right); |
570 } | 442 } |
571 // Position the windows centering the left-aligned rows vertically. | 443 // Position the windows centering the left-aligned rows vertically. |
572 gfx::Vector2d offset(0, (total_bounds.bottom() - max_bottom) / 2); | 444 gfx::Vector2d offset(0, (total_bounds.bottom() - max_bottom) / 2); |
573 for (size_t i = 0; i < window_list_.size(); ++i) { | 445 for (size_t i = 0; i < window_list_.size(); ++i) { |
574 window_list_[i]->SetBounds( | 446 window_list_[i]->SetBounds( |
575 rects[i] + offset, | 447 rects[i] + offset, |
576 animate | 448 animate |
577 ? OverviewAnimationType::OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS | 449 ? OverviewAnimationType::OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS |
578 : OverviewAnimationType::OVERVIEW_ANIMATION_NONE); | 450 : OverviewAnimationType::OVERVIEW_ANIMATION_NONE); |
579 } | 451 } |
580 | 452 |
581 // If the selection widget is active, reposition it without any animation. | 453 // If the selection widget is active, reposition it without any animation. |
582 if (selection_widget_) | 454 if (selection_widget_) |
583 MoveSelectionWidgetToTarget(animate); | 455 MoveSelectionWidgetToTarget(animate); |
584 } | 456 } |
585 | 457 |
586 void WindowGrid::PositionWindows(bool animate) { | |
587 if (window_selector_->is_shut_down()) | |
588 return; | |
589 | |
590 if (ash::MaterialDesignController::IsOverviewMaterial()) { | |
591 DCHECK(shield_widget_.get()); | |
592 // Keep the background shield widget covering the whole screen. | |
593 WmWindow* widget_window = | |
594 WmLookup::Get()->GetWindowForWidget(shield_widget_.get()); | |
595 const gfx::Rect bounds = widget_window->GetParent()->GetBounds(); | |
596 widget_window->SetBounds(bounds); | |
597 PositionWindowsMD(animate); | |
598 return; | |
599 } | |
600 CHECK(!window_list_.empty()); | |
601 gfx::Rect bounding_rect; | |
602 gfx::Size item_size; | |
603 CalculateOverviewSizes(root_window_, window_list_.size(), | |
604 window_selector_->text_filter_bottom(), &bounding_rect, | |
605 &item_size); | |
606 num_columns_ = std::min(static_cast<int>(window_list_.size()), | |
607 bounding_rect.width() / item_size.width()); | |
608 for (size_t i = 0; i < window_list_.size(); ++i) { | |
609 gfx::Transform transform; | |
610 int column = i % num_columns_; | |
611 int row = i / num_columns_; | |
612 gfx::Rect target_bounds(item_size.width() * column + bounding_rect.x(), | |
613 item_size.height() * row + bounding_rect.y(), | |
614 item_size.width(), item_size.height()); | |
615 window_list_[i]->SetBounds( | |
616 target_bounds, | |
617 animate | |
618 ? OverviewAnimationType::OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS | |
619 : OverviewAnimationType::OVERVIEW_ANIMATION_NONE); | |
620 } | |
621 | |
622 // If the selection widget is active, reposition it without any animation. | |
623 if (selection_widget_) | |
624 MoveSelectionWidgetToTarget(animate); | |
625 } | |
626 | |
627 bool WindowGrid::Move(WindowSelector::Direction direction, bool animate) { | 458 bool WindowGrid::Move(WindowSelector::Direction direction, bool animate) { |
628 bool recreate_selection_widget = false; | 459 bool recreate_selection_widget = false; |
629 bool out_of_bounds = false; | 460 bool out_of_bounds = false; |
630 bool changed_selection_index = false; | 461 bool changed_selection_index = false; |
631 const bool material = ash::MaterialDesignController::IsOverviewMaterial(); | |
632 gfx::Rect old_bounds; | 462 gfx::Rect old_bounds; |
633 if (SelectedWindow()) { | 463 if (SelectedWindow()) { |
634 old_bounds = SelectedWindow()->target_bounds(); | 464 old_bounds = SelectedWindow()->target_bounds(); |
635 // Make the old selected window header non-transparent first. | 465 // Make the old selected window header non-transparent first. |
636 SelectedWindow()->SetSelected(false); | 466 SelectedWindow()->SetSelected(false); |
637 } | 467 } |
638 | 468 |
639 // With Material Design enabled [up] key is equivalent to [left] key and | 469 // [up] key is equivalent to [left] key and [down] key is equivalent to |
640 // [down] key is equivalent to [right] key. | 470 // [right] key. |
641 if (!selection_widget_) { | 471 if (!selection_widget_) { |
642 switch (direction) { | 472 switch (direction) { |
643 case WindowSelector::UP: | 473 case WindowSelector::UP: |
644 if (!material) { | |
645 selected_index_ = | |
646 (window_list_.size() / num_columns_) * num_columns_ - 1; | |
647 break; | |
648 } | |
649 case WindowSelector::LEFT: | 474 case WindowSelector::LEFT: |
650 selected_index_ = window_list_.size() - 1; | 475 selected_index_ = window_list_.size() - 1; |
651 break; | 476 break; |
652 case WindowSelector::DOWN: | 477 case WindowSelector::DOWN: |
653 case WindowSelector::RIGHT: | 478 case WindowSelector::RIGHT: |
654 selected_index_ = 0; | 479 selected_index_ = 0; |
655 break; | 480 break; |
656 } | 481 } |
657 changed_selection_index = true; | 482 changed_selection_index = true; |
658 } | 483 } |
659 while (!changed_selection_index || | 484 while (!changed_selection_index || |
660 (!out_of_bounds && window_list_[selected_index_]->dimmed())) { | 485 (!out_of_bounds && window_list_[selected_index_]->dimmed())) { |
661 switch (direction) { | 486 switch (direction) { |
662 case WindowSelector::UP: | 487 case WindowSelector::UP: |
663 if (!material) { | |
664 if (selected_index_ == 0) | |
665 out_of_bounds = true; | |
666 if (selected_index_ < num_columns_) { | |
667 selected_index_ += | |
668 num_columns_ * | |
669 ((window_list_.size() - selected_index_) / num_columns_) - | |
670 1; | |
671 recreate_selection_widget = true; | |
672 } else { | |
673 selected_index_ -= num_columns_; | |
674 } | |
675 break; | |
676 } | |
677 case WindowSelector::LEFT: | 488 case WindowSelector::LEFT: |
678 if (selected_index_ == 0) | 489 if (selected_index_ == 0) |
679 out_of_bounds = true; | 490 out_of_bounds = true; |
680 selected_index_--; | 491 selected_index_--; |
681 if (!material && (selected_index_ + 1) % num_columns_ == 0) | |
682 recreate_selection_widget = true; | |
683 break; | 492 break; |
684 case WindowSelector::DOWN: | 493 case WindowSelector::DOWN: |
685 if (!material) { | |
686 selected_index_ += num_columns_; | |
687 if (selected_index_ >= window_list_.size()) { | |
688 selected_index_ = (selected_index_ + 1) % num_columns_; | |
689 if (selected_index_ == 0) | |
690 out_of_bounds = true; | |
691 recreate_selection_widget = true; | |
692 } | |
693 break; | |
694 } | |
695 case WindowSelector::RIGHT: | 494 case WindowSelector::RIGHT: |
696 if (selected_index_ >= window_list_.size() - 1) | 495 if (selected_index_ >= window_list_.size() - 1) |
697 out_of_bounds = true; | 496 out_of_bounds = true; |
698 selected_index_++; | 497 selected_index_++; |
699 if (!material && selected_index_ % num_columns_ == 0) | |
700 recreate_selection_widget = true; | |
701 break; | 498 break; |
702 } | 499 } |
703 if (material) { | 500 if (!out_of_bounds && SelectedWindow()) { |
704 if (!out_of_bounds && SelectedWindow()) { | 501 if (SelectedWindow()->target_bounds().y() != old_bounds.y()) |
705 if (SelectedWindow()->target_bounds().y() != old_bounds.y()) | 502 recreate_selection_widget = true; |
706 recreate_selection_widget = true; | |
707 } | |
708 } | 503 } |
709 changed_selection_index = true; | 504 changed_selection_index = true; |
710 } | 505 } |
711 | |
712 MoveSelectionWidget(direction, recreate_selection_widget, out_of_bounds, | 506 MoveSelectionWidget(direction, recreate_selection_widget, out_of_bounds, |
713 animate); | 507 animate); |
714 | 508 |
715 // Make the new selected window header fully transparent. | 509 // Make the new selected window header fully transparent. |
716 if (SelectedWindow()) | 510 if (SelectedWindow()) |
717 SelectedWindow()->SetSelected(true); | 511 SelectedWindow()->SetSelected(true); |
718 return out_of_bounds; | 512 return out_of_bounds; |
719 } | 513 } |
720 | 514 |
721 WindowSelectorItem* WindowGrid::SelectedWindow() const { | 515 WindowSelectorItem* WindowGrid::SelectedWindow() const { |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
801 // soon. | 595 // soon. |
802 if (!prepared_for_overview_) | 596 if (!prepared_for_overview_) |
803 return; | 597 return; |
804 | 598 |
805 auto iter = std::find_if(window_list_.begin(), window_list_.end(), | 599 auto iter = std::find_if(window_list_.begin(), window_list_.end(), |
806 WindowSelectorItemComparator(window)); | 600 WindowSelectorItemComparator(window)); |
807 DCHECK(iter != window_list_.end()); | 601 DCHECK(iter != window_list_.end()); |
808 | 602 |
809 // Immediately finish any active bounds animation. | 603 // Immediately finish any active bounds animation. |
810 window->StopAnimatingProperty(ui::LayerAnimationElement::BOUNDS); | 604 window->StopAnimatingProperty(ui::LayerAnimationElement::BOUNDS); |
811 | 605 PositionWindows(false); |
812 if (ash::MaterialDesignController::IsOverviewMaterial()) { | |
813 PositionWindows(false); | |
814 return; | |
815 } | |
816 // Recompute the transform for the window. | |
817 (*iter)->RecomputeWindowTransforms(); | |
818 } | 606 } |
819 | 607 |
820 void WindowGrid::InitShieldWidget() { | 608 void WindowGrid::InitShieldWidget() { |
821 // TODO(varkha): The code assumes that SHELF_BACKGROUND_MAXIMIZED is | 609 // TODO(varkha): The code assumes that SHELF_BACKGROUND_MAXIMIZED is |
822 // synonymous with a black shelf background. Update this code if that | 610 // synonymous with a black shelf background. Update this code if that |
823 // assumption is no longer valid. | 611 // assumption is no longer valid. |
824 const float initial_opacity = | 612 const float initial_opacity = |
825 (WmShelf::ForWindow(root_window_)->GetBackgroundType() == | 613 (WmShelf::ForWindow(root_window_)->GetBackgroundType() == |
826 SHELF_BACKGROUND_MAXIMIZED) | 614 SHELF_BACKGROUND_MAXIMIZED) |
827 ? 1.f | 615 ? 1.f |
(...skipping 11 matching lines...) Expand all Loading... |
839 widget_window->GetLayer()->GetAnimator()); | 627 widget_window->GetLayer()->GetAnimator()); |
840 animation_settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds( | 628 animation_settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds( |
841 kOverviewSelectorTransitionMilliseconds)); | 629 kOverviewSelectorTransitionMilliseconds)); |
842 animation_settings.SetTweenType(gfx::Tween::EASE_IN); | 630 animation_settings.SetTweenType(gfx::Tween::EASE_IN); |
843 animation_settings.SetPreemptionStrategy( | 631 animation_settings.SetPreemptionStrategy( |
844 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 632 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
845 shield_widget_->SetOpacity(kShieldOpacity); | 633 shield_widget_->SetOpacity(kShieldOpacity); |
846 } | 634 } |
847 | 635 |
848 void WindowGrid::InitSelectionWidget(WindowSelector::Direction direction) { | 636 void WindowGrid::InitSelectionWidget(WindowSelector::Direction direction) { |
849 const bool material = ash::MaterialDesignController::IsOverviewMaterial(); | 637 selection_widget_.reset(CreateBackgroundWidget( |
850 const int border_thickness = material ? kWindowSelectionBorderThicknessMD | 638 root_window_, kWindowSelectionColor, kWindowSelectionBorderThickness, |
851 : kWindowSelectionBorderThickness; | 639 kWindowSelectionRadius, kWindowSelectionBorderColor, 0.f)); |
852 const int border_color = | |
853 material ? kWindowSelectionBorderColorMD : kWindowSelectionBorderColor; | |
854 const int selection_color = | |
855 material ? kWindowSelectionColorMD : kWindowSelectionColor; | |
856 const int border_radius = | |
857 material ? kWindowSelectionRadiusMD : kWindowSelectionRadius; | |
858 selection_widget_.reset( | |
859 CreateBackgroundWidget(root_window_, selection_color, border_thickness, | |
860 border_radius, border_color, 0.f)); | |
861 WmWindow* widget_window = | 640 WmWindow* widget_window = |
862 WmLookup::Get()->GetWindowForWidget(selection_widget_.get()); | 641 WmLookup::Get()->GetWindowForWidget(selection_widget_.get()); |
863 const gfx::Rect target_bounds = | 642 const gfx::Rect target_bounds = |
864 root_window_->ConvertRectFromScreen(SelectedWindow()->target_bounds()); | 643 root_window_->ConvertRectFromScreen(SelectedWindow()->target_bounds()); |
865 gfx::Vector2d fade_out_direction = | 644 gfx::Vector2d fade_out_direction = |
866 GetSlideVectorForFadeIn(direction, target_bounds); | 645 GetSlideVectorForFadeIn(direction, target_bounds); |
867 widget_window->SetBounds(target_bounds - fade_out_direction); | 646 widget_window->SetBounds(target_bounds - fade_out_direction); |
868 widget_window->SetName("OverviewModeSelector"); | 647 widget_window->SetName("OverviewModeSelector"); |
869 | 648 |
870 if (material) { | 649 selector_shadow_.reset(new ::wm::Shadow()); |
871 selector_shadow_.reset(new ::wm::Shadow()); | 650 selector_shadow_->Init(::wm::Shadow::STYLE_ACTIVE); |
872 selector_shadow_->Init(::wm::Shadow::STYLE_ACTIVE); | 651 selector_shadow_->layer()->SetVisible(true); |
873 selector_shadow_->layer()->SetVisible(true); | 652 selection_widget_->GetLayer()->SetMasksToBounds(false); |
874 selection_widget_->GetLayer()->SetMasksToBounds(false); | 653 selection_widget_->GetLayer()->Add(selector_shadow_->layer()); |
875 selection_widget_->GetLayer()->Add(selector_shadow_->layer()); | 654 selector_shadow_->SetContentBounds(gfx::Rect(target_bounds.size())); |
876 selector_shadow_->SetContentBounds(gfx::Rect(target_bounds.size())); | |
877 } | |
878 } | 655 } |
879 | 656 |
880 void WindowGrid::MoveSelectionWidget(WindowSelector::Direction direction, | 657 void WindowGrid::MoveSelectionWidget(WindowSelector::Direction direction, |
881 bool recreate_selection_widget, | 658 bool recreate_selection_widget, |
882 bool out_of_bounds, | 659 bool out_of_bounds, |
883 bool animate) { | 660 bool animate) { |
884 // If the selection widget is already active, fade it out in the selection | 661 // If the selection widget is already active, fade it out in the selection |
885 // direction. | 662 // direction. |
886 if (selection_widget_ && (recreate_selection_widget || out_of_bounds)) { | 663 if (selection_widget_ && (recreate_selection_widget || out_of_bounds)) { |
887 // Animate the old selection widget and then destroy it. | 664 // Animate the old selection widget and then destroy it. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
929 void WindowGrid::MoveSelectionWidgetToTarget(bool animate) { | 706 void WindowGrid::MoveSelectionWidgetToTarget(bool animate) { |
930 gfx::Rect bounds = | 707 gfx::Rect bounds = |
931 root_window_->ConvertRectFromScreen(SelectedWindow()->target_bounds()); | 708 root_window_->ConvertRectFromScreen(SelectedWindow()->target_bounds()); |
932 if (animate) { | 709 if (animate) { |
933 WmWindow* selection_widget_window = | 710 WmWindow* selection_widget_window = |
934 WmLookup::Get()->GetWindowForWidget(selection_widget_.get()); | 711 WmLookup::Get()->GetWindowForWidget(selection_widget_.get()); |
935 ui::ScopedLayerAnimationSettings animation_settings( | 712 ui::ScopedLayerAnimationSettings animation_settings( |
936 selection_widget_window->GetLayer()->GetAnimator()); | 713 selection_widget_window->GetLayer()->GetAnimator()); |
937 animation_settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds( | 714 animation_settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds( |
938 kOverviewSelectorTransitionMilliseconds)); | 715 kOverviewSelectorTransitionMilliseconds)); |
939 animation_settings.SetTweenType( | 716 animation_settings.SetTweenType(gfx::Tween::EASE_IN_OUT); |
940 ash::MaterialDesignController::IsOverviewMaterial() | |
941 ? gfx::Tween::EASE_IN_OUT | |
942 : gfx::Tween::LINEAR_OUT_SLOW_IN); | |
943 animation_settings.SetPreemptionStrategy( | 717 animation_settings.SetPreemptionStrategy( |
944 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 718 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
945 selection_widget_->SetBounds(bounds); | 719 selection_widget_->SetBounds(bounds); |
946 selection_widget_->SetOpacity(1.f); | 720 selection_widget_->SetOpacity(1.f); |
947 | 721 |
948 if (selector_shadow_) { | 722 if (selector_shadow_) { |
949 ui::ScopedLayerAnimationSettings animation_settings_shadow( | 723 ui::ScopedLayerAnimationSettings animation_settings_shadow( |
950 selector_shadow_->shadow_layer()->GetAnimator()); | 724 selector_shadow_->shadow_layer()->GetAnimator()); |
951 animation_settings_shadow.SetTransitionDuration( | 725 animation_settings_shadow.SetTransitionDuration( |
952 base::TimeDelta::FromMilliseconds( | 726 base::TimeDelta::FromMilliseconds( |
953 kOverviewSelectorTransitionMilliseconds)); | 727 kOverviewSelectorTransitionMilliseconds)); |
954 animation_settings_shadow.SetTweenType( | 728 animation_settings_shadow.SetTweenType(gfx::Tween::EASE_IN_OUT); |
955 ash::MaterialDesignController::IsOverviewMaterial() | |
956 ? gfx::Tween::EASE_IN_OUT | |
957 : gfx::Tween::LINEAR_OUT_SLOW_IN); | |
958 animation_settings_shadow.SetPreemptionStrategy( | 729 animation_settings_shadow.SetPreemptionStrategy( |
959 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 730 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
960 bounds.Inset(1, 1); | 731 bounds.Inset(1, 1); |
961 selector_shadow_->SetContentBounds( | 732 selector_shadow_->SetContentBounds( |
962 gfx::Rect(gfx::Point(1, 1), bounds.size())); | 733 gfx::Rect(gfx::Point(1, 1), bounds.size())); |
963 } | 734 } |
964 return; | 735 return; |
965 } | 736 } |
966 selection_widget_->SetBounds(bounds); | 737 selection_widget_->SetBounds(bounds); |
967 selection_widget_->SetOpacity(1.f); | 738 selection_widget_->SetOpacity(1.f); |
(...skipping 18 matching lines...) Expand all Loading... |
986 int top = bounds.y(); | 757 int top = bounds.y(); |
987 | 758 |
988 // Keep track of the lowest coordinate. | 759 // Keep track of the lowest coordinate. |
989 *max_bottom = bounds.y(); | 760 *max_bottom = bounds.y(); |
990 | 761 |
991 // Right bound of the narrowest row. | 762 // Right bound of the narrowest row. |
992 *min_right = bounds.right(); | 763 *min_right = bounds.right(); |
993 // Right bound of the widest row. | 764 // Right bound of the widest row. |
994 *max_right = bounds.x(); | 765 *max_right = bounds.x(); |
995 | 766 |
996 // With Material Design all elements are of same height and only the height is | 767 // All elements are of same height and only the height is necessary to |
997 // necessary to determine each item's scale. | 768 // determine each item's scale. |
998 const gfx::Size item_size(0, height); | 769 const gfx::Size item_size(0, height); |
999 size_t i = 0; | 770 size_t i = 0; |
1000 for (auto* window : window_list_) { | 771 for (auto* window : window_list_) { |
1001 const gfx::Rect target_bounds = window->GetTargetBoundsInScreen(); | 772 const gfx::Rect target_bounds = window->GetTargetBoundsInScreen(); |
1002 const int width = | 773 const int width = |
1003 std::max(1, gfx::ToFlooredInt(target_bounds.width() * | 774 std::max(1, gfx::ToFlooredInt(target_bounds.width() * |
1004 window->GetItemScale(item_size)) + | 775 window->GetItemScale(item_size)) + |
1005 2 * kWindowMarginMD); | 776 2 * kWindowMargin); |
1006 if (left + width > bounds.right()) { | 777 if (left + width > bounds.right()) { |
1007 // Move to the next row if possible. | 778 // Move to the next row if possible. |
1008 if (*min_right > left) | 779 if (*min_right > left) |
1009 *min_right = left; | 780 *min_right = left; |
1010 if (*max_right < left) | 781 if (*max_right < left) |
1011 *max_right = left; | 782 *max_right = left; |
1012 top += height; | 783 top += height; |
1013 | 784 |
1014 // Check if the new row reaches the bottom or if the first item in the new | 785 // Check if the new row reaches the bottom or if the first item in the new |
1015 // row does not fit within the available width. | 786 // row does not fit within the available width. |
(...skipping 16 matching lines...) Expand all Loading... |
1032 if (*min_right > left) | 803 if (*min_right > left) |
1033 *min_right = left; | 804 *min_right = left; |
1034 if (*max_right < left) | 805 if (*max_right < left) |
1035 *max_right = left; | 806 *max_right = left; |
1036 } | 807 } |
1037 *max_bottom = top + height; | 808 *max_bottom = top + height; |
1038 } | 809 } |
1039 return windows_fit; | 810 return windows_fit; |
1040 } | 811 } |
1041 | 812 |
1042 void WindowGrid::PrepareForUsingMasksOrShapes(size_t windows_count) const { | |
1043 const int kUnlimited = -1; | |
1044 const base::CommandLine* command_line = | |
1045 base::CommandLine::ForCurrentProcess(); | |
1046 int windows_to_use_masks = kMaxWindowsCountToHideHeaderWithMasks; | |
1047 if (command_line->HasSwitch(switches::kAshMaxWindowsToUseMaskInOverview) && | |
1048 (!base::StringToInt(command_line->GetSwitchValueASCII( | |
1049 switches::kAshMaxWindowsToUseMaskInOverview), | |
1050 &windows_to_use_masks) || | |
1051 windows_to_use_masks <= kUnlimited)) { | |
1052 windows_to_use_masks = kMaxWindowsCountToHideHeaderWithMasks; | |
1053 } | |
1054 int windows_to_use_shapes = kUnlimited; | |
1055 if (command_line->HasSwitch(switches::kAshMaxWindowsToUseShapeInOverview) && | |
1056 (!base::StringToInt(command_line->GetSwitchValueASCII( | |
1057 switches::kAshMaxWindowsToUseShapeInOverview), | |
1058 &windows_to_use_shapes) || | |
1059 windows_to_use_shapes <= kUnlimited)) { | |
1060 windows_to_use_shapes = kUnlimited; | |
1061 } | |
1062 WindowSelectorItem::set_use_mask(windows_to_use_masks <= kUnlimited || | |
1063 static_cast<int>(windows_count) <= | |
1064 windows_to_use_masks); | |
1065 WindowSelectorItem::set_use_shape(windows_to_use_shapes <= kUnlimited || | |
1066 static_cast<int>(windows_count) <= | |
1067 windows_to_use_shapes); | |
1068 } | |
1069 | |
1070 } // namespace ash | 813 } // namespace ash |
OLD | NEW |