Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / tabs / stacked_tab_strip_layout.h
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.
4
5 #ifndef CHROME_BROWSER_UI_VIEWS_TABS_STACKED_TAB_STRIP_LAYOUT_H_
6 #define CHROME_BROWSER_UI_VIEWS_TABS_STACKED_TAB_STRIP_LAYOUT_H_
7
8 #include <algorithm>
9
10 #include "base/basictypes.h"
11 #include "ui/gfx/size.h"
12 #include "ui/views/view_model.h"
13
14 class Tab;
15
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 {
24  public:
25   static const int kAddTypeMini   = 1 << 0;
26   static const int kAddTypeActive = 1 << 1;
27
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,
34                         int padding,
35                         int stacked_padding,
36                         int max_stacked_count,
37                         views::ViewModelBase* view_model);
38   ~StackedTabStripLayout();
39
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);
43
44   // Sets the width available for sizing the tabs to.
45   void SetWidth(int width);
46
47   int width() const { return width_; }
48
49   // Sets the index of the active tab.
50   void SetActiveIndex(int index);
51
52   // Drags the active tab.
53   void DragActiveTab(int delta);
54
55   // Makes sure the tabs fill the available width. Used after a drag operation
56   // completes.
57   void SizeToFit();
58
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);
62
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);
67
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,
71                int to,
72                int new_active_index,
73                int start_x,
74                int mini_tab_count);
75
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_;
81   }
82
83   int mini_tab_count() const { return mini_tab_count_; }
84
85   // Returns true if the tab at index is stacked.
86   bool IsStacked(int index) const;
87
88   // Sets the location of the active tab as close to |x| as possible.
89   void SetActiveTabLocation(int x);
90
91 #if !defined(NDEBUG)
92   std::string BoundsString() const;
93 #endif
94
95  private:
96   friend class StackedTabStripLayoutTest;
97
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);
101
102   // Resets to an ideal layout state.
103   void ResetToIdealState();
104
105   // Makes |index| visible. This is used when a new tab is added that isn't
106   // active.
107   void MakeVisible(int index);
108
109   // Returns the x-coordinate for the active tab constrained by the current tab
110   // counts.
111   int ConstrainActiveX(int x) const;
112
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();
116
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);
121
122   // Same as LayoutByTabOffsetAfter(), but iterates toward
123   // |mini_tab_count_|.
124   void LayoutByTabOffsetBefore(int index);
125
126   // Similar to LayoutByTabOffsetAfter(), but uses the current x-coordinate
127   // if possible.
128   void LayoutUsingCurrentAfter(int index);
129   void LayoutUsingCurrentBefore(int index);
130
131   void PushTabsAfter(int index, int delta);
132   void PushTabsBefore(int index, int delta);
133
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);
138
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
141   // the tabs by.
142   void ExpandTabsBefore(int index, int delta);
143   void ExpandTabsAfter(int index, int delta);
144
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();
152
153   // Sets the bounds of the tab at |index|.
154   void SetIdealBoundsAt(int index, int x);
155
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;
159
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;
163
164   // Used when dragging to get the min/max coodinate.
165   int GetMinDragX(int index) const;
166   int GetMaxDragX(int index) const;
167
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;
172
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_);
176   }
177
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_;
181   }
182
183   // Max stacked padding.
184   int max_stacked_width() const {
185     return stacked_padding_ * max_stacked_count_;
186   }
187
188   int ideal_x(int index) const { return view_model_->ideal_bounds(index).x(); }
189
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_;
194   }
195
196   // Number of tabs.
197   int tab_count() const { return view_model_->view_size(); }
198
199   // Number of normal (non-mini) tabs.
200   int normal_tab_count() const { return tab_count() - mini_tab_count_; }
201
202   // Distance between one tab to the next.
203   int tab_offset() const { return size_.width() + padding_; }
204
205   // Size of tabs.
206   const gfx::Size size_;
207
208   // Padding between tabs.
209   const int padding_;
210
211   // Padding between stacked tabs.
212   const int stacked_padding_;
213
214   // Max number of stacked tabs.
215   const int max_stacked_count_;
216
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_;
221
222   // x-coordinate normal tabs start at.
223   int x_;
224
225   // Available width.
226   int width_;
227
228   // Number of mini-tabs.
229   int mini_tab_count_;
230
231   // Distance from the last mini-tab to the first non-mini-tab.
232   int mini_tab_to_non_mini_tab_;
233
234   // Index of the active tab.
235   int active_index_;
236
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.
239   int first_tab_x_;
240
241   DISALLOW_COPY_AND_ASSIGN(StackedTabStripLayout);
242 };
243
244 #endif  // CHROME_BROWSER_UI_VIEWS_TABS_STACKED_TAB_STRIP_LAYOUT_H_