OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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_COMMON_WM_WORKSPACE_MULTI_WINDOW_RESIZE_CONTROLLER_H_ | |
6 #define ASH_COMMON_WM_WORKSPACE_MULTI_WINDOW_RESIZE_CONTROLLER_H_ | |
7 | |
8 #include <memory> | |
9 #include <vector> | |
10 | |
11 #include "ash/ash_export.h" | |
12 #include "base/macros.h" | |
13 #include "base/timer/timer.h" | |
14 #include "ui/aura/window_observer.h" | |
15 #include "ui/gfx/geometry/rect.h" | |
16 #include "ui/views/mouse_watcher.h" | |
17 | |
18 namespace views { | |
19 class Widget; | |
20 } | |
21 | |
22 namespace ash { | |
23 class MultiWindowResizeControllerTest; | |
24 class WmWindow; | |
25 class WorkspaceWindowResizer; | |
26 | |
27 // Two directions resizes happen in. | |
28 enum Direction { | |
29 TOP_BOTTOM, | |
30 LEFT_RIGHT, | |
31 }; | |
32 | |
33 // MultiWindowResizeController is responsible for determining and showing a | |
34 // widget that allows resizing multiple windows at the same time. | |
35 // MultiWindowResizeController is driven by WorkspaceEventFilter. | |
36 class ASH_EXPORT MultiWindowResizeController | |
37 : public views::MouseWatcherListener, | |
38 public aura::WindowObserver { | |
39 public: | |
40 MultiWindowResizeController(); | |
41 ~MultiWindowResizeController() override; | |
42 | |
43 // If necessary, shows the resize widget. |window| is the window the mouse | |
44 // is over, |component| the edge and |point| the location of the mouse. | |
45 void Show(WmWindow* window, int component, const gfx::Point& point); | |
46 | |
47 // Hides the resize widget. | |
48 void Hide(); | |
49 | |
50 // MouseWatcherListenre overrides: | |
51 void MouseMovedOutOfHost() override; | |
52 | |
53 // WindowObserver overrides: | |
54 void OnWindowDestroying(aura::Window* window) override; | |
55 | |
56 private: | |
57 friend class MultiWindowResizeControllerTest; | |
58 | |
59 // Used to track the two resizable windows and direction. | |
60 struct ResizeWindows { | |
61 ResizeWindows(); | |
62 ResizeWindows(const ResizeWindows& other); | |
63 ~ResizeWindows(); | |
64 | |
65 // Returns true if |other| equals this ResizeWindows. This does *not* | |
66 // consider the windows in |other_windows|. | |
67 bool Equals(const ResizeWindows& other) const; | |
68 | |
69 // Returns true if this ResizeWindows is valid. | |
70 bool is_valid() const { return window1 && window2; } | |
71 | |
72 // The left/top window to resize. | |
73 WmWindow* window1; | |
74 | |
75 // Other window to resize. | |
76 WmWindow* window2; | |
77 | |
78 // Direction | |
79 Direction direction; | |
80 | |
81 // Windows after |window2| that are to be resized. Determined at the time | |
82 // the resize starts. | |
83 std::vector<WmWindow*> other_windows; | |
84 }; | |
85 | |
86 class ResizeMouseWatcherHost; | |
87 class ResizeView; | |
88 | |
89 void CreateMouseWatcher(); | |
90 | |
91 // Returns a ResizeWindows based on the specified arguments. Use is_valid() | |
92 // to test if the return value is a valid multi window resize location. | |
93 ResizeWindows DetermineWindows(WmWindow* window, | |
94 int window_component, | |
95 const gfx::Point& point) const; | |
96 | |
97 // Variant of DetermineWindows() that uses the current location of the mouse | |
98 // to determine the resize windows. | |
99 ResizeWindows DetermineWindowsFromScreenPoint(WmWindow* window) const; | |
100 | |
101 // Finds a window by edge (one of the constants HitTestCompat. | |
102 WmWindow* FindWindowByEdge(WmWindow* window_to_ignore, | |
103 int edge_want, | |
104 int x_in_parent, | |
105 int y_in_parent) const; | |
106 | |
107 // Returns the first window touching |window|. | |
108 WmWindow* FindWindowTouching(WmWindow* window, Direction direction) const; | |
109 | |
110 // Places any windows touching |start| into |others|. | |
111 void FindWindowsTouching(WmWindow* start, | |
112 Direction direction, | |
113 std::vector<WmWindow*>* others) const; | |
114 | |
115 // Shows the resizer if the mouse is still at a valid location. This is called | |
116 // from the |show_timer_|. | |
117 void ShowIfValidMouseLocation(); | |
118 | |
119 // Shows the widget immediately. | |
120 void ShowNow(); | |
121 | |
122 // Returns true if the widget is showing. | |
123 bool IsShowing() const; | |
124 | |
125 // Initiates a resize. | |
126 void StartResize(const gfx::Point& location_in_screen); | |
127 | |
128 // Resizes to the new location. | |
129 void Resize(const gfx::Point& location_in_screen, int event_flags); | |
130 | |
131 // Completes the resize. | |
132 void CompleteResize(); | |
133 | |
134 // Cancels the resize. | |
135 void CancelResize(); | |
136 | |
137 // Returns the bounds for the resize widget. | |
138 gfx::Rect CalculateResizeWidgetBounds( | |
139 const gfx::Point& location_in_parent) const; | |
140 | |
141 // Returns true if |location_in_screen| is over the resize widget. | |
142 bool IsOverResizeWidget(const gfx::Point& location_in_screen) const; | |
143 | |
144 // Returns true if |location_in_screen| is over the resize windows | |
145 // (or the resize widget itself). | |
146 bool IsOverWindows(const gfx::Point& location_in_screen) const; | |
147 | |
148 // Returns true if |location_in_screen| is over |component| in |window|. | |
149 bool IsOverComponent(WmWindow* window, | |
150 const gfx::Point& location_in_screen, | |
151 int component) const; | |
152 | |
153 // Windows and direction to resize. | |
154 ResizeWindows windows_; | |
155 | |
156 // Timer used before showing. | |
157 base::OneShotTimer show_timer_; | |
158 | |
159 std::unique_ptr<views::Widget> resize_widget_; | |
160 | |
161 // If non-null we're in a resize loop. | |
162 std::unique_ptr<WorkspaceWindowResizer> window_resizer_; | |
163 | |
164 // Mouse coordinate passed to Show() in container's coodinates. | |
165 gfx::Point show_location_in_parent_; | |
166 | |
167 // Bounds the widget was last shown at in screen coordinates. | |
168 gfx::Rect show_bounds_in_screen_; | |
169 | |
170 // Used to detect whether the mouse is over the windows. While | |
171 // |resize_widget_| is non-NULL (ie the widget is showing) we ignore calls | |
172 // to Show(). | |
173 std::unique_ptr<views::MouseWatcher> mouse_watcher_; | |
174 | |
175 DISALLOW_COPY_AND_ASSIGN(MultiWindowResizeController); | |
176 }; | |
177 | |
178 } // namespace ash | |
179 | |
180 #endif // ASH_COMMON_WM_WORKSPACE_MULTI_WINDOW_RESIZE_CONTROLLER_H_ | |
OLD | NEW |