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/overview_toolbar.h" | 11 #include "athena/wm/overview_toolbar.h" |
12 #include "athena/wm/public/window_list_provider.h" | 12 #include "athena/wm/public/window_list_provider.h" |
| 13 #include "athena/wm/split_view_controller.h" |
13 #include "base/bind.h" | 14 #include "base/bind.h" |
14 #include "base/macros.h" | 15 #include "base/macros.h" |
15 #include "ui/aura/scoped_window_targeter.h" | 16 #include "ui/aura/scoped_window_targeter.h" |
16 #include "ui/aura/window.h" | 17 #include "ui/aura/window.h" |
17 #include "ui/aura/window_delegate.h" | 18 #include "ui/aura/window_delegate.h" |
18 #include "ui/aura/window_property.h" | 19 #include "ui/aura/window_property.h" |
19 #include "ui/aura/window_targeter.h" | 20 #include "ui/aura/window_targeter.h" |
20 #include "ui/aura/window_tree_host.h" | 21 #include "ui/aura/window_tree_host.h" |
21 #include "ui/compositor/closure_animation_observer.h" | 22 #include "ui/compositor/closure_animation_observer.h" |
22 #include "ui/compositor/compositor.h" | 23 #include "ui/compositor/compositor.h" |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 aura::Window* target_; | 101 aura::Window* target_; |
101 DISALLOW_COPY_AND_ASSIGN(StaticWindowTargeter); | 102 DISALLOW_COPY_AND_ASSIGN(StaticWindowTargeter); |
102 }; | 103 }; |
103 | 104 |
104 class WindowOverviewModeImpl : public WindowOverviewMode, | 105 class WindowOverviewModeImpl : public WindowOverviewMode, |
105 public ui::EventHandler, | 106 public ui::EventHandler, |
106 public ui::CompositorAnimationObserver { | 107 public ui::CompositorAnimationObserver { |
107 public: | 108 public: |
108 WindowOverviewModeImpl(aura::Window* container, | 109 WindowOverviewModeImpl(aura::Window* container, |
109 const WindowListProvider* window_list_provider, | 110 const WindowListProvider* window_list_provider, |
| 111 SplitViewController* split_view_controller, |
110 WindowOverviewModeDelegate* delegate) | 112 WindowOverviewModeDelegate* delegate) |
111 : container_(container), | 113 : container_(container), |
112 window_list_provider_(window_list_provider), | 114 window_list_provider_(window_list_provider), |
113 delegate_(delegate), | 115 delegate_(delegate), |
114 scoped_targeter_(new aura::ScopedWindowTargeter( | 116 scoped_targeter_(new aura::ScopedWindowTargeter( |
115 container, | 117 container, |
116 scoped_ptr<ui::EventTargeter>( | 118 scoped_ptr<ui::EventTargeter>( |
117 new StaticWindowTargeter(container)))), | 119 new StaticWindowTargeter(container)))), |
118 dragged_window_(NULL) { | 120 dragged_window_(NULL), |
| 121 split_({false, NULL, NULL}) { |
| 122 CHECK(delegate_); |
119 container_->set_target_handler(this); | 123 container_->set_target_handler(this); |
120 | 124 |
| 125 split_.enabled = split_view_controller->IsSplitViewModeActive(); |
| 126 if (split_.enabled) { |
| 127 split_.left = split_view_controller->left_window(); |
| 128 split_.right = split_view_controller->right_window(); |
| 129 } |
| 130 |
121 // Prepare the desired transforms for all the windows, and set the initial | 131 // Prepare the desired transforms for all the windows, and set the initial |
122 // state on the windows. | 132 // state on the windows. |
123 ComputeTerminalStatesForAllWindows(); | 133 ComputeTerminalStatesForAllWindows(); |
124 SetInitialWindowStates(); | 134 SetInitialWindowStates(); |
125 } | 135 } |
126 | 136 |
127 virtual ~WindowOverviewModeImpl() { | 137 virtual ~WindowOverviewModeImpl() { |
128 container_->set_target_handler(container_->delegate()); | 138 container_->set_target_handler(container_->delegate()); |
129 RemoveAnimationObserver(); | 139 RemoveAnimationObserver(); |
130 aura::Window::Windows windows = window_list_provider_->GetWindowList(); | 140 aura::Window::Windows windows = window_list_provider_->GetWindowList(); |
(...skipping 11 matching lines...) Expand all Loading... |
142 size_t index = 0; | 152 size_t index = 0; |
143 | 153 |
144 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); | 154 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); |
145 iter != windows.rend(); | 155 iter != windows.rend(); |
146 ++iter, ++index) { | 156 ++iter, ++index) { |
147 aura::Window* window = (*iter); | 157 aura::Window* window = (*iter); |
148 wm::SetShadowType(window, wm::SHADOW_TYPE_RECTANGULAR_ALWAYS_ACTIVE); | 158 wm::SetShadowType(window, wm::SHADOW_TYPE_RECTANGULAR_ALWAYS_ACTIVE); |
149 | 159 |
150 WindowOverviewState* state = new WindowOverviewState; | 160 WindowOverviewState* state = new WindowOverviewState; |
151 window->SetProperty(kWindowOverviewState, state); | 161 window->SetProperty(kWindowOverviewState, state); |
| 162 if (split_.enabled && (window == split_.left || window == split_.right)) { |
| 163 // Do not let the left/right windows be scrolled. |
| 164 int x_translate = window->bounds().width() * (1 - kMaxScale) / 2; |
| 165 state->top.Translate(x_translate, window->bounds().height() * 0.65); |
| 166 state->top.Scale(kMaxScale, kMaxScale); |
| 167 state->bottom = state->top; |
| 168 --index; |
| 169 continue; |
| 170 } |
152 UpdateTerminalStateForWindowAtIndex(window, index, windows.size()); | 171 UpdateTerminalStateForWindowAtIndex(window, index, windows.size()); |
153 } | 172 } |
154 } | 173 } |
155 | 174 |
156 void UpdateTerminalStateForWindowAtIndex(aura::Window* window, | 175 void UpdateTerminalStateForWindowAtIndex(aura::Window* window, |
157 size_t index, | 176 size_t index, |
158 size_t window_count) { | 177 size_t window_count) { |
159 const int kGapBetweenWindowsBottom = 10; | 178 const int kGapBetweenWindowsBottom = 10; |
160 const int kGapBetweenWindowsTop = 5; | 179 const int kGapBetweenWindowsTop = 5; |
161 | 180 |
(...skipping 16 matching lines...) Expand all Loading... |
178 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); | 197 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); |
179 CHECK(state); | 198 CHECK(state); |
180 state->top = top_transform; | 199 state->top = top_transform; |
181 state->bottom = bottom_transform; | 200 state->bottom = bottom_transform; |
182 state->progress = 0.f; | 201 state->progress = 0.f; |
183 } | 202 } |
184 | 203 |
185 // Sets the initial position for the windows for the overview mode. | 204 // Sets the initial position for the windows for the overview mode. |
186 void SetInitialWindowStates() { | 205 void SetInitialWindowStates() { |
187 aura::Window::Windows windows = window_list_provider_->GetWindowList(); | 206 aura::Window::Windows windows = window_list_provider_->GetWindowList(); |
188 size_t window_count = windows.size(); | |
189 // The initial overview state of the topmost three windows. | 207 // The initial overview state of the topmost three windows. |
190 const float kInitialProgress[] = { 0.5f, 0.05f, 0.01f }; | 208 const float kInitialProgress[] = { 0.5f, 0.05f, 0.01f }; |
191 for (size_t i = 0; i < window_count; ++i) { | 209 size_t index = 0; |
| 210 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); |
| 211 iter != windows.rend(); |
| 212 ++iter) { |
192 float progress = 0.f; | 213 float progress = 0.f; |
193 aura::Window* window = windows[window_count - 1 - i]; | 214 aura::Window* window = *iter; |
194 if (i < arraysize(kInitialProgress)) | 215 if (split_.enabled && (window == split_.left || window == split_.right)) { |
195 progress = kInitialProgress[i]; | 216 progress = 1; |
| 217 } else { |
| 218 if (index < arraysize(kInitialProgress)) |
| 219 progress = kInitialProgress[index]; |
| 220 ++index; |
| 221 } |
196 | 222 |
197 scoped_refptr<ui::LayerAnimator> animator = | 223 scoped_refptr<ui::LayerAnimator> animator = |
198 window->layer()->GetAnimator(); | 224 window->layer()->GetAnimator(); |
199 | 225 |
200 // Unset any in-progress animation. | 226 // Unset any in-progress animation. |
201 animator->AbortAllAnimations(); | 227 animator->AbortAllAnimations(); |
202 window->Show(); | 228 window->Show(); |
203 window->SetTransform(gfx::Transform()); | 229 window->SetTransform(gfx::Transform()); |
204 // Setup the animation. | 230 // Setup the animation. |
205 { | 231 { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 // |delta_y_p| for the next window. | 292 // |delta_y_p| for the next window. |
267 SetWindowProgress(window, std::min(1.f, state->progress + delta_y_p)); | 293 SetWindowProgress(window, std::min(1.f, state->progress + delta_y_p)); |
268 delta_y_p /= 2.f; | 294 delta_y_p /= 2.f; |
269 } | 295 } |
270 } | 296 } |
271 } | 297 } |
272 } | 298 } |
273 | 299 |
274 int GetScrollableHeight() const { | 300 int GetScrollableHeight() const { |
275 const float kScrollableFraction = 0.65f; | 301 const float kScrollableFraction = 0.65f; |
276 return container_->bounds().height() * kScrollableFraction; | 302 const float kScrollableFractionInSplit = 0.5f; |
| 303 const float fraction = |
| 304 split_.enabled ? kScrollableFractionInSplit : kScrollableFraction; |
| 305 return container_->bounds().height() * fraction; |
277 } | 306 } |
278 | 307 |
279 void CreateFlingerFor(const ui::GestureEvent& event) { | 308 void CreateFlingerFor(const ui::GestureEvent& event) { |
280 gfx::Vector2dF velocity(event.details().velocity_x(), | 309 gfx::Vector2dF velocity(event.details().velocity_x(), |
281 event.details().velocity_y()); | 310 event.details().velocity_y()); |
282 fling_.reset(new ui::FlingCurve(velocity, gfx::FrameTime::Now())); | 311 fling_.reset(new ui::FlingCurve(velocity, gfx::FrameTime::Now())); |
283 } | 312 } |
284 | 313 |
285 void AddAnimationObserver() { | 314 void AddAnimationObserver() { |
286 ui::Compositor* compositor = container_->GetHost()->compositor(); | 315 ui::Compositor* compositor = container_->GetHost()->compositor(); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 OverviewToolbar::ActionType action = overview_toolbar_->current_action(); | 463 OverviewToolbar::ActionType action = overview_toolbar_->current_action(); |
435 overview_toolbar_.reset(); | 464 overview_toolbar_.reset(); |
436 if (action == OverviewToolbar::ACTION_TYPE_SPLIT) | 465 if (action == OverviewToolbar::ACTION_TYPE_SPLIT) |
437 delegate_->OnSplitViewMode(NULL, dragged_window_); | 466 delegate_->OnSplitViewMode(NULL, dragged_window_); |
438 else if (ShouldCloseDragWindow(gesture)) | 467 else if (ShouldCloseDragWindow(gesture)) |
439 CloseDragWindow(gesture); | 468 CloseDragWindow(gesture); |
440 else | 469 else |
441 RestoreDragWindow(); | 470 RestoreDragWindow(); |
442 } | 471 } |
443 | 472 |
| 473 void SelectWindow(aura::Window* window) { |
| 474 if (!split_.enabled) { |
| 475 delegate_->OnSelectWindow(window); |
| 476 } else { |
| 477 // If the selected window is one of the left/right windows, then keep the |
| 478 // current state. |
| 479 if (window == split_.left || window == split_.right) { |
| 480 delegate_->OnSplitViewMode(split_.left, split_.right); |
| 481 } else { |
| 482 delegate_->OnSelectWindow(window); |
| 483 } |
| 484 } |
| 485 } |
| 486 |
444 // ui::EventHandler: | 487 // ui::EventHandler: |
445 virtual void OnMouseEvent(ui::MouseEvent* mouse) OVERRIDE { | 488 virtual void OnMouseEvent(ui::MouseEvent* mouse) OVERRIDE { |
446 if (mouse->type() == ui::ET_MOUSE_PRESSED) { | 489 if (mouse->type() == ui::ET_MOUSE_PRESSED) { |
447 aura::Window* select = SelectWindowAt(mouse); | 490 aura::Window* select = SelectWindowAt(mouse); |
448 if (select) { | 491 if (select) { |
449 mouse->SetHandled(); | 492 mouse->SetHandled(); |
450 delegate_->OnSelectWindow(select); | 493 SelectWindow(select); |
451 } | 494 } |
452 } else if (mouse->type() == ui::ET_MOUSEWHEEL) { | 495 } else if (mouse->type() == ui::ET_MOUSEWHEEL) { |
453 DoScroll(static_cast<ui::MouseWheelEvent*>(mouse)->y_offset()); | 496 DoScroll(static_cast<ui::MouseWheelEvent*>(mouse)->y_offset()); |
454 } | 497 } |
455 } | 498 } |
456 | 499 |
457 virtual void OnScrollEvent(ui::ScrollEvent* scroll) OVERRIDE { | 500 virtual void OnScrollEvent(ui::ScrollEvent* scroll) OVERRIDE { |
458 if (scroll->type() == ui::ET_SCROLL) | 501 if (scroll->type() == ui::ET_SCROLL) |
459 DoScroll(scroll->y_offset()); | 502 DoScroll(scroll->y_offset()); |
460 } | 503 } |
461 | 504 |
462 virtual void OnGestureEvent(ui::GestureEvent* gesture) OVERRIDE { | 505 virtual void OnGestureEvent(ui::GestureEvent* gesture) OVERRIDE { |
463 if (gesture->type() == ui::ET_GESTURE_TAP) { | 506 if (gesture->type() == ui::ET_GESTURE_TAP) { |
464 aura::Window* select = SelectWindowAt(gesture); | 507 aura::Window* select = SelectWindowAt(gesture); |
465 if (select) { | 508 if (select) { |
466 gesture->SetHandled(); | 509 gesture->SetHandled(); |
467 delegate_->OnSelectWindow(select); | 510 SelectWindow(select); |
468 } | 511 } |
469 } else if (gesture->type() == ui::ET_GESTURE_SCROLL_BEGIN) { | 512 } else if (gesture->type() == ui::ET_GESTURE_SCROLL_BEGIN) { |
470 if (std::abs(gesture->details().scroll_x_hint()) > | 513 if (std::abs(gesture->details().scroll_x_hint()) > |
471 std::abs(gesture->details().scroll_y_hint()) * 2) { | 514 std::abs(gesture->details().scroll_y_hint()) * 2) { |
472 dragged_start_location_ = gesture->location(); | 515 dragged_start_location_ = gesture->location(); |
473 dragged_window_ = SelectWindowAt(gesture); | 516 dragged_window_ = SelectWindowAt(gesture); |
474 if (dragged_window_) | 517 if (dragged_window_) |
475 overview_toolbar_.reset(new OverviewToolbar(container_)); | 518 overview_toolbar_.reset(new OverviewToolbar(container_)); |
476 } | 519 } |
477 } else if (gesture->type() == ui::ET_GESTURE_SCROLL_UPDATE) { | 520 } else if (gesture->type() == ui::ET_GESTURE_SCROLL_UPDATE) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 if (scroll.IsZero()) { | 554 if (scroll.IsZero()) { |
512 fling_.reset(); | 555 fling_.reset(); |
513 RemoveAnimationObserver(); | 556 RemoveAnimationObserver(); |
514 } else { | 557 } else { |
515 DoScroll(scroll.y()); | 558 DoScroll(scroll.y()); |
516 } | 559 } |
517 } | 560 } |
518 | 561 |
519 const int kMinDistanceForDismissal = 300; | 562 const int kMinDistanceForDismissal = 300; |
520 const float kMinScale = 0.6f; | 563 const float kMinScale = 0.6f; |
521 const float kMaxScale = 0.95f; | 564 const float kMaxScale = 0.75f; |
522 const float kMaxOpacity = 1.0f; | 565 const float kMaxOpacity = 1.0f; |
523 const float kMinOpacity = 0.2f; | 566 const float kMinOpacity = 0.2f; |
524 | 567 |
525 aura::Window* container_; | 568 aura::Window* container_; |
526 // Provider of the stack of windows to show in the overview mode. Not owned. | 569 // Provider of the stack of windows to show in the overview mode. Not owned. |
527 const WindowListProvider* window_list_provider_; | 570 const WindowListProvider* window_list_provider_; |
528 WindowOverviewModeDelegate* delegate_; | 571 WindowOverviewModeDelegate* delegate_; |
529 scoped_ptr<aura::ScopedWindowTargeter> scoped_targeter_; | 572 scoped_ptr<aura::ScopedWindowTargeter> scoped_targeter_; |
530 scoped_ptr<ui::FlingCurve> fling_; | 573 scoped_ptr<ui::FlingCurve> fling_; |
531 | 574 |
532 aura::Window* dragged_window_; | 575 aura::Window* dragged_window_; |
533 gfx::Point dragged_start_location_; | 576 gfx::Point dragged_start_location_; |
534 scoped_ptr<OverviewToolbar> overview_toolbar_; | 577 scoped_ptr<OverviewToolbar> overview_toolbar_; |
535 | 578 |
| 579 struct { |
| 580 bool enabled; |
| 581 aura::Window* left; |
| 582 aura::Window* right; |
| 583 } split_; |
| 584 |
536 DISALLOW_COPY_AND_ASSIGN(WindowOverviewModeImpl); | 585 DISALLOW_COPY_AND_ASSIGN(WindowOverviewModeImpl); |
537 }; | 586 }; |
538 | 587 |
539 } // namespace | 588 } // namespace |
540 | 589 |
541 // static | 590 // static |
542 scoped_ptr<WindowOverviewMode> WindowOverviewMode::Create( | 591 scoped_ptr<WindowOverviewMode> WindowOverviewMode::Create( |
543 aura::Window* container, | 592 aura::Window* container, |
544 const WindowListProvider* window_list_provider, | 593 const WindowListProvider* window_list_provider, |
| 594 SplitViewController* split_view_controller, |
545 WindowOverviewModeDelegate* delegate) { | 595 WindowOverviewModeDelegate* delegate) { |
546 return scoped_ptr<WindowOverviewMode>( | 596 return scoped_ptr<WindowOverviewMode>( |
547 new WindowOverviewModeImpl(container, window_list_provider, delegate)); | 597 new WindowOverviewModeImpl(container, window_list_provider, |
| 598 split_view_controller, delegate)); |
548 } | 599 } |
549 | 600 |
550 } // namespace athena | 601 } // namespace athena |
OLD | NEW |