Home | History | Annotate | Download | only in wm
      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 
     73   aura::Window* left_window() { return left_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