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/common/closure_animation_observer.h" | 11 #include "athena/common/closure_animation_observer.h" |
| 12 #include "athena/wm/public/window_list_provider.h" |
12 #include "base/bind.h" | 13 #include "base/bind.h" |
13 #include "base/macros.h" | 14 #include "base/macros.h" |
14 #include "ui/aura/scoped_window_targeter.h" | 15 #include "ui/aura/scoped_window_targeter.h" |
15 #include "ui/aura/window.h" | 16 #include "ui/aura/window.h" |
16 #include "ui/aura/window_delegate.h" | 17 #include "ui/aura/window_delegate.h" |
17 #include "ui/aura/window_property.h" | 18 #include "ui/aura/window_property.h" |
18 #include "ui/aura/window_targeter.h" | 19 #include "ui/aura/window_targeter.h" |
19 #include "ui/aura/window_tree_host.h" | 20 #include "ui/aura/window_tree_host.h" |
20 #include "ui/compositor/compositor.h" | 21 #include "ui/compositor/compositor.h" |
21 #include "ui/compositor/compositor_animation_observer.h" | 22 #include "ui/compositor/compositor_animation_observer.h" |
(...skipping 21 matching lines...) Expand all Loading... |
43 } // namespace | 44 } // namespace |
44 | 45 |
45 DECLARE_WINDOW_PROPERTY_TYPE(WindowOverviewState*) | 46 DECLARE_WINDOW_PROPERTY_TYPE(WindowOverviewState*) |
46 DEFINE_OWNED_WINDOW_PROPERTY_KEY(WindowOverviewState, | 47 DEFINE_OWNED_WINDOW_PROPERTY_KEY(WindowOverviewState, |
47 kWindowOverviewState, | 48 kWindowOverviewState, |
48 NULL) | 49 NULL) |
49 namespace athena { | 50 namespace athena { |
50 | 51 |
51 namespace { | 52 namespace { |
52 | 53 |
53 bool ShouldShowWindowInOverviewMode(aura::Window* window) { | |
54 return window->type() == ui::wm::WINDOW_TYPE_NORMAL; | |
55 } | |
56 | |
57 // Gets the transform for the window in its current state. | 54 // Gets the transform for the window in its current state. |
58 gfx::Transform GetTransformForState(WindowOverviewState* state) { | 55 gfx::Transform GetTransformForState(WindowOverviewState* state) { |
59 return gfx::Tween::TransformValueBetween(state->progress, | 56 return gfx::Tween::TransformValueBetween(state->progress, |
60 state->top, | 57 state->top, |
61 state->bottom); | 58 state->bottom); |
62 } | 59 } |
63 | 60 |
64 // Sets the progress-state for the window in the overview mode. | 61 // Sets the progress-state for the window in the overview mode. |
65 void SetWindowProgress(aura::Window* window, float progress) { | 62 void SetWindowProgress(aura::Window* window, float progress) { |
66 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); | 63 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 | 98 |
102 aura::Window* target_; | 99 aura::Window* target_; |
103 DISALLOW_COPY_AND_ASSIGN(StaticWindowTargeter); | 100 DISALLOW_COPY_AND_ASSIGN(StaticWindowTargeter); |
104 }; | 101 }; |
105 | 102 |
106 class WindowOverviewModeImpl : public WindowOverviewMode, | 103 class WindowOverviewModeImpl : public WindowOverviewMode, |
107 public ui::EventHandler, | 104 public ui::EventHandler, |
108 public ui::CompositorAnimationObserver { | 105 public ui::CompositorAnimationObserver { |
109 public: | 106 public: |
110 WindowOverviewModeImpl(aura::Window* container, | 107 WindowOverviewModeImpl(aura::Window* container, |
| 108 const WindowListProvider* window_list_provider, |
111 WindowOverviewModeDelegate* delegate) | 109 WindowOverviewModeDelegate* delegate) |
112 : container_(container), | 110 : container_(container), |
| 111 window_list_provider_(window_list_provider), |
113 delegate_(delegate), | 112 delegate_(delegate), |
114 scoped_targeter_(new aura::ScopedWindowTargeter( | 113 scoped_targeter_(new aura::ScopedWindowTargeter( |
115 container, | 114 container, |
116 scoped_ptr<ui::EventTargeter>( | 115 scoped_ptr<ui::EventTargeter>( |
117 new StaticWindowTargeter(container)))), | 116 new StaticWindowTargeter(container)))), |
118 dragged_window_(NULL) { | 117 dragged_window_(NULL) { |
119 container_->set_target_handler(this); | 118 container_->set_target_handler(this); |
120 | 119 |
121 // Prepare the desired transforms for all the windows, and set the initial | 120 // Prepare the desired transforms for all the windows, and set the initial |
122 // state on the windows. | 121 // state on the windows. |
123 ComputeTerminalStatesForAllWindows(); | 122 ComputeTerminalStatesForAllWindows(); |
124 SetInitialWindowStates(); | 123 SetInitialWindowStates(); |
125 } | 124 } |
126 | 125 |
127 virtual ~WindowOverviewModeImpl() { | 126 virtual ~WindowOverviewModeImpl() { |
128 container_->set_target_handler(container_->delegate()); | 127 container_->set_target_handler(container_->delegate()); |
129 RemoveAnimationObserver(); | 128 RemoveAnimationObserver(); |
130 const aura::Window::Windows& windows = container_->children(); | 129 aura::Window::Windows windows = window_list_provider_->GetWindowList(); |
131 for (aura::Window::Windows::const_iterator iter = windows.begin(); | 130 if (windows.empty()) |
132 iter != windows.end(); | 131 return; |
133 ++iter) { | 132 std::for_each(windows.begin(), windows.end(), &RestoreWindowState); |
134 if ((*iter)->GetProperty(kWindowOverviewState)) | |
135 RestoreWindowState(*iter); | |
136 } | |
137 } | 133 } |
138 | 134 |
139 private: | 135 private: |
140 // Computes the transforms for all windows in both the topmost and bottom-most | 136 // Computes the transforms for all windows in both the topmost and bottom-most |
141 // positions. The transforms are set in the |kWindowOverviewState| property of | 137 // positions. The transforms are set in the |kWindowOverviewState| property of |
142 // the windows. | 138 // the windows. |
143 void ComputeTerminalStatesForAllWindows() { | 139 void ComputeTerminalStatesForAllWindows() { |
144 const aura::Window::Windows& windows = container_->children(); | 140 aura::Window::Windows windows = window_list_provider_->GetWindowList(); |
145 size_t window_count = std::count_if(windows.begin(), windows.end(), | 141 size_t window_count = windows.size(); |
146 ShouldShowWindowInOverviewMode); | |
147 | |
148 size_t index = 0; | 142 size_t index = 0; |
149 const gfx::Size container_size = container_->bounds().size(); | 143 const gfx::Size container_size = container_->bounds().size(); |
150 | 144 |
151 const int kGapBetweenWindowsBottom = 10; | 145 const int kGapBetweenWindowsBottom = 10; |
152 const int kGapBetweenWindowsTop = 5; | 146 const int kGapBetweenWindowsTop = 5; |
153 | 147 |
154 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); | 148 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); |
155 iter != windows.rend(); | 149 iter != windows.rend(); |
156 ++iter) { | 150 ++iter, ++index) { |
157 aura::Window* window = (*iter); | 151 aura::Window* window = (*iter); |
158 if (!ShouldShowWindowInOverviewMode(window)) | |
159 continue; | |
160 | 152 |
161 gfx::Transform top_transform; | 153 gfx::Transform top_transform; |
162 int top = (window_count - index - 1) * kGapBetweenWindowsTop; | 154 int top = (window_count - index - 1) * kGapBetweenWindowsTop; |
163 float x_translate = container_size.width() * (1 - kMinScale) / 2.; | 155 float x_translate = container_size.width() * (1 - kMinScale) / 2.; |
164 top_transform.Translate(x_translate, top); | 156 top_transform.Translate(x_translate, top); |
165 top_transform.Scale(kMinScale, kMinScale); | 157 top_transform.Scale(kMinScale, kMinScale); |
166 | 158 |
167 gfx::Transform bottom_transform; | 159 gfx::Transform bottom_transform; |
168 int bottom = GetScrollableHeight() - (index * kGapBetweenWindowsBottom); | 160 int bottom = GetScrollableHeight() - (index * kGapBetweenWindowsBottom); |
169 x_translate = container_size.width() * (1 - kMaxScale) / 2.; | 161 x_translate = container_size.width() * (1 - kMaxScale) / 2.; |
170 bottom_transform.Translate(x_translate, bottom - window->bounds().y()); | 162 bottom_transform.Translate(x_translate, bottom - window->bounds().y()); |
171 bottom_transform.Scale(kMaxScale, kMaxScale); | 163 bottom_transform.Scale(kMaxScale, kMaxScale); |
172 | 164 |
173 WindowOverviewState* state = new WindowOverviewState; | 165 WindowOverviewState* state = new WindowOverviewState; |
174 state->top = top_transform; | 166 state->top = top_transform; |
175 state->bottom = bottom_transform; | 167 state->bottom = bottom_transform; |
176 state->progress = 0.f; | 168 state->progress = 0.f; |
177 window->SetProperty(kWindowOverviewState, state); | 169 window->SetProperty(kWindowOverviewState, state); |
178 wm::SetShadowType(window, wm::SHADOW_TYPE_RECTANGULAR_ALWAYS_ACTIVE); | 170 wm::SetShadowType(window, wm::SHADOW_TYPE_RECTANGULAR_ALWAYS_ACTIVE); |
179 | |
180 index++; | |
181 } | 171 } |
182 } | 172 } |
183 | 173 |
184 // Sets the initial position for the windows for the overview mode. | 174 // Sets the initial position for the windows for the overview mode. |
185 void SetInitialWindowStates() { | 175 void SetInitialWindowStates() { |
| 176 aura::Window::Windows windows = window_list_provider_->GetWindowList(); |
| 177 size_t window_count = windows.size(); |
186 // The initial overview state of the topmost three windows. | 178 // The initial overview state of the topmost three windows. |
187 const float kInitialProgress[] = { 0.5f, 0.05f, 0.01f }; | 179 const float kInitialProgress[] = { 0.5f, 0.05f, 0.01f }; |
188 size_t index = 0; | 180 for (size_t i = 0; i < window_count; ++i) { |
189 const aura::Window::Windows& windows = container_->children(); | |
190 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); | |
191 iter != windows.rend(); | |
192 ++iter) { | |
193 aura::Window* window = (*iter); | |
194 if (!window->GetProperty(kWindowOverviewState)) | |
195 continue; | |
196 | |
197 float progress = 0.f; | 181 float progress = 0.f; |
198 if (index < arraysize(kInitialProgress)) | 182 aura::Window* window = windows[window_count - 1 - i]; |
199 progress = kInitialProgress[index]; | 183 if (i < arraysize(kInitialProgress)) |
| 184 progress = kInitialProgress[i]; |
200 | 185 |
201 scoped_refptr<ui::LayerAnimator> animator = | 186 scoped_refptr<ui::LayerAnimator> animator = |
202 window->layer()->GetAnimator(); | 187 window->layer()->GetAnimator(); |
203 | 188 |
204 // Unset any in-progress animation. | 189 // Unset any in-progress animation. |
205 { | 190 { |
206 ui::ScopedLayerAnimationSettings settings(animator); | 191 ui::ScopedLayerAnimationSettings settings(animator); |
207 settings.SetPreemptionStrategy( | 192 settings.SetPreemptionStrategy( |
208 ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET); | 193 ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET); |
209 window->Show(); | 194 window->Show(); |
210 window->SetTransform(gfx::Transform()); | 195 window->SetTransform(gfx::Transform()); |
211 } | 196 } |
212 // Setup the animation. | 197 // Setup the animation. |
213 { | 198 { |
214 ui::ScopedLayerAnimationSettings settings(animator); | 199 ui::ScopedLayerAnimationSettings settings(animator); |
215 settings.SetPreemptionStrategy( | 200 settings.SetPreemptionStrategy( |
216 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 201 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
217 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250)); | 202 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250)); |
218 SetWindowProgress(window, progress); | 203 SetWindowProgress(window, progress); |
219 } | 204 } |
220 index++; | |
221 } | 205 } |
222 } | 206 } |
223 | 207 |
224 aura::Window* SelectWindowAt(ui::LocatedEvent* event) { | 208 aura::Window* SelectWindowAt(ui::LocatedEvent* event) { |
225 CHECK_EQ(container_, event->target()); | 209 CHECK_EQ(container_, event->target()); |
226 // Find the old targeter to find the target of the event. | 210 // Find the old targeter to find the target of the event. |
227 ui::EventTarget* window = container_; | 211 ui::EventTarget* window = container_; |
228 ui::EventTargeter* targeter = scoped_targeter_->old_targeter(); | 212 ui::EventTargeter* targeter = scoped_targeter_->old_targeter(); |
229 while (!targeter && window->GetParentTarget()) { | 213 while (!targeter && window->GetParentTarget()) { |
230 window = window->GetParentTarget(); | 214 window = window->GetParentTarget(); |
231 targeter = window->GetEventTargeter(); | 215 targeter = window->GetEventTargeter(); |
232 } | 216 } |
233 if (!targeter) | 217 if (!targeter) |
234 return NULL; | 218 return NULL; |
235 aura::Window* target = static_cast<aura::Window*>( | 219 aura::Window* target = static_cast<aura::Window*>( |
236 targeter->FindTargetForLocatedEvent(container_, event)); | 220 targeter->FindTargetForLocatedEvent(container_, event)); |
237 while (target && target->parent() != container_) | 221 while (target && target->parent() != container_) |
238 target = target->parent(); | 222 target = target->parent(); |
239 return target; | 223 return target; |
240 } | 224 } |
241 | 225 |
242 // Scroll the window list by |delta_y| amount. |delta_y| is negative when | 226 // Scroll the window list by |delta_y| amount. |delta_y| is negative when |
243 // scrolling up; and positive when scrolling down. | 227 // scrolling up; and positive when scrolling down. |
244 void DoScroll(float delta_y) { | 228 void DoScroll(float delta_y) { |
245 const float kEpsilon = 1e-3f; | 229 const float kEpsilon = 1e-3f; |
246 float delta_y_p = std::abs(delta_y) / GetScrollableHeight(); | 230 float delta_y_p = std::abs(delta_y) / GetScrollableHeight(); |
247 const aura::Window::Windows& windows = container_->children(); | 231 aura::Window::Windows windows = window_list_provider_->GetWindowList(); |
248 if (delta_y < 0) { | 232 if (delta_y < 0) { |
249 // Scroll up. Start with the top-most (i.e. behind-most in terms of | 233 // Scroll up. Start with the top-most (i.e. behind-most in terms of |
250 // z-index) window, and try to scroll them up. | 234 // z-index) window, and try to scroll them up. |
251 for (aura::Window::Windows::const_iterator iter = windows.begin(); | 235 for (aura::Window::Windows::const_iterator iter = windows.begin(); |
252 delta_y_p > kEpsilon && iter != windows.end(); | 236 delta_y_p > kEpsilon && iter != windows.end(); |
253 ++iter) { | 237 ++iter) { |
254 aura::Window* window = (*iter); | 238 aura::Window* window = (*iter); |
255 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); | 239 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); |
256 if (!state) | |
257 continue; | |
258 if (state->progress > kEpsilon) { | 240 if (state->progress > kEpsilon) { |
259 // It is possible to scroll |window| up. Scroll it up, and update | 241 // It is possible to scroll |window| up. Scroll it up, and update |
260 // |delta_y_p| for the next window. | 242 // |delta_y_p| for the next window. |
261 float apply = delta_y_p * state->progress; | 243 float apply = delta_y_p * state->progress; |
262 SetWindowProgress(window, std::max(0.f, state->progress - apply * 3)); | 244 SetWindowProgress(window, std::max(0.f, state->progress - apply * 3)); |
263 delta_y_p -= apply; | 245 delta_y_p -= apply; |
264 } | 246 } |
265 } | 247 } |
266 } else { | 248 } else { |
267 // Scroll down. Start with the bottom-most (i.e. front-most in terms of | 249 // Scroll down. Start with the bottom-most (i.e. front-most in terms of |
268 // z-index) window, and try to scroll them down. | 250 // z-index) window, and try to scroll them down. |
269 for (aura::Window::Windows::const_reverse_iterator iter = | 251 aura::Window::Windows::const_reverse_iterator iter; |
270 windows.rbegin(); | 252 for (iter = windows.rbegin(); |
271 delta_y_p > kEpsilon && iter != windows.rend(); | 253 delta_y_p > kEpsilon && iter != windows.rend(); |
272 ++iter) { | 254 ++iter) { |
273 aura::Window* window = (*iter); | 255 aura::Window* window = (*iter); |
274 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); | 256 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); |
275 if (!state) | |
276 continue; | |
277 if (1.f - state->progress > kEpsilon) { | 257 if (1.f - state->progress > kEpsilon) { |
278 // It is possible to scroll |window| down. Scroll it down, and update | 258 // It is possible to scroll |window| down. Scroll it down, and update |
279 // |delta_y_p| for the next window. | 259 // |delta_y_p| for the next window. |
280 SetWindowProgress(window, std::min(1.f, state->progress + delta_y_p)); | 260 SetWindowProgress(window, std::min(1.f, state->progress + delta_y_p)); |
281 delta_y_p /= 2.f; | 261 delta_y_p /= 2.f; |
282 } | 262 } |
283 } | 263 } |
284 } | 264 } |
285 } | 265 } |
286 | 266 |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 } | 462 } |
483 } | 463 } |
484 | 464 |
485 const int kMinDistanceForDismissal = 300; | 465 const int kMinDistanceForDismissal = 300; |
486 const float kMinScale = 0.6f; | 466 const float kMinScale = 0.6f; |
487 const float kMaxScale = 0.95f; | 467 const float kMaxScale = 0.95f; |
488 const float kMaxOpacity = 1.0f; | 468 const float kMaxOpacity = 1.0f; |
489 const float kMinOpacity = 0.2f; | 469 const float kMinOpacity = 0.2f; |
490 | 470 |
491 aura::Window* container_; | 471 aura::Window* container_; |
| 472 // Provider of the stack of windows to show in the overview mode. Not owned. |
| 473 const WindowListProvider* window_list_provider_; |
492 WindowOverviewModeDelegate* delegate_; | 474 WindowOverviewModeDelegate* delegate_; |
493 scoped_ptr<aura::ScopedWindowTargeter> scoped_targeter_; | 475 scoped_ptr<aura::ScopedWindowTargeter> scoped_targeter_; |
494 scoped_ptr<ui::FlingCurve> fling_; | 476 scoped_ptr<ui::FlingCurve> fling_; |
495 | 477 |
496 aura::Window* dragged_window_; | 478 aura::Window* dragged_window_; |
497 gfx::Point dragged_start_location_; | 479 gfx::Point dragged_start_location_; |
498 | 480 |
499 DISALLOW_COPY_AND_ASSIGN(WindowOverviewModeImpl); | 481 DISALLOW_COPY_AND_ASSIGN(WindowOverviewModeImpl); |
500 }; | 482 }; |
501 | 483 |
502 } // namespace | 484 } // namespace |
503 | 485 |
504 // static | 486 // static |
505 scoped_ptr<WindowOverviewMode> WindowOverviewMode::Create( | 487 scoped_ptr<WindowOverviewMode> WindowOverviewMode::Create( |
506 aura::Window* container, | 488 aura::Window* container, |
| 489 const WindowListProvider* window_list_provider, |
507 WindowOverviewModeDelegate* delegate) { | 490 WindowOverviewModeDelegate* delegate) { |
508 return scoped_ptr<WindowOverviewMode>( | 491 return scoped_ptr<WindowOverviewMode>( |
509 new WindowOverviewModeImpl(container, delegate)); | 492 new WindowOverviewModeImpl(container, window_list_provider, delegate)); |
510 } | 493 } |
511 | 494 |
512 } // namespace athena | 495 } // namespace athena |
OLD | NEW |