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
3 // found in the LICENSE file.
5 #ifndef ATHENA_WM_SPLIT_VIEW_CONTROLLER_H_
6 #define ATHENA_WM_SPLIT_VIEW_CONTROLLER_H_
8 #include "athena/athena_export.h"
9 #include "athena/util/drag_handle.h"
10 #include "athena/wm/public/window_list_provider_observer.h"
11 #include "athena/wm/public/window_manager_observer.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/memory/weak_ptr.h"
21 class ScopedWindowTargeter
;
27 class ViewTargeterDelegate
;
32 class SplitViewControllerTest
;
33 class WindowListProviderImpl
;
35 // Responsible for entering split view mode, exiting from split view mode, and
36 // laying out the windows in split view mode.
37 class ATHENA_EXPORT SplitViewController
38 : public DragHandleScrollDelegate
,
39 public WindowManagerObserver
,
40 public WindowListProviderObserver
{
42 SplitViewController(aura::Window
* container
,
43 WindowListProviderImpl
* window_list_provider
);
45 ~SplitViewController() override
;
47 bool CanActivateSplitViewMode() const;
48 bool IsSplitViewModeActive() const;
50 // Activates split-view mode with |left| and |right| windows. If |left| and/or
51 // |right| is nullptr, then the first window in the window-list (which is
53 // |left| nor |right|) is selected instead. |to_activate| indicates which of
54 // |left| or |right| should be activated. If |to_activate| is nullptr, the
55 // currently active window is kept active if it is one of the split-view
57 void ActivateSplitMode(aura::Window
* left
,
59 aura::Window
* to_activate
);
61 // Resets the internal state to an inactive state.
62 void DeactivateSplitMode();
64 // Replaces |window| in split-view mode with |replace_with|. Adjusts
65 // |replace_with|'s visibility, transform and bounds. Resets |window|'s
66 // visibility and transform but does not change its bounds.
67 void ReplaceWindow(aura::Window
* window
,
68 aura::Window
* replace_with
);
70 // Returns the bounds of the left and right parts of the |container_| based
71 // on the current value of |divider_position_|.
72 gfx::Rect
GetLeftAreaBounds();
73 gfx::Rect
GetRightAreaBounds();
75 aura::Window
* left_window() { return left_window_
; }
76 aura::Window
* right_window() { return right_window_
; }
79 friend class SplitViewControllerTest
;
82 // Split View mode is not active. |left_window_| and |right_window| are
85 // Two windows |left_window_| and |right_window| are shown side by side and
86 // there is a horizontal scroll in progress which is dragging the divider
87 // between the two windows.
89 // Split View mode is active with |left_window_| and |right_window| showing
90 // side by side each occupying half the screen. No scroll in progress.
94 void SetState(State state
);
96 void InitializeDivider();
100 void UpdateLayout(bool animate
);
102 void SetWindowTransforms(const gfx::Transform
& left_transform
,
103 const gfx::Transform
& right_transform
,
104 const gfx::Transform
& divider_transform
,
107 // Called when the animation initiated by SetWindowTransforms() completes.
108 void OnAnimationCompleted();
110 // Returns the default divider position for when the split view mode is
111 // active and the divider is not being dragged.
112 int GetDefaultDividerPosition();
114 // Access to constants in anonymous namespace for testing purposes.
115 float GetMaxDistanceFromMiddleForTest() const;
116 float GetMinFlingVelocityForTest() const;
118 // DragHandleScrollDelegate:
119 void HandleScrollBegin(float delta
) override
;
120 void HandleScrollEnd(float velocity
) override
;
121 void HandleScrollUpdate(float delta
) override
;
123 // WindowManagerObserver:
124 void OnOverviewModeEnter() override
;
125 void OnOverviewModeExit() override
;
126 void OnSplitViewModeEnter() override
;
127 void OnSplitViewModeExit() override
;
129 // WindowListProviderObserver:
130 void OnWindowStackingChangedInList() override
{}
131 void OnWindowAddedToList(aura::Window
* added_window
) override
;
132 void OnWindowRemovedFromList(aura::Window
* removed_window
,
137 aura::Window
* container_
;
139 // Provider of the list of windows to cycle through. Not owned.
140 WindowListProviderImpl
* window_list_provider_
;
142 // Windows for the left and right activities shown in SCROLLING and ACTIVE
143 // states. In INACTIVE state these are nullptr.
144 aura::Window
* left_window_
;
145 aura::Window
* right_window_
;
147 // X-Coordinate of the (center of the) divider between left_window_ and
148 // right_window_ in |container_| coordinates.
149 int divider_position_
;
151 // Meaningful only when state_ is SCROLLING.
152 // X-Coordinate of the divider when the scroll started.
153 int divider_scroll_start_position_
;
155 // Visually separates the windows and contains the drag handle.
156 views::Widget
* divider_widget_
;
158 // The drag handle which can be used when split view is active to exit the
160 views::View
* drag_handle_
;
162 scoped_ptr
<aura::ScopedWindowTargeter
> window_targeter_
;
163 scoped_ptr
<views::ViewTargeterDelegate
> view_targeter_delegate_
;
165 // Windows which should be hidden when the animation initiated by
166 // UpdateLayout() completes.
167 std::vector
<aura::Window
*> to_hide_
;
169 base::WeakPtrFactory
<SplitViewController
> weak_factory_
;
171 DISALLOW_COPY_AND_ASSIGN(SplitViewController
);
174 } // namespace athena
176 #endif // ATHENA_WM_SPLIT_VIEW_CONTROLLER_H_