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

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

Issue 420603011: Split Screen mode implementation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@split_view
Patch Set: Addressing review feedback. 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/wm/public/window_list_provider.h"
11 #include "base/macros.h" 12 #include "base/macros.h"
12 #include "ui/aura/scoped_window_targeter.h" 13 #include "ui/aura/scoped_window_targeter.h"
13 #include "ui/aura/window.h" 14 #include "ui/aura/window.h"
14 #include "ui/aura/window_delegate.h" 15 #include "ui/aura/window_delegate.h"
15 #include "ui/aura/window_property.h" 16 #include "ui/aura/window_property.h"
16 #include "ui/aura/window_targeter.h" 17 #include "ui/aura/window_targeter.h"
17 #include "ui/compositor/scoped_layer_animation_settings.h" 18 #include "ui/compositor/scoped_layer_animation_settings.h"
18 #include "ui/events/event_handler.h" 19 #include "ui/events/event_handler.h"
19 #include "ui/gfx/transform.h" 20 #include "ui/gfx/transform.h"
20 #include "ui/wm/core/shadow.h" 21 #include "ui/wm/core/shadow.h"
(...skipping 17 matching lines...) Expand all
38 } // namespace 39 } // namespace
39 40
40 DECLARE_WINDOW_PROPERTY_TYPE(WindowOverviewState*) 41 DECLARE_WINDOW_PROPERTY_TYPE(WindowOverviewState*)
41 DEFINE_OWNED_WINDOW_PROPERTY_KEY(WindowOverviewState, 42 DEFINE_OWNED_WINDOW_PROPERTY_KEY(WindowOverviewState,
42 kWindowOverviewState, 43 kWindowOverviewState,
43 NULL) 44 NULL)
44 namespace athena { 45 namespace athena {
45 46
46 namespace { 47 namespace {
47 48
48 bool ShouldShowWindowInOverviewMode(aura::Window* window) {
49 return window->type() == ui::wm::WINDOW_TYPE_NORMAL;
50 }
51
52 // Sets the progress-state for the window in the overview mode. 49 // Sets the progress-state for the window in the overview mode.
53 void SetWindowProgress(aura::Window* window, float progress) { 50 void SetWindowProgress(aura::Window* window, float progress) {
54 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); 51 WindowOverviewState* state = window->GetProperty(kWindowOverviewState);
55 gfx::Transform transform = 52 gfx::Transform transform =
56 gfx::Tween::TransformValueBetween(progress, state->top, state->bottom); 53 gfx::Tween::TransformValueBetween(progress, state->top, state->bottom);
57 window->SetTransform(transform); 54 window->SetTransform(transform);
58 state->progress = progress; 55 state->progress = progress;
59 } 56 }
60 57
61 // Resets the overview-related state for |window|. 58 // Resets the overview-related state for |window|.
(...skipping 27 matching lines...) Expand all
89 } 86 }
90 87
91 aura::Window* target_; 88 aura::Window* target_;
92 DISALLOW_COPY_AND_ASSIGN(StaticWindowTargeter); 89 DISALLOW_COPY_AND_ASSIGN(StaticWindowTargeter);
93 }; 90 };
94 91
95 class WindowOverviewModeImpl : public WindowOverviewMode, 92 class WindowOverviewModeImpl : public WindowOverviewMode,
96 public ui::EventHandler { 93 public ui::EventHandler {
97 public: 94 public:
98 WindowOverviewModeImpl(aura::Window* container, 95 WindowOverviewModeImpl(aura::Window* container,
96 const WindowListProvider* window_list_provider,
99 WindowOverviewModeDelegate* delegate) 97 WindowOverviewModeDelegate* delegate)
100 : container_(container), 98 : container_(container),
99 window_list_provider_(window_list_provider),
101 delegate_(delegate), 100 delegate_(delegate),
102 scoped_targeter_(new aura::ScopedWindowTargeter( 101 scoped_targeter_(new aura::ScopedWindowTargeter(
103 container, 102 container,
104 scoped_ptr<ui::EventTargeter>( 103 scoped_ptr<ui::EventTargeter>(
105 new StaticWindowTargeter(container)))) { 104 new StaticWindowTargeter(container)))) {
106 container_->set_target_handler(this); 105 container_->set_target_handler(this);
107 106
108 // Prepare the desired transforms for all the windows, and set the initial 107 // Prepare the desired transforms for all the windows, and set the initial
109 // state on the windows. 108 // state on the windows.
110 ComputeTerminalStatesForAllWindows(); 109 ComputeTerminalStatesForAllWindows();
111 SetInitialWindowStates(); 110 SetInitialWindowStates();
112 } 111 }
113 112
114 virtual ~WindowOverviewModeImpl() { 113 virtual ~WindowOverviewModeImpl() {
115 container_->set_target_handler(container_->delegate()); 114 container_->set_target_handler(container_->delegate());
116 115 aura::Window::Windows windows = window_list_provider_->GetWindowList();
117 const aura::Window::Windows& windows = container_->children(); 116 if (windows.empty())
118 for (aura::Window::Windows::const_iterator iter = windows.begin(); 117 return;
119 iter != windows.end(); 118 std::for_each(windows.begin(), windows.end(), &RestoreWindowState);
120 ++iter) {
121 if ((*iter)->GetProperty(kWindowOverviewState))
122 RestoreWindowState(*iter);
123 }
124 } 119 }
125 120
126 private: 121 private:
127 // Computes the transforms for all windows in both the topmost and bottom-most 122 // Computes the transforms for all windows in both the topmost and bottom-most
128 // positions. The transforms are set in the |kWindowOverviewState| property of 123 // positions. The transforms are set in the |kWindowOverviewState| property of
129 // the windows. 124 // the windows.
130 void ComputeTerminalStatesForAllWindows() { 125 void ComputeTerminalStatesForAllWindows() {
131 const aura::Window::Windows& windows = container_->children(); 126 aura::Window::Windows windows = window_list_provider_->GetWindowList();
132 size_t window_count = std::count_if(windows.begin(), windows.end(), 127 size_t window_count = windows.size();
133 ShouldShowWindowInOverviewMode);
134
135 size_t index = 0; 128 size_t index = 0;
136 const gfx::Size container_size = container_->bounds().size(); 129 const gfx::Size container_size = container_->bounds().size();
137 130
138 const int kGapBetweenWindowsBottom = 10; 131 const int kGapBetweenWindowsBottom = 10;
139 const int kGapBetweenWindowsTop = 5; 132 const int kGapBetweenWindowsTop = 5;
140 const float kMinScale = 0.6f; 133 const float kMinScale = 0.6f;
141 const float kMaxScale = 0.95f; 134 const float kMaxScale = 0.95f;
142 135
143 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); 136 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin();
144 iter != windows.rend(); 137 iter != windows.rend();
145 ++iter) { 138 ++iter, ++index) {
146 aura::Window* window = (*iter); 139 aura::Window* window = (*iter);
147 if (!ShouldShowWindowInOverviewMode(window))
148 continue;
149 140
150 gfx::Transform top_transform; 141 gfx::Transform top_transform;
151 int top = (window_count - index - 1) * kGapBetweenWindowsTop; 142 int top = (window_count - index - 1) * kGapBetweenWindowsTop;
152 float x_translate = container_size.width() * (1 - kMinScale) / 2.; 143 float x_translate = container_size.width() * (1 - kMinScale) / 2.;
153 top_transform.Translate(x_translate, top); 144 top_transform.Translate(x_translate, top);
154 top_transform.Scale(kMinScale, kMinScale); 145 top_transform.Scale(kMinScale, kMinScale);
155 146
156 gfx::Transform bottom_transform; 147 gfx::Transform bottom_transform;
157 int bottom = GetScrollableHeight() - (index * kGapBetweenWindowsBottom); 148 int bottom = GetScrollableHeight() - (index * kGapBetweenWindowsBottom);
158 x_translate = container_size.width() * (1 - kMaxScale) / 2.; 149 x_translate = container_size.width() * (1 - kMaxScale) / 2.;
159 bottom_transform.Translate(x_translate, bottom - window->bounds().y()); 150 bottom_transform.Translate(x_translate, bottom - window->bounds().y());
160 bottom_transform.Scale(kMaxScale, kMaxScale); 151 bottom_transform.Scale(kMaxScale, kMaxScale);
161 152
162 WindowOverviewState* state = new WindowOverviewState; 153 WindowOverviewState* state = new WindowOverviewState;
163 state->top = top_transform; 154 state->top = top_transform;
164 state->bottom = bottom_transform; 155 state->bottom = bottom_transform;
165 state->progress = 0.f; 156 state->progress = 0.f;
166 state->shadow = CreateShadowForWindow(window); 157 state->shadow = CreateShadowForWindow(window);
167 window->SetProperty(kWindowOverviewState, state); 158 window->SetProperty(kWindowOverviewState, state);
168
169 index++;
170 } 159 }
171 } 160 }
172 161
173 // Sets the initial position for the windows for the overview mode. 162 // Sets the initial position for the windows for the overview mode.
174 void SetInitialWindowStates() { 163 void SetInitialWindowStates() {
164 aura::Window::Windows windows = window_list_provider_->GetWindowList();
165 size_t window_count = windows.size();
175 // The initial overview state of the topmost three windows. 166 // The initial overview state of the topmost three windows.
176 const float kInitialProgress[] = { 0.5f, 0.05f, 0.01f }; 167 const float kInitialProgress[] = { 0.5f, 0.05f, 0.01f };
177 size_t index = 0; 168 for (size_t i = 0; i < window_count; ++i) {
178 const aura::Window::Windows& windows = container_->children();
179 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin();
180 iter != windows.rend();
181 ++iter) {
182 aura::Window* window = (*iter);
183 if (!window->GetProperty(kWindowOverviewState))
184 continue;
185
186 float progress = 0.f; 169 float progress = 0.f;
187 if (index < arraysize(kInitialProgress)) 170 aura::Window* window = windows[window_count - 1 - i];
188 progress = kInitialProgress[index]; 171 if (i < arraysize(kInitialProgress))
172 progress = kInitialProgress[i];
189 173
190 scoped_refptr<ui::LayerAnimator> animator = 174 scoped_refptr<ui::LayerAnimator> animator =
191 window->layer()->GetAnimator(); 175 window->layer()->GetAnimator();
192 176
193 // Unset any in-progress animation. 177 // Unset any in-progress animation.
194 { 178 {
195 ui::ScopedLayerAnimationSettings settings(animator); 179 ui::ScopedLayerAnimationSettings settings(animator);
196 settings.SetPreemptionStrategy( 180 settings.SetPreemptionStrategy(
197 ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET); 181 ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET);
198 window->Show(); 182 window->Show();
199 window->SetTransform(gfx::Transform()); 183 window->SetTransform(gfx::Transform());
200 } 184 }
201 // Setup the animation. 185 // Setup the animation.
202 { 186 {
203 ui::ScopedLayerAnimationSettings settings(animator); 187 ui::ScopedLayerAnimationSettings settings(animator);
204 settings.SetPreemptionStrategy( 188 settings.SetPreemptionStrategy(
205 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); 189 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
206 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250)); 190 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250));
207 SetWindowProgress(window, progress); 191 SetWindowProgress(window, progress);
208 } 192 }
209 index++;
210 } 193 }
211 } 194 }
212 195
213 scoped_ptr<wm::Shadow> CreateShadowForWindow(aura::Window* window) { 196 scoped_ptr<wm::Shadow> CreateShadowForWindow(aura::Window* window) {
214 scoped_ptr<wm::Shadow> shadow(new wm::Shadow()); 197 scoped_ptr<wm::Shadow> shadow(new wm::Shadow());
215 shadow->Init(wm::Shadow::STYLE_ACTIVE); 198 shadow->Init(wm::Shadow::STYLE_ACTIVE);
216 shadow->SetContentBounds(gfx::Rect(window->bounds().size())); 199 shadow->SetContentBounds(gfx::Rect(container_->bounds().size()));
217 shadow->layer()->SetVisible(true); 200 shadow->layer()->SetVisible(true);
218 window->layer()->Add(shadow->layer()); 201 window->layer()->Add(shadow->layer());
219 return shadow.Pass(); 202 return shadow.Pass();
220 } 203 }
221 204
222 aura::Window* SelectWindowAt(ui::LocatedEvent* event) { 205 aura::Window* SelectWindowAt(ui::LocatedEvent* event) {
223 CHECK_EQ(container_, event->target()); 206 CHECK_EQ(container_, event->target());
224 // Find the old targeter to find the target of the event. 207 // Find the old targeter to find the target of the event.
225 ui::EventTarget* window = container_; 208 ui::EventTarget* window = container_;
226 ui::EventTargeter* targeter = scoped_targeter_->old_targeter(); 209 ui::EventTargeter* targeter = scoped_targeter_->old_targeter();
227 while (!targeter && window->GetParentTarget()) { 210 while (!targeter && window->GetParentTarget()) {
228 window = window->GetParentTarget(); 211 window = window->GetParentTarget();
229 targeter = window->GetEventTargeter(); 212 targeter = window->GetEventTargeter();
230 } 213 }
231 if (!targeter) 214 if (!targeter)
232 return NULL; 215 return NULL;
233 aura::Window* target = static_cast<aura::Window*>( 216 aura::Window* target = static_cast<aura::Window*>(
234 targeter->FindTargetForLocatedEvent(container_, event)); 217 targeter->FindTargetForLocatedEvent(container_, event));
235 while (target && target->parent() != container_) 218 while (target && target->parent() != container_)
236 target = target->parent(); 219 target = target->parent();
237 return target; 220 return target;
238 } 221 }
239 222
240 // Scroll the window list by |delta_y| amount. |delta_y| is negative when 223 // Scroll the window list by |delta_y| amount. |delta_y| is negative when
241 // scrolling up; and positive when scrolling down. 224 // scrolling up; and positive when scrolling down.
242 void DoScroll(float delta_y) { 225 void DoScroll(float delta_y) {
243 const float kEpsilon = 1e-3f; 226 const float kEpsilon = 1e-3f;
244 float delta_y_p = std::abs(delta_y) / GetScrollableHeight(); 227 float delta_y_p = std::abs(delta_y) / GetScrollableHeight();
245 const aura::Window::Windows& windows = container_->children(); 228 aura::Window::Windows windows = window_list_provider_->GetWindowList();
246 if (delta_y < 0) { 229 if (delta_y < 0) {
247 // Scroll up. Start with the top-most (i.e. behind-most in terms of 230 // Scroll up. Start with the top-most (i.e. behind-most in terms of
248 // z-index) window, and try to scroll them up. 231 // z-index) window, and try to scroll them up.
249 for (aura::Window::Windows::const_iterator iter = windows.begin(); 232 for (aura::Window::Windows::const_iterator iter = windows.begin();
250 delta_y_p > kEpsilon && iter != windows.end(); 233 delta_y_p > kEpsilon && iter != windows.end();
251 ++iter) { 234 ++iter) {
252 aura::Window* window = (*iter); 235 aura::Window* window = (*iter);
253 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); 236 WindowOverviewState* state = window->GetProperty(kWindowOverviewState);
254 if (!state)
255 continue;
256 if (state->progress > kEpsilon) { 237 if (state->progress > kEpsilon) {
257 // It is possible to scroll |window| up. Scroll it up, and update 238 // It is possible to scroll |window| up. Scroll it up, and update
258 // |delta_y_p| for the next window. 239 // |delta_y_p| for the next window.
259 float apply = delta_y_p * state->progress; 240 float apply = delta_y_p * state->progress;
260 SetWindowProgress(window, std::max(0.f, state->progress - apply * 3)); 241 SetWindowProgress(window, std::max(0.f, state->progress - apply * 3));
261 delta_y_p -= apply; 242 delta_y_p -= apply;
262 } 243 }
263 } 244 }
264 } else { 245 } else {
265 // Scroll down. Start with the bottom-most (i.e. front-most in terms of 246 // Scroll down. Start with the bottom-most (i.e. front-most in terms of
266 // z-index) window, and try to scroll them down. 247 // z-index) window, and try to scroll them down.
267 for (aura::Window::Windows::const_reverse_iterator iter = 248 aura::Window::Windows::const_reverse_iterator iter;
268 windows.rbegin(); 249 for (iter = windows.rbegin();
269 delta_y_p > kEpsilon && iter != windows.rend(); 250 delta_y_p > kEpsilon && iter != windows.rend();
270 ++iter) { 251 ++iter) {
271 aura::Window* window = (*iter); 252 aura::Window* window = (*iter);
272 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); 253 WindowOverviewState* state = window->GetProperty(kWindowOverviewState);
273 if (!state)
274 continue;
275 if (1.f - state->progress > kEpsilon) { 254 if (1.f - state->progress > kEpsilon) {
276 // It is possible to scroll |window| down. Scroll it down, and update 255 // It is possible to scroll |window| down. Scroll it down, and update
277 // |delta_y_p| for the next window. 256 // |delta_y_p| for the next window.
278 SetWindowProgress(window, std::min(1.f, state->progress + delta_y_p)); 257 SetWindowProgress(window, std::min(1.f, state->progress + delta_y_p));
279 delta_y_p /= 2.f; 258 delta_y_p /= 2.f;
280 } 259 }
281 } 260 }
282 } 261 }
283 } 262 }
284 263
(...skipping 26 matching lines...) Expand all
311 if (select) { 290 if (select) {
312 gesture->SetHandled(); 291 gesture->SetHandled();
313 delegate_->OnSelectWindow(select); 292 delegate_->OnSelectWindow(select);
314 } 293 }
315 } else if (gesture->type() == ui::ET_GESTURE_SCROLL_UPDATE) { 294 } else if (gesture->type() == ui::ET_GESTURE_SCROLL_UPDATE) {
316 DoScroll(gesture->details().scroll_y()); 295 DoScroll(gesture->details().scroll_y());
317 } 296 }
318 } 297 }
319 298
320 aura::Window* container_; 299 aura::Window* container_;
300 // Provider of the stack of windows to show in the overview mode. Not owned.
301 const WindowListProvider* window_list_provider_;
321 WindowOverviewModeDelegate* delegate_; 302 WindowOverviewModeDelegate* delegate_;
322 scoped_ptr<aura::ScopedWindowTargeter> scoped_targeter_; 303 scoped_ptr<aura::ScopedWindowTargeter> scoped_targeter_;
323 304
324 DISALLOW_COPY_AND_ASSIGN(WindowOverviewModeImpl); 305 DISALLOW_COPY_AND_ASSIGN(WindowOverviewModeImpl);
325 }; 306 };
326 307
327 } // namespace 308 } // namespace
328 309
329 // static 310 // static
330 scoped_ptr<WindowOverviewMode> WindowOverviewMode::Create( 311 scoped_ptr<WindowOverviewMode> WindowOverviewMode::Create(
331 aura::Window* container, 312 aura::Window* container,
313 const WindowListProvider* window_list_provider,
332 WindowOverviewModeDelegate* delegate) { 314 WindowOverviewModeDelegate* delegate) {
333 return scoped_ptr<WindowOverviewMode>( 315 return scoped_ptr<WindowOverviewMode>(
334 new WindowOverviewModeImpl(container, delegate)); 316 new WindowOverviewModeImpl(container, window_list_provider, delegate));
335 } 317 }
336 318
337 } // namespace athena 319 } // 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