Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: chrome/browser/ui/views/location_bar/location_bar_layout.cc

Issue 11418229: alternate ntp: implement right-aligned search token (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: re-impl layout system for separators Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/views/location_bar/location_bar_layout.h" 5 #include "chrome/browser/ui/views/location_bar/location_bar_layout.h"
6 6
7 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" 7 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
8 #include "ui/gfx/rect.h" 8 #include "ui/gfx/rect.h"
9 #include "ui/views/view.h" 9 #include "ui/views/view.h"
10 10
11 namespace {
12
13 enum DecorationType {
14 // Decoration is always visible.
15 NORMAL = 0,
16 // If there is not enough available space in the location bar, the decoration
17 // will reduce its width either to its minimal width or to zero (making it
18 // invisible), whichever fits. |LocationBarDecoration::max_fraction| must be
19 // 0.
20 AUTO_COLLAPSE,
21 // Decoration is a separator, only visible if it's not leading, or not
22 // trailing, or not next to another separator.
23 SEPARATOR,
24 };
25
26 } // namespace
27
28
11 // Description of a decoration to be added inside the location bar, either to 29 // Description of a decoration to be added inside the location bar, either to
12 // the left or to the right. 30 // the left or to the right.
13 struct LocationBarDecoration { 31 struct LocationBarDecoration {
14 LocationBarDecoration(int y, 32 LocationBarDecoration(DecorationType type,
33 int y,
15 int height, 34 int height,
16 bool auto_collapse,
17 double max_fraction, 35 double max_fraction,
18 int edge_item_padding, 36 int edge_item_padding,
19 int item_padding, 37 int item_padding,
20 int builtin_padding, 38 int builtin_padding,
21 views::View* view); 39 views::View* view);
22 40
41 // The type of decoration.
42 DecorationType type;
43
23 // The y position of the view inside its parent. 44 // The y position of the view inside its parent.
24 int y; 45 int y;
25 46
26 // If 0, will use the preferred height of the view. 47 // If 0, will use the preferred height of the view.
27 int height; 48 int height;
28 49
29 // True means that, if there is not enough available space in the location
30 // bar, the view will reduce its width either to its minimal width or to zero
31 // (making it invisible), whichever fits. If true, |max_fraction| must be 0.
32 bool auto_collapse;
33
34 // Used for resizeable decorations, indicates the maximum fraction of the 50 // Used for resizeable decorations, indicates the maximum fraction of the
35 // location bar that can be taken by this decoration, 0 for non-resizable 51 // location bar that can be taken by this decoration, 0 for non-resizable
36 // decorations. If non-zero, |auto_collapse| must be false. 52 // decorations. If non-zero, |type| must not be AUTO_COLLAPSE.
37 double max_fraction; 53 double max_fraction;
38 54
39 // Padding to use if the decoration is the first element next to the edge. 55 // Padding to use if the decoration is the first element next to the edge.
40 int edge_item_padding; 56 int edge_item_padding;
41 57
42 // Padding to use if the decoration follows another decoration. 58 // Padding to use if the decoration follows another decoration.
43 int item_padding; 59 int item_padding;
44 60
45 // Padding built into the decoration and that should be removed, on 61 // Padding built into the decoration and that should be removed, on
46 // both sides, during layout. 62 // both sides, during layout.
47 int builtin_padding; 63 int builtin_padding;
48 64
49 views::View* view; 65 views::View* view;
50 66
51 // The width computed by the layout process. 67 // The width computed by the layout process.
52 double computed_width; 68 double computed_width;
53 }; 69 };
54 70
55 LocationBarDecoration::LocationBarDecoration(int y, 71 LocationBarDecoration::LocationBarDecoration(DecorationType type,
72 int y,
56 int height, 73 int height,
57 bool auto_collapse,
58 double max_fraction, 74 double max_fraction,
59 int edge_item_padding, 75 int edge_item_padding,
60 int item_padding, 76 int item_padding,
61 int builtin_padding, 77 int builtin_padding,
62 views::View* view) 78 views::View* view)
63 : y(y), 79 : type(type),
80 y(y),
64 height(height), 81 height(height),
65 auto_collapse(auto_collapse),
66 max_fraction(max_fraction), 82 max_fraction(max_fraction),
67 edge_item_padding(edge_item_padding), 83 edge_item_padding(edge_item_padding),
68 item_padding(item_padding), 84 item_padding(item_padding),
69 builtin_padding(builtin_padding), 85 builtin_padding(builtin_padding),
70 view(view), 86 view(view),
71 computed_width(0) { 87 computed_width(0) {
72 DCHECK(!auto_collapse || max_fraction == 0.0); 88 DCHECK(type != AUTO_COLLAPSE || max_fraction == 0.0);
beaudoin 2013/01/12 05:47:15 DCHECK(type == NORMAL || max_fraction == 0.0);
kuan 2013/01/14 16:47:47 Done.
73 DCHECK(max_fraction >= 0.0); 89 DCHECK(max_fraction >= 0.0);
74 } 90 }
75 91
76 92
77 // LocationBarLayout --------------------------------------------------------- 93 // LocationBarLayout ---------------------------------------------------------
78 94
79 LocationBarLayout::LocationBarLayout(Position position, 95 LocationBarLayout::LocationBarLayout(Position position,
80 int item_edit_padding, 96 int item_edit_padding,
81 int edge_edit_padding) 97 int edge_edit_padding)
82 : position_(position), 98 : position_(position),
83 item_edit_padding_(item_edit_padding), 99 item_edit_padding_(item_edit_padding),
84 edge_edit_padding_(edge_edit_padding) {} 100 edge_edit_padding_(edge_edit_padding) {}
85 101
86 102
87 LocationBarLayout::~LocationBarLayout() { 103 LocationBarLayout::~LocationBarLayout() {
88 } 104 }
89 105
90 void LocationBarLayout::AddDecoration(int y, 106 void LocationBarLayout::AddDecoration(int y,
91 int height, 107 int height,
92 bool auto_collapse, 108 bool auto_collapse,
93 double max_fraction, 109 double max_fraction,
94 int edge_item_padding, 110 int edge_item_padding,
95 int item_padding, 111 int item_padding,
96 int builtin_padding, 112 int builtin_padding,
97 views::View* view) { 113 views::View* view) {
98 decorations_.push_back(new LocationBarDecoration(y, height, auto_collapse, 114 decorations_.push_back(new LocationBarDecoration(
99 max_fraction, edge_item_padding, item_padding, builtin_padding, view)); 115 auto_collapse ? AUTO_COLLAPSE : NORMAL, y, height, max_fraction,
116 edge_item_padding, item_padding, builtin_padding, view));
100 } 117 }
101 118
102 void LocationBarLayout::AddDecoration(int height, 119 void LocationBarLayout::AddDecoration(int height,
103 int builtin_padding, 120 int builtin_padding,
104 views::View* view) { 121 views::View* view) {
105 decorations_.push_back(new LocationBarDecoration( 122 decorations_.push_back(new LocationBarDecoration(NORMAL,
106 LocationBarView::kVerticalEdgeThickness, height, false, 0, 123 LocationBarView::kVerticalEdgeThickness, height, 0,
107 LocationBarView::GetEdgeItemPadding(), LocationBarView::GetItemPadding(), 124 LocationBarView::GetEdgeItemPadding(), LocationBarView::GetItemPadding(),
108 builtin_padding, view)); 125 builtin_padding, view));
109 } 126 }
110 127
128 void LocationBarLayout::AddSeparator(int y,
129 int height,
130 int padding,
131 views::View* view) {
132 // Edge item padding won't apply since a separator won't be by the edge, so
133 // use the same as item padding to simplify calculation in LayoutPass1().
134 decorations_.push_back(new LocationBarDecoration(SEPARATOR, y, height, 0,
135 padding, padding, 0, view));
beaudoin 2013/01/12 05:47:15 edge_item_padding can be 0 because edge separators
kuan 2013/01/14 16:47:47 Done.
136 }
137
111 void LocationBarLayout::LayoutPass1(int* entry_width) { 138 void LocationBarLayout::LayoutPass1(int* entry_width) {
112
113 bool first_item = true; 139 bool first_item = true;
114 bool at_least_one_visible = false; 140 bool at_least_one_visible = false;
115 for (ScopedVector<LocationBarDecoration>::iterator it(decorations_.begin()); 141 for (ScopedVector<LocationBarDecoration>::iterator it(decorations_.begin());
116 it != decorations_.end(); ++it) { 142 it != decorations_.end(); ++it) {
117 // Autocollapsing decorations are ignored in this pass. 143 // Autocollapsing decorations are ignored in this pass.
118 if (!(*it)->auto_collapse) { 144 if ((*it)->type != AUTO_COLLAPSE) {
119 at_least_one_visible = true; 145 at_least_one_visible = true;
120 *entry_width -= -2 * (*it)->builtin_padding + 146 *entry_width -= -2 * (*it)->builtin_padding +
121 (first_item ? (*it)->edge_item_padding : (*it)->item_padding); 147 (first_item ? (*it)->edge_item_padding : (*it)->item_padding);
122 } 148 }
123 first_item = false; 149 first_item = false;
124 // Resizing decorations are ignored in this pass. 150 // Resizing decorations are ignored in this pass.
125 if (!(*it)->auto_collapse && (*it)->max_fraction == 0.0) { 151 if ((*it)->type != AUTO_COLLAPSE && (*it)->max_fraction == 0.0) {
126 (*it)->computed_width = (*it)->view->GetPreferredSize().width(); 152 (*it)->computed_width = (*it)->view->GetPreferredSize().width();
127 *entry_width -= (*it)->computed_width; 153 *entry_width -= (*it)->computed_width;
128 } 154 }
129 } 155 }
130 *entry_width -= at_least_one_visible ? item_edit_padding_ : 156 *entry_width -= at_least_one_visible ? item_edit_padding_ :
131 edge_edit_padding_; 157 edge_edit_padding_;
132 } 158 }
133 159
134 void LocationBarLayout::LayoutPass2(int *entry_width) { 160 void LocationBarLayout::LayoutPass2(int *entry_width) {
135 for (ScopedVector<LocationBarDecoration>::iterator it(decorations_.begin()); 161 for (ScopedVector<LocationBarDecoration>::iterator it(decorations_.begin());
136 it != decorations_.end(); ++it) { 162 it != decorations_.end(); ++it) {
137 if ((*it)->max_fraction > 0.0) { 163 if ((*it)->max_fraction > 0.0) {
138 int max_width = static_cast<int>(*entry_width * (*it)->max_fraction); 164 int max_width = static_cast<int>(*entry_width * (*it)->max_fraction);
139 (*it)->computed_width = std::min((*it)->view->GetPreferredSize().width(), 165 (*it)->computed_width = std::min((*it)->view->GetPreferredSize().width(),
140 std::max((*it)->view->GetMinimumSize().width(), max_width)); 166 std::max((*it)->view->GetMinimumSize().width(), max_width));
141 *entry_width -= (*it)->computed_width; 167 *entry_width -= (*it)->computed_width;
142 } 168 }
143 } 169 }
144 } 170 }
145 171
146 void LocationBarLayout::LayoutPass3(gfx::Rect* bounds, int* available_width) { 172 void LocationBarLayout::LayoutPass3(gfx::Rect* bounds, int* available_width) {
173 SetVisibilityForDecorations(available_width);
174 SetSeparatorsInvisible(available_width);
175 SetBoundsForDecorations(bounds);
176 }
177
178 void LocationBarLayout::SetVisibilityForDecorations(int* available_width) {
147 bool first_visible = true; 179 bool first_visible = true;
148 for (ScopedVector<LocationBarDecoration>::iterator it(decorations_.begin()); 180 for (ScopedVector<LocationBarDecoration>::iterator it(decorations_.begin());
149 it != decorations_.end(); ++it) { 181 it != decorations_.end(); ++it) {
150 // Collapse decorations if needed. 182 // Collapse decorations if needed.
151 if ((*it)->auto_collapse) { 183 if ((*it)->type == AUTO_COLLAPSE) {
152 int padding = -2 * (*it)->builtin_padding + 184 int padding = -2 * (*it)->builtin_padding +
153 (first_visible ? (*it)->edge_item_padding : (*it)->item_padding); 185 (first_visible ? (*it)->edge_item_padding : (*it)->item_padding);
154 // Try preferred size, if it fails try minimum size, if it fails collapse. 186 // Try preferred size, if it fails try minimum size, if it fails
187 // collapse.
155 (*it)->computed_width = (*it)->view->GetPreferredSize().width(); 188 (*it)->computed_width = (*it)->view->GetPreferredSize().width();
156 if ((*it)->computed_width + padding > *available_width) 189 if ((*it)->computed_width + padding > *available_width)
157 (*it)->computed_width = (*it)->view->GetMinimumSize().width(); 190 (*it)->computed_width = (*it)->view->GetMinimumSize().width();
158 if ((*it)->computed_width + padding > *available_width) { 191 if ((*it)->computed_width + padding > *available_width) {
159 (*it)->computed_width = 0; 192 (*it)->computed_width = 0;
160 (*it)->view->SetVisible(false); 193 (*it)->view->SetVisible(false);
161 } else { 194 } else {
162 (*it)->view->SetVisible(true); 195 (*it)->view->SetVisible(true);
163 (*available_width) -= (*it)->computed_width + padding; 196 (*available_width) -= (*it)->computed_width + padding;
164 } 197 }
165 } else { 198 } else {
166 (*it)->view->SetVisible(true); 199 (*it)->view->SetVisible(true);
167 } 200 }
168 // Layout visible decorations. 201
169 if ((*it)->view->visible()) { 202 if ((*it)->view->visible())
170 int padding = -(*it)->builtin_padding +
171 (first_visible ? (*it)->edge_item_padding : (*it)->item_padding);
172 first_visible = false; 203 first_visible = false;
173 int x; 204 }
174 if (position_ == LEFT_EDGE) 205 }
175 x = bounds->x() + padding; 206
176 else 207 void LocationBarLayout::SetSeparatorsInvisible(int* available_width) {
beaudoin 2013/01/12 05:47:15 Maybe rename to: HideUnneededSeparators
kuan 2013/01/14 16:47:47 Done.
177 x = bounds->x() + bounds->width() - padding - (*it)->computed_width; 208 ScopedVector<LocationBarDecoration>::iterator prev = decorations_.end();
178 int height = (*it)->height == 0 ? 209 ScopedVector<LocationBarDecoration>::iterator last_visible_separator =
179 (*it)->view->GetPreferredSize().height() : (*it)->height; 210 decorations_.end();
180 (*it)->view->SetBounds(x, (*it)->y, (*it)->computed_width, height); 211 ScopedVector<LocationBarDecoration>::iterator last_visible_decoration =
181 bounds->set_width(bounds->width() - padding - (*it)->computed_width + 212 decorations_.end();
182 (*it)->builtin_padding); 213 for (ScopedVector<LocationBarDecoration>::iterator it(decorations_.begin());
183 if (position_ == LEFT_EDGE) { 214 it != decorations_.end(); ++it) {
184 bounds->set_x(bounds->x() + padding + (*it)->computed_width - 215 if ((*it)->type == SEPARATOR) {
216 bool visible = prev != decorations_.end() && // Not first item.
217 // Previous item is a visible non-spearator decoration.
beaudoin 2013/01/12 05:47:15 typo: separator
kuan 2013/01/14 16:47:47 Done.
218 ((*prev)->type != SEPARATOR && (*prev)->view->visible());
beaudoin 2013/01/12 05:47:15 Not sure the logic is correct here. If the list is
kuan 2013/01/14 16:47:47 Done. i added one more bool at_least_one_non_sepa
beaudoin 2013/01/14 18:12:14 I though last_visible_was_a_separator would be eno
kuan 2013/01/14 18:33:11 Done. i thot of that, but worried that it might b
219 if (!visible) {
220 (*it)->view->SetVisible(false);
221 // Add back what was subtracted when setting this separator visible in
222 // LayoutPass1().
223 (*available_width) += (*it)->item_padding + (*it)->computed_width;
224 } else {
225 DCHECK(last_visible_decoration != decorations_.end());
226 last_visible_separator = it;
227 }
228 } else if ((*it)->view->visible()) {
229 last_visible_decoration = it;
230 }
231 prev = it;
232 }
233 // If last visible separator is trailing, hide it.
234 if (last_visible_separator != decorations_.end() &&
235 last_visible_separator > last_visible_decoration) {
beaudoin 2013/01/12 05:47:15 I think it would be simpler to keep just one extra
kuan 2013/01/14 16:47:47 Done.
236 (*last_visible_separator)->view->SetVisible(false);
237 // Add back what was subtracted when setting this separator visible in
238 // LayoutPass1().
239 (*available_width) += (*last_visible_separator)->item_padding +
240 (*last_visible_separator)->computed_width;
241 }
242 }
243
244 void LocationBarLayout::SetBoundsForDecorations(gfx::Rect* bounds) {
245 bool first_visible = true;
246 for (ScopedVector<LocationBarDecoration>::iterator it(decorations_.begin());
247 it != decorations_.end(); ++it) {
248 if (!(*it)->view->visible())
249 continue;
beaudoin 2013/01/12 05:47:15 indentation (2 lines above)
kuan 2013/01/14 16:47:47 Done.
250 int padding = -(*it)->builtin_padding +
251 (first_visible ? (*it)->edge_item_padding : (*it)->item_padding);
252 first_visible = false;
253 int x;
254 if (position_ == LEFT_EDGE)
255 x = bounds->x() + padding;
256 else
257 x = bounds->right() - padding - (*it)->computed_width;
258 int height = (*it)->height == 0 ?
259 (*it)->view->GetPreferredSize().height() : (*it)->height;
260 (*it)->view->SetBounds(x, (*it)->y, (*it)->computed_width, height);
261 bounds->set_width(bounds->width() - padding - (*it)->computed_width +
185 (*it)->builtin_padding); 262 (*it)->builtin_padding);
186 } 263 if (position_ == LEFT_EDGE) {
264 bounds->set_x(bounds->x() + padding + (*it)->computed_width -
265 (*it)->builtin_padding);
187 } 266 }
188 } 267 }
189 int final_padding = first_visible ? edge_edit_padding_ : item_edit_padding_; 268 int final_padding = first_visible ? edge_edit_padding_ : item_edit_padding_;
190 bounds->set_width(bounds->width() - final_padding); 269 bounds->set_width(bounds->width() - final_padding);
191 if (position_ == LEFT_EDGE) 270 if (position_ == LEFT_EDGE)
192 bounds->set_x(bounds->x() + final_padding); 271 bounds->set_x(bounds->x() + final_padding);
193 } 272 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698