diff options
Diffstat (limited to 'chrome/browser/views/tabs/tab_strip.h')
-rw-r--r-- | chrome/browser/views/tabs/tab_strip.h | 248 |
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); }; |