summaryrefslogtreecommitdiffstats
path: root/chrome/browser/views/tabs/dragged_tab_controller.h
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/views/tabs/dragged_tab_controller.h')
-rw-r--r--chrome/browser/views/tabs/dragged_tab_controller.h286
1 files changed, 286 insertions, 0 deletions
diff --git a/chrome/browser/views/tabs/dragged_tab_controller.h b/chrome/browser/views/tabs/dragged_tab_controller.h
new file mode 100644
index 0000000..6c6aed6
--- /dev/null
+++ b/chrome/browser/views/tabs/dragged_tab_controller.h
@@ -0,0 +1,286 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_VIEWS_TABS_DRAGGED_TAB_CONTROLLER_H_
+#define CHROME_BROWSER_VIEWS_TABS_DRAGGED_TAB_CONTROLLER_H_
+
+#include "base/gfx/rect.h"
+#include "base/message_loop.h"
+#include "chrome/browser/tab_contents_delegate.h"
+#include "chrome/browser/views/tabs/tab_renderer.h"
+#include "chrome/common/notification_service.h"
+
+namespace ChromeViews {
+class MouseEvent;
+class View;
+}
+class DraggedTabView;
+class HWNDPhotobooth;
+class SkBitmap;
+class Tab;
+class TabStrip;
+class TabStripModel;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// DraggedTabController
+//
+// An object that handles a drag session for an individual Tab within a
+// TabStrip. This object is created whenever the mouse is pressed down on a
+// Tab and destroyed when the mouse is released or the drag operation is
+// aborted. The Tab that the user dragged (the "source tab") owns this object
+// and must be the only one to destroy it (via |DestroyDragController|).
+//
+///////////////////////////////////////////////////////////////////////////////
+class DraggedTabController : public TabContentsDelegate,
+ public NotificationObserver,
+ public MessageLoopForUI::Observer{
+ public:
+ DraggedTabController(Tab* source_tab, TabStrip* source_tabstrip);
+ virtual ~DraggedTabController();
+
+ // Capture information needed to be used during a drag session for this
+ // controller's associated source Tab and TabStrip. |mouse_offset| is the
+ // distance of the mouse pointer from the Tab's origin.
+ void CaptureDragInfo(const gfx::Point& mouse_offset);
+
+ // Responds to drag events subsequent to StartDrag. 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 so the helper can revert the state to the world before the drag
+ // begun.
+ void EndDrag(bool canceled);
+
+ // Retrieve the source Tab if the TabContents specified matches the one being
+ // dragged by this controller, or NULL if the specified TabContents is not
+ // the same as the one being dragged.
+ Tab* GetDragSourceTabForContents(TabContents* contents) const;
+
+ // Returns true if the specified Tab matches the Tab being dragged.
+ bool IsDragSourceTab(Tab* tab) const;
+
+ private:
+ // Enumeration of the ways a drag session can end.
+ enum EndDragType {
+ // Drag session exited normally: the user released the mouse.
+ NORMAL,
+
+ // The drag session was canceled (alt-tab during drag, escape ...)
+ CANCELED,
+
+ // The tab (NavigationController) was destroyed during the drag.
+ TAB_DESTROYED
+ };
+
+ // Overridden from TabContentsDelegate:
+ virtual void OpenURLFromTab(TabContents* source,
+ const GURL& url,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition,
+ const std::string& override_encoding);
+ virtual void NavigationStateChanged(const TabContents* source,
+ unsigned changed_flags);
+ virtual void ReplaceContents(TabContents* source,
+ TabContents* new_contents);
+ virtual void AddNewContents(TabContents* source,
+ TabContents* new_contents,
+ WindowOpenDisposition disposition,
+ const gfx::Rect& initial_pos,
+ bool user_gesture);
+ virtual void ActivateContents(TabContents* contents);
+ virtual void LoadingStateChanged(TabContents* source);
+ virtual void CloseContents(TabContents* source);
+ virtual void MoveContents(TabContents* source, const gfx::Rect& pos);
+ virtual bool IsPopup(TabContents* source);
+ virtual void ToolbarSizeChanged(TabContents* source, bool is_animating);
+ virtual void URLStarredChanged(TabContents* source, bool starred);
+ virtual void UpdateTargetURL(TabContents* source, const GURL& url);
+
+ // Overridden from NotificationObserver:
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ // Overridden from MessageLoop::Observer:
+ virtual void WillProcessMessage(const MSG& msg);
+ virtual void DidProcessMessage(const MSG& msg);
+
+ // Initialize the offset used to calculate the position to create windows
+ // in |GetWindowCreatePoint|.
+ void InitWindowCreatePoint();
+
+ // Returns the point where a detached window should be created given the
+ // current mouse position.
+ gfx::Point GetWindowCreatePoint() const;
+
+ // Replaces the TabContents being dragged with the specified |new_contents|.
+ // This can occur if the active TabContents for the tab being dragged is
+ // replaced, e.g. if a transition from one TabContentsType to another occurs
+ // during the drag.
+ void ChangeDraggedContents(TabContents* new_contents);
+
+ // Saves focus in the window that the drag initiated from. Focus will be
+ // restored appropriately if the drag ends within this same window.
+ void SaveFocus();
+
+ // Restore focus to the View that had focus before the drag was started, if
+ // the drag ends within the same Window as it began.
+ void RestoreFocus();
+
+ // Tests whether the position of the mouse is past a minimum elasticity
+ // threshold required to start a drag.
+ bool CanStartDrag() const;
+
+ // Move the DraggedTabView according to the current mouse screen position,
+ // potentially updating the source and other TabStrips.
+ void ContinueDragging();
+
+ // Handles moving the Tab within a TabStrip as well as updating the View.
+ void MoveTab(const gfx::Point& screen_point);
+
+ // 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) const;
+
+ // 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();
+
+ // Returns the index where the dragged TabContents should be inserted into
+ // the attached TabStripModel given the DraggedTabView's bounds
+ // |dragged_bounds| in coordinates relative to the attached TabStrip.
+ int GetInsertionIndexForDraggedBounds(const gfx::Rect& dragged_bounds) const;
+
+ // Retrieve the bounds of the DraggedTabView, relative to the attached
+ // TabStrip, given location of the dragged tab in screen coordinates.
+ gfx::Rect GetDraggedViewTabStripBounds(const gfx::Point& screen_point);
+
+ // Get the position of the dragged tab view relative to the attached tab
+ // strip.
+ gfx::Point GetDraggedViewPoint(const gfx::Point& screen_point);
+
+ // Finds the Tab within the specified TabStrip that corresponds to the
+ // dragged TabContents.
+ Tab* GetTabMatchingDraggedContents(TabStrip* tabstrip) const;
+
+ // Does the work for EndDrag.
+ void EndDragImpl(EndDragType how_end);
+
+ // If the drag was aborted for some reason, this function is called to un-do
+ // the changes made during the drag operation.
+ void RevertDrag();
+
+ // Finishes the drag operation. Returns true if the drag controller should
+ // be destroyed immediately, false otherwise.
+ bool CompleteDrag();
+
+ // Create the DraggedTabView, if it does not yet exist.
+ void EnsureDraggedView();
+
+ // Utility for getting the mouse position in screen coordinates.
+ gfx::Point GetCursorScreenPoint() const;
+
+ // Returns the bounds (in screen coordinates) of the specified View.
+ gfx::Rect GetViewScreenBounds(ChromeViews::View* tabstrip) const;
+
+ // Utility to convert the specified TabStripModel index to something valid
+ // for the attached TabStrip.
+ int NormalizeIndexToAttachedTabStrip(int index) const;
+
+ // Hides the frame for the window that contains the TabStrip the current
+ // drag session was initiated from.
+ void HideFrame();
+
+ // Closes a hidden frame at the end of a drag session.
+ void CleanUpHiddenFrame();
+
+ // Cleans up a source tab that is no longer used.
+ void CleanUpSourceTab();
+
+ // Completes the drag session after the view has animated to its final
+ // position.
+ void OnAnimateToBoundsComplete();
+
+ // The TabContents being dragged. This can get replaced during the drag if
+ // the associated NavigationController is navigated to a different
+ // TabContentsType.
+ TabContents* dragged_contents_;
+
+ // The original TabContentsDelegate of |dragged_contents_|, before it was
+ // detached from the browser window. We store this so that we can forward
+ // certain delegate notifications back to it if we can't handle them locally.
+ TabContentsDelegate* original_delegate_;
+
+ // The Tab that initiated the drag session.
+ Tab* source_tab_;
+
+ // The TabStrip |source_tab_| originated from.
+ TabStrip* source_tabstrip_;
+
+ // This is the index of the |source_tab_| in |source_tabstrip_| when the drag
+ // began. This is used to restore the previous state if the drag is aborted.
+ int source_model_index_;
+
+ // The TabStrip the dragged Tab is currently attached to, or NULL if the
+ // dragged Tab is detached.
+ TabStrip* attached_tabstrip_;
+
+ // The visual representation of the dragged Tab.
+ scoped_ptr<DraggedTabView> view_;
+
+ // The photo-booth the TabContents sits in when the Tab is detached, to
+ // obtain screen shots.
+ scoped_ptr<HWNDPhotobooth> photobooth_;
+
+ // The position of the mouse (in screen coordinates) at the start of the drag
+ // operation. This is used to calculate minimum elasticity before a
+ // DraggedTabView is constructed.
+ gfx::Point start_screen_point_;
+
+ // This is the offset of the mouse from the top left of the Tab where
+ // dragging begun. This is used to ensure that the dragged view is always
+ // positioned at the correct location during the drag, and to ensure that the
+ // detached window is created at the right location.
+ gfx::Point mouse_offset_;
+
+ // A hint to use when positioning new windows created by detaching Tabs. This
+ // is the distance of the mouse from the top left of the dragged tab as if it
+ // were the distance of the mouse from the top left of the first tab in the
+ // attached TabStrip from the top left of the window.
+ gfx::Point window_create_point_;
+
+ // The bounds of the browser window before the last Tab was detached. When
+ // the last Tab is detached, rather than destroying the frame (which would
+ // abort the drag session), the frame is moved off-screen. If the drag is
+ // aborted (e.g. by the user pressing Esc, or capture being lost), the Tab is
+ // attached to the hidden frame and the frame moved back to these bounds.
+ gfx::Rect restore_bounds_;
+
+ // The last view that had focus in the window containing |source_tab_|. This
+ // is saved so that focus can be restored properly when a drag begins and
+ // ends within this same window.
+ ChromeViews::View* old_focused_view_;
+
+ bool in_destructor_;
+
+ // The horizontal position of the mouse cursor in screen coordinates at the
+ // time of the last re-order event.
+ int last_move_screen_x_;
+
+ DISALLOW_COPY_AND_ASSIGN(DraggedTabController);
+};
+
+#endif // CHROME_BROWSER_VIEWS_TABS_DRAGGED_TAB_CONTROLLER_H_
+