Chromium Code Reviews| 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/wm/overview/window_grid.h" | 5 #include "ash/wm/overview/window_grid.h" |
| 6 | 6 |
| 7 #include "ash/screen_util.h" | 7 #include "ash/screen_util.h" |
| 8 #include "ash/shell.h" | 8 #include "ash/shell.h" |
| 9 #include "ash/shell_window_ids.h" | 9 #include "ash/shell_window_ids.h" |
| 10 #include "ash/wm/overview/scoped_transform_overview_window.h" | 10 #include "ash/wm/overview/scoped_transform_overview_window.h" |
| 11 #include "ash/wm/overview/window_selector.h" | 11 #include "ash/wm/overview/window_selector.h" |
| 12 #include "ash/wm/overview/window_selector_item.h" | 12 #include "ash/wm/overview/window_selector_item.h" |
| 13 #include "ash/wm/overview/window_selector_panels.h" | 13 #include "ash/wm/overview/window_selector_panels.h" |
| 14 #include "ash/wm/overview/window_selector_window.h" | 14 #include "ash/wm/overview/window_selector_window.h" |
| 15 #include "ash/wm/window_state.h" | 15 #include "ash/wm/window_state.h" |
| 16 #include "base/memory/scoped_vector.h" | 16 #include "base/memory/scoped_vector.h" |
| 17 #include "base/strings/string_util.h" | |
| 18 #include "base/strings/utf_string_conversions.h" | |
| 19 #include "third_party/icu/source/i18n/unicode/translit.h" | |
| 17 #include "third_party/skia/include/core/SkColor.h" | 20 #include "third_party/skia/include/core/SkColor.h" |
| 18 #include "ui/aura/window.h" | 21 #include "ui/aura/window.h" |
| 19 #include "ui/compositor/layer_animation_observer.h" | 22 #include "ui/compositor/layer_animation_observer.h" |
| 20 #include "ui/compositor/scoped_layer_animation_settings.h" | 23 #include "ui/compositor/scoped_layer_animation_settings.h" |
| 21 #include "ui/gfx/animation/tween.h" | 24 #include "ui/gfx/animation/tween.h" |
| 22 #include "ui/gfx/vector2d.h" | 25 #include "ui/gfx/vector2d.h" |
| 23 #include "ui/views/background.h" | 26 #include "ui/views/background.h" |
| 24 #include "ui/views/view.h" | 27 #include "ui/views/view.h" |
| 25 #include "ui/views/widget/widget.h" | 28 #include "ui/views/widget/widget.h" |
| 26 #include "ui/wm/core/window_animations.h" | 29 #include "ui/wm/core/window_animations.h" |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 121 } | 124 } |
| 122 return vector; | 125 return vector; |
| 123 } | 126 } |
| 124 | 127 |
| 125 } // namespace | 128 } // namespace |
| 126 | 129 |
| 127 WindowGrid::WindowGrid(aura::Window* root_window, | 130 WindowGrid::WindowGrid(aura::Window* root_window, |
| 128 const std::vector<aura::Window*>& windows, | 131 const std::vector<aura::Window*>& windows, |
| 129 WindowSelector* window_selector) | 132 WindowSelector* window_selector) |
| 130 : root_window_(root_window), | 133 : root_window_(root_window), |
| 131 window_selector_(window_selector) { | 134 window_selector_(window_selector), |
| 135 item_active_(true) { | |
| 132 WindowSelectorPanels* panels_item = NULL; | 136 WindowSelectorPanels* panels_item = NULL; |
| 133 for (aura::Window::Windows::const_iterator iter = windows.begin(); | 137 for (aura::Window::Windows::const_iterator iter = windows.begin(); |
| 134 iter != windows.end(); ++iter) { | 138 iter != windows.end(); ++iter) { |
| 135 if ((*iter)->GetRootWindow() != root_window) | 139 if ((*iter)->GetRootWindow() != root_window) |
| 136 continue; | 140 continue; |
| 137 (*iter)->AddObserver(this); | 141 (*iter)->AddObserver(this); |
| 138 observed_windows_.insert(*iter); | 142 observed_windows_.insert(*iter); |
| 139 WindowSelectorItem* item = NULL; | 143 WindowSelectorItem* item = NULL; |
| 140 | 144 |
| 141 if ((*iter)->type() == ui::wm::WINDOW_TYPE_PANEL && | 145 if ((*iter)->type() == ui::wm::WINDOW_TYPE_PANEL && |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 190 static_cast<int>(total_bounds.width() / num_columns_), | 194 static_cast<int>(total_bounds.width() / num_columns_), |
| 191 static_cast<int>(total_bounds.height() * kCardAspectRatio / num_rows))); | 195 static_cast<int>(total_bounds.height() * kCardAspectRatio / num_rows))); |
| 192 window_size.set_height(window_size.width() / kCardAspectRatio); | 196 window_size.set_height(window_size.width() / kCardAspectRatio); |
| 193 | 197 |
| 194 // Calculate the X and Y offsets necessary to center the grid. | 198 // Calculate the X and Y offsets necessary to center the grid. |
| 195 int x_offset = total_bounds.x() + ((window_list_.size() >= num_columns_ ? 0 : | 199 int x_offset = total_bounds.x() + ((window_list_.size() >= num_columns_ ? 0 : |
| 196 (num_columns_ - window_list_.size()) * window_size.width()) + | 200 (num_columns_ - window_list_.size()) * window_size.width()) + |
| 197 (total_bounds.width() - num_columns_ * window_size.width())) / 2; | 201 (total_bounds.width() - num_columns_ * window_size.width())) / 2; |
| 198 int y_offset = total_bounds.y() + (total_bounds.height() - | 202 int y_offset = total_bounds.y() + (total_bounds.height() - |
| 199 num_rows * window_size.height()) / 2; | 203 num_rows * window_size.height()) / 2; |
| 204 | |
| 200 for (size_t i = 0; i < window_list_.size(); ++i) { | 205 for (size_t i = 0; i < window_list_.size(); ++i) { |
| 201 gfx::Transform transform; | 206 gfx::Transform transform; |
| 202 int column = i % num_columns_; | 207 int column = i % num_columns_; |
| 203 int row = i / num_columns_; | 208 int row = i / num_columns_; |
| 204 gfx::Rect target_bounds(window_size.width() * column + x_offset, | 209 gfx::Rect target_bounds(window_size.width() * column + x_offset, |
| 205 window_size.height() * row + y_offset, | 210 window_size.height() * row + y_offset, |
| 206 window_size.width(), | 211 window_size.width(), |
| 207 window_size.height()); | 212 window_size.height()); |
| 208 window_list_[i]->SetBounds(root_window_, target_bounds, animate); | 213 window_list_[i]->SetBounds(root_window_, target_bounds, animate); |
| 209 } | 214 } |
| 210 | 215 |
| 211 // If we have less than |kMinCardsMajor| windows, adjust the column_ value to | 216 // If we have less than |kMinCardsMajor| windows, adjust the column_ value to |
| 212 // reflect how many "real" columns we have. | 217 // reflect how many "real" columns we have. |
| 213 if (num_columns_ > window_list_.size()) | 218 if (num_columns_ > window_list_.size()) |
| 214 num_columns_ = window_list_.size(); | 219 num_columns_ = window_list_.size(); |
| 215 | 220 |
| 216 // If the selection widget is active, reposition it without any animation. | 221 // If the selection widget is active, reposition it without any animation. |
| 217 if (selection_widget_) | 222 if (selection_widget_) |
| 218 MoveSelectionWidgetToTarget(animate); | 223 MoveSelectionWidgetToTarget(animate); |
| 219 } | 224 } |
| 220 | 225 |
| 221 bool WindowGrid::Move(WindowSelector::Direction direction) { | 226 bool WindowGrid::Move(WindowSelector::Direction direction) { |
| 227 if (!item_active_) | |
| 228 return false; | |
| 229 | |
| 222 bool recreate_selection_widget = false; | 230 bool recreate_selection_widget = false; |
| 223 bool out_of_bounds = false; | 231 bool out_of_bounds = false; |
| 224 if (!selection_widget_) { | 232 if (!selection_widget_) { |
| 225 switch (direction) { | 233 switch (direction) { |
| 226 case WindowSelector::LEFT: | 234 case WindowSelector::LEFT: |
| 227 selected_index_ = window_list_.size() - 1; | 235 selected_index_ = window_list_.size() - 1; |
| 228 break; | 236 break; |
| 229 case WindowSelector::UP: | 237 case WindowSelector::UP: |
| 230 selected_index_ = | 238 selected_index_ = |
| 231 (window_list_.size() / num_columns_) * num_columns_ - 1; | 239 (window_list_.size() / num_columns_) * num_columns_ - 1; |
| 232 break; | 240 break; |
| 233 case WindowSelector::RIGHT: | 241 case WindowSelector::RIGHT: |
| 234 case WindowSelector::DOWN: | 242 case WindowSelector::DOWN: |
| 235 selected_index_ = 0; | 243 selected_index_ = 0; |
| 236 break; | 244 break; |
| 237 } | 245 } |
| 238 } else { | 246 } |
| 247 while (!SelectedWindow()->active() || selection_widget_) { | |
| 239 switch (direction) { | 248 switch (direction) { |
| 240 case WindowSelector::RIGHT: | 249 case WindowSelector::RIGHT: |
| 241 if (selected_index_ >= window_list_.size() - 1) | 250 if (selected_index_ >= window_list_.size() - 1) |
| 242 out_of_bounds = true; | 251 out_of_bounds = true; |
| 243 selected_index_++; | 252 selected_index_++; |
| 244 if (selected_index_ % num_columns_ == 0) | 253 if (selected_index_ % num_columns_ == 0) |
| 245 recreate_selection_widget = true; | 254 recreate_selection_widget = true; |
| 246 break; | 255 break; |
| 247 case WindowSelector::LEFT: | 256 case WindowSelector::LEFT: |
| 248 if (selected_index_ == 0) | 257 if (selected_index_ == 0) |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 265 out_of_bounds = true; | 274 out_of_bounds = true; |
| 266 if (selected_index_ < num_columns_) { | 275 if (selected_index_ < num_columns_) { |
| 267 selected_index_ += num_columns_ * | 276 selected_index_ += num_columns_ * |
| 268 ((window_list_.size() - selected_index_) / num_columns_) - 1; | 277 ((window_list_.size() - selected_index_) / num_columns_) - 1; |
| 269 recreate_selection_widget = true; | 278 recreate_selection_widget = true; |
| 270 } else { | 279 } else { |
| 271 selected_index_ -= num_columns_; | 280 selected_index_ -= num_columns_; |
| 272 } | 281 } |
| 273 break; | 282 break; |
| 274 } | 283 } |
| 284 // Exit the loop if we broke free from the grid or found an active item. | |
| 285 if (out_of_bounds || SelectedWindow()->active()) | |
| 286 break; | |
| 275 } | 287 } |
| 276 | 288 |
| 277 MoveSelectionWidget(direction, recreate_selection_widget, out_of_bounds); | 289 MoveSelectionWidget(direction, recreate_selection_widget, out_of_bounds); |
| 278 return out_of_bounds; | 290 return out_of_bounds; |
| 279 } | 291 } |
| 280 | 292 |
| 281 WindowSelectorItem* WindowGrid::SelectedWindow() const { | 293 WindowSelectorItem* WindowGrid::SelectedWindow() const { |
| 282 CHECK(selected_index_ < window_list_.size()); | 294 CHECK(selected_index_ < window_list_.size()); |
| 283 return window_list_[selected_index_]; | 295 return window_list_[selected_index_]; |
| 284 } | 296 } |
| 285 | 297 |
| 286 bool WindowGrid::Contains(const aura::Window* window) const { | 298 bool WindowGrid::Contains(const aura::Window* window) const { |
| 287 return std::find_if(window_list_.begin(), window_list_.end(), | 299 return std::find_if(window_list_.begin(), window_list_.end(), |
| 288 WindowSelectorItemTargetComparator(window)) != | 300 WindowSelectorItemTargetComparator(window)) != |
| 289 window_list_.end(); | 301 window_list_.end(); |
| 290 } | 302 } |
| 291 | 303 |
| 304 void WindowGrid::Filter(const base::string16& pattern) { | |
| 305 item_active_ = false; | |
| 306 UErrorCode status = U_ZERO_ERROR; | |
| 307 | |
| 308 // Construct a transilterator that removes accents and converts uppercase | |
| 309 // letters to lowercase in a l10n sensitive context. | |
|
tdanderson
2014/06/25 15:48:23
I would instead mention the fact that your filteri
Nina
2014/06/26 15:20:17
Done.
| |
| 310 icu::Transliterator* translit = icu::Transliterator::createInstance( | |
| 311 "Lower (Upper); NFD; [:Nonspacing Mark:] Remove; NFC", | |
| 312 UTRANS_FORWARD, status); | |
| 313 icu::UnicodeString target(pattern.c_str()); | |
| 314 translit->transliterate(target); | |
| 315 | |
| 316 for (ScopedVector<WindowSelectorItem>::iterator iter = window_list_.begin(); | |
| 317 iter != window_list_.end(); iter++) { | |
| 318 icu::UnicodeString title_string( | |
| 319 (*iter)->SelectionWindow()->title().c_str()); | |
| 320 translit->transliterate(title_string); | |
| 321 const base::string16& title(title_string.getTerminatedBuffer()); | |
| 322 if (title.find(target.getTerminatedBuffer()) != base::string16::npos) { | |
| 323 (*iter)->SetActive(true); | |
| 324 item_active_ = true; | |
| 325 } else { | |
| 326 (*iter)->SetActive(false); | |
| 327 if (selection_widget_ && SelectedWindow() == *iter) | |
| 328 selection_widget_.reset(); | |
| 329 } | |
| 330 } | |
| 331 // If the selection widget is not active, execute a Move() command so that it | |
| 332 // shows up. | |
|
tdanderson
2014/06/25 15:48:23
"shows up on the first unfiltered item"?
Nina
2014/06/26 15:20:17
Done.
| |
| 333 if (!selection_widget_) | |
| 334 Move(WindowSelector::RIGHT); | |
| 335 } | |
| 336 | |
| 292 void WindowGrid::OnWindowDestroying(aura::Window* window) { | 337 void WindowGrid::OnWindowDestroying(aura::Window* window) { |
| 293 window->RemoveObserver(this); | 338 window->RemoveObserver(this); |
| 294 observed_windows_.erase(window); | 339 observed_windows_.erase(window); |
| 295 ScopedVector<WindowSelectorItem>::iterator iter = | 340 ScopedVector<WindowSelectorItem>::iterator iter = |
| 296 std::find_if(window_list_.begin(), window_list_.end(), | 341 std::find_if(window_list_.begin(), window_list_.end(), |
| 297 WindowSelectorItemComparator(window)); | 342 WindowSelectorItemComparator(window)); |
| 298 | 343 |
| 299 DCHECK(iter != window_list_.end()); | 344 DCHECK(iter != window_list_.end()); |
| 300 | 345 |
| 301 (*iter)->RemoveWindow(window); | 346 (*iter)->RemoveWindow(window); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 434 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 479 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 435 selection_widget_->SetBounds(SelectedWindow()->target_bounds()); | 480 selection_widget_->SetBounds(SelectedWindow()->target_bounds()); |
| 436 selection_widget_->SetOpacity(kWindowOverviewSelectorOpacity); | 481 selection_widget_->SetOpacity(kWindowOverviewSelectorOpacity); |
| 437 return; | 482 return; |
| 438 } | 483 } |
| 439 selection_widget_->SetBounds(SelectedWindow()->target_bounds()); | 484 selection_widget_->SetBounds(SelectedWindow()->target_bounds()); |
| 440 selection_widget_->SetOpacity(kWindowOverviewSelectorOpacity); | 485 selection_widget_->SetOpacity(kWindowOverviewSelectorOpacity); |
| 441 } | 486 } |
| 442 | 487 |
| 443 } // namespace ash | 488 } // namespace ash |
| OLD | NEW |