| Index: chrome/browser/ui/views/tabs/tab_drag_controller.h
|
| ===================================================================
|
| --- chrome/browser/ui/views/tabs/tab_drag_controller.h (revision 135842)
|
| +++ chrome/browser/ui/views/tabs/tab_drag_controller.h (working copy)
|
| @@ -2,8 +2,8 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#ifndef CHROME_BROWSER_UI_VIEWS_TABS_DEFAULT_TAB_DRAG_CONTROLLER_H_
|
| -#define CHROME_BROWSER_UI_VIEWS_TABS_DEFAULT_TAB_DRAG_CONTROLLER_H_
|
| +#ifndef CHROME_BROWSER_UI_VIEWS_TABS_TAB_DRAG_CONTROLLER_H_
|
| +#define CHROME_BROWSER_UI_VIEWS_TABS_TAB_DRAG_CONTROLLER_H_
|
| #pragma once
|
|
|
| #include <vector>
|
| @@ -11,36 +11,53 @@
|
| #include "base/memory/scoped_ptr.h"
|
| #include "base/message_loop.h"
|
| #include "base/timer.h"
|
| +#include "chrome/browser/tabs/tab_strip_model_observer.h"
|
| #include "chrome/browser/tabs/tab_strip_selection_model.h"
|
| #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
|
| #include "chrome/browser/ui/tabs/dock_info.h"
|
| -#include "chrome/browser/ui/views/tabs/tab_drag_controller.h"
|
| #include "content/public/browser/notification_observer.h"
|
| #include "content/public/browser/notification_registrar.h"
|
| #include "content/public/browser/web_contents_delegate.h"
|
| #include "ui/gfx/rect.h"
|
| +#include "ui/views/widget/widget.h"
|
|
|
| namespace views {
|
| class View;
|
| }
|
| class BaseTab;
|
| +class Browser;
|
| class DraggedTabView;
|
| +struct TabRendererData;
|
| class TabStrip;
|
| class TabStripModel;
|
| +class TabStripSelectionModel;
|
|
|
| -struct TabRendererData;
|
| -
|
| -// TabDragController implementation that creates a widget representing the
|
| -// dragged tabs when detached (dragged out of the source window).
|
| -class DefaultTabDragController : public TabDragController,
|
| - public content::WebContentsDelegate,
|
| - public content::NotificationObserver,
|
| - public MessageLoopForUI::Observer {
|
| +// TabDragController is responsible for managing the tab dragging session. When
|
| +// the user presses the mouse on a tab a new TabDragController is created and
|
| +// Drag() is invoked as the mouse is dragged. If the mouse is dragged far enough
|
| +// TabDragController starts a drag session. The drag session is completed when
|
| +// EndDrag() is invoked (or the TabDragController is destroyed).
|
| +//
|
| +// While dragging within a tab strip TabDragController sets the bounds of the
|
| +// tabs (this is referred to as attached). When the user drags far enough such
|
| +// that the tabs should be moved out of the tab strip two possible things
|
| +// can happen (this state is referred to as detached):
|
| +// . If |detach_into_browser_| is true then a new Browser is created and
|
| +// RunMoveLoop() is invoked on the Widget to drag the browser around. This is
|
| +// the default on chromeos and can be enabled on windows with a flag.
|
| +// . If |detach_into_browser_| is false a small representation of the active tab
|
| +// is created and that is dragged around. This mode does not run a nested
|
| +// message loop.
|
| +class TabDragController : public content::WebContentsDelegate,
|
| + public content::NotificationObserver,
|
| + public MessageLoopForUI::Observer,
|
| + public views::Widget::Observer,
|
| + public TabStripModelObserver {
|
| public:
|
| - DefaultTabDragController();
|
| - virtual ~DefaultTabDragController();
|
| + TabDragController();
|
| + virtual ~TabDragController();
|
|
|
| - // Initializes DefaultTabDragController to drag the tabs in |tabs| originating
|
| + // Initializes TabDragController to drag the tabs in |tabs| originating
|
| // from |source_tabstrip|. |source_tab| is the tab that initiated the drag and
|
| // is contained in |tabs|. |mouse_offset| is the distance of the mouse
|
| // pointer from the origin of the first tab in |tabs| and |source_tab_offset|
|
| @@ -57,10 +74,31 @@
|
| const TabStripSelectionModel& initial_selection_model,
|
| bool move_only);
|
|
|
| + // Returns true if there is a drag underway and the drag is attached to
|
| + // |tab_strip|.
|
| + // NOTE: this returns false if the TabDragController is in the process of
|
| + // finishing the drag.
|
| + static bool IsAttachedTo(TabStrip* tab_strip);
|
| +
|
| + // Returns true if there is a drag underway.
|
| + static bool IsActive();
|
| +
|
| // See description above fields for details on these.
|
| bool active() const { return active_; }
|
| const TabStrip* attached_tabstrip() const { return attached_tabstrip_; }
|
|
|
| + // Returns true if a drag started.
|
| + bool started_drag() const { return started_drag_; }
|
| +
|
| + // Invoked as the mouse is dragged. If the mouse moves a sufficient distance
|
| + // before the mouse is released, a drag session is initiated.
|
| + void Drag();
|
| +
|
| + // Complete the current drag session. If the drag session was canceled
|
| + // because the user pressed escape or something interrupted it, |canceled|
|
| + // is true and the drag is reverted.
|
| + void EndDrag(bool canceled);
|
| +
|
| private:
|
| class DockDisplayer;
|
| friend class DockDisplayer;
|
| @@ -83,6 +121,32 @@
|
| TAB_DESTROYED
|
| };
|
|
|
| + // Specifies what should happen when RunMoveLoop complets.
|
| + enum EndRunLoopBehavior {
|
| + // Indicates the drag should end.
|
| + END_RUN_LOOP_STOP_DRAGGING,
|
| +
|
| + // Indicates the drag should continue.
|
| + END_RUN_LOOP_CONTINUE_DRAGGING
|
| + };
|
| +
|
| + // Enumeration of the possible positions the detached tab may detach from.
|
| + enum DetachPosition {
|
| + DETACH_BEFORE,
|
| + DETACH_AFTER,
|
| + DETACH_ABOVE_OR_BELOW
|
| + };
|
| +
|
| + // Indicates the caller should do after invoking DragBrowserToNewTabStrip().
|
| + enum DragBrowserResultType {
|
| + // The caller should return immediately. This return value is used if a
|
| + // nested message loop was created.
|
| + DRAG_BROWSER_RESULT_STOP,
|
| +
|
| + // The caller should continue.
|
| + DRAG_BROWSER_RESULT_CONTINUE,
|
| + };
|
| +
|
| // Stores the date associated with a single tab that is being dragged.
|
| struct TabDragData {
|
| TabDragData();
|
| @@ -114,11 +178,6 @@
|
| // notifications and resets the delegate of the TabContentsWrapper.
|
| void InitTabDragData(BaseTab* tab, TabDragData* drag_data);
|
|
|
| - // TabDragController overrides:
|
| - virtual void Drag() OVERRIDE;
|
| - virtual void EndDrag(bool canceled) OVERRIDE;
|
| - virtual bool GetStartedDrag() const OVERRIDE;
|
| -
|
| // Overridden from content::WebContentsDelegate:
|
| virtual content::WebContents* OpenURLFromTab(
|
| content::WebContents* source,
|
| @@ -141,12 +200,16 @@
|
| const content::NotificationDetails& details) OVERRIDE;
|
|
|
| // Overridden from MessageLoop::Observer:
|
| -#if defined(OS_WIN) || defined(USE_AURA)
|
| virtual base::EventStatus WillProcessEvent(
|
| const base::NativeEvent& event) OVERRIDE;
|
| virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE;
|
| -#endif
|
|
|
| + // Overriden from views::Widget::Observer:
|
| + virtual void OnWidgetMoved(views::Widget* widget) OVERRIDE;
|
| +
|
| + // Overriden from TabStripModelObserver:
|
| + virtual void TabStripEmpty() OVERRIDE;
|
| +
|
| // Initialize the offset used to calculate the position to create windows
|
| // in |GetWindowCreatePoint|. This should only be invoked from |Init|.
|
| void InitWindowCreatePoint();
|
| @@ -173,6 +236,13 @@
|
| // potentially updating the source and other TabStrips.
|
| void ContinueDragging();
|
|
|
| + // Transitions dragging from |attached_tabstrip_| to |target_tabstrip|.
|
| + // |target_tabstrip| is NULL if the mouse is not over a valid tab strip. See
|
| + // DragBrowserResultType for details of the return type.
|
| + DragBrowserResultType DragBrowserToNewTabStrip(
|
| + TabStrip* target_tabstrip,
|
| + const gfx::Point& screen_point);
|
| +
|
| // Handles dragging for a touch tabstrip when the tabs are stacked. Doesn't
|
| // actually reorder the tabs in anyway, just changes what's visible.
|
| void DragActiveTabStacked(const gfx::Point& screen_point);
|
| @@ -192,25 +262,38 @@
|
| // close enough to an edge with stacked tabs.
|
| void StartMoveStackedTimerIfNecessary(int delay_ms);
|
|
|
| -#if defined(OS_WIN) && !defined(USE_AURA)
|
| + // Returns the TabStrip for the specified window, or NULL if one doesn't exist
|
| + // or isn't appropriate.
|
| + TabStrip* GetTabStripForWindow(gfx::NativeWindow window);
|
| +
|
| // Returns the compatible TabStrip that is under the specified point (screen
|
| // coordinates), or NULL if there is none.
|
| TabStrip* GetTabStripForPoint(const gfx::Point& screen_point);
|
| -#endif
|
|
|
| + // Returns true if |tabstrip| contains the specified point in screen
|
| + // coordinates.
|
| + bool DoesTabStripContain(TabStrip* tabstrip,
|
| + const gfx::Point& screen_point) const;
|
| +
|
| + // Returns the DetachPosition given the specified location in screen
|
| + // coordinates.
|
| + DetachPosition GetDetachPosition(const gfx::Point& screen_point);
|
| +
|
| DockInfo GetDockInfoAtPoint(const gfx::Point& screen_point);
|
|
|
| - // Returns the specified |tabstrip| if it contains the specified point
|
| - // (screen coordinates), NULL if it does not.
|
| - TabStrip* GetTabStripIfItContains(TabStrip* tabstrip,
|
| - const gfx::Point& screen_point) const;
|
| -
|
| // Attach the dragged Tab to the specified TabStrip.
|
| void Attach(TabStrip* attached_tabstrip, const gfx::Point& screen_point);
|
|
|
| // Detach the dragged Tab from the current TabStrip.
|
| void Detach();
|
|
|
| + // Detaches the tabs being dragged, creates a new Browser to contain them and
|
| + // runs a nested move loop.
|
| + void DetachIntoNewBrowserAndRunMoveLoop(const gfx::Point& screen_point);
|
| +
|
| + // Runs a nested message loop that handles moving the current Browser.
|
| + void RunMoveLoop();
|
| +
|
| // Determines the index to insert tabs at. |dragged_bounds| is the bounds of
|
| // the tabs being dragged, |start| the index of the tab to start looking from
|
| // and |delta| the amount to increment (1 or -1).
|
| @@ -252,6 +335,8 @@
|
| // WebContents of the dragged tabs. Returns an empty vector if not attached.
|
| std::vector<BaseTab*> GetTabsMatchingDraggedContents(TabStrip* tabstrip);
|
|
|
| + std::vector<gfx::Rect> CalculateBoundsForDraggedTabs(int x_offset);
|
| +
|
| // Does the work for EndDrag. If we actually started a drag and |how_end| is
|
| // not TAB_DESTROYED then one of EndDrag or RevertDrag is invoked.
|
| void EndDragImpl(EndDragType how_end);
|
| @@ -305,13 +390,24 @@
|
| return source_tab_drag_data()->contents;
|
| }
|
|
|
| + // Returns the Widget of the currently attached TabStrip's BrowserView.
|
| + views::Widget* GetAttachedBrowserWidget();
|
| +
|
| // Returns true if the tabs were originality one after the other in
|
| // |source_tabstrip_|.
|
| bool AreTabsConsecutive();
|
|
|
| + // Creates and returns a new Browser to handle the drag.
|
| + Browser* CreateBrowserForDrag(TabStrip* source,
|
| + const gfx::Point& screen_point,
|
| + std::vector<gfx::Rect>* drag_bounds);
|
| +
|
| // Returns the TabStripModel for the specified tabstrip.
|
| TabStripModel* GetModel(TabStrip* tabstrip) const;
|
|
|
| + // If true Detaching creates a new browser and enters a nested message loop.
|
| + const bool detach_into_browser_;
|
| +
|
| // Handles registering for notifications.
|
| content::NotificationRegistrar registrar_;
|
|
|
| @@ -378,11 +474,11 @@
|
| // Timer used to bring the window under the cursor to front. If the user
|
| // stops moving the mouse for a brief time over a browser window, it is
|
| // brought to front.
|
| - base::OneShotTimer<DefaultTabDragController> bring_to_front_timer_;
|
| + base::OneShotTimer<TabDragController> bring_to_front_timer_;
|
|
|
| // Timer used to move the stacked tabs. See comment aboue
|
| // StartMoveStackedTimerIfNecessary().
|
| - base::OneShotTimer<DefaultTabDragController> move_stacked_timer_;
|
| + base::OneShotTimer<TabDragController> move_stacked_timer_;
|
|
|
| // Did the mouse move enough that we started a drag?
|
| bool started_drag_;
|
| @@ -420,7 +516,27 @@
|
| // Coordinate last used in MoveAttached().
|
| gfx::Point last_screen_point_;
|
|
|
| - DISALLOW_COPY_AND_ASSIGN(DefaultTabDragController);
|
| + // The following are needed when detaching into a real browser.
|
| +
|
| + // Set to true if we've detached from a tabstrip and are running a nested
|
| + // move message loop.
|
| + bool is_dragging_window_;
|
| +
|
| + EndRunLoopBehavior end_run_loop_behavior_;
|
| +
|
| + // If true, we're waiting for a move loop to complete.
|
| + bool waiting_for_run_loop_to_exit_;
|
| +
|
| + // The TabStrip to attach to after the move loop completes.
|
| + TabStrip* tab_strip_to_attach_to_after_exit_;
|
| +
|
| + // Non-null for the duration of RunMoveLoop.
|
| + views::Widget* move_loop_widget_;
|
| +
|
| + // If non-null set to true from destructor.
|
| + bool* destroyed_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(TabDragController);
|
| };
|
|
|
| -#endif // CHROME_BROWSER_UI_VIEWS_TABS_DEFAULT_TAB_DRAG_CONTROLLER_H_
|
| +#endif // CHROME_BROWSER_UI_VIEWS_TABS_TAB_DRAG_CONTROLLER_H_
|
|
|