172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
24a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
34a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// found in the LICENSE file.
44a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
54a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#ifndef CHROME_BROWSER_UI_VIEWS_TABS_DRAGGED_TAB_CONTROLLER_H_
64a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#define CHROME_BROWSER_UI_VIEWS_TABS_DRAGGED_TAB_CONTROLLER_H_
74a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#pragma once
84a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <vector>
10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "base/message_loop.h"
134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "base/timer.h"
1421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
1521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/tabs/dock_info.h"
16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents_delegate.h"
17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_observer.h"
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_registrar.h"
1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/rect.h"
204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochnamespace views {
224a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochclass View;
234a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
244a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochclass BaseTab;
254a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochclass BaseTabStrip;
264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochclass DraggedTabView;
274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochclass TabStripModel;
284a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
294a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochstruct TabRendererData;
304a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch///////////////////////////////////////////////////////////////////////////////
324a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch//
334a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// DraggedTabController
344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch//
354a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch//  An object that handles a drag session for an individual Tab within a
364a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch//  TabStrip. This object is created whenever the mouse is pressed down on a
374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch//  Tab and destroyed when the mouse is released or the drag operation is
384a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch//  aborted. The Tab that the user dragged (the "source tab") owns this object
394a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch//  and must be the only one to destroy it (via |DestroyDragController|).
404a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch//
414a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch///////////////////////////////////////////////////////////////////////////////
424a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochclass DraggedTabController : public TabContentsDelegate,
434a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                             public NotificationObserver,
444a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                             public MessageLoopForUI::Observer {
454a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch public:
46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DraggedTabController();
474a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  virtual ~DraggedTabController();
484a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Initializes DraggedTabController to drag the tabs in |tabs| originating
50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // from |source_tabstrip|. |source_tab| is the tab that initiated the drag and
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // is contained in |tabs|.  |mouse_offset| is the distance of the mouse
52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // pointer from the origin of the first tab in |tabs| and |source_tab_offset|
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // the offset from |source_tab|. |source_tab_offset| is the horizontal distant
54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // for a horizontal tab strip, and the vertical distance for a vertical tab
55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // strip.
56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void Init(BaseTabStrip* source_tabstrip,
57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            BaseTab* source_tab,
58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            const std::vector<BaseTab*>& tabs,
59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            const gfx::Point& mouse_offset,
60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            int source_tab_offset);
61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
624a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Returns true if there is a drag underway and the drag is attached to
634a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // |tab_strip|.
644a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // NOTE: this returns false if the dragged tab controller is in the process
654a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // of finishing the drag.
664a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  static bool IsAttachedTo(BaseTabStrip* tab_strip);
674a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
684a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Responds to drag events subsequent to StartDrag. If the mouse moves a
694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // sufficient distance before the mouse is released, a drag session is
704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // initiated.
714a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  void Drag();
724a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
734a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Complete the current drag session. If the drag session was canceled
744a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // because the user pressed Escape or something interrupted it, |canceled|
754a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // is true so the helper can revert the state to the world before the drag
764a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // begun.
774a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  void EndDrag(bool canceled);
784a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
794a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Returns true if a drag started.
804a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  bool started_drag() const { return started_drag_; }
814a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
824a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch private:
834a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  class DockDisplayer;
844a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  friend class DockDisplayer;
854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
864a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  typedef std::set<gfx::NativeView> DockWindows;
874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
884a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Enumeration of the ways a drag session can end.
894a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  enum EndDragType {
904a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // Drag session exited normally: the user released the mouse.
914a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    NORMAL,
924a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // The drag session was canceled (alt-tab during drag, escape ...)
944a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    CANCELED,
954a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
964a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // The tab (NavigationController) was destroyed during the drag.
974a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    TAB_DESTROYED
984a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  };
994a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Stores the date associated with a single tab that is being dragged.
101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  struct TabDragData {
102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    TabDragData();
103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ~TabDragData();
104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // The TabContentsWrapper being dragged.
106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    TabContentsWrapper* contents;
107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // The original TabContentsDelegate of |contents|, before it was detached
109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // from the browser window. We store this so that we can forward certain
110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // delegate notifications back to it if we can't handle them locally.
111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    TabContentsDelegate* original_delegate;
112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // This is the index of the tab in |source_tabstrip_| when the drag
114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // began. This is used to restore the previous state if the drag is aborted.
115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    int source_model_index;
116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // If attached this is the tab in |attached_tabstrip_|.
118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BaseTab* attached_tab;
119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Is the tab pinned?
121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    bool pinned;
122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  typedef std::vector<TabDragData> DragData;
125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Sets |drag_data| from |tab|. This also registers for necessary
127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // notifications and resets the delegate of the TabContentsWrapper.
128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void InitTabDragData(BaseTab* tab, TabDragData* drag_data);
129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1304a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Overridden from TabContentsDelegate:
1314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  virtual void OpenURLFromTab(TabContents* source,
1324a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                              const GURL& url,
1334a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                              const GURL& referrer,
1344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                              WindowOpenDisposition disposition,
135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                              PageTransition::Type transition) OVERRIDE;
1364a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  virtual void NavigationStateChanged(const TabContents* source,
137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                      unsigned changed_flags) OVERRIDE;
1384a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  virtual void AddNewContents(TabContents* source,
1394a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                              TabContents* new_contents,
1404a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                              WindowOpenDisposition disposition,
1414a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                              const gfx::Rect& initial_pos,
142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                              bool user_gesture) OVERRIDE;
143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void ActivateContents(TabContents* contents) OVERRIDE;
144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void DeactivateContents(TabContents* contents) OVERRIDE;
145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void LoadingStateChanged(TabContents* source) OVERRIDE;
146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void CloseContents(TabContents* source) OVERRIDE;
147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void MoveContents(TabContents* source,
148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            const gfx::Rect& pos) OVERRIDE;
149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void UpdateTargetURL(TabContents* source, const GURL& url) OVERRIDE;
150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual bool ShouldSuppressDialogs() OVERRIDE;
1514a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1524a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Overridden from NotificationObserver:
1534a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  virtual void Observe(NotificationType type,
1544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                       const NotificationSource& source,
155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                       const NotificationDetails& details) OVERRIDE;
1564a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1574a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Overridden from MessageLoop::Observer:
1584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#if defined(OS_WIN)
159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void WillProcessMessage(const MSG& msg) OVERRIDE;
160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void DidProcessMessage(const MSG& msg) OVERRIDE;
1614a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#else
162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void WillProcessEvent(GdkEvent* event) OVERRIDE;
163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void DidProcessEvent(GdkEvent* event) OVERRIDE;
1644a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#endif
1654a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1664a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Initialize the offset used to calculate the position to create windows
167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // in |GetWindowCreatePoint|. This should only be invoked from |Init|.
1684a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  void InitWindowCreatePoint();
1694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Returns the point where a detached window should be created given the
1714a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // current mouse position.
1724a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  gfx::Point GetWindowCreatePoint() const;
1734a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1744a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  void UpdateDockInfo(const gfx::Point& screen_point);
1754a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1764a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Saves focus in the window that the drag initiated from. Focus will be
1774a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // restored appropriately if the drag ends within this same window.
1784a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  void SaveFocus();
1794a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1804a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Restore focus to the View that had focus before the drag was started, if
1814a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // the drag ends within the same Window as it began.
1824a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  void RestoreFocus();
1834a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1844a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Tests whether the position of the mouse is past a minimum elasticity
1854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // threshold required to start a drag.
1864a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  bool CanStartDrag() const;
1874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1884a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Move the DraggedTabView according to the current mouse screen position,
1894a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // potentially updating the source and other TabStrips.
1904a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  void ContinueDragging();
1914a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Handles dragging tabs while the tabs are attached.
193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void MoveAttached(const gfx::Point& screen_point);
1944a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Handles dragging while the tabs are detached.
196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void MoveDetached(const gfx::Point& screen_point);
1974a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1984a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Returns the compatible TabStrip that is under the specified point (screen
1994a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // coordinates), or NULL if there is none.
2004a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  BaseTabStrip* GetTabStripForPoint(const gfx::Point& screen_point);
2014a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
2024a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DockInfo GetDockInfoAtPoint(const gfx::Point& screen_point);
2034a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
2044a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Returns the specified |tabstrip| if it contains the specified point
2054a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // (screen coordinates), NULL if it does not.
2064a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  BaseTabStrip* GetTabStripIfItContains(BaseTabStrip* tabstrip,
2074a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                                        const gfx::Point& screen_point) const;
2084a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
2094a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Attach the dragged Tab to the specified TabStrip.
2104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  void Attach(BaseTabStrip* attached_tabstrip, const gfx::Point& screen_point);
2114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
2124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Detach the dragged Tab from the current TabStrip.
2134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  void Detach();
2144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
2154a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Returns the index where the dragged TabContents should be inserted into
216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // |attached_tabstrip_| given the DraggedTabView's bounds |dragged_bounds| in
217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // coordinates relative to |attached_tabstrip_| and has had the mirroring
218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // transformation applied.
219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // NOTE: this is invoked from |Attach| before the tabs have been inserted.
220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  int GetInsertionIndexForDraggedBounds(const gfx::Rect& dragged_bounds) const;
2214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Retrieve the bounds of the DraggedTabView relative to the attached
223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // TabStrip. |tab_strip_point| is in the attached TabStrip's coordinate
224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // system.
225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  gfx::Rect GetDraggedViewTabStripBounds(const gfx::Point& tab_strip_point);
2264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
2274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Get the position of the dragged tab view relative to the attached tab
228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // strip with the mirroring transform applied.
229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  gfx::Point GetAttachedDragPoint(const gfx::Point& screen_point);
2304a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Finds the Tabs within the specified TabStrip that corresponds to the
232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // TabContents of the dragged tabs. Returns an empty vector if not attached.
233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<BaseTab*> GetTabsMatchingDraggedContents(BaseTabStrip* tabstrip);
2344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
2354a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Does the work for EndDrag. If we actually started a drag and |how_end| is
2364a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // not TAB_DESTROYED then one of EndDrag or RevertDrag is invoked.
2374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  void EndDragImpl(EndDragType how_end);
2384a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
2394a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Reverts a cancelled drag operation.
2404a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  void RevertDrag();
2414a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Reverts the tab at |drag_index| in |drag_data_|.
243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void RevertDragAt(size_t drag_index);
244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Selects the dragged tabs in |model|. Does nothing if there are no longer
246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // any dragged contents (as happens when a TabContents is deleted out from
247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // under us).
248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void ResetSelection(TabStripModel* model);
249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2504a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Finishes a succesful drag operation.
2514a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  void CompleteDrag();
2524a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Resets the delegates of the TabContents.
254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void ResetDelegates();
255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Create the DraggedTabView.
257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void CreateDraggedView(const std::vector<TabRendererData>& data,
258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                         const std::vector<gfx::Rect>& renderer_bounds);
2594a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
2604a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Utility for getting the mouse position in screen coordinates.
2614a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  gfx::Point GetCursorScreenPoint() const;
2624a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
2634a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Returns the bounds (in screen coordinates) of the specified View.
2644a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  gfx::Rect GetViewScreenBounds(views::View* tabstrip) const;
2654a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
2664a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Hides the frame for the window that contains the TabStrip the current
2674a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // drag session was initiated from.
2684a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  void HideFrame();
2694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
2704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Closes a hidden frame at the end of a drag session.
2714a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  void CleanUpHiddenFrame();
2724a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
2734a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  void DockDisplayerDestroyed(DockDisplayer* controller);
2744a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
2754a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  void BringWindowUnderMouseToFront();
2764a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Convenience for getting the TabDragData corresponding to the tab the user
278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // started dragging.
279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TabDragData* source_tab_drag_data() {
280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return &(drag_data_[source_tab_index_]);
281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Convenience for |source_tab_drag_data()->contents|.
284ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TabContentsWrapper* source_dragged_contents() {
285ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return source_tab_drag_data()->contents;
286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Returns true if the tabs were originality one after the other in
289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // |source_tabstrip_|.
290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool AreTabsConsecutive();
291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2924a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Returns the TabStripModel for the specified tabstrip.
2934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  TabStripModel* GetModel(BaseTabStrip* tabstrip) const;
2944a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
2954a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Handles registering for notifications.
2964a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  NotificationRegistrar registrar_;
2974a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // The TabStrip the drag originated from.
2994a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  BaseTabStrip* source_tabstrip_;
3004a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
3014a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // The TabStrip the dragged Tab is currently attached to, or NULL if the
3024a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // dragged Tab is detached.
3034a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  BaseTabStrip* attached_tabstrip_;
3044a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
3054a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // The visual representation of the dragged Tab.
3064a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  scoped_ptr<DraggedTabView> view_;
3074a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
3084a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // The position of the mouse (in screen coordinates) at the start of the drag
3094a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // operation. This is used to calculate minimum elasticity before a
3104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // DraggedTabView is constructed.
3114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  gfx::Point start_screen_point_;
3124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
3134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // This is the offset of the mouse from the top left of the Tab where
3144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // dragging begun. This is used to ensure that the dragged view is always
3154a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // positioned at the correct location during the drag, and to ensure that the
3164a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // detached window is created at the right location.
3174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  gfx::Point mouse_offset_;
3184a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Offset of the mouse relative to the source tab.
320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  int source_tab_offset_;
321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Ratio of the x-coordinate of the |source_tab_offset_| to the width of the
323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // tab. Not used for vertical tabs.
3244a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  float offset_to_width_ratio_;
3254a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
3264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // A hint to use when positioning new windows created by detaching Tabs. This
3274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // is the distance of the mouse from the top left of the dragged tab as if it
3284a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // were the distance of the mouse from the top left of the first tab in the
3294a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // attached TabStrip from the top left of the window.
3304a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  gfx::Point window_create_point_;
3314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
3324a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Location of the first tab in the source tabstrip in screen coordinates.
3334a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // This is used to calculate window_create_point_.
3344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  gfx::Point first_source_tab_point_;
3354a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
3364a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // The bounds of the browser window before the last Tab was detached. When
3374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // the last Tab is detached, rather than destroying the frame (which would
3384a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // abort the drag session), the frame is moved off-screen. If the drag is
3394a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // aborted (e.g. by the user pressing Esc, or capture being lost), the Tab is
3404a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // attached to the hidden frame and the frame moved back to these bounds.
3414a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  gfx::Rect restore_bounds_;
3424a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
3434a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // The last view that had focus in the window containing |source_tab_|. This
3444a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // is saved so that focus can be restored properly when a drag begins and
3454a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // ends within this same window.
3464a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  views::View* old_focused_view_;
3474a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
3484a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // The position along the major axis of the mouse cursor in screen coordinates
3494a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // at the time of the last re-order event.
3504a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  int last_move_screen_loc_;
3514a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
3524a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DockInfo dock_info_;
3534a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
3544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DockWindows dock_windows_;
3554a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
3564a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  std::vector<DockDisplayer*> dock_controllers_;
3574a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
3584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Timer used to bring the window under the cursor to front. If the user
3594a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // stops moving the mouse for a brief time over a browser window, it is
3604a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // brought to front.
3614a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  base::OneShotTimer<DraggedTabController> bring_to_front_timer_;
3624a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
3634a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Did the mouse move enough that we started a drag?
3644a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  bool started_drag_;
3654a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
3664a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Is the drag active?
3674a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  bool active_;
3684a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DragData drag_data_;
370ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
371ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Index of the source tab in drag_data_.
372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  size_t source_tab_index_;
373ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
374ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // True until |MoveAttached| is invoked once.
375ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool initial_move_;
376ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3774a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(DraggedTabController);
3784a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch};
3794a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
3804a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#endif  // CHROME_BROWSER_UI_VIEWS_TABS_DRAGGED_TAB_CONTROLLER_H_
381