Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(110)

Unified Diff: chrome/browser/ui/views/tabs/tab_drag_controller.h

Issue 10382060: Unifies the two tab dragging variants. I would have liked to better (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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_
« no previous file with comments | « chrome/browser/ui/views/tabs/default_tab_drag_controller.cc ('k') | chrome/browser/ui/views/tabs/tab_drag_controller.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698