dragged_tab_controller_gtk.h revision dc0f95d653279beabeb9817299e2902918ba123e
1// Copyright (c) 2011 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#pragma once 8 9#include <gtk/gtk.h> 10 11#include <set> 12 13#include "base/scoped_ptr.h" 14#include "base/timer.h" 15#include "chrome/browser/ui/tabs/dock_info.h" 16#include "content/browser/tab_contents/tab_contents_delegate.h" 17#include "content/common/notification_observer.h" 18#include "content/common/notification_registrar.h" 19#include "ui/base/x/x11_util.h" 20 21class DraggedTabGtk; 22class TabGtk; 23class TabStripGtk; 24class TabContentsWrapper; 25 26class DraggedTabControllerGtk : public NotificationObserver, 27 public TabContentsDelegate { 28 public: 29 DraggedTabControllerGtk(TabGtk* source_tab, TabStripGtk* source_tabstrip); 30 virtual ~DraggedTabControllerGtk(); 31 32 // Capture information needed to be used during a drag session for this 33 // controller's associated source Tab and TabStrip. |mouse_offset| is the 34 // distance of the mouse pointer from the Tab's origin. 35 void CaptureDragInfo(const gfx::Point& mouse_offset); 36 37 // Responds to drag events subsequent to StartDrag. If the mouse moves a 38 // sufficient distance before the mouse is released, a drag session is 39 // initiated. 40 void Drag(); 41 42 // Complete the current drag session. If the drag session was canceled 43 // because the user pressed Escape or something interrupted it, |canceled| 44 // is true so the helper can revert the state to the world before the drag 45 // begun. Returns whether the tab has been destroyed. 46 bool EndDrag(bool canceled); 47 48 // Retrieve the source tab if the TabContents specified matches the one being 49 // dragged by this controller, or NULL if the specified TabContents is not 50 // the same as the one being dragged. 51 TabGtk* GetDragSourceTabForContents(TabContents* contents) const; 52 53 // Returns true if the specified tab matches the tab being dragged. 54 bool IsDragSourceTab(const TabGtk* tab) const; 55 56 // Returns true if the specified tab is detached. 57 bool IsTabDetached(const TabGtk* tab) const; 58 59 private: 60 // Enumeration of the ways a drag session can end. 61 enum EndDragType { 62 // Drag session exited normally: the user released the mouse. 63 NORMAL, 64 65 // The drag session was canceled (alt-tab during drag, escape ...) 66 CANCELED, 67 68 // The tab (NavigationController) was destroyed during the drag. 69 TAB_DESTROYED 70 }; 71 72 // Overridden from TabContentsDelegate: 73 virtual void OpenURLFromTab(TabContents* source, 74 const GURL& url, 75 const GURL& referrer, 76 WindowOpenDisposition disposition, 77 PageTransition::Type transition); 78 virtual void NavigationStateChanged(const TabContents* source, 79 unsigned changed_flags); 80 virtual void AddNewContents(TabContents* source, 81 TabContents* new_contents, 82 WindowOpenDisposition disposition, 83 const gfx::Rect& initial_pos, 84 bool user_gesture); 85 virtual void ActivateContents(TabContents* contents); 86 virtual void DeactivateContents(TabContents* contents); 87 virtual void LoadingStateChanged(TabContents* source); 88 virtual void CloseContents(TabContents* source); 89 virtual void MoveContents(TabContents* source, const gfx::Rect& pos); 90 virtual bool IsPopup(const TabContents* source) const; 91 virtual void ToolbarSizeChanged(TabContents* source, bool is_animating); 92 virtual void UpdateTargetURL(TabContents* source, const GURL& url); 93 94 // Overridden from NotificationObserver: 95 virtual void Observe(NotificationType type, 96 const NotificationSource& source, 97 const NotificationDetails& details); 98 99 // Initialize the offset used to calculate the position to create windows 100 // in |GetWindowCreatePoint|. 101 void InitWindowCreatePoint(); 102 103 // Returns the point where a detached window should be created given the 104 // current mouse position. 105 gfx::Point GetWindowCreatePoint() const; 106 107 // Sets the TabContents being dragged with the specified |new_contents|. 108 void SetDraggedContents(TabContentsWrapper* new_contents); 109 110 // Move the DraggedTabView according to the current mouse screen position, 111 // potentially updating the source and other TabStrips. 112 void ContinueDragging(); 113 114 // Handles moving the Tab within a TabStrip as well as updating the View. 115 void MoveTab(const gfx::Point& screen_point); 116 117 // Returns the compatible TabStrip that is under the specified point (screen 118 // coordinates), or NULL if there is none. 119 TabStripGtk* GetTabStripForPoint(const gfx::Point& screen_point); 120 121 // Returns the specified |tabstrip| if it contains the specified point 122 // (screen coordinates), NULL if it does not. 123 TabStripGtk* GetTabStripIfItContains(TabStripGtk* tabstrip, 124 const gfx::Point& screen_point) const; 125 126 // Attach the dragged Tab to the specified TabStrip. 127 void Attach(TabStripGtk* attached_tabstrip, const gfx::Point& screen_point); 128 129 // Detach the dragged Tab from the current TabStrip. 130 void Detach(); 131 132 // Converts a screen point to a point relative to the tab strip. 133 gfx::Point ConvertScreenPointToTabStripPoint(TabStripGtk* tabstrip, 134 const gfx::Point& screen_point); 135 136 // Retrieve the bounds of the DraggedTabGtk, relative to the attached 137 // TabStrip, given location of the dragged tab in screen coordinates. 138 gfx::Rect GetDraggedTabTabStripBounds(const gfx::Point& screen_point); 139 140 // Returns the index where the dragged TabContents should be inserted into 141 // the attached TabStripModel given the DraggedTabView's bounds 142 // |dragged_bounds| in coordinates relative to the attached TabStrip. 143 // |is_tab_attached| is true if the tab has already been added. 144 int GetInsertionIndexForDraggedBounds(const gfx::Rect& dragged_bounds, 145 bool is_tab_attached) const; 146 147 // Get the position of the dragged tab relative to the attached tab strip. 148 gfx::Point GetDraggedTabPoint(const gfx::Point& screen_point); 149 150 // Finds the Tab within the specified TabStrip that corresponds to the 151 // dragged TabContents. 152 TabGtk* GetTabMatchingDraggedContents(TabStripGtk* tabstrip) const; 153 154 // Does the work for EndDrag. Returns whether the tab has been destroyed. 155 bool EndDragImpl(EndDragType how_end); 156 157 // If the drag was aborted for some reason, this function is called to un-do 158 // the changes made during the drag operation. 159 void RevertDrag(); 160 161 // Finishes the drag operation. Returns true if the drag controller should 162 // be destroyed immediately, false otherwise. 163 bool CompleteDrag(); 164 165 // Create the DraggedTabGtk if it does not yet exist. 166 void EnsureDraggedTab(); 167 168 // Utility for getting the mouse position in screen coordinates. 169 gfx::Point GetCursorScreenPoint() const; 170 171 // Gets the screen bounds of a tab. 172 static gfx::Rect GetTabScreenBounds(TabGtk* tab); 173 174 // Utility to convert the specified TabStripModel index to something valid 175 // for the attached TabStrip. 176 int NormalizeIndexToAttachedTabStrip(int index) const; 177 178 // Hides the window that contains the tab strip the current drag session was 179 // initiated from. 180 void HideWindow(); 181 182 // Presents the window that was hidden by HideWindow. 183 void ShowWindow(); 184 185 // Closes a hidden frame at the end of a drag session. 186 void CleanUpHiddenFrame(); 187 188 // Cleans up a source tab that is no longer used. 189 void CleanUpSourceTab(); 190 191 // Completes the drag session after the view has animated to its final 192 // position. 193 void OnAnimateToBoundsComplete(); 194 195 // Activates whichever window is under the mouse. 196 void BringWindowUnderMouseToFront(); 197 198 // Handles registering for notifications. 199 NotificationRegistrar registrar_; 200 201 // The TabContents being dragged. 202 TabContentsWrapper* dragged_contents_; 203 204 // The original TabContentsDelegate of |dragged_contents_|, before it was 205 // detached from the browser window. We store this so that we can forward 206 // certain delegate notifications back to it if we can't handle them locally. 207 TabContentsDelegate* original_delegate_; 208 209 // The tab that initiated the drag session. 210 TabGtk* source_tab_; 211 212 // The tab strip |source_tab_| originated from. 213 TabStripGtk* source_tabstrip_; 214 215 // This is the index of the |source_tab_| in |source_tabstrip_| when the drag 216 // began. This is used to restore the previous state if the drag is aborted. 217 int source_model_index_; 218 219 // The TabStrip the dragged Tab is currently attached to, or NULL if the 220 // dragged Tab is detached. 221 TabStripGtk* attached_tabstrip_; 222 223 // The visual representation of the dragged Tab. 224 scoped_ptr<DraggedTabGtk> dragged_tab_; 225 226 // The position of the mouse (in screen coordinates) at the start of the drag 227 // operation. This is used to calculate minimum elasticity before a 228 // DraggedTabView is constructed. 229 gfx::Point start_screen_point_; 230 231 // This is the offset of the mouse from the top left of the Tab where 232 // dragging begun. This is used to ensure that the dragged view is always 233 // positioned at the correct location during the drag, and to ensure that the 234 // detached window is created at the right location. 235 gfx::Point mouse_offset_; 236 237 // A hint to use when positioning new windows created by detaching Tabs. This 238 // is the distance of the mouse from the top left of the dragged tab as if it 239 // were the distance of the mouse from the top left of the first tab in the 240 // attached TabStrip from the top left of the window. 241 gfx::Point window_create_point_; 242 243 // Whether we're in the destructor or not. Makes sure we don't destroy the 244 // drag controller more than once. 245 bool in_destructor_; 246 247 // The horizontal position of the mouse cursor in screen coordinates at the 248 // time of the last re-order event. 249 int last_move_screen_x_; 250 251 // DockInfo for the tabstrip. 252 DockInfo dock_info_; 253 254 typedef std::set<GtkWidget*> DockWindows; 255 DockWindows dock_windows_; 256 257 // Is the tab mini? 258 const bool mini_; 259 260 // Is the tab pinned? 261 const bool pinned_; 262 263 // Timer used to bring the window under the cursor to front. If the user 264 // stops moving the mouse for a brief time over a browser window, it is 265 // brought to front. 266 base::OneShotTimer<DraggedTabControllerGtk> bring_to_front_timer_; 267 268 DISALLOW_COPY_AND_ASSIGN(DraggedTabControllerGtk); 269}; 270 271#endif // CHROME_BROWSER_UI_GTK_TABS_DRAGGED_TAB_CONTROLLER_GTK_H_ 272