| 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 "athena/wm/split_view_controller.h" |
| 14 #include "base/bind.h" | 14 #include "base/bind.h" |
| 15 #include "base/macros.h" | 15 #include "base/macros.h" |
| 16 #include "ui/aura/scoped_window_targeter.h" | 16 #include "ui/aura/scoped_window_targeter.h" |
| 17 #include "ui/aura/window.h" | 17 #include "ui/aura/window.h" |
| 18 #include "ui/aura/window_delegate.h" | 18 #include "ui/aura/window_delegate.h" |
| 19 #include "ui/aura/window_property.h" | 19 #include "ui/aura/window_property.h" |
| 20 #include "ui/aura/window_targeter.h" | 20 #include "ui/aura/window_targeter.h" |
| 21 #include "ui/aura/window_tree_host.h" | 21 #include "ui/aura/window_tree_host.h" |
| 22 #include "ui/compositor/closure_animation_observer.h" | 22 #include "ui/compositor/closure_animation_observer.h" |
| 23 #include "ui/compositor/compositor.h" | 23 #include "ui/compositor/compositor.h" |
| 24 #include "ui/compositor/compositor_animation_observer.h" | 24 #include "ui/compositor/compositor_animation_observer.h" |
| 25 #include "ui/compositor/layer_animation_observer.h" |
| 25 #include "ui/compositor/scoped_layer_animation_settings.h" | 26 #include "ui/compositor/scoped_layer_animation_settings.h" |
| 26 #include "ui/events/event_handler.h" | 27 #include "ui/events/event_handler.h" |
| 27 #include "ui/events/gestures/fling_curve.h" | 28 #include "ui/events/gestures/fling_curve.h" |
| 28 #include "ui/gfx/frame_time.h" | 29 #include "ui/gfx/frame_time.h" |
| 29 #include "ui/gfx/transform.h" | 30 #include "ui/gfx/transform.h" |
| 30 #include "ui/wm/core/shadow_types.h" | 31 #include "ui/wm/core/shadow_types.h" |
| 31 #include "ui/wm/core/window_util.h" | 32 #include "ui/wm/core/window_util.h" |
| 32 | 33 |
| 33 namespace { | 34 namespace { |
| 34 | 35 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 61 state->bottom); | 62 state->bottom); |
| 62 } | 63 } |
| 63 | 64 |
| 64 // Sets the progress-state for the window in the overview mode. | 65 // Sets the progress-state for the window in the overview mode. |
| 65 void SetWindowProgress(aura::Window* window, float progress) { | 66 void SetWindowProgress(aura::Window* window, float progress) { |
| 66 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); | 67 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); |
| 67 state->progress = progress; | 68 state->progress = progress; |
| 68 window->SetTransform(GetTransformForState(state)); | 69 window->SetTransform(GetTransformForState(state)); |
| 69 } | 70 } |
| 70 | 71 |
| 71 void HideWindowIfNotVisible(aura::Window* window, | 72 void HideWindowIfTransparent(aura::Window* window) { |
| 72 SplitViewController* split_view_controller) { | 73 if (window->layer()->opacity() == 0.0f) { |
| 73 bool should_hide = true; | 74 window->Hide(); |
| 74 if (split_view_controller->IsSplitViewModeActive()) { | 75 window->layer()->SetOpacity(1.0f); |
| 75 should_hide = window != split_view_controller->left_window() && | |
| 76 window != split_view_controller->right_window(); | |
| 77 } else { | |
| 78 should_hide = !wm::IsActiveWindow(window); | |
| 79 } | 76 } |
| 80 if (should_hide) | |
| 81 window->Hide(); | |
| 82 } | 77 } |
| 83 | 78 |
| 84 // Resets the overview-related state for |window|. | 79 // Resets the overview-related state for |window|. |
| 85 void RestoreWindowState(aura::Window* window, | 80 void RestoreWindowState(aura::Window* window) { |
| 86 SplitViewController* split_view_controller) { | |
| 87 window->ClearProperty(kWindowOverviewState); | 81 window->ClearProperty(kWindowOverviewState); |
| 82 wm::SetShadowType(window, wm::SHADOW_TYPE_NONE); |
| 88 | 83 |
| 89 ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); | 84 { |
| 90 settings.SetPreemptionStrategy( | 85 ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); |
| 91 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 86 settings.SetPreemptionStrategy( |
| 92 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250)); | 87 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 88 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250)); |
| 89 window->SetTransform(gfx::Transform()); |
| 90 } |
| 93 | 91 |
| 94 settings.AddObserver(new ui::ClosureAnimationObserver( | 92 { |
| 95 base::Bind(&HideWindowIfNotVisible, window, split_view_controller))); | 93 ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); |
| 94 settings.SetPreemptionStrategy( |
| 95 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 96 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250)); |
| 97 settings.AddObserver(new ui::ClosureAnimationObserver( |
| 98 base::Bind(&HideWindowIfTransparent, base::Unretained(window)))); |
| 96 | 99 |
| 97 window->SetTransform(gfx::Transform()); | 100 // The window opacity may not be 1.0f if the user was dragging a window. |
| 101 window->layer()->SetOpacity(1.0f); |
| 98 | 102 |
| 99 // Reset the window opacity in case the user is dragging a window. | 103 // Ideally we would animate the window's visibility. However, animating the |
| 100 window->layer()->SetOpacity(1.0f); | 104 // window's visibility causes the web contents to hide before the animation |
| 101 | 105 // completes. Enqueue a zero duration opacity animation and hide |window| if |
| 102 wm::SetShadowType(window, wm::SHADOW_TYPE_NONE); | 106 // the opacity animation is not aborted. |
| 107 settings.SetPreemptionStrategy( |
| 108 ui::LayerAnimator::ENQUEUE_NEW_ANIMATION); |
| 109 settings.SetTransitionDuration(base::TimeDelta()); |
| 110 window->layer()->SetOpacity(0.0f); |
| 111 } |
| 103 } | 112 } |
| 104 | 113 |
| 105 gfx::RectF GetTransformedBounds(aura::Window* window) { | 114 gfx::RectF GetTransformedBounds(aura::Window* window) { |
| 106 gfx::Transform transform; | 115 gfx::Transform transform; |
| 107 gfx::RectF bounds = window->bounds(); | 116 gfx::RectF bounds = window->bounds(); |
| 108 transform.Translate(bounds.x(), bounds.y()); | 117 transform.Translate(bounds.x(), bounds.y()); |
| 109 transform.PreconcatTransform(window->layer()->transform()); | 118 transform.PreconcatTransform(window->layer()->transform()); |
| 110 transform.Translate(-bounds.x(), -bounds.y()); | 119 transform.Translate(-bounds.x(), -bounds.y()); |
| 111 transform.TransformRect(&bounds); | 120 transform.TransformRect(&bounds); |
| 112 return bounds; | 121 return bounds; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 SplitViewController* split_view_controller, | 169 SplitViewController* split_view_controller, |
| 161 WindowOverviewModeDelegate* delegate) | 170 WindowOverviewModeDelegate* delegate) |
| 162 : container_(container), | 171 : container_(container), |
| 163 window_list_provider_(window_list_provider), | 172 window_list_provider_(window_list_provider), |
| 164 split_view_controller_(split_view_controller), | 173 split_view_controller_(split_view_controller), |
| 165 delegate_(delegate), | 174 delegate_(delegate), |
| 166 scoped_targeter_(new aura::ScopedWindowTargeter( | 175 scoped_targeter_(new aura::ScopedWindowTargeter( |
| 167 container, | 176 container, |
| 168 scoped_ptr<ui::EventTargeter>( | 177 scoped_ptr<ui::EventTargeter>( |
| 169 new StaticWindowTargeter(container)))), | 178 new StaticWindowTargeter(container)))), |
| 170 dragged_window_(NULL) { | 179 dragged_window_(NULL), |
| 180 selected_window_(false) { |
| 171 CHECK(delegate_); | 181 CHECK(delegate_); |
| 172 container_->set_target_handler(this); | 182 container_->set_target_handler(this); |
| 173 | 183 |
| 174 // Prepare the desired transforms for all the windows, and set the initial | 184 // Prepare the desired transforms for all the windows, and set the initial |
| 175 // state on the windows. | 185 // state on the windows. |
| 176 ComputeTerminalStatesForAllWindows(); | 186 ComputeTerminalStatesForAllWindows(); |
| 177 SetInitialWindowStates(); | 187 SetInitialWindowStates(); |
| 178 } | 188 } |
| 179 | 189 |
| 180 virtual ~WindowOverviewModeImpl() { | 190 virtual ~WindowOverviewModeImpl() { |
| 181 container_->set_target_handler(container_->delegate()); | 191 container_->set_target_handler(container_->delegate()); |
| 182 RemoveAnimationObserver(); | 192 RemoveAnimationObserver(); |
| 193 |
| 194 // Abort any in progress animations. This can have significant consequences |
| 195 // such as deleting one of |windows|. |
| 183 aura::Window::Windows windows = window_list_provider_->GetWindowList(); | 196 aura::Window::Windows windows = window_list_provider_->GetWindowList(); |
| 197 for (size_t i = 0; i < windows.size(); ++i) |
| 198 windows[i]->layer()->GetAnimator()->AbortAllAnimations(); |
| 199 |
| 200 windows = window_list_provider_->GetWindowList(); |
| 184 if (windows.empty()) | 201 if (windows.empty()) |
| 185 return; | 202 return; |
| 186 std::for_each(windows.begin(), windows.end(), | 203 std::for_each(windows.begin(), windows.end(), &RestoreWindowState); |
| 187 std::bind2nd(std::ptr_fun(&RestoreWindowState), | 204 |
| 188 split_view_controller_)); | 205 if (!selected_window_) { |
| 206 aura::Window* to_select = *windows.rbegin(); |
| 207 SelectWindow(to_select, GetDefaultSplitType(to_select)); |
| 208 } |
| 189 } | 209 } |
| 190 | 210 |
| 191 private: | 211 private: |
| 192 // Computes the transforms for all windows in both the topmost and bottom-most | 212 // Computes the transforms for all windows in both the topmost and bottom-most |
| 193 // positions. The transforms are set in the |kWindowOverviewState| property of | 213 // positions. The transforms are set in the |kWindowOverviewState| property of |
| 194 // the windows. | 214 // the windows. |
| 195 void ComputeTerminalStatesForAllWindows() { | 215 void ComputeTerminalStatesForAllWindows() { |
| 196 aura::Window::Windows windows = window_list_provider_->GetWindowList(); | 216 aura::Window::Windows windows = window_list_provider_->GetWindowList(); |
| 197 size_t index = 0; | 217 size_t index = 0; |
| 198 | 218 |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 564 dragged_window_->layer()->SetOpacity(1.f); | 584 dragged_window_->layer()->SetOpacity(1.f); |
| 565 dragged_window_ = NULL; | 585 dragged_window_ = NULL; |
| 566 } | 586 } |
| 567 | 587 |
| 568 void EndDragWindow(const ui::GestureEvent& gesture) { | 588 void EndDragWindow(const ui::GestureEvent& gesture) { |
| 569 CHECK(dragged_window_); | 589 CHECK(dragged_window_); |
| 570 CHECK(overview_toolbar_); | 590 CHECK(overview_toolbar_); |
| 571 OverviewToolbar::ActionType action = overview_toolbar_->current_action(); | 591 OverviewToolbar::ActionType action = overview_toolbar_->current_action(); |
| 572 overview_toolbar_.reset(); | 592 overview_toolbar_.reset(); |
| 573 if (action == OverviewToolbar::ACTION_TYPE_SPLIT) { | 593 if (action == OverviewToolbar::ACTION_TYPE_SPLIT) { |
| 574 delegate_->OnSplitViewMode(NULL, dragged_window_); | 594 SelectWindow(dragged_window_, |
| 595 WindowOverviewModeDelegate::SPLIT_RIGHT); |
| 575 return; | 596 return; |
| 576 } | 597 } |
| 577 | 598 |
| 578 // If the window is dropped on one of the left/right windows in split-mode, | 599 // If the window is dropped on one of the left/right windows in split-mode, |
| 579 // then switch that window. | 600 // then switch that window. |
| 580 aura::Window* split_drop = GetSplitWindowDropTarget(gesture); | 601 aura::Window* split_drop = GetSplitWindowDropTarget(gesture); |
| 581 if (split_drop) { | 602 if (split_drop) { |
| 582 aura::Window* left = split_view_controller_->left_window(); | 603 WindowOverviewModeDelegate::SplitType split_type = |
| 583 aura::Window* right = split_view_controller_->right_window(); | 604 (split_view_controller_->left_window() == split_drop) |
| 584 if (left == split_drop) | 605 ? WindowOverviewModeDelegate::SPLIT_LEFT |
| 585 left = dragged_window_; | 606 : WindowOverviewModeDelegate::SPLIT_RIGHT; |
| 586 else | 607 SelectWindow(dragged_window_, split_type); |
| 587 right = dragged_window_; | |
| 588 delegate_->OnSplitViewMode(left, right); | |
| 589 return; | 608 return; |
| 590 } | 609 } |
| 591 | 610 |
| 592 if (ShouldCloseDragWindow(gesture)) | 611 if (ShouldCloseDragWindow(gesture)) |
| 593 CloseDragWindow(gesture); | 612 CloseDragWindow(gesture); |
| 594 else | 613 else |
| 595 RestoreDragWindow(); | 614 RestoreDragWindow(); |
| 596 } | 615 } |
| 597 | 616 |
| 598 void SelectWindow(aura::Window* window) { | 617 WindowOverviewModeDelegate::SplitType GetDefaultSplitType( |
| 599 if (!split_view_controller_->IsSplitViewModeActive()) { | 618 aura::Window* window) { |
| 600 delegate_->OnSelectWindow(window); | 619 if (split_view_controller_->IsSplitViewModeActive()) { |
| 601 } else { | 620 // Do not exit split view if the split view's left/right window was |
| 602 // If the selected window is one of the left/right windows, then keep the | 621 // selected. |
| 603 // current state. | 622 if (window == split_view_controller_->left_window()) |
| 604 if (window == split_view_controller_->left_window() || | 623 return WindowOverviewModeDelegate::SPLIT_LEFT; |
| 605 window == split_view_controller_->right_window()) { | 624 else if (window == split_view_controller_->right_window()) |
| 606 delegate_->OnSplitViewMode(split_view_controller_->left_window(), | 625 return WindowOverviewModeDelegate::SPLIT_RIGHT; |
| 607 split_view_controller_->right_window()); | |
| 608 } else { | |
| 609 delegate_->OnSelectWindow(window); | |
| 610 } | |
| 611 } | 626 } |
| 627 return WindowOverviewModeDelegate::SPLIT_NONE; |
| 628 } |
| 629 |
| 630 void SelectWindow(aura::Window* window, |
| 631 WindowOverviewModeDelegate::SplitType split_type) { |
| 632 selected_window_ = true; |
| 633 delegate_->OnSelectWindow(window, split_type); |
| 612 } | 634 } |
| 613 | 635 |
| 614 // ui::EventHandler: | 636 // ui::EventHandler: |
| 615 virtual void OnMouseEvent(ui::MouseEvent* mouse) OVERRIDE { | 637 virtual void OnMouseEvent(ui::MouseEvent* mouse) OVERRIDE { |
| 616 if (mouse->type() == ui::ET_MOUSE_PRESSED) { | 638 if (mouse->type() == ui::ET_MOUSE_PRESSED) { |
| 617 aura::Window* select = SelectWindowAt(mouse); | 639 aura::Window* select = SelectWindowAt(mouse); |
| 618 if (select) { | 640 if (select) { |
| 619 mouse->SetHandled(); | 641 mouse->SetHandled(); |
| 620 SelectWindow(select); | 642 SelectWindow(select, GetDefaultSplitType(select)); |
| 621 } | 643 } |
| 622 } else if (mouse->type() == ui::ET_MOUSEWHEEL) { | 644 } else if (mouse->type() == ui::ET_MOUSEWHEEL) { |
| 623 DoScroll(static_cast<ui::MouseWheelEvent*>(mouse)->y_offset()); | 645 DoScroll(static_cast<ui::MouseWheelEvent*>(mouse)->y_offset()); |
| 624 } | 646 } |
| 625 } | 647 } |
| 626 | 648 |
| 627 virtual void OnScrollEvent(ui::ScrollEvent* scroll) OVERRIDE { | 649 virtual void OnScrollEvent(ui::ScrollEvent* scroll) OVERRIDE { |
| 628 if (scroll->type() == ui::ET_SCROLL) | 650 if (scroll->type() == ui::ET_SCROLL) |
| 629 DoScroll(scroll->y_offset()); | 651 DoScroll(scroll->y_offset()); |
| 630 } | 652 } |
| 631 | 653 |
| 632 virtual void OnGestureEvent(ui::GestureEvent* gesture) OVERRIDE { | 654 virtual void OnGestureEvent(ui::GestureEvent* gesture) OVERRIDE { |
| 633 if (gesture->type() == ui::ET_GESTURE_TAP) { | 655 if (gesture->type() == ui::ET_GESTURE_TAP) { |
| 634 aura::Window* select = SelectWindowAt(gesture); | 656 aura::Window* select = SelectWindowAt(gesture); |
| 635 if (select) { | 657 if (select) { |
| 636 gesture->SetHandled(); | 658 gesture->SetHandled(); |
| 637 SelectWindow(select); | 659 SelectWindow(select, GetDefaultSplitType(select)); |
| 638 } | 660 } |
| 639 } else if (gesture->type() == ui::ET_GESTURE_SCROLL_BEGIN) { | 661 } else if (gesture->type() == ui::ET_GESTURE_SCROLL_BEGIN) { |
| 640 if (std::abs(gesture->details().scroll_x_hint()) > | 662 if (std::abs(gesture->details().scroll_x_hint()) > |
| 641 std::abs(gesture->details().scroll_y_hint()) * 2) { | 663 std::abs(gesture->details().scroll_y_hint()) * 2) { |
| 642 dragged_start_location_ = gesture->location(); | 664 dragged_start_location_ = gesture->location(); |
| 643 dragged_window_ = SelectWindowAt(gesture); | 665 dragged_window_ = SelectWindowAt(gesture); |
| 644 if (split_view_controller_->IsSplitViewModeActive() && | 666 if (split_view_controller_->IsSplitViewModeActive() && |
| 645 (dragged_window_ == split_view_controller_->left_window() || | 667 (dragged_window_ == split_view_controller_->left_window() || |
| 646 dragged_window_ == split_view_controller_->right_window())) { | 668 dragged_window_ == split_view_controller_->right_window())) { |
| 647 // TODO(sad): Allow closing the left/right window. Closing one of | 669 // TODO(sad): Allow closing the left/right window. Closing one of |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 717 SplitViewController* split_view_controller_; | 739 SplitViewController* split_view_controller_; |
| 718 | 740 |
| 719 WindowOverviewModeDelegate* delegate_; | 741 WindowOverviewModeDelegate* delegate_; |
| 720 scoped_ptr<aura::ScopedWindowTargeter> scoped_targeter_; | 742 scoped_ptr<aura::ScopedWindowTargeter> scoped_targeter_; |
| 721 scoped_ptr<ui::FlingCurve> fling_; | 743 scoped_ptr<ui::FlingCurve> fling_; |
| 722 | 744 |
| 723 aura::Window* dragged_window_; | 745 aura::Window* dragged_window_; |
| 724 gfx::Point dragged_start_location_; | 746 gfx::Point dragged_start_location_; |
| 725 scoped_ptr<OverviewToolbar> overview_toolbar_; | 747 scoped_ptr<OverviewToolbar> overview_toolbar_; |
| 726 | 748 |
| 749 // Whether a window was selected. |
| 750 bool selected_window_; |
| 751 |
| 727 DISALLOW_COPY_AND_ASSIGN(WindowOverviewModeImpl); | 752 DISALLOW_COPY_AND_ASSIGN(WindowOverviewModeImpl); |
| 728 }; | 753 }; |
| 729 | 754 |
| 730 } // namespace | 755 } // namespace |
| 731 | 756 |
| 732 // static | 757 // static |
| 733 scoped_ptr<WindowOverviewMode> WindowOverviewMode::Create( | 758 scoped_ptr<WindowOverviewMode> WindowOverviewMode::Create( |
| 734 aura::Window* container, | 759 aura::Window* container, |
| 735 const WindowListProvider* window_list_provider, | 760 const WindowListProvider* window_list_provider, |
| 736 SplitViewController* split_view_controller, | 761 SplitViewController* split_view_controller, |
| 737 WindowOverviewModeDelegate* delegate) { | 762 WindowOverviewModeDelegate* delegate) { |
| 738 return scoped_ptr<WindowOverviewMode>( | 763 return scoped_ptr<WindowOverviewMode>( |
| 739 new WindowOverviewModeImpl(container, window_list_provider, | 764 new WindowOverviewModeImpl(container, window_list_provider, |
| 740 split_view_controller, delegate)); | 765 split_view_controller, delegate)); |
| 741 } | 766 } |
| 742 | 767 |
| 743 } // namespace athena | 768 } // namespace athena |
| OLD | NEW |