1 // Copyright (c) 2012 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.
5 #ifndef CHROME_BROWSER_UI_VIEWS_TABS_STACKED_TAB_STRIP_LAYOUT_H_
6 #define CHROME_BROWSER_UI_VIEWS_TABS_STACKED_TAB_STRIP_LAYOUT_H_
10 #include "base/basictypes.h"
11 #include "ui/gfx/geometry/size.h"
12 #include "ui/views/view_model.h"
16 // StackedTabStripLayout is used by TabStrip in touch
17 // mode. StackedTabStripLayout is responsible for managing the bounds of the
18 // tabs. StackedTabStripLayout differs from the normal layout in that it stacks
19 // tabs. Stacked tabs are tabs placed nearly on top of each other, and if enough
20 // consecutive stacked tabs exist they are placed on top of each other. Normally
21 // stacked tabs are placed after mini-tabs, or at the end of the tabstrip, but
22 // during dragging tabs may be stacked before or after the active tab.
23 class StackedTabStripLayout
{
25 static const int kAddTypeMini
= 1 << 0;
26 static const int kAddTypeActive
= 1 << 1;
28 // |size| is the size for tabs, |padding| the padding between consecutive
29 // tabs, |stacked_padding| the padding between stacked tabs,
30 // |max_stacked_count| the maximum number of consecutive tabs that can be
31 // stacked before they are placed on top of each other, |view_model| is the
32 // ViewModel the bounds of the tabs are placed in.
33 StackedTabStripLayout(const gfx::Size
& size
,
36 int max_stacked_count
,
37 views::ViewModelBase
* view_model
);
38 ~StackedTabStripLayout();
40 // Sets the x-coordinate the normal tabs start at as well as the mini-tab
41 // count. This is only useful if the mini-tab count or x-coordinate change.
42 void SetXAndMiniCount(int x
, int mini_tab_count
);
44 // Sets the width available for sizing the tabs to.
45 void SetWidth(int width
);
47 int width() const { return width_
; }
49 // Sets the index of the active tab.
50 void SetActiveIndex(int index
);
52 // Drags the active tab.
53 void DragActiveTab(int delta
);
55 // Makes sure the tabs fill the available width. Used after a drag operation
59 // Adds a new tab at the specified index. |add_types| is a bitmask of
60 // kAddType*. |start_x| is the new x-coordinate non-mini tabs start at.
61 void AddTab(int index
, int add_types
, int start_x
);
63 // Removes the tab at the specified index. |start_x| is the new x-coordinate
64 // normal tabs start at, and |old_x| the old x-coordinate of the tab. It is
65 // expected that the ViewModel hash been updated at the time this is invoked.
66 void RemoveTab(int index
, int start_x
, int old_x
);
68 // Moves the tab from |from| to |to|. |new_active_index| is the index of the
69 // currently active tab.
70 void MoveTab(int from
,
76 // Returns the active index as used by this class. The active index dictates
77 // stacking and what tabs are visible. As mini-tabs are never stacked,
78 // StackedTabStripLayout forces the active index to be in the normal tabs.
79 int active_index() const {
80 return active_index_
< mini_tab_count_
? mini_tab_count_
: active_index_
;
83 int mini_tab_count() const { return mini_tab_count_
; }
85 // Returns true if the tab at index is stacked.
86 bool IsStacked(int index
) const;
88 // Sets the location of the active tab as close to |x| as possible.
89 void SetActiveTabLocation(int x
);
92 std::string
BoundsString() const;
96 friend class StackedTabStripLayoutTest
;
98 // Sets the x-coordinate normal tabs start at, width mini-tab count and
99 // active index at once.
100 void Reset(int x
, int width
, int mini_tab_count
, int active_index
);
102 // Resets to an ideal layout state.
103 void ResetToIdealState();
105 // Makes |index| visible. This is used when a new tab is added that isn't
107 void MakeVisible(int index
);
109 // Returns the x-coordinate for the active tab constrained by the current tab
111 int ConstrainActiveX(int x
) const;
113 // Reset the bounds of the active tab (based on ConstrainActiveX()) and resets
114 // the bounds of the remaining tabs by way of LayoutUsingCurrent*.
115 void SetActiveBoundsAndLayoutFromActiveTab();
117 // Sets the bounds of the tabs after |index| relative to the position of the
118 // tab at |index|. Each tab is placed |tab_offset()| pixels after the previous
119 // tab, stacking as necessary.
120 void LayoutByTabOffsetAfter(int index
);
122 // Same as LayoutByTabOffsetAfter(), but iterates toward
123 // |mini_tab_count_|.
124 void LayoutByTabOffsetBefore(int index
);
126 // Similar to LayoutByTabOffsetAfter(), but uses the current x-coordinate
128 void LayoutUsingCurrentAfter(int index
);
129 void LayoutUsingCurrentBefore(int index
);
131 void PushTabsAfter(int index
, int delta
);
132 void PushTabsBefore(int index
, int delta
);
134 // Does a layout for drag. Similar to LayoutUsingCurrentXXX() but does not
135 // contrain. Used when dragging the active tab.
136 void LayoutForDragAfter(int index
);
137 void LayoutForDragBefore(int index
);
139 // Used when the tabs are stacked at one side. The remaining tabs are stacked
140 // against the |active_index()|. |delta| is the amount of space to resize the
142 void ExpandTabsBefore(int index
, int delta
);
143 void ExpandTabsAfter(int index
, int delta
);
145 // Adjusts the stacked tabs so that if there are more than
146 // |max_stacked_count_| tabs, the set > max_stacked_count_ have an
147 // x-coordinate of |x_|. Similarly those at the end have the same x-coordinate
148 // and are pushed all the way to the right.
149 void AdjustStackedTabs();
150 void AdjustLeadingStackedTabs();
151 void AdjustTrailingStackedTabs();
153 // Sets the bounds of the tab at |index|.
154 void SetIdealBoundsAt(int index
, int x
);
156 // Returns the min x-coordinate for the sepcified index. This is calculated
157 // assuming all the tabs before |index| are stacked.
158 int GetMinX(int index
) const;
160 // Returns the max x-coordinate for the speficifed index. This is calculated
161 // assuming all the tabs after |index| are stacked.
162 int GetMaxX(int index
) const;
164 // Used when dragging to get the min/max coodinate.
165 int GetMinDragX(int index
) const;
166 int GetMaxDragX(int index
) const;
168 // Returns the min x-coordinate for the tab at |index|. This is relative
169 // to the |active_index()| and is only useful when the active tab is pushed
170 // against the left side.
171 int GetMinXCompressed(int index
) const;
173 // Width needed to display |count| tabs.
174 int width_for_count(int count
) const {
175 return (count
* size_
.width()) + (std::max(count
- 1, 0) * padding_
);
178 // Padding needed for |count| stacked tabs.
179 int stacked_padding_for_count(int count
) const {
180 return std::min(count
, max_stacked_count_
) * stacked_padding_
;
183 // Max stacked padding.
184 int max_stacked_width() const {
185 return stacked_padding_
* max_stacked_count_
;
188 int ideal_x(int index
) const { return view_model_
->ideal_bounds(index
).x(); }
190 // Returns true if some of the tabs need to be stacked.
191 bool requires_stacking() const {
192 return tab_count() != mini_tab_count_
&&
193 x_
+ width_for_count(tab_count() - mini_tab_count_
) > width_
;
197 int tab_count() const { return view_model_
->view_size(); }
199 // Number of normal (non-mini) tabs.
200 int normal_tab_count() const { return tab_count() - mini_tab_count_
; }
202 // Distance between one tab to the next.
203 int tab_offset() const { return size_
.width() + padding_
; }
206 const gfx::Size size_
;
208 // Padding between tabs.
211 // Padding between stacked tabs.
212 const int stacked_padding_
;
214 // Max number of stacked tabs.
215 const int max_stacked_count_
;
217 // Where bounds are placed. This is owned by TabStrip.
218 // (Note: This is a ViewModelBase, not a ViewModelT<Tab>, because the tests do
219 // not populate the model with Tab views.)
220 views::ViewModelBase
* view_model_
;
222 // x-coordinate normal tabs start at.
228 // Number of mini-tabs.
231 // Distance from the last mini-tab to the first non-mini-tab.
232 int mini_tab_to_non_mini_tab_
;
234 // Index of the active tab.
237 // X-coordinate of the first tab. This is either |x_| if there are no
238 // mini-tabs, or the x-coordinate of the first mini-tab.
241 DISALLOW_COPY_AND_ASSIGN(StackedTabStripLayout
);
244 #endif // CHROME_BROWSER_UI_VIEWS_TABS_STACKED_TAB_STRIP_LAYOUT_H_