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 "athena/wm/window_overview_mode.h" | 5 #include "athena/wm/window_overview_mode.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <functional> | 8 #include <functional> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
| 11 #include "athena/wm/public/window_list_provider.h" |
11 #include "base/bind.h" | 12 #include "base/bind.h" |
12 #include "base/macros.h" | 13 #include "base/macros.h" |
13 #include "ui/aura/scoped_window_targeter.h" | 14 #include "ui/aura/scoped_window_targeter.h" |
14 #include "ui/aura/window.h" | 15 #include "ui/aura/window.h" |
15 #include "ui/aura/window_delegate.h" | 16 #include "ui/aura/window_delegate.h" |
16 #include "ui/aura/window_property.h" | 17 #include "ui/aura/window_property.h" |
17 #include "ui/aura/window_targeter.h" | 18 #include "ui/aura/window_targeter.h" |
18 #include "ui/aura/window_tree_host.h" | 19 #include "ui/aura/window_tree_host.h" |
19 #include "ui/compositor/compositor.h" | 20 #include "ui/compositor/compositor.h" |
20 #include "ui/compositor/compositor_animation_observer.h" | 21 #include "ui/compositor/compositor_animation_observer.h" |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 } // namespace | 68 } // namespace |
68 | 69 |
69 DECLARE_WINDOW_PROPERTY_TYPE(WindowOverviewState*) | 70 DECLARE_WINDOW_PROPERTY_TYPE(WindowOverviewState*) |
70 DEFINE_OWNED_WINDOW_PROPERTY_KEY(WindowOverviewState, | 71 DEFINE_OWNED_WINDOW_PROPERTY_KEY(WindowOverviewState, |
71 kWindowOverviewState, | 72 kWindowOverviewState, |
72 NULL) | 73 NULL) |
73 namespace athena { | 74 namespace athena { |
74 | 75 |
75 namespace { | 76 namespace { |
76 | 77 |
77 bool ShouldShowWindowInOverviewMode(aura::Window* window) { | |
78 return window->type() == ui::wm::WINDOW_TYPE_NORMAL; | |
79 } | |
80 | |
81 // Gets the transform for the window in its current state. | 78 // Gets the transform for the window in its current state. |
82 gfx::Transform GetTransformForState(WindowOverviewState* state) { | 79 gfx::Transform GetTransformForState(WindowOverviewState* state) { |
83 return gfx::Tween::TransformValueBetween(state->progress, | 80 return gfx::Tween::TransformValueBetween(state->progress, |
84 state->top, | 81 state->top, |
85 state->bottom); | 82 state->bottom); |
86 } | 83 } |
87 | 84 |
88 // Sets the progress-state for the window in the overview mode. | 85 // Sets the progress-state for the window in the overview mode. |
89 void SetWindowProgress(aura::Window* window, float progress) { | 86 void SetWindowProgress(aura::Window* window, float progress) { |
90 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); | 87 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 | 121 |
125 aura::Window* target_; | 122 aura::Window* target_; |
126 DISALLOW_COPY_AND_ASSIGN(StaticWindowTargeter); | 123 DISALLOW_COPY_AND_ASSIGN(StaticWindowTargeter); |
127 }; | 124 }; |
128 | 125 |
129 class WindowOverviewModeImpl : public WindowOverviewMode, | 126 class WindowOverviewModeImpl : public WindowOverviewMode, |
130 public ui::EventHandler, | 127 public ui::EventHandler, |
131 public ui::CompositorAnimationObserver { | 128 public ui::CompositorAnimationObserver { |
132 public: | 129 public: |
133 WindowOverviewModeImpl(aura::Window* container, | 130 WindowOverviewModeImpl(aura::Window* container, |
| 131 const WindowListProvider* window_list_provider, |
134 WindowOverviewModeDelegate* delegate) | 132 WindowOverviewModeDelegate* delegate) |
135 : container_(container), | 133 : container_(container), |
| 134 window_list_provider_(window_list_provider), |
136 delegate_(delegate), | 135 delegate_(delegate), |
137 scoped_targeter_(new aura::ScopedWindowTargeter( | 136 scoped_targeter_(new aura::ScopedWindowTargeter( |
138 container, | 137 container, |
139 scoped_ptr<ui::EventTargeter>( | 138 scoped_ptr<ui::EventTargeter>( |
140 new StaticWindowTargeter(container)))), | 139 new StaticWindowTargeter(container)))), |
141 dragged_window_(NULL) { | 140 dragged_window_(NULL) { |
142 container_->set_target_handler(this); | 141 container_->set_target_handler(this); |
143 | 142 |
144 // Prepare the desired transforms for all the windows, and set the initial | 143 // Prepare the desired transforms for all the windows, and set the initial |
145 // state on the windows. | 144 // state on the windows. |
146 ComputeTerminalStatesForAllWindows(); | 145 ComputeTerminalStatesForAllWindows(); |
147 SetInitialWindowStates(); | 146 SetInitialWindowStates(); |
148 } | 147 } |
149 | 148 |
150 virtual ~WindowOverviewModeImpl() { | 149 virtual ~WindowOverviewModeImpl() { |
151 container_->set_target_handler(container_->delegate()); | 150 container_->set_target_handler(container_->delegate()); |
152 RemoveAnimationObserver(); | 151 RemoveAnimationObserver(); |
153 const aura::Window::Windows& windows = container_->children(); | 152 aura::Window::Windows windows = window_list_provider_->GetWindowList(); |
154 for (aura::Window::Windows::const_iterator iter = windows.begin(); | 153 if (windows.empty()) |
155 iter != windows.end(); | 154 return; |
156 ++iter) { | 155 std::for_each(windows.begin(), windows.end(), &RestoreWindowState); |
157 if ((*iter)->GetProperty(kWindowOverviewState)) | |
158 RestoreWindowState(*iter); | |
159 } | |
160 } | 156 } |
161 | 157 |
162 private: | 158 private: |
163 // Computes the transforms for all windows in both the topmost and bottom-most | 159 // Computes the transforms for all windows in both the topmost and bottom-most |
164 // positions. The transforms are set in the |kWindowOverviewState| property of | 160 // positions. The transforms are set in the |kWindowOverviewState| property of |
165 // the windows. | 161 // the windows. |
166 void ComputeTerminalStatesForAllWindows() { | 162 void ComputeTerminalStatesForAllWindows() { |
167 const aura::Window::Windows& windows = container_->children(); | 163 aura::Window::Windows windows = window_list_provider_->GetWindowList(); |
168 size_t window_count = std::count_if(windows.begin(), windows.end(), | 164 size_t window_count = windows.size(); |
169 ShouldShowWindowInOverviewMode); | |
170 | |
171 size_t index = 0; | 165 size_t index = 0; |
172 const gfx::Size container_size = container_->bounds().size(); | 166 const gfx::Size container_size = container_->bounds().size(); |
173 | 167 |
174 const int kGapBetweenWindowsBottom = 10; | 168 const int kGapBetweenWindowsBottom = 10; |
175 const int kGapBetweenWindowsTop = 5; | 169 const int kGapBetweenWindowsTop = 5; |
176 | 170 |
177 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); | 171 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); |
178 iter != windows.rend(); | 172 iter != windows.rend(); |
179 ++iter) { | 173 ++iter, ++index) { |
180 aura::Window* window = (*iter); | 174 aura::Window* window = (*iter); |
181 if (!ShouldShowWindowInOverviewMode(window)) | |
182 continue; | |
183 | 175 |
184 gfx::Transform top_transform; | 176 gfx::Transform top_transform; |
185 int top = (window_count - index - 1) * kGapBetweenWindowsTop; | 177 int top = (window_count - index - 1) * kGapBetweenWindowsTop; |
186 float x_translate = container_size.width() * (1 - kMinScale) / 2.; | 178 float x_translate = container_size.width() * (1 - kMinScale) / 2.; |
187 top_transform.Translate(x_translate, top); | 179 top_transform.Translate(x_translate, top); |
188 top_transform.Scale(kMinScale, kMinScale); | 180 top_transform.Scale(kMinScale, kMinScale); |
189 | 181 |
190 gfx::Transform bottom_transform; | 182 gfx::Transform bottom_transform; |
191 int bottom = GetScrollableHeight() - (index * kGapBetweenWindowsBottom); | 183 int bottom = GetScrollableHeight() - (index * kGapBetweenWindowsBottom); |
192 x_translate = container_size.width() * (1 - kMaxScale) / 2.; | 184 x_translate = container_size.width() * (1 - kMaxScale) / 2.; |
193 bottom_transform.Translate(x_translate, bottom - window->bounds().y()); | 185 bottom_transform.Translate(x_translate, bottom - window->bounds().y()); |
194 bottom_transform.Scale(kMaxScale, kMaxScale); | 186 bottom_transform.Scale(kMaxScale, kMaxScale); |
195 | 187 |
196 WindowOverviewState* state = new WindowOverviewState; | 188 WindowOverviewState* state = new WindowOverviewState; |
197 state->top = top_transform; | 189 state->top = top_transform; |
198 state->bottom = bottom_transform; | 190 state->bottom = bottom_transform; |
199 state->progress = 0.f; | 191 state->progress = 0.f; |
200 state->shadow = CreateShadowForWindow(window); | 192 state->shadow = CreateShadowForWindow(window); |
201 window->SetProperty(kWindowOverviewState, state); | 193 window->SetProperty(kWindowOverviewState, state); |
202 | |
203 index++; | |
204 } | 194 } |
205 } | 195 } |
206 | 196 |
207 // Sets the initial position for the windows for the overview mode. | 197 // Sets the initial position for the windows for the overview mode. |
208 void SetInitialWindowStates() { | 198 void SetInitialWindowStates() { |
| 199 aura::Window::Windows windows = window_list_provider_->GetWindowList(); |
| 200 size_t window_count = windows.size(); |
209 // The initial overview state of the topmost three windows. | 201 // The initial overview state of the topmost three windows. |
210 const float kInitialProgress[] = { 0.5f, 0.05f, 0.01f }; | 202 const float kInitialProgress[] = { 0.5f, 0.05f, 0.01f }; |
211 size_t index = 0; | 203 for (size_t i = 0; i < window_count; ++i) { |
212 const aura::Window::Windows& windows = container_->children(); | |
213 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); | |
214 iter != windows.rend(); | |
215 ++iter) { | |
216 aura::Window* window = (*iter); | |
217 if (!window->GetProperty(kWindowOverviewState)) | |
218 continue; | |
219 | |
220 float progress = 0.f; | 204 float progress = 0.f; |
221 if (index < arraysize(kInitialProgress)) | 205 aura::Window* window = windows[window_count - 1 - i]; |
222 progress = kInitialProgress[index]; | 206 if (i < arraysize(kInitialProgress)) |
| 207 progress = kInitialProgress[i]; |
223 | 208 |
224 scoped_refptr<ui::LayerAnimator> animator = | 209 scoped_refptr<ui::LayerAnimator> animator = |
225 window->layer()->GetAnimator(); | 210 window->layer()->GetAnimator(); |
226 | 211 |
227 // Unset any in-progress animation. | 212 // Unset any in-progress animation. |
228 { | 213 { |
229 ui::ScopedLayerAnimationSettings settings(animator); | 214 ui::ScopedLayerAnimationSettings settings(animator); |
230 settings.SetPreemptionStrategy( | 215 settings.SetPreemptionStrategy( |
231 ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET); | 216 ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET); |
232 window->Show(); | 217 window->Show(); |
233 window->SetTransform(gfx::Transform()); | 218 window->SetTransform(gfx::Transform()); |
234 } | 219 } |
235 // Setup the animation. | 220 // Setup the animation. |
236 { | 221 { |
237 ui::ScopedLayerAnimationSettings settings(animator); | 222 ui::ScopedLayerAnimationSettings settings(animator); |
238 settings.SetPreemptionStrategy( | 223 settings.SetPreemptionStrategy( |
239 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 224 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
240 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250)); | 225 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250)); |
241 SetWindowProgress(window, progress); | 226 SetWindowProgress(window, progress); |
242 } | 227 } |
243 index++; | |
244 } | 228 } |
245 } | 229 } |
246 | 230 |
247 scoped_ptr<wm::Shadow> CreateShadowForWindow(aura::Window* window) { | 231 scoped_ptr<wm::Shadow> CreateShadowForWindow(aura::Window* window) { |
248 scoped_ptr<wm::Shadow> shadow(new wm::Shadow()); | 232 scoped_ptr<wm::Shadow> shadow(new wm::Shadow()); |
249 shadow->Init(wm::Shadow::STYLE_ACTIVE); | 233 shadow->Init(wm::Shadow::STYLE_ACTIVE); |
250 shadow->SetContentBounds(gfx::Rect(window->bounds().size())); | 234 shadow->SetContentBounds(gfx::Rect(container_->bounds().size())); |
251 shadow->layer()->SetVisible(true); | 235 shadow->layer()->SetVisible(true); |
252 window->layer()->Add(shadow->layer()); | 236 window->layer()->Add(shadow->layer()); |
253 return shadow.Pass(); | 237 return shadow.Pass(); |
254 } | 238 } |
255 | 239 |
256 aura::Window* SelectWindowAt(ui::LocatedEvent* event) { | 240 aura::Window* SelectWindowAt(ui::LocatedEvent* event) { |
257 CHECK_EQ(container_, event->target()); | 241 CHECK_EQ(container_, event->target()); |
258 // Find the old targeter to find the target of the event. | 242 // Find the old targeter to find the target of the event. |
259 ui::EventTarget* window = container_; | 243 ui::EventTarget* window = container_; |
260 ui::EventTargeter* targeter = scoped_targeter_->old_targeter(); | 244 ui::EventTargeter* targeter = scoped_targeter_->old_targeter(); |
261 while (!targeter && window->GetParentTarget()) { | 245 while (!targeter && window->GetParentTarget()) { |
262 window = window->GetParentTarget(); | 246 window = window->GetParentTarget(); |
263 targeter = window->GetEventTargeter(); | 247 targeter = window->GetEventTargeter(); |
264 } | 248 } |
265 if (!targeter) | 249 if (!targeter) |
266 return NULL; | 250 return NULL; |
267 aura::Window* target = static_cast<aura::Window*>( | 251 aura::Window* target = static_cast<aura::Window*>( |
268 targeter->FindTargetForLocatedEvent(container_, event)); | 252 targeter->FindTargetForLocatedEvent(container_, event)); |
269 while (target && target->parent() != container_) | 253 while (target && target->parent() != container_) |
270 target = target->parent(); | 254 target = target->parent(); |
271 return target; | 255 return target; |
272 } | 256 } |
273 | 257 |
274 // Scroll the window list by |delta_y| amount. |delta_y| is negative when | 258 // Scroll the window list by |delta_y| amount. |delta_y| is negative when |
275 // scrolling up; and positive when scrolling down. | 259 // scrolling up; and positive when scrolling down. |
276 void DoScroll(float delta_y) { | 260 void DoScroll(float delta_y) { |
277 const float kEpsilon = 1e-3f; | 261 const float kEpsilon = 1e-3f; |
278 float delta_y_p = std::abs(delta_y) / GetScrollableHeight(); | 262 float delta_y_p = std::abs(delta_y) / GetScrollableHeight(); |
279 const aura::Window::Windows& windows = container_->children(); | 263 aura::Window::Windows windows = window_list_provider_->GetWindowList(); |
280 if (delta_y < 0) { | 264 if (delta_y < 0) { |
281 // Scroll up. Start with the top-most (i.e. behind-most in terms of | 265 // Scroll up. Start with the top-most (i.e. behind-most in terms of |
282 // z-index) window, and try to scroll them up. | 266 // z-index) window, and try to scroll them up. |
283 for (aura::Window::Windows::const_iterator iter = windows.begin(); | 267 for (aura::Window::Windows::const_iterator iter = windows.begin(); |
284 delta_y_p > kEpsilon && iter != windows.end(); | 268 delta_y_p > kEpsilon && iter != windows.end(); |
285 ++iter) { | 269 ++iter) { |
286 aura::Window* window = (*iter); | 270 aura::Window* window = (*iter); |
287 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); | 271 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); |
288 if (!state) | |
289 continue; | |
290 if (state->progress > kEpsilon) { | 272 if (state->progress > kEpsilon) { |
291 // It is possible to scroll |window| up. Scroll it up, and update | 273 // It is possible to scroll |window| up. Scroll it up, and update |
292 // |delta_y_p| for the next window. | 274 // |delta_y_p| for the next window. |
293 float apply = delta_y_p * state->progress; | 275 float apply = delta_y_p * state->progress; |
294 SetWindowProgress(window, std::max(0.f, state->progress - apply * 3)); | 276 SetWindowProgress(window, std::max(0.f, state->progress - apply * 3)); |
295 delta_y_p -= apply; | 277 delta_y_p -= apply; |
296 } | 278 } |
297 } | 279 } |
298 } else { | 280 } else { |
299 // Scroll down. Start with the bottom-most (i.e. front-most in terms of | 281 // Scroll down. Start with the bottom-most (i.e. front-most in terms of |
300 // z-index) window, and try to scroll them down. | 282 // z-index) window, and try to scroll them down. |
301 for (aura::Window::Windows::const_reverse_iterator iter = | 283 aura::Window::Windows::const_reverse_iterator iter; |
302 windows.rbegin(); | 284 for (iter = windows.rbegin(); |
303 delta_y_p > kEpsilon && iter != windows.rend(); | 285 delta_y_p > kEpsilon && iter != windows.rend(); |
304 ++iter) { | 286 ++iter) { |
305 aura::Window* window = (*iter); | 287 aura::Window* window = (*iter); |
306 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); | 288 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); |
307 if (!state) | |
308 continue; | |
309 if (1.f - state->progress > kEpsilon) { | 289 if (1.f - state->progress > kEpsilon) { |
310 // It is possible to scroll |window| down. Scroll it down, and update | 290 // It is possible to scroll |window| down. Scroll it down, and update |
311 // |delta_y_p| for the next window. | 291 // |delta_y_p| for the next window. |
312 SetWindowProgress(window, std::min(1.f, state->progress + delta_y_p)); | 292 SetWindowProgress(window, std::min(1.f, state->progress + delta_y_p)); |
313 delta_y_p /= 2.f; | 293 delta_y_p /= 2.f; |
314 } | 294 } |
315 } | 295 } |
316 } | 296 } |
317 } | 297 } |
318 | 298 |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 } | 494 } |
515 } | 495 } |
516 | 496 |
517 const int kMinDistanceForDismissal = 300; | 497 const int kMinDistanceForDismissal = 300; |
518 const float kMinScale = 0.6f; | 498 const float kMinScale = 0.6f; |
519 const float kMaxScale = 0.95f; | 499 const float kMaxScale = 0.95f; |
520 const float kMaxOpacity = 1.0f; | 500 const float kMaxOpacity = 1.0f; |
521 const float kMinOpacity = 0.2f; | 501 const float kMinOpacity = 0.2f; |
522 | 502 |
523 aura::Window* container_; | 503 aura::Window* container_; |
| 504 // Provider of the stack of windows to show in the overview mode. Not owned. |
| 505 const WindowListProvider* window_list_provider_; |
524 WindowOverviewModeDelegate* delegate_; | 506 WindowOverviewModeDelegate* delegate_; |
525 scoped_ptr<aura::ScopedWindowTargeter> scoped_targeter_; | 507 scoped_ptr<aura::ScopedWindowTargeter> scoped_targeter_; |
526 scoped_ptr<ui::FlingCurve> fling_; | 508 scoped_ptr<ui::FlingCurve> fling_; |
527 | 509 |
528 aura::Window* dragged_window_; | 510 aura::Window* dragged_window_; |
529 gfx::Point dragged_start_location_; | 511 gfx::Point dragged_start_location_; |
530 | 512 |
531 DISALLOW_COPY_AND_ASSIGN(WindowOverviewModeImpl); | 513 DISALLOW_COPY_AND_ASSIGN(WindowOverviewModeImpl); |
532 }; | 514 }; |
533 | 515 |
534 } // namespace | 516 } // namespace |
535 | 517 |
536 // static | 518 // static |
537 scoped_ptr<WindowOverviewMode> WindowOverviewMode::Create( | 519 scoped_ptr<WindowOverviewMode> WindowOverviewMode::Create( |
538 aura::Window* container, | 520 aura::Window* container, |
| 521 const WindowListProvider* window_list_provider, |
539 WindowOverviewModeDelegate* delegate) { | 522 WindowOverviewModeDelegate* delegate) { |
540 return scoped_ptr<WindowOverviewMode>( | 523 return scoped_ptr<WindowOverviewMode>( |
541 new WindowOverviewModeImpl(container, delegate)); | 524 new WindowOverviewModeImpl(container, window_list_provider, delegate)); |
542 } | 525 } |
543 | 526 |
544 } // namespace athena | 527 } // namespace athena |
OLD | NEW |