summaryrefslogtreecommitdiffstats
path: root/chrome/browser/views/tabs/tab_strip.h
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/views/tabs/tab_strip.h')
-rw-r--r--chrome/browser/views/tabs/tab_strip.h248
1 files changed, 151 insertions, 97 deletions
diff --git a/chrome/browser/views/tabs/tab_strip.h b/chrome/browser/views/tabs/tab_strip.h
index af6cc34..e1cbfda 100644
--- a/chrome/browser/views/tabs/tab_strip.h
+++ b/chrome/browser/views/tabs/tab_strip.h
@@ -5,11 +5,16 @@
#ifndef CHROME_BROWSER_VIEWS_TABS_TAB_STRIP_H_
#define CHROME_BROWSER_VIEWS_TABS_TAB_STRIP_H_
+#include "app/animation_container.h"
#include "base/message_loop.h"
+#include "base/ref_counted.h"
+#include "base/timer.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/views/tabs/base_tab_strip.h"
#include "chrome/browser/views/tabs/tab.h"
#include "gfx/point.h"
+#include "gfx/rect.h"
+#include "views/animation/bounds_animator.h"
#include "views/controls/button/image_button.h"
class DraggedTabController;
@@ -42,7 +47,8 @@ class TabStrip : public BaseTabStrip,
public TabStripModelObserver,
public Tab::TabDelegate,
public views::ButtonListener,
- public MessageLoopForUI::Observer {
+ public MessageLoopForUI::Observer,
+ public views::BoundsAnimatorObserver {
public:
explicit TabStrip(TabStripModel* model);
virtual ~TabStrip();
@@ -62,7 +68,7 @@ class TabStrip : public BaseTabStrip,
void DestroyDraggedSourceTab(Tab* tab);
// Retrieves the ideal bounds for the Tab at the specified index.
- gfx::Rect GetIdealBounds(int index);
+ gfx::Rect GetIdealBounds(int tab_data_index);
// Returns the currently selected tab.
Tab* GetSelectedTab() const;
@@ -103,6 +109,9 @@ class TabStrip : public BaseTabStrip,
virtual views::View* GetViewForPoint(const gfx::Point& point);
virtual void ThemeChanged();
+ // BoundsAnimator::Observer overrides:
+ virtual void OnBoundsAnimatorDone(views::BoundsAnimator* animator);
+
protected:
// Creates a new tab.
virtual Tab* CreateTab();
@@ -114,21 +123,24 @@ class TabStrip : public BaseTabStrip,
// TabStripModelObserver implementation:
virtual void TabInsertedAt(TabContents* contents,
- int index,
+ int model_index,
bool foreground);
- virtual void TabDetachedAt(TabContents* contents, int index);
+ virtual void TabDetachedAt(TabContents* contents, int model_index);
virtual void TabSelectedAt(TabContents* old_contents,
TabContents* contents,
- int index,
+ int model_index,
bool user_gesture);
- virtual void TabMoved(TabContents* contents, int from_index, int to_index);
- virtual void TabChangedAt(TabContents* contents, int index,
+ virtual void TabMoved(TabContents* contents,
+ int from_model_index,
+ int to_model_index);
+ virtual void TabChangedAt(TabContents* contents,
+ int model_index,
TabChangeType change_type);
virtual void TabReplacedAt(TabContents* old_contents,
TabContents* new_contents,
- int index);
- virtual void TabMiniStateChanged(TabContents* contents, int index);
- virtual void TabBlockedStateChanged(TabContents* contents, int index);
+ int model_index);
+ virtual void TabMiniStateChanged(TabContents* contents, int model_index);
+ virtual void TabBlockedStateChanged(TabContents* contents, int model_index);
// Tab::Delegate implementation:
virtual bool IsTabSelected(const Tab* tab) const;
@@ -165,22 +177,70 @@ class TabStrip : public BaseTabStrip,
static const int mini_to_non_mini_gap_;
private:
- class InsertTabAnimation;
- class MiniMoveAnimation;
- class MiniTabAnimation;
- class MoveTabAnimation;
- class RemoveTabAnimation;
- class ResizeLayoutAnimation;
- class TabAnimation;
+ class RemoveTabDelegate;
friend class DraggedTabController;
- friend class InsertTabAnimation;
- friend class MiniMoveAnimation;
- friend class MiniTabAnimation;
- friend class MoveTabAnimation;
- friend class RemoveTabAnimation;
- friend class ResizeLayoutAnimation;
- friend class TabAnimation;
+
+ // AnimationType used for tracking animations that require additional
+ // state beyond just animating the bounds of a view.
+ //
+ // Currently the only animation special cased is that of inserting the new tab
+ // page at the end of the tab strip. Here's the steps that take place when
+ // this happens.
+ // . The newly inserted tab is set to render for the new tab animation
+ // |set_render_as_new_tab|. The timer new_tab_timer_ is used to determine
+ // when to turn this off. This is represented by state ANIMATION_NEW_TAB_1.
+ // . The new tab is rendered in the background with an ever increasing alpha
+ // value and the tab goes slightly past the new tab button. The new tab
+ // button is not visible during this animation. This is represented by the
+ // state ANIMATION_NEW_TAB_2.
+ // . The new tab is animated to its final position and the new tab button is
+ // rendered beneath the selected tab. This is represented by the state
+ // ANIMATION_NEW_TAB_3.
+ enum AnimationType {
+ ANIMATION_DEFAULT,
+
+ ANIMATION_NEW_TAB_1,
+ ANIMATION_NEW_TAB_2,
+ ANIMATION_NEW_TAB_3
+ };
+
+ // Used during a drop session of a url. Tracks the position of the drop as
+ // well as a window used to highlight where the drop occurs.
+ struct DropInfo {
+ DropInfo(int index, bool drop_before, bool paint_down);
+ ~DropInfo();
+
+ // Index of the tab to drop on. If drop_before is true, the drop should
+ // occur between the tab at drop_index - 1 and drop_index.
+ // WARNING: if drop_before is true it is possible this will == tab_count,
+ // which indicates the drop should create a new tab at the end of the tabs.
+ int drop_index;
+ bool drop_before;
+
+ // Direction the arrow should point in. If true, the arrow is displayed
+ // above the tab and points down. If false, the arrow is displayed beneath
+ // the tab and points up.
+ bool point_down;
+
+ // Renders the drop indicator.
+ // TODO(beng): should be views::Widget.
+#if defined(OS_WIN)
+ views::WidgetWin* arrow_window;
+#else
+ views::WidgetGtk* arrow_window;
+#endif
+ views::ImageView* arrow_view;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DropInfo);
+ };
+
+ // The Tabs we contain, and their last generated "good" bounds.
+ struct TabData {
+ Tab* tab;
+ gfx::Rect ideal_bounds;
+ };
TabStrip();
void Init();
@@ -188,9 +248,9 @@ class TabStrip : public BaseTabStrip,
// Set the images for the new tab button.
void LoadNewTabButtonImage();
- // Retrieves the Tab at the specified index. Take care in using this, you may
- // need to use GetTabAtAdjustForAnimation.
- Tab* GetTabAt(int index) const;
+ // Retrieves the Tab at the specified index. Remember, the specified index
+ // is in terms of tab_data, *not* the model.
+ Tab* GetTabAtTabDataIndex(int tab_data_index) const;
// Returns the tab at the specified index. If a remove animation is on going
// and the index is >= the index of the tab being removed, the index is
@@ -198,10 +258,13 @@ class TabStrip : public BaseTabStrip,
// do not line up with the indices of the view. This method adjusts the index
// accordingly.
//
- // Use this instead of GetTabAt if the index comes from the model.
- Tab* GetTabAtAdjustForAnimation(int index) const;
+ // Use this instead of GetTabAtTabDataIndex if the index comes from the model.
+ Tab* GetTabAtModelIndex(int model_index) const;
// Gets the number of Tabs in the collection.
+ // WARNING: this is the number of tabs displayed by the tabstrip, which if
+ // an animation is ongoing is not necessarily the same as the number of tabs
+ // in the model.
int GetTabCount() const;
// Returns the number of mini-tabs.
@@ -224,9 +287,6 @@ class TabStrip : public BaseTabStrip,
double* unselected_width,
double* selected_width) const;
- // Returns the horizontal offset before the tab at |tab_index|.
- int GetTabHOffset(int tab_index);
-
// Perform an animated resize-relayout of the TabStrip immediately.
void ResizeLayoutTabs();
@@ -250,7 +310,7 @@ class TabStrip : public BaseTabStrip,
void UpdateDropIndex(const views::DropTargetEvent& event);
// Sets the location of the drop, repainting as necessary.
- void SetDropIndex(int index, bool drop_before);
+ void SetDropIndex(int tab_data_index, bool drop_before);
// Returns the drop effect for dropping a URL on the tab strip. This does
// not query the data in anyway, it only looks at the source operations.
@@ -268,32 +328,38 @@ class TabStrip : public BaseTabStrip,
// stable representations of Tab positions.
void GenerateIdealBounds();
- // Lays out the New Tab button, assuming the right edge of the last Tab on
- // the TabStrip at |last_tab_right|.
- void LayoutNewTabButton(double last_tab_right, double unselected_width);
+ // Both of these are invoked when a part of the new tab animation completes.
+ // They configure state for the next step in the animation and start it.
+ void NewTabAnimation1Done();
+ void NewTabAnimation2Done();
+
+ // Animates all the views to their ideal bounds.
+ // NOTE: this does *not* invoke GenerateIdealBounds, it uses the bounds
+ // currently set in ideal_bounds.
+ void AnimateToIdealBounds();
- // A generic Layout method for various classes of TabStrip animations,
- // including Insert, Remove and Resize Layout cases/
- void AnimationLayout(double unselected_width);
+ // Returns true if a new tab inserted at specified index should start the
+ // new tab animation. See description above AnimationType for details on
+ // this animation.
+ bool ShouldStartIntertTabAnimationAtEnd(int model_index, bool foreground);
// Starts various types of TabStrip animations.
void StartResizeLayoutAnimation();
- void StartInsertTabAnimation(int index);
- void StartRemoveTabAnimation(int index, TabContents* contents);
- void StartMoveTabAnimation(int from_index, int to_index);
- void StartMiniTabAnimation(int index);
- void StartMiniMoveTabAnimation(int from_index,
- int to_index,
- const gfx::Rect& start_bounds);
-
- // Notifies the TabStrip that the specified TabAnimation has completed.
- // Optionally a full Layout will be performed, specified by |layout|.
- void FinishAnimation(TabAnimation* animation, bool layout);
-
- // Finds the index of the TabContents corresponding to |tab| in our
- // associated TabStripModel, or -1 if there is none (e.g. the specified |tab|
- // is being animated closed).
- int GetIndexOfTab(const Tab* tab) const;
+ void StartInsertTabAnimationAtEnd();
+ void StartInsertTabAnimation(int model_index);
+ void StartRemoveTabAnimation(int model_index);
+ void StartMoveTabAnimation(int from_model_index,
+ int to_model_index);
+ void StartMiniTabAnimation();
+
+ // Stops any ongoing animations. If |layout| is true and an animation is
+ // ongoing this does a layout.
+ void StopAnimating(bool layout);
+
+ // Resets all state related to animations. This is invoked when an animation
+ // completes, prior to starting an animation or when we cancel an animation.
+ // If |stop_new_tab_timer| is true, |new_tab_timer_| is stopped.
+ void ResetAnimationState(bool stop_new_tab_timer);
// Calculates the available width for tabs, assuming a Tab is to be closed.
int GetAvailableWidthForTabs(Tab* last_tab) const;
@@ -302,9 +368,9 @@ class TabStrip : public BaseTabStrip,
// hit-test region of the specified Tab.
bool IsPointInTab(Tab* tab, const gfx::Point& point_in_tabstrip_coords);
- // Cleans up the Tab from the TabStrip at the specified |index|. This is
- // called from the tab animation code and is not a general-purpose method.
- void RemoveTabAt(int index);
+ // Cleans up the Tab from the TabStrip. This is called from the tab animation
+ // code and is not a general-purpose method.
+ void RemoveTab(Tab* tab);
// Called from the message loop observer when a mouse movement has occurred
// anywhere over our containing window.
@@ -313,6 +379,19 @@ class TabStrip : public BaseTabStrip,
// Returns true if any of the tabs are phantom.
bool HasPhantomTabs() const;
+ // Returns the index of the specified tab in the model coordiate system, or
+ // -1 if tab is closing or not in |tab_data_|.
+ int GetModelIndexOfTab(const Tab* tab) const;
+
+ // Returns the index into |tab_data_| corresponding to the index from the
+ // TabStripModel, or |tab_data_.size()| if there is no tab representing
+ // |model_index|.
+ int ModelIndexToTabDataIndex(int model_index) const;
+
+ // Returns the index into |tab_data_| corresponding to the specified tab, or
+ // -1 if the tab isn't in |tab_data_|.
+ int TabDataIndexOfTab(Tab* tab) const;
+
// -- Member Variables ------------------------------------------------------
// Our model.
@@ -331,7 +410,9 @@ class TabStrip : public BaseTabStrip,
// The "New Tab" button.
views::ImageButton* newtab_button_;
- gfx::Size newtab_button_size_;
+
+ // Ideal bounds of the new tab button.
+ gfx::Rect newtab_button_bounds_;
// The current widths of various types of tabs. We save these so that, as
// users close tabs while we're holding them at the same size, we can lay out
@@ -359,37 +440,6 @@ class TabStrip : public BaseTabStrip,
static const int kNewTabButtonWidth = 28;
static const int kNewTabButtonHeight = 18;
- // Used during a drop session of a url. Tracks the position of the drop as
- // well as a window used to highlight where the drop occurs.
- struct DropInfo {
- DropInfo(int index, bool drop_before, bool paint_down);
- ~DropInfo();
-
- // Index of the tab to drop on. If drop_before is true, the drop should
- // occur between the tab at drop_index - 1 and drop_index.
- // WARNING: if drop_before is true it is possible this will == tab_count,
- // which indicates the drop should create a new tab at the end of the tabs.
- int drop_index;
- bool drop_before;
-
- // Direction the arrow should point in. If true, the arrow is displayed
- // above the tab and points down. If false, the arrow is displayed beneath
- // the tab and points up.
- bool point_down;
-
- // Renders the drop indicator.
- // TODO(beng): should be views::Widget.
-#if defined(OS_WIN)
- views::WidgetWin* arrow_window;
-#else
- views::WidgetGtk* arrow_window;
-#endif
- views::ImageView* arrow_view;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(DropInfo);
- };
-
// Valid for the lifetime of a drag over us.
scoped_ptr<DropInfo> drop_info_;
@@ -397,15 +447,19 @@ class TabStrip : public BaseTabStrip,
// the drag session.
scoped_ptr<DraggedTabController> drag_controller_;
- // The Tabs we contain, and their last generated "good" bounds.
- struct TabData {
- Tab* tab;
- gfx::Rect ideal_bounds;
- };
std::vector<TabData> tab_data_;
- // The currently running animation.
- scoped_ptr<TabAnimation> active_animation_;
+ // To ensure all tabs pulse at the same time they share the same animation
+ // container. This is that animation container.
+ scoped_refptr<AnimationContainer> animation_container_;
+
+ views::BoundsAnimator bounds_animator_;
+
+ // Used for stage 1 of new tab animation.
+ base::OneShotTimer<TabStrip> new_tab_timer_;
+
+ // Set for special animations.
+ AnimationType animation_type_;
DISALLOW_COPY_AND_ASSIGN(TabStrip);
};