• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #ifndef ATHENA_WM_SPLIT_VIEW_CONTROLLER_H_
6 #define ATHENA_WM_SPLIT_VIEW_CONTROLLER_H_
7 
8 #include "athena/athena_export.h"
9 #include "athena/util/drag_handle.h"
10 #include "athena/wm/bezel_controller.h"
11 #include "athena/wm/public/window_manager_observer.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/memory/weak_ptr.h"
14 
15 namespace gfx {
16 class Rect;
17 class Transform;
18 }
19 
20 namespace aura {
21 class ScopedWindowTargeter;
22 class Window;
23 class WindowTargeter;
24 }
25 
26 namespace views {
27 class ViewTargeterDelegate;
28 class Widget;
29 }
30 
31 namespace athena {
32 class WindowListProvider;
33 
34 // Responsible for entering split view mode, exiting from split view mode, and
35 // laying out the windows in split view mode.
36 class ATHENA_EXPORT SplitViewController
37     : public BezelController::ScrollDelegate,
38       public DragHandleScrollDelegate,
39       public WindowManagerObserver {
40  public:
41   SplitViewController(aura::Window* container,
42                       WindowListProvider* window_list_provider);
43 
44   virtual ~SplitViewController();
45 
46   bool CanActivateSplitViewMode() const;
47   bool IsSplitViewModeActive() const;
48 
49   // Activates split-view mode with |left| and |right| windows. If |left| and/or
50   // |right| is NULL, then the first window in the window-list (which is neither
51   // |left| nor |right|) is selected instead. |to_activate| indicates which of
52   // |left| or |right| should be activated. If |to_activate| is NULL, the
53   // currently active window is kept active if it is one of the split-view
54   // windows.
55   void ActivateSplitMode(aura::Window* left,
56                          aura::Window* right,
57                          aura::Window* to_activate);
58 
59   // Resets the internal state to an inactive state.
60   void DeactivateSplitMode();
61 
62   // Replaces |window| in split-view mode with |replace_with|. Adjusts
63   // |replace_with|'s visibility, transform and bounds. Resets |window|'s
64   // visibility and transform but does not change its bounds.
65   void ReplaceWindow(aura::Window* window,
66                      aura::Window* replace_with);
67 
68   // Returns the bounds of the left and right parts of the |container_| based
69   // on the current value of |divider_position_|.
70   gfx::Rect GetLeftAreaBounds();
71   gfx::Rect GetRightAreaBounds();
72 
left_window()73   aura::Window* left_window() { return left_window_; }
right_window()74   aura::Window* right_window() { return right_window_; }
75 
76  private:
77   enum State {
78     // Split View mode is not active. |left_window_| and |right_window| are
79     // NULL.
80     INACTIVE,
81     // Two windows |left_window_| and |right_window| are shown side by side and
82     // there is a horizontal scroll in progress which is dragging the divider
83     // between the two windows.
84     SCROLLING,
85     // Split View mode is active with |left_window_| and |right_window| showing
86     // side by side each occupying half the screen. No scroll in progress.
87     ACTIVE
88   };
89 
90   void SetState(State state);
91 
92   void InitializeDivider();
93   void HideDivider();
94   void ShowDivider();
95 
96   void UpdateLayout(bool animate);
97 
98   void SetWindowTransforms(const gfx::Transform& left_transform,
99                            const gfx::Transform& right_transform,
100                            const gfx::Transform& divider_transform,
101                            bool animate);
102 
103   // Called when the animation initiated by SetWindowTransforms() completes.
104   void OnAnimationCompleted();
105 
106   // Returns the default divider position for when the split view mode is
107   // active and the divider is not being dragged.
108   int GetDefaultDividerPosition();
109 
110   // BezelController::ScrollDelegate:
111   virtual void BezelScrollBegin(BezelController::Bezel bezel,
112                                 float delta) OVERRIDE;
113   virtual void BezelScrollEnd() OVERRIDE;
114   virtual void BezelScrollUpdate(float delta) OVERRIDE;
115   virtual bool BezelCanScroll() OVERRIDE;
116 
117   // DragHandleScrollDelegate:
118   virtual void HandleScrollBegin(float delta) OVERRIDE;
119   virtual void HandleScrollEnd() OVERRIDE;
120   virtual void HandleScrollUpdate(float delta) OVERRIDE;
121 
122   // WindowManagerObserver:
123   virtual void OnOverviewModeEnter() OVERRIDE;
124   virtual void OnOverviewModeExit() OVERRIDE;
125   virtual void OnSplitViewModeEnter() OVERRIDE;
126   virtual void OnSplitViewModeExit() OVERRIDE;
127 
128   State state_;
129 
130   aura::Window* container_;
131 
132   // Provider of the list of windows to cycle through. Not owned.
133   WindowListProvider* window_list_provider_;
134 
135   // Windows for the left and right activities shown in SCROLLING and ACTIVE
136   // states. In INACTIVE state these are NULL.
137   aura::Window* left_window_;
138   aura::Window* right_window_;
139 
140   // X-Coordinate of the (center of the) divider between left_window_ and
141   // right_window_ in |container_| coordinates.
142   int divider_position_;
143 
144   // Meaningful only when state_ is SCROLLING.
145   // X-Coordinate of the divider when the scroll started.
146   int divider_scroll_start_position_;
147 
148   // Visually separates the windows and contains the drag handle.
149   views::Widget* divider_widget_;
150 
151   // The drag handle which can be used when split view is active to exit the
152   // split view mode.
153   views::View* drag_handle_;
154 
155   scoped_ptr<aura::ScopedWindowTargeter> window_targeter_;
156   scoped_ptr<views::ViewTargeterDelegate> view_targeter_delegate_;
157 
158   // Windows which should be hidden when the animation initiated by
159   // UpdateLayout() completes.
160   std::vector<aura::Window*> to_hide_;
161 
162   base::WeakPtrFactory<SplitViewController> weak_factory_;
163 
164   DISALLOW_COPY_AND_ASSIGN(SplitViewController);
165 };
166 
167 }  // namespace athena
168 
169 #endif  // ATHENA_WM_SPLIT_VIEW_CONTROLLER_H_
170