| 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_overview.h" | 5 #include "ash/wm/overview/window_overview.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "ash/screen_ash.h" | 9 #include "ash/screen_ash.h" |
| 10 #include "ash/shell.h" | 10 #include "ash/shell.h" |
| 11 #include "ash/shell_window_ids.h" | 11 #include "ash/shell_window_ids.h" |
| 12 #include "ash/wm/overview/window_selector.h" | 12 #include "ash/wm/overview/window_selector.h" |
| 13 #include "ash/wm/overview/window_selector_window.h" | 13 #include "ash/wm/overview/window_selector_item.h" |
| 14 #include "third_party/skia/include/core/SkColor.h" | 14 #include "third_party/skia/include/core/SkColor.h" |
| 15 #include "ui/aura/root_window.h" | 15 #include "ui/aura/root_window.h" |
| 16 #include "ui/aura/window.h" | 16 #include "ui/aura/window.h" |
| 17 #include "ui/base/events/event.h" | 17 #include "ui/base/events/event.h" |
| 18 #include "ui/compositor/scoped_layer_animation_settings.h" | 18 #include "ui/compositor/scoped_layer_animation_settings.h" |
| 19 #include "ui/views/widget/widget.h" | 19 #include "ui/views/widget/widget.h" |
| 20 | 20 |
| 21 namespace ash { | 21 namespace ash { |
| 22 | 22 |
| 23 namespace { | 23 namespace { |
| 24 | 24 |
| 25 const float kCardAspectRatio = 4.0f / 3.0f; | 25 const float kCardAspectRatio = 4.0f / 3.0f; |
| 26 const int kWindowMargin = 30; | 26 const int kWindowMargin = 30; |
| 27 const int kMinCardsMajor = 3; | 27 const int kMinCardsMajor = 3; |
| 28 const int kOverviewSelectorTransitionMilliseconds = 100; | 28 const int kOverviewSelectorTransitionMilliseconds = 100; |
| 29 const SkColor kWindowOverviewSelectionColor = SK_ColorBLACK; | 29 const SkColor kWindowOverviewSelectionColor = SK_ColorBLACK; |
| 30 const float kWindowOverviewSelectionOpacity = 0.5f; | 30 const float kWindowOverviewSelectionOpacity = 0.5f; |
| 31 const int kWindowOverviewSelectionPadding = 15; | 31 const int kWindowOverviewSelectionPadding = 15; |
| 32 | 32 |
| 33 // A comparator for locating a given target window. | 33 // A comparator for locating a given target window. |
| 34 struct WindowSelectorWindowComparator | 34 struct WindowSelectorItemComparator |
| 35 : public std::unary_function<WindowSelectorWindow*, bool> { | 35 : public std::unary_function<WindowSelectorItem*, bool> { |
| 36 explicit WindowSelectorWindowComparator(const aura::Window* target_window) | 36 explicit WindowSelectorItemComparator(const aura::Window* target_window) |
| 37 : target(target_window) { | 37 : target(target_window) { |
| 38 } | 38 } |
| 39 | 39 |
| 40 bool operator()(const WindowSelectorWindow* window) const { | 40 bool operator()(const WindowSelectorItem* window) const { |
| 41 return target == window->window(); | 41 return window->TargetedWindow(target) != NULL; |
| 42 } | 42 } |
| 43 | 43 |
| 44 const aura::Window* target; | 44 const aura::Window* target; |
| 45 }; | 45 }; |
| 46 | 46 |
| 47 } // namespace | 47 } // namespace |
| 48 | 48 |
| 49 WindowOverview::WindowOverview(WindowSelector* window_selector, | 49 WindowOverview::WindowOverview(WindowSelector* window_selector, |
| 50 WindowSelectorWindowList* windows, | 50 WindowSelectorItemList* windows, |
| 51 aura::RootWindow* single_root_window) | 51 aura::RootWindow* single_root_window) |
| 52 : window_selector_(window_selector), | 52 : window_selector_(window_selector), |
| 53 windows_(windows), | 53 windows_(windows), |
| 54 single_root_window_(single_root_window) { | 54 single_root_window_(single_root_window) { |
| 55 PositionWindows(); | 55 PositionWindows(); |
| 56 ash::Shell::GetInstance()->AddPreTargetHandler(this); | 56 ash::Shell::GetInstance()->AddPreTargetHandler(this); |
| 57 } | 57 } |
| 58 | 58 |
| 59 WindowOverview::~WindowOverview() { | 59 WindowOverview::~WindowOverview() { |
| 60 ash::Shell::GetInstance()->RemovePreTargetHandler(this); | 60 ash::Shell::GetInstance()->RemovePreTargetHandler(this); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 82 } | 82 } |
| 83 | 83 |
| 84 void WindowOverview::OnWindowsChanged() { | 84 void WindowOverview::OnWindowsChanged() { |
| 85 PositionWindows(); | 85 PositionWindows(); |
| 86 } | 86 } |
| 87 | 87 |
| 88 void WindowOverview::OnEvent(ui::Event* event) { | 88 void WindowOverview::OnEvent(ui::Event* event) { |
| 89 // If the event is targetted at any of the windows in the overview, then | 89 // If the event is targetted at any of the windows in the overview, then |
| 90 // prevent it from propagating. | 90 // prevent it from propagating. |
| 91 aura::Window* target = static_cast<aura::Window*>(event->target()); | 91 aura::Window* target = static_cast<aura::Window*>(event->target()); |
| 92 for (WindowSelectorWindowList::iterator iter = windows_->begin(); | 92 for (WindowSelectorItemList::iterator iter = windows_->begin(); |
| 93 iter != windows_->end(); ++iter) { | 93 iter != windows_->end(); ++iter) { |
| 94 if ((*iter)->Contains(target)) { | 94 if ((*iter)->TargetedWindow(target)) { |
| 95 // TODO(flackr): StopPropogation prevents generation of gesture events. | 95 // TODO(flackr): StopPropogation prevents generation of gesture events. |
| 96 // We should find a better way to prevent events from being delivered to | 96 // We should find a better way to prevent events from being delivered to |
| 97 // the window, perhaps a transparent window in front of the target window | 97 // the window, perhaps a transparent window in front of the target window |
| 98 // or using EventClientImpl::CanProcessEventsWithinSubtree. | 98 // or using EventClientImpl::CanProcessEventsWithinSubtree. |
| 99 event->StopPropagation(); | 99 event->StopPropagation(); |
| 100 break; | 100 break; |
| 101 } | 101 } |
| 102 } | 102 } |
| 103 | 103 |
| 104 // This object may not be valid after this call as a selection event can | 104 // This object may not be valid after this call as a selection event can |
| 105 // trigger deletion of the window selector. | 105 // trigger deletion of the window selector. |
| 106 ui::EventHandler::OnEvent(event); | 106 ui::EventHandler::OnEvent(event); |
| 107 } | 107 } |
| 108 | 108 |
| 109 void WindowOverview::OnKeyEvent(ui::KeyEvent* event) { | 109 void WindowOverview::OnKeyEvent(ui::KeyEvent* event) { |
| 110 if (event->type() != ui::ET_KEY_PRESSED) | 110 if (event->type() != ui::ET_KEY_PRESSED) |
| 111 return; | 111 return; |
| 112 if (event->key_code() == ui::VKEY_ESCAPE) | 112 if (event->key_code() == ui::VKEY_ESCAPE) |
| 113 window_selector_->CancelSelection(); | 113 window_selector_->CancelSelection(); |
| 114 } | 114 } |
| 115 | 115 |
| 116 void WindowOverview::OnMouseEvent(ui::MouseEvent* event) { | 116 void WindowOverview::OnMouseEvent(ui::MouseEvent* event) { |
| 117 if (event->type() != ui::ET_MOUSE_RELEASED) | 117 if (event->type() != ui::ET_MOUSE_RELEASED) |
| 118 return; | 118 return; |
| 119 WindowSelectorWindow* target = GetEventTarget(event); | 119 aura::Window* target = GetEventTarget(event); |
| 120 if (!target) | 120 if (!target) |
| 121 return; | 121 return; |
| 122 | 122 |
| 123 window_selector_->SelectWindow(target->window()); | 123 window_selector_->SelectWindow(target); |
| 124 } | 124 } |
| 125 | 125 |
| 126 void WindowOverview::OnTouchEvent(ui::TouchEvent* event) { | 126 void WindowOverview::OnTouchEvent(ui::TouchEvent* event) { |
| 127 if (event->type() != ui::ET_TOUCH_PRESSED) | 127 if (event->type() != ui::ET_TOUCH_PRESSED) |
| 128 return; | 128 return; |
| 129 WindowSelectorWindow* target = GetEventTarget(event); | 129 aura::Window* target = GetEventTarget(event); |
| 130 if (!target) | 130 if (!target) |
| 131 return; | 131 return; |
| 132 | 132 |
| 133 window_selector_->SelectWindow(target->window()); | 133 window_selector_->SelectWindow(target); |
| 134 } | 134 } |
| 135 | 135 |
| 136 WindowSelectorWindow* WindowOverview::GetEventTarget(ui::LocatedEvent* event) { | 136 aura::Window* WindowOverview::GetEventTarget(ui::LocatedEvent* event) { |
| 137 aura::Window* target = static_cast<aura::Window*>(event->target()); | 137 aura::Window* target = static_cast<aura::Window*>(event->target()); |
| 138 // If the target window doesn't actually contain the event location (i.e. | 138 // If the target window doesn't actually contain the event location (i.e. |
| 139 // mouse down over the window and mouse up elsewhere) then do not select the | 139 // mouse down over the window and mouse up elsewhere) then do not select the |
| 140 // window. | 140 // window. |
| 141 if (!target->HitTest(event->location())) | 141 if (!target->HitTest(event->location())) |
| 142 return NULL; | 142 return NULL; |
| 143 | 143 |
| 144 for (WindowSelectorWindowList::iterator iter = windows_->begin(); | 144 for (WindowSelectorItemList::iterator iter = windows_->begin(); |
| 145 iter != windows_->end(); ++iter) { | 145 iter != windows_->end(); ++iter) { |
| 146 if ((*iter)->Contains(target)) | 146 aura::Window* selected = (*iter)->TargetedWindow(target); |
| 147 return *iter; | 147 if (selected) |
| 148 return selected; |
| 148 } | 149 } |
| 149 return NULL; | 150 return NULL; |
| 150 } | 151 } |
| 151 | 152 |
| 152 void WindowOverview::PositionWindows() { | 153 void WindowOverview::PositionWindows() { |
| 153 if (single_root_window_) { | 154 if (single_root_window_) { |
| 154 std::vector<WindowSelectorWindow*> windows; | 155 std::vector<WindowSelectorItem*> windows; |
| 155 for (WindowSelectorWindowList::iterator iter = windows_->begin(); | 156 for (WindowSelectorItemList::iterator iter = windows_->begin(); |
| 156 iter != windows_->end(); ++iter) { | 157 iter != windows_->end(); ++iter) { |
| 157 windows.push_back(*iter); | 158 windows.push_back(*iter); |
| 158 } | 159 } |
| 159 PositionWindowsOnRoot(single_root_window_, windows); | 160 PositionWindowsOnRoot(single_root_window_, windows); |
| 160 } else { | 161 } else { |
| 161 Shell::RootWindowList root_window_list = Shell::GetAllRootWindows(); | 162 Shell::RootWindowList root_window_list = Shell::GetAllRootWindows(); |
| 162 for (size_t i = 0; i < root_window_list.size(); ++i) | 163 for (size_t i = 0; i < root_window_list.size(); ++i) |
| 163 PositionWindowsFromRoot(root_window_list[i]); | 164 PositionWindowsFromRoot(root_window_list[i]); |
| 164 } | 165 } |
| 165 } | 166 } |
| 166 | 167 |
| 167 void WindowOverview::PositionWindowsFromRoot(aura::RootWindow* root_window) { | 168 void WindowOverview::PositionWindowsFromRoot(aura::RootWindow* root_window) { |
| 168 std::vector<WindowSelectorWindow*> windows; | 169 std::vector<WindowSelectorItem*> windows; |
| 169 for (WindowSelectorWindowList::iterator iter = windows_->begin(); | 170 for (WindowSelectorItemList::iterator iter = windows_->begin(); |
| 170 iter != windows_->end(); ++iter) { | 171 iter != windows_->end(); ++iter) { |
| 171 if ((*iter)->window()->GetRootWindow() == root_window) | 172 if ((*iter)->GetRootWindow() == root_window) |
| 172 windows.push_back(*iter); | 173 windows.push_back(*iter); |
| 173 } | 174 } |
| 174 PositionWindowsOnRoot(root_window, windows); | 175 PositionWindowsOnRoot(root_window, windows); |
| 175 } | 176 } |
| 176 | 177 |
| 177 void WindowOverview::PositionWindowsOnRoot( | 178 void WindowOverview::PositionWindowsOnRoot( |
| 178 aura::RootWindow* root_window, | 179 aura::RootWindow* root_window, |
| 179 const std::vector<WindowSelectorWindow*>& windows) { | 180 const std::vector<WindowSelectorItem*>& windows) { |
| 180 if (windows.empty()) | 181 if (windows.empty()) |
| 181 return; | 182 return; |
| 182 | 183 |
| 183 gfx::Size window_size; | 184 gfx::Size window_size; |
| 184 gfx::Rect total_bounds = ScreenAsh::ConvertRectToScreen(root_window, | 185 gfx::Rect total_bounds = ScreenAsh::ConvertRectToScreen(root_window, |
| 185 ScreenAsh::GetDisplayWorkAreaBoundsInParent( | 186 ScreenAsh::GetDisplayWorkAreaBoundsInParent( |
| 186 Shell::GetContainer(root_window, | 187 Shell::GetContainer(root_window, |
| 187 internal::kShellWindowId_DefaultContainer))); | 188 internal::kShellWindowId_DefaultContainer))); |
| 188 | 189 |
| 189 // Find the minimum number of windows per row that will fit all of the | 190 // Find the minimum number of windows per row that will fit all of the |
| (...skipping 16 matching lines...) Expand all Loading... |
| 206 rows * window_size.height()) / 2; | 207 rows * window_size.height()) / 2; |
| 207 for (size_t i = 0; i < windows.size(); ++i) { | 208 for (size_t i = 0; i < windows.size(); ++i) { |
| 208 gfx::Transform transform; | 209 gfx::Transform transform; |
| 209 int column = i % columns; | 210 int column = i % columns; |
| 210 int row = i / columns; | 211 int row = i / columns; |
| 211 gfx::Rect target_bounds(window_size.width() * column + x_offset, | 212 gfx::Rect target_bounds(window_size.width() * column + x_offset, |
| 212 window_size.height() * row + y_offset, | 213 window_size.height() * row + y_offset, |
| 213 window_size.width(), | 214 window_size.width(), |
| 214 window_size.height()); | 215 window_size.height()); |
| 215 target_bounds.Inset(kWindowMargin, kWindowMargin); | 216 target_bounds.Inset(kWindowMargin, kWindowMargin); |
| 216 windows[i]->TransformToFitBounds(root_window, target_bounds); | 217 windows[i]->SetBounds(root_window, target_bounds); |
| 217 } | 218 } |
| 218 } | 219 } |
| 219 | 220 |
| 220 void WindowOverview::InitializeSelectionWidget() { | 221 void WindowOverview::InitializeSelectionWidget() { |
| 221 selection_widget_.reset(new views::Widget); | 222 selection_widget_.reset(new views::Widget); |
| 222 views::Widget::InitParams params; | 223 views::Widget::InitParams params; |
| 223 params.type = views::Widget::InitParams::TYPE_POPUP; | 224 params.type = views::Widget::InitParams::TYPE_POPUP; |
| 224 params.can_activate = false; | 225 params.can_activate = false; |
| 225 params.keep_on_top = false; | 226 params.keep_on_top = false; |
| 226 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 227 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 227 params.opacity = views::Widget::InitParams::OPAQUE_WINDOW; | 228 params.opacity = views::Widget::InitParams::OPAQUE_WINDOW; |
| 228 params.parent = Shell::GetContainer( | 229 params.parent = Shell::GetContainer( |
| 229 single_root_window_, | 230 single_root_window_, |
| 230 internal::kShellWindowId_DefaultContainer); | 231 internal::kShellWindowId_DefaultContainer); |
| 231 params.accept_events = false; | 232 params.accept_events = false; |
| 232 selection_widget_->set_focus_on_creation(false); | 233 selection_widget_->set_focus_on_creation(false); |
| 233 selection_widget_->Init(params); | 234 selection_widget_->Init(params); |
| 234 views::View* content_view = new views::View; | 235 views::View* content_view = new views::View; |
| 235 content_view->set_background( | 236 content_view->set_background( |
| 236 views::Background::CreateSolidBackground(kWindowOverviewSelectionColor)); | 237 views::Background::CreateSolidBackground(kWindowOverviewSelectionColor)); |
| 237 selection_widget_->SetContentsView(content_view); | 238 selection_widget_->SetContentsView(content_view); |
| 238 selection_widget_->GetNativeWindow()->parent()->StackChildAtBottom( | 239 selection_widget_->GetNativeWindow()->parent()->StackChildAtBottom( |
| 239 selection_widget_->GetNativeWindow()); | 240 selection_widget_->GetNativeWindow()); |
| 240 selection_widget_->Show(); | 241 selection_widget_->Show(); |
| 241 selection_widget_->GetNativeWindow()->layer()->SetOpacity( | 242 selection_widget_->GetNativeWindow()->layer()->SetOpacity( |
| 242 kWindowOverviewSelectionOpacity); | 243 kWindowOverviewSelectionOpacity); |
| 243 } | 244 } |
| 244 | 245 |
| 245 } // namespace ash | 246 } // namespace ash |
| OLD | NEW |