1 // Copyright 2017 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 ASH_WM_SPLITVIEW_SPLIT_VIEW_DRAG_INDICATORS_H_
6 #define ASH_WM_SPLITVIEW_SPLIT_VIEW_DRAG_INDICATORS_H_
7 
8 #include <memory>
9 
10 #include "ash/ash_export.h"
11 #include "ash/wm/splitview/split_view_controller.h"
12 #include "base/gtest_prod_util.h"
13 #include "base/macros.h"
14 #include "ui/gfx/geometry/point.h"
15 #include "ui/gfx/geometry/rect.h"
16 
17 namespace aura {
18 class Window;
19 }  // namespace aura
20 
21 namespace views {
22 class Widget;
23 }  // namespace views
24 
25 namespace ash {
26 
27 // Enum which contains the indicators that SplitViewDragIndicators can display.
28 // Converted to a bitmask to make testing easier.
29 enum class IndicatorType {
30   kLeftHighlight = 1,
31   kLeftText = 2,
32   kRightHighlight = 4,
33   kRightText = 8
34 };
35 
36 // An overlay in overview mode which guides users while they are attempting to
37 // enter splitview. Displays text and highlights when dragging an overview
38 // window. Displays a highlight of where the window will end up when an overview
39 // window has entered a snap region.
40 class ASH_EXPORT SplitViewDragIndicators {
41  public:
42   // Enum for purposes of providing |SplitViewDragIndicators| with information
43   // about window dragging.
44   enum class WindowDraggingState {
45     // Not dragging, or split view is unsupported (see |ShouldAllowSplitView|).
46     kNoDrag,
47 
48     // Dragging is in another display. Split view is supported.
49     // Note: The distinction between |kNoDrag| and |kOtherDisplay| affects
50     // animation when the previous state is |kToSnapLeft| or |kToSnapRight|.
51     kOtherDisplay,
52 
53     // Started dragging from overview or from the shelf. Split view is
54     // supported. Not currently dragging in a snap area, or the dragged window
55     // is not eligible to be snapped in split view.
56     kFromOverview,
57 
58     // Started dragging from the top. Split view is supported. Not currently
59     // dragging in a snap area, or the dragged window is not eligible to be
60     // snapped in split view.
61     kFromTop,
62 
63     // Started dragging from the shelf. Split view is supported. Not currently
64     // dragging in a snap area, or the dragged window is not eligible to be
65     // snapped in split view.
66     kFromShelf,
67 
68     // Currently dragging in the |SplitViewController::LEFT| snap area, and the
69     // dragged window is eligible to be snapped in split view.
70     kToSnapLeft,
71 
72     // Currently dragging in the |SplitViewController::RIGHT| snap area, and the
73     // dragged window is eligible to be snapped in split view.
74     kToSnapRight
75   };
76 
77   // |SplitViewController::LEFT|, if |window_dragging_state| is |kToSnapLeft|
78   // |SplitViewController::RIGHT|, if |window_dragging_state| is |kToSnapRight|
79   // |SplitViewController::NONE| otherwise
80   static SplitViewController::SnapPosition GetSnapPosition(
81       WindowDraggingState window_dragging_state);
82 
83   // |kNoDrag| if |is_dragging| is false or split view is unsupported. If
84   // |is_dragging| is true and split view is supported, then:
85   // |non_snap_state|, if |snap_position| is |SplitViewController::NONE|
86   // |kToSnapLeft|, if |snap_position| is |SplitViewController::LEFT|
87   // |kToSnapRight|, if |snap_position| is |SplitViewController::RIGHT|
88   static WindowDraggingState ComputeWindowDraggingState(
89       bool is_dragging,
90       WindowDraggingState non_snap_state,
91       SplitViewController::SnapPosition snap_position);
92 
93   SplitViewDragIndicators(aura::Window* root_window);
94   ~SplitViewDragIndicators();
95 
96   void SetDraggedWindow(aura::Window* dragged_window);
97   void SetWindowDraggingState(WindowDraggingState window_dragging_state);
98   void OnDisplayBoundsChanged();
99   bool GetIndicatorTypeVisibilityForTesting(IndicatorType type) const;
100   gfx::Rect GetLeftHighlightViewBounds() const;
current_window_dragging_state()101   WindowDraggingState current_window_dragging_state() const {
102     return current_window_dragging_state_;
103   }
104 
105  private:
106   FRIEND_TEST_ALL_PREFIXES(SplitViewDragIndicatorsTest,
107                            SplitViewDragIndicatorsWidgetReparenting);
108   class RotatedImageLabelView;
109   class SplitViewDragIndicatorsView;
110 
111   // The root content view of |widget_|.
112   SplitViewDragIndicatorsView* indicators_view_ = nullptr;
113 
114   WindowDraggingState current_window_dragging_state_ =
115       WindowDraggingState::kNoDrag;
116 
117   // The SplitViewDragIndicators widget. It covers the entire root window
118   // and displays regions and text indicating where users should drag windows
119   // enter split view.
120   std::unique_ptr<views::Widget> widget_;
121 
122   DISALLOW_COPY_AND_ASSIGN(SplitViewDragIndicators);
123 };
124 
125 }  // namespace ash
126 
127 #endif  // ASH_WM_SPLITVIEW_SPLIT_VIEW_DRAG_INDICATORS_H_
128