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 |