Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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_selector.h" | 5 #include "ash/wm/overview/window_selector.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "ash/accessibility_delegate.h" | 9 #include "ash/accessibility_delegate.h" |
| 10 #include "ash/ash_switches.h" | 10 #include "ash/ash_switches.h" |
| 11 #include "ash/metrics/user_metrics_recorder.h" | 11 #include "ash/metrics/user_metrics_recorder.h" |
| 12 #include "ash/root_window_controller.h" | 12 #include "ash/root_window_controller.h" |
| 13 #include "ash/shell.h" | 13 #include "ash/shell.h" |
| 14 #include "ash/shell_window_ids.h" | 14 #include "ash/shell_window_ids.h" |
| 15 #include "ash/switchable_windows.h" | 15 #include "ash/switchable_windows.h" |
| 16 #include "ash/wm/overview/scoped_transform_overview_window.h" | 16 #include "ash/wm/overview/scoped_transform_overview_window.h" |
| 17 #include "ash/wm/overview/window_grid.h" | 17 #include "ash/wm/overview/window_grid.h" |
| 18 #include "ash/wm/overview/window_selector_delegate.h" | 18 #include "ash/wm/overview/window_selector_delegate.h" |
| 19 #include "ash/wm/overview/window_selector_item.h" | 19 #include "ash/wm/overview/window_selector_item.h" |
| 20 #include "ash/wm/window_state.h" | 20 #include "ash/wm/window_state.h" |
| 21 #include "base/auto_reset.h" | 21 #include "base/auto_reset.h" |
| 22 #include "base/command_line.h" | 22 #include "base/command_line.h" |
| 23 #include "base/metrics/histogram.h" | 23 #include "base/metrics/histogram.h" |
| 24 #include "ui/aura/client/focus_client.h" | 24 #include "ui/aura/client/focus_client.h" |
| 25 #include "ui/aura/window.h" | 25 #include "ui/aura/window.h" |
| 26 #include "ui/aura/window_event_dispatcher.h" | 26 #include "ui/aura/window_event_dispatcher.h" |
| 27 #include "ui/aura/window_observer.h" | 27 #include "ui/aura/window_observer.h" |
| 28 #include "ui/base/resource/resource_bundle.h" | |
| 28 #include "ui/compositor/scoped_layer_animation_settings.h" | 29 #include "ui/compositor/scoped_layer_animation_settings.h" |
| 29 #include "ui/events/event.h" | 30 #include "ui/events/event.h" |
| 30 #include "ui/gfx/screen.h" | 31 #include "ui/gfx/screen.h" |
| 32 #include "ui/views/background.h" | |
| 31 #include "ui/views/border.h" | 33 #include "ui/views/border.h" |
| 32 #include "ui/views/controls/textfield/textfield.h" | 34 #include "ui/views/controls/textfield/textfield.h" |
| 35 #include "ui/views/layout/box_layout.h" | |
| 33 #include "ui/wm/core/window_util.h" | 36 #include "ui/wm/core/window_util.h" |
| 34 #include "ui/wm/public/activation_client.h" | 37 #include "ui/wm/public/activation_client.h" |
| 35 | 38 |
| 36 namespace ash { | 39 namespace ash { |
| 37 | 40 |
| 38 namespace { | 41 namespace { |
| 39 | 42 |
| 40 // The proportion of screen width that the text filter takes. | 43 // The proportion of screen width that the text filter takes. |
| 41 const float kTextFilterScreenProportion = 0.5; | 44 const float kTextFilterScreenProportion = 0.25; |
| 42 | 45 |
| 43 // The height of the text filter. | 46 // The amount of padding surrounding the text in the text filtering textbox. |
| 44 const int kTextFilterHeight = 50; | 47 const int kTextFilterPadding = 3; |
| 48 | |
| 49 // The font style used for text filtering. | |
| 50 static const ::ui::ResourceBundle::FontStyle kTextFilterFontStyle = | |
| 51 ::ui::ResourceBundle::FontStyle::BaseFont; | |
| 45 | 52 |
| 46 // Solid shadow length from the text filter. | 53 // Solid shadow length from the text filter. |
| 47 const int kVerticalShadowOffset = 1; | 54 const int kVerticalShadowOffset = 1; |
| 48 | 55 |
| 49 // Amount of blur applied to the text filter shadow. | 56 // Amount of blur applied to the text filter shadow. |
| 50 const int kShadowBlur = 10; | 57 const int kShadowBlur = 10; |
| 51 | 58 |
| 52 // Text filter shadow color. | 59 // Text filter shadow color. |
| 53 const SkColor kTextFilterShadow = 0xB0000000; | 60 const SkColor kTextFilterShadow = 0xB0000000; |
| 61 const unsigned char kTextFilterOpacity = 128; | |
|
tdanderson
2014/07/17 19:45:26
Admittedly a copy of WindowGrid::kWindowOverviewSe
flackr
2014/07/18 13:41:51
As a static class var (like kTransitionMillisecond
| |
| 54 | 62 |
| 55 // A comparator for locating a grid with a given root window. | 63 // A comparator for locating a grid with a given root window. |
| 56 struct RootWindowGridComparator | 64 struct RootWindowGridComparator |
| 57 : public std::unary_function<WindowGrid*, bool> { | 65 : public std::unary_function<WindowGrid*, bool> { |
| 58 explicit RootWindowGridComparator(const aura::Window* root_window) | 66 explicit RootWindowGridComparator(const aura::Window* root_window) |
| 59 : root_window_(root_window) { | 67 : root_window_(root_window) { |
| 60 } | 68 } |
| 61 | 69 |
| 62 bool operator()(WindowGrid* grid) const { | 70 bool operator()(WindowGrid* grid) const { |
| 63 return (grid->root_window() == root_window_); | 71 return (grid->root_window() == root_window_); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 98 void UpdateShelfVisibility() { | 106 void UpdateShelfVisibility() { |
| 99 Shell::RootWindowControllerList root_window_controllers = | 107 Shell::RootWindowControllerList root_window_controllers = |
| 100 Shell::GetInstance()->GetAllRootWindowControllers(); | 108 Shell::GetInstance()->GetAllRootWindowControllers(); |
| 101 for (Shell::RootWindowControllerList::iterator iter = | 109 for (Shell::RootWindowControllerList::iterator iter = |
| 102 root_window_controllers.begin(); | 110 root_window_controllers.begin(); |
| 103 iter != root_window_controllers.end(); ++iter) { | 111 iter != root_window_controllers.end(); ++iter) { |
| 104 (*iter)->UpdateShelfVisibility(); | 112 (*iter)->UpdateShelfVisibility(); |
| 105 } | 113 } |
| 106 } | 114 } |
| 107 | 115 |
| 108 // Initializes the text filter on the top of the main root window and requests | |
| 109 // focus on its textfield. | |
| 110 views::Widget* CreateTextFilter(views::TextfieldController* controller, | |
| 111 aura::Window* root_window) { | |
| 112 views::Widget* widget = new views::Widget; | |
| 113 views::Widget::InitParams params; | |
| 114 params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS; | |
| 115 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
| 116 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; | |
| 117 params.parent = | |
| 118 Shell::GetContainer(root_window, ash::kShellWindowId_OverlayContainer); | |
| 119 params.accept_events = true; | |
| 120 params.bounds = gfx::Rect( | |
| 121 root_window->bounds().width() / 2 * (1 - kTextFilterScreenProportion), 0, | |
| 122 root_window->bounds().width() * kTextFilterScreenProportion, | |
| 123 kTextFilterHeight); | |
| 124 widget->Init(params); | |
| 125 | |
| 126 views::Textfield* textfield = new views::Textfield; | |
| 127 textfield->set_controller(controller); | |
| 128 textfield->SetBackgroundColor(SK_ColorTRANSPARENT); | |
| 129 textfield->SetBorder(views::Border::NullBorder()); | |
| 130 textfield->SetTextColor(SK_ColorWHITE); | |
| 131 textfield->SetShadows(gfx::ShadowValues(1, gfx::ShadowValue( | |
| 132 gfx::Point(0, kVerticalShadowOffset), kShadowBlur, kTextFilterShadow))); | |
| 133 widget->SetContentsView(textfield); | |
| 134 | |
| 135 gfx::Transform transform; | |
| 136 transform.Translate(0, -kTextFilterHeight); | |
| 137 widget->GetNativeWindow()->SetTransform(transform); | |
| 138 widget->Show(); | |
| 139 textfield->RequestFocus(); | |
| 140 | |
| 141 return widget; | |
| 142 } | |
| 143 | |
| 144 } // namespace | 116 } // namespace |
| 145 | 117 |
| 146 WindowSelector::WindowSelector(const WindowList& windows, | 118 WindowSelector::WindowSelector(const WindowList& windows, |
| 147 WindowSelectorDelegate* delegate) | 119 WindowSelectorDelegate* delegate) |
| 148 : delegate_(delegate), | 120 : delegate_(delegate), |
| 149 restore_focus_window_(aura::client::GetFocusClient( | 121 restore_focus_window_(aura::client::GetFocusClient( |
| 150 Shell::GetPrimaryRootWindow())->GetFocusedWindow()), | 122 Shell::GetPrimaryRootWindow())->GetFocusedWindow()), |
| 151 ignore_activations_(false), | 123 ignore_activations_(false), |
| 152 selected_grid_index_(0), | 124 selected_grid_index_(0), |
| 153 overview_start_time_(base::Time::Now()), | 125 overview_start_time_(base::Time::Now()), |
| 154 num_key_presses_(0), | 126 num_key_presses_(0), |
| 155 num_items_(0), | 127 num_items_(0), |
| 156 showing_selection_widget_(false) { | 128 showing_selection_widget_(false), |
| 129 text_height_(0) { | |
| 157 DCHECK(delegate_); | 130 DCHECK(delegate_); |
| 158 Shell* shell = Shell::GetInstance(); | 131 Shell* shell = Shell::GetInstance(); |
| 159 shell->OnOverviewModeStarting(); | 132 shell->OnOverviewModeStarting(); |
| 160 | 133 |
| 134 // Compute and store the height of the text used in text filtering. | |
| 135 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); | |
| 136 text_height_ = bundle.GetFontList(kTextFilterFontStyle).GetHeight(); | |
| 137 | |
| 161 if (restore_focus_window_) | 138 if (restore_focus_window_) |
| 162 restore_focus_window_->AddObserver(this); | 139 restore_focus_window_->AddObserver(this); |
| 163 | 140 |
| 164 const aura::Window::Windows root_windows = Shell::GetAllRootWindows(); | 141 const aura::Window::Windows root_windows = Shell::GetAllRootWindows(); |
| 165 for (aura::Window::Windows::const_iterator iter = root_windows.begin(); | 142 for (aura::Window::Windows::const_iterator iter = root_windows.begin(); |
| 166 iter != root_windows.end(); iter++) { | 143 iter != root_windows.end(); iter++) { |
| 167 // Observed switchable containers for newly created windows on all root | 144 // Observed switchable containers for newly created windows on all root |
| 168 // windows. | 145 // windows. |
| 169 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { | 146 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { |
| 170 aura::Window* container = Shell::GetContainer(*iter, | 147 aura::Window* container = Shell::GetContainer(*iter, |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 246 | 223 |
| 247 // TODO(flackr): Change this to OnOverviewModeEnded and move it to when | 224 // TODO(flackr): Change this to OnOverviewModeEnded and move it to when |
| 248 // everything is done. | 225 // everything is done. |
| 249 shell->OnOverviewModeEnding(); | 226 shell->OnOverviewModeEnding(); |
| 250 | 227 |
| 251 // Clearing the window list resets the ignored_by_shelf flag on the windows. | 228 // Clearing the window list resets the ignored_by_shelf flag on the windows. |
| 252 grid_list_.clear(); | 229 grid_list_.clear(); |
| 253 UpdateShelfVisibility(); | 230 UpdateShelfVisibility(); |
| 254 } | 231 } |
| 255 | 232 |
| 233 int WindowSelector::TextFilterHeight() const { | |
|
flackr
2014/07/18 13:41:51
Can this be in anonymous namespace and use a stati
tdanderson
2014/08/07 20:13:07
This is gone in the next patch set.
| |
| 234 DCHECK(text_height_ > 0); | |
| 235 return text_height_ + 2 * kTextFilterPadding; | |
| 236 } | |
| 237 | |
| 256 void WindowSelector::CancelSelection() { | 238 void WindowSelector::CancelSelection() { |
| 257 delegate_->OnSelectionEnded(); | 239 delegate_->OnSelectionEnded(); |
| 258 } | 240 } |
| 259 | 241 |
| 260 void WindowSelector::OnGridEmpty(WindowGrid* grid) { | 242 void WindowSelector::OnGridEmpty(WindowGrid* grid) { |
| 261 ScopedVector<WindowGrid>::iterator iter = | 243 ScopedVector<WindowGrid>::iterator iter = |
| 262 std::find(grid_list_.begin(), grid_list_.end(), grid); | 244 std::find(grid_list_.begin(), grid_list_.end(), grid); |
| 263 DCHECK(iter != grid_list_.end()); | 245 DCHECK(iter != grid_list_.end()); |
| 264 grid_list_.erase(iter); | 246 grid_list_.erase(iter); |
| 265 // TODO(flackr): Use the previous index for more than two displays. | 247 // TODO(flackr): Use the previous index for more than two displays. |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 395 text_filter_widget_->GetNativeWindow()->layer()->GetAnimator()); | 377 text_filter_widget_->GetNativeWindow()->layer()->GetAnimator()); |
| 396 animation_settings.SetPreemptionStrategy( | 378 animation_settings.SetPreemptionStrategy( |
| 397 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 379 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 398 animation_settings.SetTweenType(showing_selection_widget_ ? | 380 animation_settings.SetTweenType(showing_selection_widget_ ? |
| 399 gfx::Tween::FAST_OUT_LINEAR_IN : gfx::Tween::LINEAR_OUT_SLOW_IN); | 381 gfx::Tween::FAST_OUT_LINEAR_IN : gfx::Tween::LINEAR_OUT_SLOW_IN); |
| 400 | 382 |
| 401 gfx::Transform transform; | 383 gfx::Transform transform; |
| 402 if (should_show_selection_widget) | 384 if (should_show_selection_widget) |
| 403 transform.Translate(0, 0); | 385 transform.Translate(0, 0); |
| 404 else | 386 else |
| 405 transform.Translate(0, -kTextFilterHeight); | 387 transform.Translate(0, -TextFilterHeight()); |
| 406 | 388 |
| 407 text_filter_widget_->GetNativeWindow()->SetTransform(transform); | 389 text_filter_widget_->GetNativeWindow()->SetTransform(transform); |
| 408 showing_selection_widget_ = should_show_selection_widget; | 390 showing_selection_widget_ = should_show_selection_widget; |
| 409 } | 391 } |
| 410 for (ScopedVector<WindowGrid>::iterator iter = grid_list_.begin(); | 392 for (ScopedVector<WindowGrid>::iterator iter = grid_list_.begin(); |
| 411 iter != grid_list_.end(); iter++) { | 393 iter != grid_list_.end(); iter++) { |
| 412 (*iter)->FilterItems(new_contents); | 394 (*iter)->FilterItems(new_contents); |
| 413 } | 395 } |
| 414 | 396 |
| 415 // If the selection widget is not active, execute a Move() command so that it | 397 // If the selection widget is not active, execute a Move() command so that it |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 486 // we made a full cycle on all the grids. | 468 // we made a full cycle on all the grids. |
| 487 for (size_t i = 0; | 469 for (size_t i = 0; |
| 488 i <= grid_list_.size() && | 470 i <= grid_list_.size() && |
| 489 grid_list_[selected_grid_index_]->Move(direction, animate); i++) { | 471 grid_list_[selected_grid_index_]->Move(direction, animate); i++) { |
| 490 // TODO(flackr): If there are more than two monitors, move between grids | 472 // TODO(flackr): If there are more than two monitors, move between grids |
| 491 // in the requested direction. | 473 // in the requested direction. |
| 492 selected_grid_index_ = (selected_grid_index_ + 1) % grid_list_.size(); | 474 selected_grid_index_ = (selected_grid_index_ + 1) % grid_list_.size(); |
| 493 } | 475 } |
| 494 } | 476 } |
| 495 | 477 |
| 478 views::Widget* WindowSelector::CreateTextFilter( | |
| 479 views::TextfieldController* controller, | |
| 480 aura::Window* root_window) { | |
|
flackr
2014/07/18 13:41:51
Seems like this could still be in the anonymous na
tdanderson
2014/08/07 20:13:07
Done.
| |
| 481 views::Widget* widget = new views::Widget; | |
| 482 views::Widget::InitParams params; | |
| 483 params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS; | |
| 484 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
| 485 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; | |
| 486 params.parent = | |
| 487 Shell::GetContainer(root_window, ash::kShellWindowId_OverlayContainer); | |
| 488 params.accept_events = true; | |
| 489 params.bounds = gfx::Rect( | |
| 490 root_window->bounds().width() / 2 * (1 - kTextFilterScreenProportion), 0, | |
| 491 root_window->bounds().width() * kTextFilterScreenProportion, | |
| 492 TextFilterHeight()); | |
| 493 widget->Init(params); | |
| 494 | |
| 495 views::View* container = new views::View; | |
| 496 container->set_background( | |
| 497 views::Background::CreateSolidBackground(SK_ColorBLACK)); | |
| 498 container->SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, | |
| 499 kTextFilterPadding, | |
| 500 kTextFilterPadding, | |
| 501 kTextFilterPadding)); | |
| 502 | |
| 503 views::Textfield* textfield = new views::Textfield; | |
| 504 textfield->set_controller(controller); | |
| 505 textfield->SetBackgroundColor(SK_ColorTRANSPARENT); | |
| 506 textfield->SetBorder(views::Border::NullBorder()); | |
| 507 textfield->SetTextColor(SK_ColorWHITE); | |
| 508 textfield->SetShadows(gfx::ShadowValues(1, gfx::ShadowValue( | |
| 509 gfx::Point(0, kVerticalShadowOffset), kShadowBlur, kTextFilterShadow))); | |
| 510 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); | |
| 511 textfield->SetFontList(bundle.GetFontList(kTextFilterFontStyle)); | |
| 512 | |
| 513 container->AddChildView(textfield); | |
| 514 widget->SetContentsView(container); | |
| 515 | |
| 516 gfx::Transform transform; | |
| 517 transform.Translate(0, -TextFilterHeight()); | |
| 518 widget->GetNativeWindow()->SetTransform(transform); | |
| 519 widget->SetOpacity(kTextFilterOpacity); | |
| 520 | |
| 521 widget->Show(); | |
| 522 textfield->RequestFocus(); | |
| 523 | |
| 524 return widget; | |
| 525 } | |
| 526 | |
| 496 } // namespace ash | 527 } // namespace ash |
| OLD | NEW |