Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(49)

Side by Side Diff: athena/wm/window_overview_mode.cc

Issue 461503002: Split Screen mode implementation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@coordinate_conversion
Patch Set: Rebase Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 23 matching lines...) Expand all
45 } // namespace 46 } // namespace
46 47
47 DECLARE_WINDOW_PROPERTY_TYPE(WindowOverviewState*) 48 DECLARE_WINDOW_PROPERTY_TYPE(WindowOverviewState*)
48 DEFINE_OWNED_WINDOW_PROPERTY_KEY(WindowOverviewState, 49 DEFINE_OWNED_WINDOW_PROPERTY_KEY(WindowOverviewState,
49 kWindowOverviewState, 50 kWindowOverviewState,
50 NULL) 51 NULL)
51 namespace athena { 52 namespace athena {
52 53
53 namespace { 54 namespace {
54 55
55 bool ShouldShowWindowInOverviewMode(aura::Window* window) {
56 return window->type() == ui::wm::WINDOW_TYPE_NORMAL;
57 }
58
59 // Gets the transform for the window in its current state. 56 // Gets the transform for the window in its current state.
60 gfx::Transform GetTransformForState(WindowOverviewState* state) { 57 gfx::Transform GetTransformForState(WindowOverviewState* state) {
61 return gfx::Tween::TransformValueBetween(state->progress, 58 return gfx::Tween::TransformValueBetween(state->progress,
62 state->top, 59 state->top,
63 state->bottom); 60 state->bottom);
64 } 61 }
65 62
66 // Sets the progress-state for the window in the overview mode. 63 // Sets the progress-state for the window in the overview mode.
67 void SetWindowProgress(aura::Window* window, float progress) { 64 void SetWindowProgress(aura::Window* window, float progress) {
68 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); 65 WindowOverviewState* state = window->GetProperty(kWindowOverviewState);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 99
103 aura::Window* target_; 100 aura::Window* target_;
104 DISALLOW_COPY_AND_ASSIGN(StaticWindowTargeter); 101 DISALLOW_COPY_AND_ASSIGN(StaticWindowTargeter);
105 }; 102 };
106 103
107 class WindowOverviewModeImpl : public WindowOverviewMode, 104 class WindowOverviewModeImpl : public WindowOverviewMode,
108 public ui::EventHandler, 105 public ui::EventHandler,
109 public ui::CompositorAnimationObserver { 106 public ui::CompositorAnimationObserver {
110 public: 107 public:
111 WindowOverviewModeImpl(aura::Window* container, 108 WindowOverviewModeImpl(aura::Window* container,
109 const WindowListProvider* window_list_provider,
112 WindowOverviewModeDelegate* delegate) 110 WindowOverviewModeDelegate* delegate)
113 : container_(container), 111 : container_(container),
112 window_list_provider_(window_list_provider),
114 delegate_(delegate), 113 delegate_(delegate),
115 scoped_targeter_(new aura::ScopedWindowTargeter( 114 scoped_targeter_(new aura::ScopedWindowTargeter(
116 container, 115 container,
117 scoped_ptr<ui::EventTargeter>( 116 scoped_ptr<ui::EventTargeter>(
118 new StaticWindowTargeter(container)))), 117 new StaticWindowTargeter(container)))),
119 dragged_window_(NULL) { 118 dragged_window_(NULL) {
120 container_->set_target_handler(this); 119 container_->set_target_handler(this);
121 120
122 // Prepare the desired transforms for all the windows, and set the initial 121 // Prepare the desired transforms for all the windows, and set the initial
123 // state on the windows. 122 // state on the windows.
124 ComputeTerminalStatesForAllWindows(); 123 ComputeTerminalStatesForAllWindows();
125 SetInitialWindowStates(); 124 SetInitialWindowStates();
126 } 125 }
127 126
128 virtual ~WindowOverviewModeImpl() { 127 virtual ~WindowOverviewModeImpl() {
129 container_->set_target_handler(container_->delegate()); 128 container_->set_target_handler(container_->delegate());
130 RemoveAnimationObserver(); 129 RemoveAnimationObserver();
131 const aura::Window::Windows& windows = container_->children(); 130 aura::Window::Windows windows = window_list_provider_->GetWindowList();
132 for (aura::Window::Windows::const_iterator iter = windows.begin(); 131 if (windows.empty())
133 iter != windows.end(); 132 return;
134 ++iter) { 133 std::for_each(windows.begin(), windows.end(), &RestoreWindowState);
135 if ((*iter)->GetProperty(kWindowOverviewState))
136 RestoreWindowState(*iter);
137 }
138 } 134 }
139 135
140 private: 136 private:
141 // Computes the transforms for all windows in both the topmost and bottom-most 137 // Computes the transforms for all windows in both the topmost and bottom-most
142 // positions. The transforms are set in the |kWindowOverviewState| property of 138 // positions. The transforms are set in the |kWindowOverviewState| property of
143 // the windows. 139 // the windows.
144 void ComputeTerminalStatesForAllWindows() { 140 void ComputeTerminalStatesForAllWindows() {
145 const aura::Window::Windows& windows = container_->children(); 141 aura::Window::Windows windows = window_list_provider_->GetWindowList();
146 size_t window_count = std::count_if(windows.begin(), windows.end(), 142 size_t window_count = windows.size();
147 ShouldShowWindowInOverviewMode);
148
149 size_t index = 0; 143 size_t index = 0;
150 const gfx::Size container_size = container_->bounds().size(); 144 const gfx::Size container_size = container_->bounds().size();
151 145
152 const int kGapBetweenWindowsBottom = 10; 146 const int kGapBetweenWindowsBottom = 10;
153 const int kGapBetweenWindowsTop = 5; 147 const int kGapBetweenWindowsTop = 5;
154 148
155 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); 149 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin();
156 iter != windows.rend(); 150 iter != windows.rend();
157 ++iter) { 151 ++iter, ++index) {
158 aura::Window* window = (*iter); 152 aura::Window* window = (*iter);
159 if (!ShouldShowWindowInOverviewMode(window))
160 continue;
161 153
162 gfx::Transform top_transform; 154 gfx::Transform top_transform;
163 int top = (window_count - index - 1) * kGapBetweenWindowsTop; 155 int top = (window_count - index - 1) * kGapBetweenWindowsTop;
164 float x_translate = container_size.width() * (1 - kMinScale) / 2.; 156 float x_translate = container_size.width() * (1 - kMinScale) / 2.;
165 top_transform.Translate(x_translate, top); 157 top_transform.Translate(x_translate, top);
166 top_transform.Scale(kMinScale, kMinScale); 158 top_transform.Scale(kMinScale, kMinScale);
167 159
168 gfx::Transform bottom_transform; 160 gfx::Transform bottom_transform;
169 int bottom = GetScrollableHeight() - (index * kGapBetweenWindowsBottom); 161 int bottom = GetScrollableHeight() - (index * kGapBetweenWindowsBottom);
170 x_translate = container_size.width() * (1 - kMaxScale) / 2.; 162 x_translate = container_size.width() * (1 - kMaxScale) / 2.;
171 bottom_transform.Translate(x_translate, bottom - window->bounds().y()); 163 bottom_transform.Translate(x_translate, bottom - window->bounds().y());
172 bottom_transform.Scale(kMaxScale, kMaxScale); 164 bottom_transform.Scale(kMaxScale, kMaxScale);
173 165
174 WindowOverviewState* state = new WindowOverviewState; 166 WindowOverviewState* state = new WindowOverviewState;
175 state->top = top_transform; 167 state->top = top_transform;
176 state->bottom = bottom_transform; 168 state->bottom = bottom_transform;
177 state->progress = 0.f; 169 state->progress = 0.f;
178 state->shadow = CreateShadowForWindow(window); 170 state->shadow = CreateShadowForWindow(window);
179 window->SetProperty(kWindowOverviewState, state); 171 window->SetProperty(kWindowOverviewState, state);
180
181 index++;
182 } 172 }
183 } 173 }
184 174
185 // Sets the initial position for the windows for the overview mode. 175 // Sets the initial position for the windows for the overview mode.
186 void SetInitialWindowStates() { 176 void SetInitialWindowStates() {
177 aura::Window::Windows windows = window_list_provider_->GetWindowList();
178 size_t window_count = windows.size();
187 // The initial overview state of the topmost three windows. 179 // The initial overview state of the topmost three windows.
188 const float kInitialProgress[] = { 0.5f, 0.05f, 0.01f }; 180 const float kInitialProgress[] = { 0.5f, 0.05f, 0.01f };
189 size_t index = 0; 181 for (size_t i = 0; i < window_count; ++i) {
190 const aura::Window::Windows& windows = container_->children();
191 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin();
192 iter != windows.rend();
193 ++iter) {
194 aura::Window* window = (*iter);
195 if (!window->GetProperty(kWindowOverviewState))
196 continue;
197
198 float progress = 0.f; 182 float progress = 0.f;
199 if (index < arraysize(kInitialProgress)) 183 aura::Window* window = windows[window_count - 1 - i];
200 progress = kInitialProgress[index]; 184 if (i < arraysize(kInitialProgress))
185 progress = kInitialProgress[i];
201 186
202 scoped_refptr<ui::LayerAnimator> animator = 187 scoped_refptr<ui::LayerAnimator> animator =
203 window->layer()->GetAnimator(); 188 window->layer()->GetAnimator();
204 189
205 // Unset any in-progress animation. 190 // Unset any in-progress animation.
206 { 191 {
207 ui::ScopedLayerAnimationSettings settings(animator); 192 ui::ScopedLayerAnimationSettings settings(animator);
208 settings.SetPreemptionStrategy( 193 settings.SetPreemptionStrategy(
209 ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET); 194 ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET);
210 window->Show(); 195 window->Show();
211 window->SetTransform(gfx::Transform()); 196 window->SetTransform(gfx::Transform());
212 } 197 }
213 // Setup the animation. 198 // Setup the animation.
214 { 199 {
215 ui::ScopedLayerAnimationSettings settings(animator); 200 ui::ScopedLayerAnimationSettings settings(animator);
216 settings.SetPreemptionStrategy( 201 settings.SetPreemptionStrategy(
217 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); 202 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
218 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250)); 203 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250));
219 SetWindowProgress(window, progress); 204 SetWindowProgress(window, progress);
220 } 205 }
221 index++;
222 } 206 }
223 } 207 }
224 208
225 scoped_ptr<wm::Shadow> CreateShadowForWindow(aura::Window* window) { 209 scoped_ptr<wm::Shadow> CreateShadowForWindow(aura::Window* window) {
226 scoped_ptr<wm::Shadow> shadow(new wm::Shadow()); 210 scoped_ptr<wm::Shadow> shadow(new wm::Shadow());
227 shadow->Init(wm::Shadow::STYLE_ACTIVE); 211 shadow->Init(wm::Shadow::STYLE_ACTIVE);
228 shadow->SetContentBounds(gfx::Rect(window->bounds().size())); 212 shadow->SetContentBounds(gfx::Rect(container_->bounds().size()));
229 shadow->layer()->SetVisible(true); 213 shadow->layer()->SetVisible(true);
230 window->layer()->Add(shadow->layer()); 214 window->layer()->Add(shadow->layer());
231 return shadow.Pass(); 215 return shadow.Pass();
232 } 216 }
233 217
234 aura::Window* SelectWindowAt(ui::LocatedEvent* event) { 218 aura::Window* SelectWindowAt(ui::LocatedEvent* event) {
235 CHECK_EQ(container_, event->target()); 219 CHECK_EQ(container_, event->target());
236 // Find the old targeter to find the target of the event. 220 // Find the old targeter to find the target of the event.
237 ui::EventTarget* window = container_; 221 ui::EventTarget* window = container_;
238 ui::EventTargeter* targeter = scoped_targeter_->old_targeter(); 222 ui::EventTargeter* targeter = scoped_targeter_->old_targeter();
239 while (!targeter && window->GetParentTarget()) { 223 while (!targeter && window->GetParentTarget()) {
240 window = window->GetParentTarget(); 224 window = window->GetParentTarget();
241 targeter = window->GetEventTargeter(); 225 targeter = window->GetEventTargeter();
242 } 226 }
243 if (!targeter) 227 if (!targeter)
244 return NULL; 228 return NULL;
245 aura::Window* target = static_cast<aura::Window*>( 229 aura::Window* target = static_cast<aura::Window*>(
246 targeter->FindTargetForLocatedEvent(container_, event)); 230 targeter->FindTargetForLocatedEvent(container_, event));
247 while (target && target->parent() != container_) 231 while (target && target->parent() != container_)
248 target = target->parent(); 232 target = target->parent();
249 return target; 233 return target;
250 } 234 }
251 235
252 // Scroll the window list by |delta_y| amount. |delta_y| is negative when 236 // Scroll the window list by |delta_y| amount. |delta_y| is negative when
253 // scrolling up; and positive when scrolling down. 237 // scrolling up; and positive when scrolling down.
254 void DoScroll(float delta_y) { 238 void DoScroll(float delta_y) {
255 const float kEpsilon = 1e-3f; 239 const float kEpsilon = 1e-3f;
256 float delta_y_p = std::abs(delta_y) / GetScrollableHeight(); 240 float delta_y_p = std::abs(delta_y) / GetScrollableHeight();
257 const aura::Window::Windows& windows = container_->children(); 241 aura::Window::Windows windows = window_list_provider_->GetWindowList();
258 if (delta_y < 0) { 242 if (delta_y < 0) {
259 // Scroll up. Start with the top-most (i.e. behind-most in terms of 243 // Scroll up. Start with the top-most (i.e. behind-most in terms of
260 // z-index) window, and try to scroll them up. 244 // z-index) window, and try to scroll them up.
261 for (aura::Window::Windows::const_iterator iter = windows.begin(); 245 for (aura::Window::Windows::const_iterator iter = windows.begin();
262 delta_y_p > kEpsilon && iter != windows.end(); 246 delta_y_p > kEpsilon && iter != windows.end();
263 ++iter) { 247 ++iter) {
264 aura::Window* window = (*iter); 248 aura::Window* window = (*iter);
265 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); 249 WindowOverviewState* state = window->GetProperty(kWindowOverviewState);
266 if (!state)
267 continue;
268 if (state->progress > kEpsilon) { 250 if (state->progress > kEpsilon) {
269 // It is possible to scroll |window| up. Scroll it up, and update 251 // It is possible to scroll |window| up. Scroll it up, and update
270 // |delta_y_p| for the next window. 252 // |delta_y_p| for the next window.
271 float apply = delta_y_p * state->progress; 253 float apply = delta_y_p * state->progress;
272 SetWindowProgress(window, std::max(0.f, state->progress - apply * 3)); 254 SetWindowProgress(window, std::max(0.f, state->progress - apply * 3));
273 delta_y_p -= apply; 255 delta_y_p -= apply;
274 } 256 }
275 } 257 }
276 } else { 258 } else {
277 // Scroll down. Start with the bottom-most (i.e. front-most in terms of 259 // Scroll down. Start with the bottom-most (i.e. front-most in terms of
278 // z-index) window, and try to scroll them down. 260 // z-index) window, and try to scroll them down.
279 for (aura::Window::Windows::const_reverse_iterator iter = 261 aura::Window::Windows::const_reverse_iterator iter;
280 windows.rbegin(); 262 for (iter = windows.rbegin();
281 delta_y_p > kEpsilon && iter != windows.rend(); 263 delta_y_p > kEpsilon && iter != windows.rend();
282 ++iter) { 264 ++iter) {
283 aura::Window* window = (*iter); 265 aura::Window* window = (*iter);
284 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); 266 WindowOverviewState* state = window->GetProperty(kWindowOverviewState);
285 if (!state)
286 continue;
287 if (1.f - state->progress > kEpsilon) { 267 if (1.f - state->progress > kEpsilon) {
288 // It is possible to scroll |window| down. Scroll it down, and update 268 // It is possible to scroll |window| down. Scroll it down, and update
289 // |delta_y_p| for the next window. 269 // |delta_y_p| for the next window.
290 SetWindowProgress(window, std::min(1.f, state->progress + delta_y_p)); 270 SetWindowProgress(window, std::min(1.f, state->progress + delta_y_p));
291 delta_y_p /= 2.f; 271 delta_y_p /= 2.f;
292 } 272 }
293 } 273 }
294 } 274 }
295 } 275 }
296 276
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 } 472 }
493 } 473 }
494 474
495 const int kMinDistanceForDismissal = 300; 475 const int kMinDistanceForDismissal = 300;
496 const float kMinScale = 0.6f; 476 const float kMinScale = 0.6f;
497 const float kMaxScale = 0.95f; 477 const float kMaxScale = 0.95f;
498 const float kMaxOpacity = 1.0f; 478 const float kMaxOpacity = 1.0f;
499 const float kMinOpacity = 0.2f; 479 const float kMinOpacity = 0.2f;
500 480
501 aura::Window* container_; 481 aura::Window* container_;
482 // Provider of the stack of windows to show in the overview mode. Not owned.
483 const WindowListProvider* window_list_provider_;
502 WindowOverviewModeDelegate* delegate_; 484 WindowOverviewModeDelegate* delegate_;
503 scoped_ptr<aura::ScopedWindowTargeter> scoped_targeter_; 485 scoped_ptr<aura::ScopedWindowTargeter> scoped_targeter_;
504 scoped_ptr<ui::FlingCurve> fling_; 486 scoped_ptr<ui::FlingCurve> fling_;
505 487
506 aura::Window* dragged_window_; 488 aura::Window* dragged_window_;
507 gfx::Point dragged_start_location_; 489 gfx::Point dragged_start_location_;
508 490
509 DISALLOW_COPY_AND_ASSIGN(WindowOverviewModeImpl); 491 DISALLOW_COPY_AND_ASSIGN(WindowOverviewModeImpl);
510 }; 492 };
511 493
512 } // namespace 494 } // namespace
513 495
514 // static 496 // static
515 scoped_ptr<WindowOverviewMode> WindowOverviewMode::Create( 497 scoped_ptr<WindowOverviewMode> WindowOverviewMode::Create(
516 aura::Window* container, 498 aura::Window* container,
499 const WindowListProvider* window_list_provider,
517 WindowOverviewModeDelegate* delegate) { 500 WindowOverviewModeDelegate* delegate) {
518 return scoped_ptr<WindowOverviewMode>( 501 return scoped_ptr<WindowOverviewMode>(
519 new WindowOverviewModeImpl(container, delegate)); 502 new WindowOverviewModeImpl(container, window_list_provider, delegate));
520 } 503 }
521 504
522 } // namespace athena 505 } // namespace athena
OLDNEW
« athena/wm/window_manager_impl.cc ('K') | « athena/wm/window_overview_mode.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698