• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CHROME_BROWSER_UI_VIEWS_TABS_BASE_TAB_STRIP_H_
6 #define CHROME_BROWSER_UI_VIEWS_TABS_BASE_TAB_STRIP_H_
7 #pragma once
8 
9 #include <vector>
10 
11 #include "base/memory/scoped_ptr.h"
12 #include "chrome/browser/ui/views/tabs/abstract_tab_strip_view.h"
13 #include "chrome/browser/ui/views/tabs/base_tab.h"
14 #include "chrome/browser/ui/views/tabs/tab_controller.h"
15 #include "views/animation/bounds_animator.h"
16 #include "views/view.h"
17 
18 class BaseTab;
19 class DraggedTabController;
20 class TabStripController;
21 
22 // Base class for the view tab strip implementations.
23 class BaseTabStrip : public AbstractTabStripView,
24                      public TabController {
25  public:
26   enum Type {
27     HORIZONTAL_TAB_STRIP,
28     VERTICAL_TAB_STRIP
29   };
30 
31   BaseTabStrip(TabStripController* controller, Type type);
32   virtual ~BaseTabStrip();
33 
type()34   Type type() const { return type_; }
35 
36   // Starts highlighting the tab at the specified index.
37   virtual void StartHighlight(int model_index) = 0;
38 
39   // Stops all tab higlighting.
40   virtual void StopAllHighlighting() = 0;
41 
42   // Retrieves the ideal bounds for the Tab at the specified index.
ideal_bounds(int tab_data_index)43   const gfx::Rect& ideal_bounds(int tab_data_index) {
44     return tab_data_[tab_data_index].ideal_bounds;
45   }
46 
47   // Creates and returns a tab that can be used for dragging. Ownership passes
48   // to the caller.
49   virtual BaseTab* CreateTabForDragging() = 0;
50 
51   // Adds a tab at the specified index.
52   void AddTabAt(int model_index, const TabRendererData& data);
53 
54   // Invoked from the controller when the close initiates from the TabController
55   // (the user clicked the tab close button or middle clicked the tab). This is
56   // invoked from Close. Because of unload handlers Close is not always
57   // immediately followed by RemoveTabAt.
PrepareForCloseAt(int model_index)58   virtual void PrepareForCloseAt(int model_index) {}
59 
60   // Removes a tab at the specified index.
61   virtual void RemoveTabAt(int model_index) = 0;
62 
63   // Selects a tab at the specified index. |old_model_index| is the selected
64   // index prior to the selection change.
65   virtual void SelectTabAt(int old_model_index, int new_model_index) = 0;
66 
67   // Moves a tab.
68   virtual void MoveTab(int from_model_index, int to_model_index);
69 
70   // Invoked when the title of a tab changes and the tab isn't loading.
71   virtual void TabTitleChangedNotLoading(int model_index) = 0;
72 
73   // Sets the tab data at the specified model index.
74   virtual void SetTabData(int model_index, const TabRendererData& data);
75 
76   // Returns the tab at the specified model index.
77   virtual BaseTab* GetBaseTabAtModelIndex(int model_index) const;
78 
79   // Returns the tab at the specified tab index.
base_tab_at_tab_index(int tab_index)80   BaseTab* base_tab_at_tab_index(int tab_index) const {
81     return tab_data_[tab_index].tab;
82   }
83 
84   // Returns the index of the specified tab in the model coordiate system, or
85   // -1 if tab is closing or not valid.
86   int GetModelIndexOfBaseTab(const BaseTab* tab) const;
87 
88   // Gets the number of Tabs in the tab strip.
89   // WARNING: this is the number of tabs displayed by the tabstrip, which if
90   // an animation is ongoing is not necessarily the same as the number of tabs
91   // in the model.
tab_count()92   int tab_count() const { return static_cast<int>(tab_data_.size()); }
93 
94   // Cover method for TabStripController::GetCount.
95   int GetModelCount() const;
96 
97   // Cover method for TabStripController::IsValidIndex.
98   bool IsValidModelIndex(int model_index) const;
99 
100   // Returns the index into |tab_data_| corresponding to the index from the
101   // TabStripModel, or |tab_data_.size()| if there is no tab representing
102   // |model_index|.
103   int ModelIndexToTabIndex(int model_index) const;
104 
controller()105   TabStripController* controller() const { return controller_.get(); }
106 
107   // Returns true if a drag session is currently active.
108   bool IsDragSessionActive() const;
109 
110   // Returns true if a tab is being dragged into this tab strip.
111   bool IsActiveDropTarget() const;
112 
113   // AbstractTabStripView implementation
114   virtual bool IsTabStripEditable() const OVERRIDE;
115   virtual bool IsTabStripCloseable() const OVERRIDE;
116   virtual void UpdateLoadingAnimations() OVERRIDE;
117 
118   // TabController overrides:
119   virtual void SelectTab(BaseTab* tab) OVERRIDE;
120   virtual void ExtendSelectionTo(BaseTab* tab) OVERRIDE;
121   virtual void ToggleSelected(BaseTab* tab) OVERRIDE;
122   virtual void AddSelectionFromAnchorTo(BaseTab* tab) OVERRIDE;
123   virtual void CloseTab(BaseTab* tab) OVERRIDE;
124   virtual void ShowContextMenuForTab(BaseTab* tab,
125                                      const gfx::Point& p) OVERRIDE;
126   virtual bool IsActiveTab(const BaseTab* tab) const OVERRIDE;
127   virtual bool IsTabSelected(const BaseTab* tab) const OVERRIDE;
128   virtual bool IsTabPinned(const BaseTab* tab) const OVERRIDE;
129   virtual bool IsTabCloseable(const BaseTab* tab) const OVERRIDE;
130   virtual void MaybeStartDrag(BaseTab* tab,
131                               const views::MouseEvent& event) OVERRIDE;
132   virtual void ContinueDrag(const views::MouseEvent& event) OVERRIDE;
133   virtual bool EndDrag(bool canceled) OVERRIDE;
134   virtual BaseTab* GetTabAt(BaseTab* tab,
135                             const gfx::Point& tab_in_tab_coordinates) OVERRIDE;
136 
137   // View overrides:
138   virtual void Layout() OVERRIDE;
139 
140  protected:
141   // The Tabs we contain, and their last generated "good" bounds.
142   struct TabData {
143     BaseTab* tab;
144     gfx::Rect ideal_bounds;
145   };
146 
147   // View overrides.
148   virtual bool OnMouseDragged(const views::MouseEvent& event) OVERRIDE;
149   virtual void OnMouseReleased(const views::MouseEvent& event) OVERRIDE;
150   virtual void OnMouseCaptureLost() OVERRIDE;
151 
152   // Creates and returns a new tab. The caller owners the returned tab.
153   virtual BaseTab* CreateTab() = 0;
154 
155   // Invoked from |AddTabAt| after the newly created tab has been inserted.
156   // Subclasses should either start an animation, or layout.
157   virtual void StartInsertTabAnimation(int model_index) = 0;
158 
159   // Invoked from |MoveTab| after |tab_data_| has been updated to animate the
160   // move.
161   virtual void StartMoveTabAnimation();
162 
163   // Starts the remove tab animation.
164   virtual void StartRemoveTabAnimation(int model_index);
165 
166   // Starts the mini-tab animation.
167   virtual void StartMiniTabAnimation();
168 
169   // Returns whether the highlight button should be highlighted after a remove.
170   virtual bool ShouldHighlightCloseButtonAfterRemove();
171 
172   // Animates all the views to their ideal bounds.
173   // NOTE: this does *not* invoke GenerateIdealBounds, it uses the bounds
174   // currently set in ideal_bounds.
175   virtual void AnimateToIdealBounds() = 0;
176 
177   // Cleans up the Tab from the TabStrip. This is called from the tab animation
178   // code and is not a general-purpose method.
179   void RemoveAndDeleteTab(BaseTab* tab);
180 
181   // Resets the bounds of all non-closing tabs.
182   virtual void GenerateIdealBounds() = 0;
183 
184   // Invoked during drag to layout the tabs being dragged in |tabs| at
185   // |location|. If |initial_drag| is true, this is the initial layout after the
186   // user moved the mouse far enough to trigger a drag.
187   virtual void LayoutDraggedTabsAt(const std::vector<BaseTab*>& tabs,
188                                    BaseTab* active_tab,
189                                    const gfx::Point& location,
190                                    bool initial_drag) = 0;
191 
192   // Calculates the bounds needed for each of the tabs, placing the result in
193   // |bounds|.
194   virtual void CalculateBoundsForDraggedTabs(
195       const std::vector<BaseTab*>& tabs,
196       std::vector<gfx::Rect>* bounds) = 0;
197 
set_ideal_bounds(int index,const gfx::Rect & bounds)198   void set_ideal_bounds(int index, const gfx::Rect& bounds) {
199     tab_data_[index].ideal_bounds = bounds;
200   }
201 
202   // Returns the index into |tab_data_| corresponding to the specified tab, or
203   // -1 if the tab isn't in |tab_data_|.
204   int TabIndexOfTab(BaseTab* tab) const;
205 
206   // Stops any ongoing animations. If |layout| is true and an animation is
207   // ongoing this does a layout.
208   virtual void StopAnimating(bool layout);
209 
210   // Destroys the active drag controller.
211   void DestroyDragController();
212 
213   // Used by DraggedTabController when the user starts or stops dragging tabs.
214   void StartedDraggingTabs(const std::vector<BaseTab*>& tabs);
215   void StoppedDraggingTabs(const std::vector<BaseTab*>& tabs);
216 
217   // Returns the size needed for the specified tabs. This is invoked during drag
218   // and drop to calculate offsets and positioning.
219   virtual int GetSizeNeededForTabs(const std::vector<BaseTab*>& tabs) = 0;
220 
221   // See description above field for details.
attaching_dragged_tab()222   bool attaching_dragged_tab() const { return attaching_dragged_tab_; }
223 
bounds_animator()224   views::BoundsAnimator& bounds_animator() { return bounds_animator_; }
225 
226   // Invoked prior to starting a new animation.
227   virtual void PrepareForAnimation();
228 
229   // Creates an AnimationDelegate that resets state after a remove animation
230   // completes. The caller owns the returned object.
231   ui::AnimationDelegate* CreateRemoveTabDelegate(BaseTab* tab);
232 
233   // Invoked from Layout if the size changes or layout is really needed.
234   virtual void DoLayout();
235 
236   // Returns true if Tabs in this TabStrip are currently changing size or
237   // position.
238   bool IsAnimating() const;
239 
240   // Get tab at a point in local view coordinates.
241   BaseTab* GetTabAtLocal(const gfx::Point& local_point);
242 
243  private:
244   class RemoveTabDelegate;
245 
246   friend class DraggedTabController;
247 
248   // Invoked from StoppedDraggingTabs to cleanup |tab|. If |tab| is known
249   // |is_first_tab| is set to true.
250   void StoppedDraggingTab(BaseTab* tab, bool* is_first_tab);
251 
252   // See description above field for details.
set_attaching_dragged_tab(bool value)253   void set_attaching_dragged_tab(bool value) { attaching_dragged_tab_ = value; }
254 
255   scoped_ptr<TabStripController> controller_;
256 
257   const Type type_;
258 
259   std::vector<TabData> tab_data_;
260 
261   // The controller for a drag initiated from a Tab. Valid for the lifetime of
262   // the drag session.
263   scoped_ptr<DraggedTabController> drag_controller_;
264 
265   // If true, the insert is a result of a drag attaching the tab back to the
266   // model.
267   bool attaching_dragged_tab_;
268 
269   views::BoundsAnimator bounds_animator_;
270 
271   // Size we last layed out at.
272   gfx::Size last_layout_size_;
273 };
274 
275 #endif  // CHROME_BROWSER_UI_VIEWS_TABS_BASE_TAB_STRIP_H_
276