tab_drag_controller.h revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_UI_VIEWS_TABS_TAB_DRAG_CONTROLLER_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_UI_VIEWS_TABS_TAB_DRAG_CONTROLLER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
11d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/memory/weak_ptr.h"
129ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/tabs/dock_info.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/tabs/tab_strip_types.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_observer.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_registrar.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_delegate.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/models/list_selection_model.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget_observer.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Screen;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace ui {
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ListSelectionModel;
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class View;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Browser;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DraggedTabView;
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class Tab;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct TabRendererData;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TabStrip;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TabStripModel;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TabDragController is responsible for managing the tab dragging session. When
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the user presses the mouse on a tab a new TabDragController is created and
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Drag() is invoked as the mouse is dragged. If the mouse is dragged far enough
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TabDragController starts a drag session. The drag session is completed when
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// EndDrag() is invoked (or the TabDragController is destroyed).
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// While dragging within a tab strip TabDragController sets the bounds of the
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// tabs (this is referred to as attached). When the user drags far enough such
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that the tabs should be moved out of the tab strip two possible things
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// can happen (this state is referred to as detached):
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// . If |detach_into_browser_| is true then a new Browser is created and
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   RunMoveLoop() is invoked on the Widget to drag the browser around. This is
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)//   the default on aura.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// . If |detach_into_browser_| is false a small representation of the active tab
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   is created and that is dragged around. This mode does not run a nested
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   message loop.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TabDragController : public content::WebContentsDelegate,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          public content::NotificationObserver,
58b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                          public base::MessageLoopForUI::Observer,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          public views::WidgetObserver,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          public TabStripModelObserver {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum DetachBehavior {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DETACHABLE,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOT_DETACHABLE
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // What should happen as the mouse is dragged within the tabstrip.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum MoveBehavior {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Only the set of visible tabs should change. This is only applicable when
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // using touch layout.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MOVE_VISIBILE_TABS,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Typical behavior where tabs are dragged around.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    REORDER
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Indicates the event source that initiated the drag.
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  enum EventSource {
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EVENT_SOURCE_MOUSE,
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EVENT_SOURCE_TOUCH,
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Amount above or below the tabstrip the user has to drag before detaching.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kTouchVerticalDetachMagnetism;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kVerticalDetachMagnetism;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TabDragController();
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~TabDragController();
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Initializes TabDragController to drag the tabs in |tabs| originating from
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |source_tabstrip|. |source_tab| is the tab that initiated the drag and is
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // contained in |tabs|.  |mouse_offset| is the distance of the mouse pointer
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // from the origin of the first tab in |tabs| and |source_tab_offset| the
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // offset from |source_tab|. |source_tab_offset| is the horizontal offset of
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |mouse_offset| relative to |source_tab|. |initial_selection_model| is the
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // selection model before the drag started and is only non-empty if
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |source_tab| was not initially selected.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Init(TabStrip* source_tabstrip,
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            Tab* source_tab,
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            const std::vector<Tab*>& tabs,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            const gfx::Point& mouse_offset,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            int source_tab_offset,
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            const ui::ListSelectionModel& initial_selection_model,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            DetachBehavior detach_behavior,
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            MoveBehavior move_behavior,
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            EventSource event_source);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if there is a drag underway and the drag is attached to
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |tab_strip|.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: this returns false if the TabDragController is in the process of
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // finishing the drag.
1121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  static bool IsAttachedTo(const TabStrip* tab_strip);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if there is a drag underway.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool IsActive();
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Used to determine whether the tab drag controller detaches dragged tabs
1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // into new browser windows while the drag is in process.
1197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static bool ShouldDetachIntoNewBrowser();
1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets the move behavior. Has no effect if started_drag() is true.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetMoveBehavior(MoveBehavior behavior);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MoveBehavior move_behavior() const { return move_behavior_; }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventSource event_source() const { return event_source_; }
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See description above fields for details on these.
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool active() const { return active_; }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TabStrip* attached_tabstrip() const { return attached_tabstrip_; }
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if a drag started.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool started_drag() const { return started_drag_; }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if mutating the TabStripModel.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_mutating() const { return is_mutating_; }
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if we've detached from a tabstrip and are running a nested
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // move message loop.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_dragging_window() const { return is_dragging_window_; }
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invoked to drag to the new location, in screen coordinates.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Drag(const gfx::Point& point_in_screen);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the current drag session.
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void EndDrag(EndDragReason reason);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class DockDisplayer;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class DockDisplayer;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::set<gfx::NativeView> DockWindows;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used to indicate the direction the mouse has moved when attached.
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kMovedMouseLeft  = 1 << 0;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kMovedMouseRight = 1 << 1;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enumeration of the ways a drag session can end.
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum EndDragType {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Drag session exited normally: the user released the mouse.
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NORMAL,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The drag session was canceled (alt-tab during drag, escape ...)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CANCELED,
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The tab (NavigationController) was destroyed during the drag.
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TAB_DESTROYED
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Whether Detach() should release capture or not.
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum ReleaseCapture {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RELEASE_CAPTURE,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DONT_RELEASE_CAPTURE,
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Specifies what should happen when RunMoveLoop completes.
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum EndRunLoopBehavior {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Indicates the drag should end.
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    END_RUN_LOOP_STOP_DRAGGING,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Indicates the drag should continue.
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    END_RUN_LOOP_CONTINUE_DRAGGING
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enumeration of the possible positions the detached tab may detach from.
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum DetachPosition {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DETACH_BEFORE,
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DETACH_AFTER,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DETACH_ABOVE_OR_BELOW
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Indicates what should happen after invoking DragBrowserToNewTabStrip().
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum DragBrowserResultType {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The caller should return immediately. This return value is used if a
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // nested message loop was created or we're in a nested message loop and
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // need to exit it.
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DRAG_BROWSER_RESULT_STOP,
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The caller should continue.
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DRAG_BROWSER_RESULT_CONTINUE,
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Stores the date associated with a single tab that is being dragged.
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct TabDragData {
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TabDragData();
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~TabDragData();
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The WebContents being dragged.
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content::WebContents* contents;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // content::WebContentsDelegate for |contents| before it was detached from
2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // the browser window. We store this so that we can forward certain delegate
2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // notifications back to it if we can't handle them locally.
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::WebContentsDelegate* original_delegate;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This is the index of the tab in |source_tabstrip_| when the drag
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // began. This is used to restore the previous state if the drag is aborted.
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int source_model_index;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If attached this is the tab in |attached_tabstrip_|.
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Tab* attached_tab;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Is the tab pinned?
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool pinned;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::vector<TabDragData> DragData;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets |drag_data| from |tab|. This also registers for necessary
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // notifications and resets the delegate of the WebContents.
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void InitTabDragData(Tab* tab, TabDragData* drag_data);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from content::WebContentsDelegate:
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual content::WebContents* OpenURLFromTab(
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::WebContents* source,
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const content::OpenURLParams& params) OVERRIDE;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void NavigationStateChanged(const content::WebContents* source,
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      unsigned changed_flags) OVERRIDE;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void AddNewContents(content::WebContents* source,
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              content::WebContents* new_contents,
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              WindowOpenDisposition disposition,
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const gfx::Rect& initial_pos,
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              bool user_gesture,
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              bool* was_blocked) OVERRIDE;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void LoadingStateChanged(content::WebContents* source) OVERRIDE;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool ShouldSuppressDialogs() OVERRIDE;
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual content::JavaScriptDialogManager*
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetJavaScriptDialogManager() OVERRIDE;
248d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  virtual void RequestMediaAccessPermission(
249d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      content::WebContents* web_contents,
250d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      const content::MediaStreamRequest& request,
251d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      const content::MediaResponseCallback& callback) OVERRIDE;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from content::NotificationObserver:
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Observe(int type,
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationSource& source,
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from MessageLoop::Observer:
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual base::EventStatus WillProcessEvent(
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const base::NativeEvent& event) OVERRIDE;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overriden from views::WidgetObserver:
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWidgetBoundsChanged(views::Widget* widget,
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const gfx::Rect& new_bounds) OVERRIDE;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overriden from TabStripModelObserver:
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TabStripEmpty() OVERRIDE;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initialize the offset used to calculate the position to create windows
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in |GetWindowCreatePoint|. This should only be invoked from |Init|.
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InitWindowCreatePoint();
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the point where a detached window should be created given the
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // current mouse position |origin|.
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point GetWindowCreatePoint(const gfx::Point& origin) const;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UpdateDockInfo(const gfx::Point& point_in_screen);
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Saves focus in the window that the drag initiated from. Focus will be
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // restored appropriately if the drag ends within this same window.
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SaveFocus();
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Restore focus to the View that had focus before the drag was started, if
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the drag ends within the same Window as it began.
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RestoreFocus();
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tests whether |point_in_screen| is past a minimum elasticity threshold
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // required to start a drag.
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool CanStartDrag(const gfx::Point& point_in_screen) const;
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move the DraggedTabView according to the current mouse screen position,
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // potentially updating the source and other TabStrips.
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ContinueDragging(const gfx::Point& point_in_screen);
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transitions dragging from |attached_tabstrip_| to |target_tabstrip|.
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |target_tabstrip| is NULL if the mouse is not over a valid tab strip.  See
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DragBrowserResultType for details of the return type.
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DragBrowserResultType DragBrowserToNewTabStrip(
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TabStrip* target_tabstrip,
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const gfx::Point& point_in_screen);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handles dragging for a touch tabstrip when the tabs are stacked. Doesn't
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // actually reorder the tabs in anyway, just changes what's visible.
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DragActiveTabStacked(const gfx::Point& point_in_screen);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Moves the active tab to the next/previous tab. Used when the next/previous
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // tab is stacked.
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MoveAttachedToNextStackedIndex(const gfx::Point& point_in_screen);
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MoveAttachedToPreviousStackedIndex(const gfx::Point& point_in_screen);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handles dragging tabs while the tabs are attached.
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MoveAttached(const gfx::Point& point_in_screen);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handles dragging while the tabs are detached.
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MoveDetached(const gfx::Point& point_in_screen);
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If necessary starts the |move_stacked_timer_|. The timer is started if
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // close enough to an edge with stacked tabs.
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartMoveStackedTimerIfNecessary(
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const gfx::Point& point_in_screen,
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int delay_ms);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the TabStrip for the specified window, or NULL if one doesn't exist
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or isn't compatible.
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TabStrip* GetTabStripForWindow(gfx::NativeWindow window);
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the compatible TabStrip to drag to at the specified point (screen
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // coordinates), or NULL if there is none.
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TabStrip* GetTargetTabStripForPoint(const gfx::Point& point_in_screen);
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if |tabstrip| contains the specified point in screen
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // coordinates.
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool DoesTabStripContain(TabStrip* tabstrip,
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const gfx::Point& point_in_screen) const;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the DetachPosition given the specified location in screen
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // coordinates.
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DetachPosition GetDetachPosition(const gfx::Point& point_in_screen);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DockInfo GetDockInfoAtPoint(const gfx::Point& point_in_screen);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Attach the dragged Tab to the specified TabStrip.
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Attach(TabStrip* attached_tabstrip, const gfx::Point& point_in_screen);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Detach the dragged Tab from the current TabStrip.
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Detach(ReleaseCapture release_capture);
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Detaches the tabs being dragged, creates a new Browser to contain them and
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // runs a nested move loop.
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DetachIntoNewBrowserAndRunMoveLoop(const gfx::Point& point_in_screen);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Runs a nested message loop that handles moving the current
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Browser. |drag_offset| is the offset from the window origin and is used in
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // calculating the location of the window offset from the cursor while
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // dragging.
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RunMoveLoop(const gfx::Vector2d& drag_offset);
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Determines the index to insert tabs at. |dragged_bounds| is the bounds of
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the tabs being dragged, |start| the index of the tab to start looking from
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and |delta| the amount to increment (1 or -1).
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int GetInsertionIndexFrom(const gfx::Rect& dragged_bounds,
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            int start,
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            int delta) const;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the index where the dragged WebContents should be inserted into
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |attached_tabstrip_| given the DraggedTabView's bounds |dragged_bounds| in
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // coordinates relative to |attached_tabstrip_| and has had the mirroring
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transformation applied.
3704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // NOTE: this is invoked from Attach() before the tabs have been inserted.
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int GetInsertionIndexForDraggedBounds(const gfx::Rect& dragged_bounds) const;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if |dragged_bounds| is close enough to the next stacked tab
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so that the active tab should be dragged there.
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ShouldDragToNextStackedTab(const gfx::Rect& dragged_bounds,
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  int index) const;
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if |dragged_bounds| is close enough to the previous stacked
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // tab so that the active tab should be dragged there.
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ShouldDragToPreviousStackedTab(const gfx::Rect& dragged_bounds,
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      int index) const;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used by GetInsertionIndexForDraggedBounds() when the tabstrip is stacked.
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int GetInsertionIndexForDraggedBoundsStacked(
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const gfx::Rect& dragged_bounds) const;
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieve the bounds of the DraggedTabView relative to the attached
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TabStrip. |tab_strip_point| is in the attached TabStrip's coordinate
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // system.
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect GetDraggedViewTabStripBounds(const gfx::Point& tab_strip_point);
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the position of the dragged tab view relative to the attached tab
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // strip with the mirroring transform applied.
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point GetAttachedDragPoint(const gfx::Point& point_in_screen);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finds the Tabs within the specified TabStrip that corresponds to the
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WebContents of the dragged tabs. Returns an empty vector if not attached.
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<Tab*> GetTabsMatchingDraggedContents(TabStrip* tabstrip);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Returns the bounds for the tabs based on the attached tab strip.
4014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<gfx::Rect> CalculateBoundsForDraggedTabs();
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Does the work for EndDrag(). If we actually started a drag and |how_end| is
4044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // not TAB_DESTROYED then one of EndDrag() or RevertDrag() is invoked.
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void EndDragImpl(EndDragType how_end);
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reverts a cancelled drag operation.
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RevertDrag();
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reverts the tab at |drag_index| in |drag_data_|.
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RevertDragAt(size_t drag_index);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Selects the dragged tabs in |model|. Does nothing if there are no longer
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // any dragged contents (as happens when a WebContents is deleted out from
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // under us).
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ResetSelection(TabStripModel* model);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finishes a succesful drag operation.
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CompleteDrag();
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Resets the delegates of the WebContents.
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ResetDelegates();
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create the DraggedTabView.
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CreateDraggedView(const std::vector<TabRendererData>& data,
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const std::vector<gfx::Rect>& renderer_bounds);
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the bounds (in screen coordinates) of the specified View.
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect GetViewScreenBounds(views::View* tabstrip) const;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Hides the frame for the window that contains the TabStrip the current
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // drag session was initiated from.
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HideFrame();
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Closes a hidden frame at the end of a drag session.
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CleanUpHiddenFrame();
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DockDisplayerDestroyed(DockDisplayer* controller);
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void BringWindowUnderPointToFront(const gfx::Point& point_in_screen);
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Convenience for getting the TabDragData corresponding to the tab the user
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // started dragging.
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TabDragData* source_tab_drag_data() {
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return &(drag_data_[source_tab_index_]);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Convenience for |source_tab_drag_data()->contents|.
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebContents* source_dragged_contents() {
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return source_tab_drag_data()->contents;
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the Widget of the currently attached TabStrip's BrowserView.
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::Widget* GetAttachedBrowserWidget();
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the tabs were originality one after the other in
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |source_tabstrip_|.
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool AreTabsConsecutive();
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
460a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Calculates and returns new bounds for the dragged browser window.
461a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Takes into consideration current and restore bounds of |source| tab strip
462a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // preventing the dragged size from being too small. Positions the new bounds
463a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // such that the tab that was dragged remains under the |point_in_screen|.
464a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Offsets |drag_bounds| if necessary when dragging to the right from the
465a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // source browser.
466a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gfx::Rect CalculateDraggedBrowserBounds(TabStrip* source,
467a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                          const gfx::Point& point_in_screen,
468a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                          std::vector<gfx::Rect>* drag_bounds);
469a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Calculates scaled |drag_bounds| for dragged tabs and sets the tabs bounds.
471a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Layout of the tabstrip is performed and a new tabstrip width calculated.
472a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // When |last_tabstrip_width| is larger than the new tabstrip width the tabs
473a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // in attached tabstrip are scaled and the attached browser is positioned such
474a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // that the tab that was dragged remains under the |point_in_screen|.
475a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void AdjustBrowserAndTabBoundsForDrag(int last_tabstrip_width,
476a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                        const gfx::Point& point_in_screen,
477a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                        std::vector<gfx::Rect>* drag_bounds);
478a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates and returns a new Browser to handle the drag.
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Browser* CreateBrowserForDrag(TabStrip* source,
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const gfx::Point& point_in_screen,
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                gfx::Vector2d* drag_offset,
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                std::vector<gfx::Rect>* drag_bounds);
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the TabStripModel for the specified tabstrip.
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TabStripModel* GetModel(TabStrip* tabstrip) const;
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the location of the cursor. This is either the location of the
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // mouse or the location of the current touch point.
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point GetCursorScreenPoint();
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the offset from the top left corner of the window to
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |point_in_screen|.
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Vector2d GetWindowOffset(const gfx::Point& point_in_screen);
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if moving the mouse only changes the visible tabs.
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool move_only() const {
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (move_behavior_ == MOVE_VISIBILE_TABS) != 0;
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // If true detaching creates a new browser and enters a nested message loop.
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool detach_into_browser_;
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handles registering for notifications.
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationRegistrar registrar_;
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventSource event_source_;
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The TabStrip the drag originated from.
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TabStrip* source_tabstrip_;
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The TabStrip the dragged Tab is currently attached to, or NULL if the
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // dragged Tab is detached.
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TabStrip* attached_tabstrip_;
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The screen that this drag is associated with. Cached, because other UI
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // elements are NULLd at various points during the lifetime of this object.
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Screen* screen_;
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The desktop type that this drag is associated with. Cached, because other
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // UI elements are NULLd at various points during the lifetime of this
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // object.
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::HostDesktopType host_desktop_type_;
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The visual representation of the dragged Tab.
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DraggedTabView> view_;
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The position of the mouse (in screen coordinates) at the start of the drag
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // operation. This is used to calculate minimum elasticity before a
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DraggedTabView is constructed.
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point start_point_in_screen_;
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // This is the offset of the mouse from the top left of the first Tab where
5344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // dragging began. This is used to ensure that the dragged view is always
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // positioned at the correct location during the drag, and to ensure that the
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // detached window is created at the right location.
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point mouse_offset_;
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Ratio of the x-coordinate of the |source_tab_offset| to the width of the
5404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // tab.
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float offset_to_width_ratio_;
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A hint to use when positioning new windows created by detaching Tabs. This
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is the distance of the mouse from the top left of the dragged tab as if it
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // were the distance of the mouse from the top left of the first tab in the
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // attached TabStrip from the top left of the window.
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point window_create_point_;
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Location of the first tab in the source tabstrip in screen coordinates.
5504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // This is used to calculate |window_create_point_|.
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point first_source_tab_point_;
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The bounds of the browser window before the last Tab was detached. When
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the last Tab is detached, rather than destroying the frame (which would
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // abort the drag session), the frame is moved off-screen. If the drag is
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // aborted (e.g. by the user pressing Esc, or capture being lost), the Tab is
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // attached to the hidden frame and the frame moved back to these bounds.
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect restore_bounds_;
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
560f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Storage ID in ViewStorage where the last view that had focus in the window
561f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // containing |source_tab_| is saved. This is saved so that focus can be
562f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // restored properly when a drag begins and ends within this same window.
56358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const int old_focused_view_id_;
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // The horizontal position of the mouse cursor in screen coordinates at the
5664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // time of the last re-order event.
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int last_move_screen_loc_;
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DockInfo dock_info_;
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DockWindows dock_windows_;
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<DockDisplayer*> dock_controllers_;
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Timer used to bring the window under the cursor to front. If the user
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // stops moving the mouse for a brief time over a browser window, it is
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // brought to front.
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::OneShotTimer<TabDragController> bring_to_front_timer_;
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Timer used to move the stacked tabs. See comment aboue
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // StartMoveStackedTimerIfNecessary().
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::OneShotTimer<TabDragController> move_stacked_timer_;
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Did the mouse move enough that we started a drag?
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool started_drag_;
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Is the drag active?
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool active_;
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DragData drag_data_;
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Index of the source tab in |drag_data_|.
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t source_tab_index_;
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // True until MoveAttached() is first invoked.
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool initial_move_;
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The selection model before the drag started. See comment above Init() for
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // details.
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ListSelectionModel initial_selection_model_;
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The selection model of |attached_tabstrip_| before the tabs were attached.
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ListSelectionModel selection_model_before_attach_;
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initial x-coordinates of the tabs when the drag started. Only used for
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // touch mode.
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<int> initial_tab_positions_;
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DetachBehavior detach_behavior_;
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MoveBehavior move_behavior_;
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Updated as the mouse is moved when attached. Indicates whether the mouse
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // has ever moved to the left or right. If the tabs are ever detached this
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is set to kMovedMouseRight | kMovedMouseLeft.
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int mouse_move_direction_;
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Last location used in screen coordinates.
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point last_point_in_screen_;
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The following are needed when detaching into a browser
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (|detach_into_browser_| is true).
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See description above getter.
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_dragging_window_;
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // True if |attached_tabstrip_| is in a browser specifically created for
62768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // the drag.
62868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  bool is_dragging_new_browser_;
62968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
63068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // True if |source_tabstrip_| was maximized before the drag.
63168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  bool was_source_maximized_;
63268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
63368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // True if |source_tabstrip_| was in immersive fullscreen before the drag.
63468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  bool was_source_fullscreen_;
63568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EndRunLoopBehavior end_run_loop_behavior_;
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If true, we're waiting for a move loop to complete.
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool waiting_for_run_loop_to_exit_;
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The TabStrip to attach to after the move loop completes.
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TabStrip* tab_strip_to_attach_to_after_exit_;
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Non-null for the duration of RunMoveLoop.
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::Widget* move_loop_widget_;
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See description above getter.
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_mutating_;
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |attach_x_| and |attach_index_| are set to the x-coordinate of the mouse
6514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // (in terms of the tabstrip) and the insertion index at the time tabs are
6524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // dragged into a new browser (attached). They are used to ensure we don't
6534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // shift the tabs around in the wrong direction. The two are only valid if
6544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |attach_index_| is not -1.
6554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // See comment around use for more details.
6564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int attach_x_;
6574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int attach_index_;
6584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
659d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  base::WeakPtrFactory<TabDragController> weak_factory_;
660d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TabDragController);
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_BROWSER_UI_VIEWS_TABS_TAB_DRAG_CONTROLLER_H_
665