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 |