| 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 |