stacked_tab_strip_layout.h revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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 "base/basictypes.h" 9#include "ui/gfx/size.h" 10#include "ui/views/view_model.h" 11 12namespace views { 13class ViewModel; 14} 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. 23class 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::ViewModel* 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 views::ViewModel* view_model_; 219 220 // x-coordinate normal tabs start at. 221 int x_; 222 223 // Available width. 224 int width_; 225 226 // Number of mini-tabs. 227 int mini_tab_count_; 228 229 // Distance from the last mini-tab to the first non-mini-tab. 230 int mini_tab_to_non_mini_tab_; 231 232 // Index of the active tab. 233 int active_index_; 234 235 // X-coordinate of the first tab. This is either |x_| if there are no 236 // mini-tabs, or the x-coordinate of the first mini-tab. 237 int first_tab_x_; 238 239 DISALLOW_COPY_AND_ASSIGN(StackedTabStripLayout); 240}; 241 242#endif // CHROME_BROWSER_UI_VIEWS_TABS_STACKED_TAB_STRIP_LAYOUT_H_ 243