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/i18n/string_search.cc" | |
16 #include "base/memory/scoped_vector.h" | 17 #include "base/memory/scoped_vector.h" |
17 #include "third_party/skia/include/core/SkColor.h" | 18 #include "third_party/skia/include/core/SkColor.h" |
18 #include "ui/aura/window.h" | 19 #include "ui/aura/window.h" |
19 #include "ui/compositor/layer_animation_observer.h" | 20 #include "ui/compositor/layer_animation_observer.h" |
20 #include "ui/compositor/scoped_layer_animation_settings.h" | 21 #include "ui/compositor/scoped_layer_animation_settings.h" |
21 #include "ui/gfx/animation/tween.h" | 22 #include "ui/gfx/animation/tween.h" |
22 #include "ui/gfx/vector2d.h" | 23 #include "ui/gfx/vector2d.h" |
23 #include "ui/views/background.h" | 24 #include "ui/views/background.h" |
24 #include "ui/views/view.h" | 25 #include "ui/views/view.h" |
25 #include "ui/views/widget/widget.h" | 26 #include "ui/views/widget/widget.h" |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
121 } | 122 } |
122 return vector; | 123 return vector; |
123 } | 124 } |
124 | 125 |
125 } // namespace | 126 } // namespace |
126 | 127 |
127 WindowGrid::WindowGrid(aura::Window* root_window, | 128 WindowGrid::WindowGrid(aura::Window* root_window, |
128 const std::vector<aura::Window*>& windows, | 129 const std::vector<aura::Window*>& windows, |
129 WindowSelector* window_selector) | 130 WindowSelector* window_selector) |
130 : root_window_(root_window), | 131 : root_window_(root_window), |
131 window_selector_(window_selector) { | 132 window_selector_(window_selector), |
133 has_active_item_(true) { | |
132 WindowSelectorPanels* panels_item = NULL; | 134 WindowSelectorPanels* panels_item = NULL; |
133 for (aura::Window::Windows::const_iterator iter = windows.begin(); | 135 for (aura::Window::Windows::const_iterator iter = windows.begin(); |
134 iter != windows.end(); ++iter) { | 136 iter != windows.end(); ++iter) { |
135 if ((*iter)->GetRootWindow() != root_window) | 137 if ((*iter)->GetRootWindow() != root_window) |
136 continue; | 138 continue; |
137 (*iter)->AddObserver(this); | 139 (*iter)->AddObserver(this); |
138 observed_windows_.insert(*iter); | 140 observed_windows_.insert(*iter); |
139 WindowSelectorItem* item = NULL; | 141 WindowSelectorItem* item = NULL; |
140 | 142 |
141 if ((*iter)->type() == ui::wm::WINDOW_TYPE_PANEL && | 143 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_), | 192 static_cast<int>(total_bounds.width() / num_columns_), |
191 static_cast<int>(total_bounds.height() * kCardAspectRatio / num_rows))); | 193 static_cast<int>(total_bounds.height() * kCardAspectRatio / num_rows))); |
192 window_size.set_height(window_size.width() / kCardAspectRatio); | 194 window_size.set_height(window_size.width() / kCardAspectRatio); |
193 | 195 |
194 // Calculate the X and Y offsets necessary to center the grid. | 196 // Calculate the X and Y offsets necessary to center the grid. |
195 int x_offset = total_bounds.x() + ((window_list_.size() >= num_columns_ ? 0 : | 197 int x_offset = total_bounds.x() + ((window_list_.size() >= num_columns_ ? 0 : |
196 (num_columns_ - window_list_.size()) * window_size.width()) + | 198 (num_columns_ - window_list_.size()) * window_size.width()) + |
197 (total_bounds.width() - num_columns_ * window_size.width())) / 2; | 199 (total_bounds.width() - num_columns_ * window_size.width())) / 2; |
198 int y_offset = total_bounds.y() + (total_bounds.height() - | 200 int y_offset = total_bounds.y() + (total_bounds.height() - |
199 num_rows * window_size.height()) / 2; | 201 num_rows * window_size.height()) / 2; |
202 | |
200 for (size_t i = 0; i < window_list_.size(); ++i) { | 203 for (size_t i = 0; i < window_list_.size(); ++i) { |
201 gfx::Transform transform; | 204 gfx::Transform transform; |
202 int column = i % num_columns_; | 205 int column = i % num_columns_; |
203 int row = i / num_columns_; | 206 int row = i / num_columns_; |
204 gfx::Rect target_bounds(window_size.width() * column + x_offset, | 207 gfx::Rect target_bounds(window_size.width() * column + x_offset, |
205 window_size.height() * row + y_offset, | 208 window_size.height() * row + y_offset, |
206 window_size.width(), | 209 window_size.width(), |
207 window_size.height()); | 210 window_size.height()); |
208 window_list_[i]->SetBounds(root_window_, target_bounds, animate); | 211 window_list_[i]->SetBounds(root_window_, target_bounds, animate); |
209 } | 212 } |
210 | 213 |
211 // If we have less than |kMinCardsMajor| windows, adjust the column_ value to | 214 // If we have less than |kMinCardsMajor| windows, adjust the column_ value to |
212 // reflect how many "real" columns we have. | 215 // reflect how many "real" columns we have. |
213 if (num_columns_ > window_list_.size()) | 216 if (num_columns_ > window_list_.size()) |
214 num_columns_ = window_list_.size(); | 217 num_columns_ = window_list_.size(); |
215 | 218 |
216 // If the selection widget is active, reposition it without any animation. | 219 // If the selection widget is active, reposition it without any animation. |
217 if (selection_widget_) | 220 if (selection_widget_) |
218 MoveSelectionWidgetToTarget(animate); | 221 MoveSelectionWidgetToTarget(animate); |
219 } | 222 } |
220 | 223 |
221 bool WindowGrid::Move(WindowSelector::Direction direction) { | 224 bool WindowGrid::Move(WindowSelector::Direction direction, bool animate) { |
225 if (!has_active_item_) | |
flackr
2014/06/27 20:00:06
This is the only place where has_active_item_ is u
Nina
2014/06/27 22:42:01
Done.
| |
226 return true; | |
227 | |
222 bool recreate_selection_widget = false; | 228 bool recreate_selection_widget = false; |
223 bool out_of_bounds = false; | 229 bool out_of_bounds = false; |
224 if (!selection_widget_) { | 230 if (!selection_widget_) { |
225 switch (direction) { | 231 switch (direction) { |
226 case WindowSelector::LEFT: | 232 case WindowSelector::LEFT: |
227 selected_index_ = window_list_.size() - 1; | 233 selected_index_ = window_list_.size() - 1; |
228 break; | 234 break; |
229 case WindowSelector::UP: | 235 case WindowSelector::UP: |
230 selected_index_ = | 236 selected_index_ = |
231 (window_list_.size() / num_columns_) * num_columns_ - 1; | 237 (window_list_.size() / num_columns_) * num_columns_ - 1; |
232 break; | 238 break; |
233 case WindowSelector::RIGHT: | 239 case WindowSelector::RIGHT: |
234 case WindowSelector::DOWN: | 240 case WindowSelector::DOWN: |
235 selected_index_ = 0; | 241 selected_index_ = 0; |
236 break; | 242 break; |
237 } | 243 } |
238 } else { | 244 } |
245 while (SelectedWindow()->dimmed() || selection_widget_) { | |
239 switch (direction) { | 246 switch (direction) { |
240 case WindowSelector::RIGHT: | 247 case WindowSelector::RIGHT: |
241 if (selected_index_ >= window_list_.size() - 1) | 248 if (selected_index_ >= window_list_.size() - 1) |
242 out_of_bounds = true; | 249 out_of_bounds = true; |
243 selected_index_++; | 250 selected_index_++; |
244 if (selected_index_ % num_columns_ == 0) | 251 if (selected_index_ % num_columns_ == 0) |
245 recreate_selection_widget = true; | 252 recreate_selection_widget = true; |
246 break; | 253 break; |
247 case WindowSelector::LEFT: | 254 case WindowSelector::LEFT: |
248 if (selected_index_ == 0) | 255 if (selected_index_ == 0) |
(...skipping 16 matching lines...) Expand all Loading... | |
265 out_of_bounds = true; | 272 out_of_bounds = true; |
266 if (selected_index_ < num_columns_) { | 273 if (selected_index_ < num_columns_) { |
267 selected_index_ += num_columns_ * | 274 selected_index_ += num_columns_ * |
268 ((window_list_.size() - selected_index_) / num_columns_) - 1; | 275 ((window_list_.size() - selected_index_) / num_columns_) - 1; |
269 recreate_selection_widget = true; | 276 recreate_selection_widget = true; |
270 } else { | 277 } else { |
271 selected_index_ -= num_columns_; | 278 selected_index_ -= num_columns_; |
272 } | 279 } |
273 break; | 280 break; |
274 } | 281 } |
282 // Exit the loop if we broke free from the grid or found an active item. | |
283 if (out_of_bounds || !SelectedWindow()->dimmed()) | |
284 break; | |
275 } | 285 } |
276 | 286 |
277 MoveSelectionWidget(direction, recreate_selection_widget, out_of_bounds); | 287 MoveSelectionWidget(direction, recreate_selection_widget, |
288 out_of_bounds, animate); | |
278 return out_of_bounds; | 289 return out_of_bounds; |
279 } | 290 } |
280 | 291 |
281 WindowSelectorItem* WindowGrid::SelectedWindow() const { | 292 WindowSelectorItem* WindowGrid::SelectedWindow() const { |
282 CHECK(selected_index_ < window_list_.size()); | 293 CHECK(selected_index_ < window_list_.size()); |
283 return window_list_[selected_index_]; | 294 return window_list_[selected_index_]; |
284 } | 295 } |
285 | 296 |
286 bool WindowGrid::Contains(const aura::Window* window) const { | 297 bool WindowGrid::Contains(const aura::Window* window) const { |
287 return std::find_if(window_list_.begin(), window_list_.end(), | 298 return std::find_if(window_list_.begin(), window_list_.end(), |
288 WindowSelectorItemTargetComparator(window)) != | 299 WindowSelectorItemTargetComparator(window)) != |
289 window_list_.end(); | 300 window_list_.end(); |
290 } | 301 } |
291 | 302 |
303 void WindowGrid::FilterItems(const base::string16& pattern) { | |
304 has_active_item_ = false; | |
305 base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents finder(pattern); | |
306 for (ScopedVector<WindowSelectorItem>::iterator iter = window_list_.begin(); | |
307 iter != window_list_.end(); iter++) { | |
308 if (finder.Search((*iter)->SelectionWindow()->title(), NULL, NULL)) { | |
309 (*iter)->SetDimmed(false); | |
310 has_active_item_ = true; | |
311 } else { | |
312 (*iter)->SetDimmed(true); | |
313 if (selection_widget_ && SelectedWindow() == *iter) | |
314 selection_widget_.reset(); | |
315 } | |
316 } | |
317 } | |
318 | |
292 void WindowGrid::OnWindowDestroying(aura::Window* window) { | 319 void WindowGrid::OnWindowDestroying(aura::Window* window) { |
293 window->RemoveObserver(this); | 320 window->RemoveObserver(this); |
294 observed_windows_.erase(window); | 321 observed_windows_.erase(window); |
295 ScopedVector<WindowSelectorItem>::iterator iter = | 322 ScopedVector<WindowSelectorItem>::iterator iter = |
296 std::find_if(window_list_.begin(), window_list_.end(), | 323 std::find_if(window_list_.begin(), window_list_.end(), |
297 WindowSelectorItemComparator(window)); | 324 WindowSelectorItemComparator(window)); |
298 | 325 |
299 DCHECK(iter != window_list_.end()); | 326 DCHECK(iter != window_list_.end()); |
300 | 327 |
301 (*iter)->RemoveWindow(window); | 328 (*iter)->RemoveWindow(window); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
376 gfx::Vector2d fade_out_direction = | 403 gfx::Vector2d fade_out_direction = |
377 GetSlideVectorForFadeIn(direction, target_bounds); | 404 GetSlideVectorForFadeIn(direction, target_bounds); |
378 gfx::Display dst_display = gfx::Screen::GetScreenFor(root_window_)-> | 405 gfx::Display dst_display = gfx::Screen::GetScreenFor(root_window_)-> |
379 GetDisplayMatching(target_bounds); | 406 GetDisplayMatching(target_bounds); |
380 selection_widget_->GetNativeWindow()->SetBoundsInScreen( | 407 selection_widget_->GetNativeWindow()->SetBoundsInScreen( |
381 target_bounds - fade_out_direction, dst_display); | 408 target_bounds - fade_out_direction, dst_display); |
382 } | 409 } |
383 | 410 |
384 void WindowGrid::MoveSelectionWidget(WindowSelector::Direction direction, | 411 void WindowGrid::MoveSelectionWidget(WindowSelector::Direction direction, |
385 bool recreate_selection_widget, | 412 bool recreate_selection_widget, |
386 bool out_of_bounds) { | 413 bool out_of_bounds, |
414 bool animate) { | |
387 // If the selection widget is already active, fade it out in the selection | 415 // If the selection widget is already active, fade it out in the selection |
388 // direction. | 416 // direction. |
389 if (selection_widget_ && (recreate_selection_widget || out_of_bounds)) { | 417 if (selection_widget_ && (recreate_selection_widget || out_of_bounds)) { |
390 // Animate the old selection widget and then destroy it. | 418 // Animate the old selection widget and then destroy it. |
391 views::Widget* old_selection = selection_widget_.get(); | 419 views::Widget* old_selection = selection_widget_.get(); |
392 gfx::Vector2d fade_out_direction = | 420 gfx::Vector2d fade_out_direction = |
393 GetSlideVectorForFadeIn( | 421 GetSlideVectorForFadeIn( |
394 direction, old_selection->GetNativeWindow()->bounds()); | 422 direction, old_selection->GetNativeWindow()->bounds()); |
395 | 423 |
396 ui::ScopedLayerAnimationSettings animation_settings( | 424 ui::ScopedLayerAnimationSettings animation_settings( |
(...skipping 16 matching lines...) Expand all Loading... | |
413 if (out_of_bounds) | 441 if (out_of_bounds) |
414 return; | 442 return; |
415 | 443 |
416 if (!selection_widget_) | 444 if (!selection_widget_) |
417 InitSelectionWidget(direction); | 445 InitSelectionWidget(direction); |
418 // Send an a11y alert so that if ChromeVox is enabled, the item label is | 446 // Send an a11y alert so that if ChromeVox is enabled, the item label is |
419 // read. | 447 // read. |
420 SelectedWindow()->SendFocusAlert(); | 448 SelectedWindow()->SendFocusAlert(); |
421 // The selection widget is moved to the newly selected item in the same | 449 // The selection widget is moved to the newly selected item in the same |
422 // grid. | 450 // grid. |
423 MoveSelectionWidgetToTarget(true); | 451 MoveSelectionWidgetToTarget(animate); |
424 } | 452 } |
425 | 453 |
426 void WindowGrid::MoveSelectionWidgetToTarget(bool animate) { | 454 void WindowGrid::MoveSelectionWidgetToTarget(bool animate) { |
427 if (animate) { | 455 if (animate) { |
428 ui::ScopedLayerAnimationSettings animation_settings( | 456 ui::ScopedLayerAnimationSettings animation_settings( |
429 selection_widget_->GetNativeWindow()->layer()->GetAnimator()); | 457 selection_widget_->GetNativeWindow()->layer()->GetAnimator()); |
430 animation_settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds( | 458 animation_settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds( |
431 kOverviewSelectorTransitionMilliseconds)); | 459 kOverviewSelectorTransitionMilliseconds)); |
432 animation_settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN); | 460 animation_settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN); |
433 animation_settings.SetPreemptionStrategy( | 461 animation_settings.SetPreemptionStrategy( |
434 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 462 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
435 selection_widget_->SetBounds(SelectedWindow()->target_bounds()); | 463 selection_widget_->SetBounds(SelectedWindow()->target_bounds()); |
436 selection_widget_->SetOpacity(kWindowOverviewSelectorOpacity); | 464 selection_widget_->SetOpacity(kWindowOverviewSelectorOpacity); |
437 return; | 465 return; |
438 } | 466 } |
439 selection_widget_->SetBounds(SelectedWindow()->target_bounds()); | 467 selection_widget_->SetBounds(SelectedWindow()->target_bounds()); |
440 selection_widget_->SetOpacity(kWindowOverviewSelectorOpacity); | 468 selection_widget_->SetOpacity(kWindowOverviewSelectorOpacity); |
441 } | 469 } |
442 | 470 |
443 } // namespace ash | 471 } // namespace ash |
OLD | NEW |