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 CHROME_BROWSER_UI_GTK_TABS_DRAGGED_TAB_CONTROLLER_GTK_H_ | |
6 #define CHROME_BROWSER_UI_GTK_TABS_DRAGGED_TAB_CONTROLLER_GTK_H_ | |
7 | |
8 #include <gtk/gtk.h> | |
9 | |
10 #include <vector> | |
11 | |
12 #include "base/basictypes.h" | |
13 #include "base/compiler_specific.h" | |
14 #include "base/memory/scoped_ptr.h" | |
15 #include "base/timer/timer.h" | |
16 #include "chrome/browser/ui/gtk/tabs/drag_data.h" | |
17 #include "content/public/browser/notification_observer.h" | |
18 #include "content/public/browser/notification_registrar.h" | |
19 #include "content/public/browser/web_contents_delegate.h" | |
20 #include "ui/base/x/x11_util.h" | |
21 | |
22 class DraggedViewGtk; | |
23 class TabGtk; | |
24 class TabStripGtk; | |
25 class TabStripModel; | |
26 | |
27 class DraggedTabControllerGtk : public content::NotificationObserver, | |
28 public content::WebContentsDelegate { | |
29 public: | |
30 // |source_tabstrip| is the tabstrip where the tabs reside before any | |
31 // dragging occurs. |source_tab| is the tab that is under the mouse pointer | |
32 // when dragging starts, it also becomes the active tab if not active | |
33 // already. |tabs| contains all the selected tabs when dragging starts. | |
34 DraggedTabControllerGtk(TabStripGtk* source_tabstrip, TabGtk* source_tab, | |
35 const std::vector<TabGtk*>& tabs); | |
36 virtual ~DraggedTabControllerGtk(); | |
37 | |
38 // Capture information needed to be used during a drag session for this | |
39 // controller's associated source Tab and TabStrip. |mouse_offset| is the | |
40 // distance of the mouse pointer from the Tab's origin. | |
41 void CaptureDragInfo(const gfx::Point& mouse_offset); | |
42 | |
43 // Responds to drag events subsequent to StartDrag. If the mouse moves a | |
44 // sufficient distance before the mouse is released, a drag session is | |
45 // initiated. | |
46 void Drag(); | |
47 | |
48 // Complete the current drag session. If the drag session was canceled | |
49 // because the user pressed Escape or something interrupted it, |canceled| | |
50 // is true so the helper can revert the state to the world before the drag | |
51 // begun. Returns whether the tab has been destroyed. | |
52 bool EndDrag(bool canceled); | |
53 | |
54 // Retrieve the tab that corresponds to |contents| if it is being dragged by | |
55 // this controller, or NULL if |contents| does not correspond to any tab | |
56 // being dragged. | |
57 TabGtk* GetDraggedTabForContents(content::WebContents* contents); | |
58 | |
59 // Returns true if |tab| matches any tab being dragged. | |
60 bool IsDraggingTab(const TabGtk* tab); | |
61 | |
62 // Returns true if |web_contents| matches any tab contents being dragged. | |
63 bool IsDraggingWebContents(const content::WebContents* web_contents); | |
64 | |
65 // Returns true if the specified tab is detached. | |
66 bool IsTabDetached(const TabGtk* tab); | |
67 | |
68 private: | |
69 // Enumeration of the ways a drag session can end. | |
70 enum EndDragType { | |
71 // Drag session exited normally: the user released the mouse. | |
72 NORMAL, | |
73 | |
74 // The drag session was canceled (alt-tab during drag, escape ...) | |
75 CANCELED, | |
76 | |
77 // The tab (NavigationController) was destroyed during the drag. | |
78 TAB_DESTROYED | |
79 }; | |
80 | |
81 DraggedTabData InitDraggedTabData(TabGtk* tab); | |
82 | |
83 // Overridden from content::WebContentsDelegate: | |
84 virtual content::WebContents* OpenURLFromTab( | |
85 content::WebContents* source, | |
86 const content::OpenURLParams& params) OVERRIDE; | |
87 virtual void NavigationStateChanged(const content::WebContents* source, | |
88 unsigned changed_flags) OVERRIDE; | |
89 virtual void AddNewContents(content::WebContents* source, | |
90 content::WebContents* new_contents, | |
91 WindowOpenDisposition disposition, | |
92 const gfx::Rect& initial_pos, | |
93 bool user_gesture, | |
94 bool* was_blocked) OVERRIDE; | |
95 virtual void LoadingStateChanged(content::WebContents* source, | |
96 bool to_different_document) OVERRIDE; | |
97 virtual content::JavaScriptDialogManager* | |
98 GetJavaScriptDialogManager() OVERRIDE; | |
99 virtual void RequestMediaAccessPermission( | |
100 content::WebContents* web_contents, | |
101 const content::MediaStreamRequest& request, | |
102 const content::MediaResponseCallback& callback) OVERRIDE; | |
103 | |
104 // Overridden from content::NotificationObserver: | |
105 virtual void Observe(int type, | |
106 const content::NotificationSource& source, | |
107 const content::NotificationDetails& details) OVERRIDE; | |
108 | |
109 // Returns the point where a detached window should be created given the | |
110 // current mouse position. | |
111 gfx::Point GetWindowCreatePoint() const; | |
112 | |
113 // Move the DraggedTabView according to the current mouse screen position, | |
114 // potentially updating the source and other TabStrips. | |
115 void ContinueDragging(); | |
116 | |
117 // Handles dragging tabs while the tabs are attached. | |
118 void MoveAttached(const gfx::Point& screen_point); | |
119 | |
120 // Handles dragging while the tabs are detached. | |
121 void MoveDetached(const gfx::Point& screen_point); | |
122 | |
123 // Selects the dragged tabs within |model|. | |
124 void RestoreSelection(TabStripModel* model); | |
125 | |
126 // Returns the compatible TabStrip that is under the specified point (screen | |
127 // coordinates), or NULL if there is none. | |
128 TabStripGtk* GetTabStripForPoint(const gfx::Point& screen_point); | |
129 | |
130 // Returns the specified |tabstrip| if it contains the specified point | |
131 // (screen coordinates), NULL if it does not. | |
132 TabStripGtk* GetTabStripIfItContains(TabStripGtk* tabstrip, | |
133 const gfx::Point& screen_point) const; | |
134 | |
135 // Attach the dragged Tab to the specified TabStrip. | |
136 void Attach(TabStripGtk* attached_tabstrip, const gfx::Point& screen_point); | |
137 | |
138 // Detach the dragged Tab from the current TabStrip. | |
139 void Detach(); | |
140 | |
141 // Converts a screen point to a point relative to the tab strip. | |
142 gfx::Point ConvertScreenPointToTabStripPoint(TabStripGtk* tabstrip, | |
143 const gfx::Point& screen_point); | |
144 | |
145 // Retrieve the bounds of the DraggedTabGtk, relative to the attached | |
146 // TabStrip, given location of the dragged tab in screen coordinates. | |
147 gfx::Rect GetDraggedViewTabStripBounds(const gfx::Point& screen_point); | |
148 | |
149 // Returns the index where the dragged WebContents should be inserted into | |
150 // the attached TabStripModel given the DraggedTabView's bounds | |
151 // |dragged_bounds| in coordinates relative to the attached TabStrip. | |
152 int GetInsertionIndexForDraggedBounds(const gfx::Rect& dragged_bounds); | |
153 | |
154 // Get the position of the dragged view relative to the upper left corner of | |
155 // the screen. |screen_point| is the current position of mouse cursor. | |
156 gfx::Point GetDraggedViewPoint(const gfx::Point& screen_point); | |
157 | |
158 // Finds the Tab within the specified TabStrip that corresponds to the | |
159 // dragged WebContents. | |
160 TabGtk* GetTabMatchingDraggedContents(TabStripGtk* tabstrip, | |
161 content::WebContents* contents); | |
162 | |
163 // Finds all the tabs within the specified TabStrip that correspond to the | |
164 // dragged WebContents. | |
165 std::vector<TabGtk*> GetTabsMatchingDraggedContents(TabStripGtk* tabstrip); | |
166 | |
167 // Sets the visible and draggging property of all dragged tabs. If |repaint| | |
168 // is true it also schedules a repaint. | |
169 void SetDraggedTabsVisible(bool visible, bool repaint); | |
170 | |
171 // Does the work for EndDrag. Returns whether the tab has been destroyed. | |
172 bool EndDragImpl(EndDragType how_end); | |
173 | |
174 // If the drag was aborted for some reason, this function is called to un-do | |
175 // the changes made during the drag operation. | |
176 void RevertDrag(); | |
177 | |
178 // Finishes the drag operation. Returns true if the drag controller should | |
179 // be destroyed immediately, false otherwise. | |
180 bool CompleteDrag(); | |
181 | |
182 // Resets the delegates of the WebContents. | |
183 void ResetDelegates(); | |
184 | |
185 // Create the DraggedViewGtk if it does not yet exist. | |
186 void EnsureDraggedView(); | |
187 | |
188 // Gets the bounds to animate the dragged view when dragging is over. | |
189 gfx::Rect GetAnimateBounds(); | |
190 | |
191 // Utility to convert the specified TabStripModel index to something valid | |
192 // for the attached TabStrip. | |
193 int NormalizeIndexToAttachedTabStrip(int index) const; | |
194 | |
195 // Hides the window that contains the tab strip the current drag session was | |
196 // initiated from. | |
197 void HideWindow(); | |
198 | |
199 // Presents the window that was hidden by HideWindow. | |
200 void ShowWindow(); | |
201 | |
202 // Closes a hidden frame at the end of a drag session. | |
203 void CleanUpHiddenFrame(); | |
204 | |
205 // Cleans up all the dragged tabs when they are no longer used. | |
206 void CleanUpDraggedTabs(); | |
207 | |
208 // Completes the drag session after the view has animated to its final | |
209 // position. | |
210 void OnAnimateToBoundsComplete(); | |
211 | |
212 // Activates whichever window is under the mouse. | |
213 void BringWindowUnderMouseToFront(); | |
214 | |
215 // Returns true if the tabs were originally one after the other in | |
216 // |source_tabstrip_|. | |
217 bool AreTabsConsecutive(); | |
218 | |
219 // Returns the NativeWindow at the specified point, not including the window | |
220 // being dragged. | |
221 gfx::NativeWindow GetLocalProcessWindow(const gfx::Point& screen_point); | |
222 | |
223 // Handles registering for notifications. | |
224 content::NotificationRegistrar registrar_; | |
225 | |
226 // The tab strip |source_tab_| originated from. | |
227 TabStripGtk* source_tabstrip_; | |
228 | |
229 // Holds various data for each dragged tab needed to handle dragging. | |
230 scoped_ptr<DragData> drag_data_; | |
231 | |
232 // The TabStrip the dragged Tab is currently attached to, or NULL if the | |
233 // dragged Tab is detached. | |
234 TabStripGtk* attached_tabstrip_; | |
235 | |
236 // The visual representation of all the dragged tabs. | |
237 scoped_ptr<DraggedViewGtk> dragged_view_; | |
238 | |
239 // The position of the mouse (in screen coordinates) at the start of the drag | |
240 // operation. This is used to calculate minimum elasticity before a | |
241 // DraggedTabView is constructed. | |
242 gfx::Point start_screen_point_; | |
243 | |
244 // This is the offset of the mouse from the top left of the Tab where | |
245 // dragging begun. This is used to ensure that the dragged view is always | |
246 // positioned at the correct location during the drag, and to ensure that the | |
247 // detached window is created at the right location. | |
248 gfx::Point mouse_offset_; | |
249 | |
250 // Whether we're in the destructor or not. Makes sure we don't destroy the | |
251 // drag controller more than once. | |
252 bool in_destructor_; | |
253 | |
254 // The horizontal position of the mouse cursor in screen coordinates at the | |
255 // time of the last re-order event. | |
256 int last_move_screen_x_; | |
257 | |
258 // True until |MoveAttached| is invoked once. | |
259 bool initial_move_; | |
260 | |
261 // Timer used to bring the window under the cursor to front. If the user | |
262 // stops moving the mouse for a brief time over a browser window, it is | |
263 // brought to front. | |
264 base::OneShotTimer<DraggedTabControllerGtk> bring_to_front_timer_; | |
265 | |
266 DISALLOW_COPY_AND_ASSIGN(DraggedTabControllerGtk); | |
267 }; | |
268 | |
269 #endif // CHROME_BROWSER_UI_GTK_TABS_DRAGGED_TAB_CONTROLLER_GTK_H_ | |
OLD | NEW |