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