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

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: impl new design to handle separator in layout system 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) 2013 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 // Description of a decoration to be added inside the location bar, either to 11 // Description of a decoration to be added inside the location bar, either to
12 // the left or to the right. 12 // the left or to the right.
13 struct LocationBarDecoration { 13 struct LocationBarDecoration {
14 LocationBarDecoration(int y, 14 LocationBarDecoration(int y,
15 int height, 15 int height,
16 bool auto_collapse, 16 bool auto_collapse,
17 double max_fraction, 17 double max_fraction,
18 int edge_item_padding, 18 int edge_item_padding,
19 int item_padding, 19 int item_padding,
20 int builtin_padding, 20 int builtin_padding,
21 views::View* view); 21 LocationBarLayout::Separator separator,
22 int separator_padding,
23 int separator_height,
24 views::View* view,
25 views::View* separator_view);
22 26
23 // The y position of the view inside its parent. 27 // The y position of the view inside its parent.
24 int y; 28 int y;
25 29
26 // If 0, will use the preferred height of the view. 30 // If 0, will use the preferred height of the view.
27 int height; 31 int height;
28 32
29 // True means that, if there is not enough available space in the location 33 // 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 34 // 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. 35 // (making it invisible), whichever fits. If true, |max_fraction| must be 0.
32 bool auto_collapse; 36 bool auto_collapse;
33 37
34 // Used for resizeable decorations, indicates the maximum fraction of the 38 // Used for resizeable decorations, indicates the maximum fraction of the
35 // location bar that can be taken by this decoration, 0 for non-resizable 39 // location bar that can be taken by this decoration, 0 for non-resizable
36 // decorations. If non-zero, |auto_collapse| must be false. 40 // decorations. If non-zero, |auto_collapse| must be false.
37 double max_fraction; 41 double max_fraction;
38 42
39 // Padding to use if the decoration is the first element next to the edge. 43 // Padding to use if the decoration is the first element next to the edge.
40 int edge_item_padding; 44 int edge_item_padding;
41 45
42 // Padding to use if the decoration follows another decoration. 46 // Padding to use if the decoration follows another decoration.
43 int item_padding; 47 int item_padding;
44 48
45 // Padding built into the decoration and that should be removed, on 49 // Padding built into the decoration and that should be removed, on
46 // both sides, during layout. 50 // both sides, during layout.
47 int builtin_padding; 51 int builtin_padding;
48 52
53 // Indicates if decoration needs a separator, and where if so.
54 LocationBarLayout::Separator separator;
55
56 // Padding to use between decoration and separator.
57 int separator_padding;
58
59 // If 0, use the final height of the |view|.
60 int separator_height;
61
49 views::View* view; 62 views::View* view;
50 63
64 views::View* separator_view;
65
51 // The width computed by the layout process. 66 // The width computed by the layout process.
52 double computed_width; 67 double computed_width;
68
69 // Determined by the layout process if this decoration is sharing a separator
70 // with a previous decoration in the stack; if true, this view uses the
71 // neighbor's separator and doesn't show its own.
72 bool share_separator;
53 }; 73 };
54 74
55 LocationBarDecoration::LocationBarDecoration(int y, 75 LocationBarDecoration::LocationBarDecoration(
56 int height, 76 int y,
57 bool auto_collapse, 77 int height,
58 double max_fraction, 78 bool auto_collapse,
59 int edge_item_padding, 79 double max_fraction,
60 int item_padding, 80 int edge_item_padding,
61 int builtin_padding, 81 int item_padding,
62 views::View* view) 82 int builtin_padding,
83 LocationBarLayout::Separator separator,
84 int separator_padding,
85 int separator_height,
86 views::View* view,
87 views::View* separator_view)
beaudoin 2013/01/09 20:36:52 If you change the API according to my proposal, th
kuan 2013/01/11 21:21:20 Done.
63 : y(y), 88 : y(y),
64 height(height), 89 height(height),
65 auto_collapse(auto_collapse), 90 auto_collapse(auto_collapse),
66 max_fraction(max_fraction), 91 max_fraction(max_fraction),
67 edge_item_padding(edge_item_padding), 92 edge_item_padding(edge_item_padding),
68 item_padding(item_padding), 93 item_padding(item_padding),
69 builtin_padding(builtin_padding), 94 builtin_padding(builtin_padding),
95 separator(separator),
96 separator_padding(separator_padding),
97 separator_height(separator_height),
70 view(view), 98 view(view),
71 computed_width(0) { 99 separator_view(separator_view),
100 computed_width(0),
101 share_separator(false) {
72 DCHECK(!auto_collapse || max_fraction == 0.0); 102 DCHECK(!auto_collapse || max_fraction == 0.0);
73 DCHECK(max_fraction >= 0.0); 103 DCHECK(max_fraction >= 0.0);
104 DCHECK(separator == LocationBarLayout::SEPARATOR_NONE || separator_view);
74 } 105 }
75 106
76
77 // LocationBarLayout --------------------------------------------------------- 107 // LocationBarLayout ---------------------------------------------------------
78 108
79 LocationBarLayout::LocationBarLayout(Position position, 109 LocationBarLayout::LocationBarLayout(Position position,
80 int item_edit_padding, 110 int item_edit_padding,
81 int edge_edit_padding) 111 int edge_edit_padding)
82 : position_(position), 112 : position_(position),
83 item_edit_padding_(item_edit_padding), 113 item_edit_padding_(item_edit_padding),
84 edge_edit_padding_(edge_edit_padding) {} 114 edge_edit_padding_(edge_edit_padding) {}
85 115
86 116
87 LocationBarLayout::~LocationBarLayout() { 117 LocationBarLayout::~LocationBarLayout() {
88 } 118 }
89 119
90 void LocationBarLayout::AddDecoration(int y, 120 void LocationBarLayout::AddDecoration(int y,
91 int height, 121 int height,
92 bool auto_collapse, 122 bool auto_collapse,
93 double max_fraction, 123 double max_fraction,
94 int edge_item_padding, 124 int edge_item_padding,
95 int item_padding, 125 int item_padding,
96 int builtin_padding, 126 int builtin_padding,
97 views::View* view) { 127 views::View* view) {
98 decorations_.push_back(new LocationBarDecoration(y, height, auto_collapse, 128 decorations_.push_back(new LocationBarDecoration(y, height, auto_collapse,
99 max_fraction, edge_item_padding, item_padding, builtin_padding, view)); 129 max_fraction, edge_item_padding, item_padding, builtin_padding,
130 SEPARATOR_NONE, 0, 0, view, NULL));
100 } 131 }
101 132
102 void LocationBarLayout::AddDecoration(int height, 133 void LocationBarLayout::AddDecoration(int height,
103 int builtin_padding, 134 int builtin_padding,
104 views::View* view) { 135 views::View* view) {
105 decorations_.push_back(new LocationBarDecoration( 136 decorations_.push_back(new LocationBarDecoration(
106 LocationBarView::kVerticalEdgeThickness, height, false, 0, 137 LocationBarView::kVerticalEdgeThickness, height, false, 0,
107 LocationBarView::GetEdgeItemPadding(), LocationBarView::GetItemPadding(), 138 LocationBarView::GetEdgeItemPadding(), LocationBarView::GetItemPadding(),
108 builtin_padding, view)); 139 builtin_padding, SEPARATOR_NONE, 0, 0, view, NULL));
140 }
141
142 void LocationBarLayout::AddDecorationWithSeparator(
143 int y,
144 int height,
145 bool auto_collapse,
146 double max_fraction,
147 int edge_item_padding,
148 int item_padding,
149 int builtin_padding,
150 Separator separator,
151 int separator_padding,
152 int separator_height,
153 views::View* view,
154 views::View* separator_view) {
155 decorations_.push_back(new LocationBarDecoration(y, height, auto_collapse,
156 max_fraction, edge_item_padding, item_padding, builtin_padding,
157 separator, separator_padding, separator_height, view, separator_view));
109 } 158 }
110 159
111 void LocationBarLayout::LayoutPass1(int* entry_width) { 160 void LocationBarLayout::LayoutPass1(int* entry_width) {
112
113 bool first_item = true; 161 bool first_item = true;
114 bool at_least_one_visible = false; 162 bool at_least_one_visible = false;
115 for (ScopedVector<LocationBarDecoration>::iterator it(decorations_.begin()); 163 for (ScopedVector<LocationBarDecoration>::iterator it(decorations_.begin());
116 it != decorations_.end(); ++it) { 164 it != decorations_.end(); ++it) {
117 // Autocollapsing decorations are ignored in this pass. 165 // Autocollapsing decorations are ignored in this pass.
118 if (!(*it)->auto_collapse) { 166 if (!(*it)->auto_collapse) {
119 at_least_one_visible = true; 167 at_least_one_visible = true;
120 *entry_width -= -2 * (*it)->builtin_padding + 168 *entry_width -= -2 * (*it)->builtin_padding +
121 (first_item ? (*it)->edge_item_padding : (*it)->item_padding); 169 (first_item ? (*it)->edge_item_padding : (*it)->item_padding);
122 } 170 }
123 first_item = false;
124 // Resizing decorations are ignored in this pass. 171 // Resizing decorations are ignored in this pass.
125 if (!(*it)->auto_collapse && (*it)->max_fraction == 0.0) { 172 if (!(*it)->auto_collapse && (*it)->max_fraction == 0.0) {
126 (*it)->computed_width = (*it)->view->GetPreferredSize().width(); 173 (*it)->computed_width = (*it)->view->GetPreferredSize().width();
127 *entry_width -= (*it)->computed_width; 174 *entry_width -= (*it)->computed_width;
175 DetermineSeparatorVisibility(it, first_item, 0 /* not used */,
176 entry_width);
beaudoin 2013/01/09 20:36:52 I would not bother to determine separator visibili
kuan 2013/01/11 21:21:20 Done.
128 } 177 }
178 first_item = false;
129 } 179 }
130 *entry_width -= at_least_one_visible ? item_edit_padding_ : 180 *entry_width -= at_least_one_visible ? item_edit_padding_ :
131 edge_edit_padding_; 181 edge_edit_padding_;
132 } 182 }
133 183
134 void LocationBarLayout::LayoutPass2(int *entry_width) { 184 void LocationBarLayout::LayoutPass2(int *entry_width) {
185 bool first_item = true;
135 for (ScopedVector<LocationBarDecoration>::iterator it(decorations_.begin()); 186 for (ScopedVector<LocationBarDecoration>::iterator it(decorations_.begin());
136 it != decorations_.end(); ++it) { 187 it != decorations_.end(); ++it) {
137 if ((*it)->max_fraction > 0.0) { 188 if ((*it)->max_fraction > 0.0) {
138 int max_width = static_cast<int>(*entry_width * (*it)->max_fraction); 189 int max_width = static_cast<int>(*entry_width * (*it)->max_fraction);
139 (*it)->computed_width = std::min((*it)->view->GetPreferredSize().width(), 190 (*it)->computed_width = std::min((*it)->view->GetPreferredSize().width(),
140 std::max((*it)->view->GetMinimumSize().width(), max_width)); 191 std::max((*it)->view->GetMinimumSize().width(), max_width));
141 *entry_width -= (*it)->computed_width; 192 *entry_width -= (*it)->computed_width;
193 DetermineSeparatorVisibility(it, first_item, 0 /* not used */,
194 entry_width);
142 } 195 }
196 first_item = false;
143 } 197 }
144 } 198 }
145 199
146 void LocationBarLayout::LayoutPass3(gfx::Rect* bounds, int* available_width) { 200 void LocationBarLayout::LayoutPass3(gfx::Rect* bounds, int* available_width) {
147 bool first_visible = true; 201 bool first_visible = true;
148 for (ScopedVector<LocationBarDecoration>::iterator it(decorations_.begin()); 202 for (ScopedVector<LocationBarDecoration>::iterator it(decorations_.begin());
149 it != decorations_.end(); ++it) { 203 it != decorations_.end(); ++it) {
150 // Collapse decorations if needed. 204 // Collapse decorations if needed.
151 if ((*it)->auto_collapse) { 205 if ((*it)->auto_collapse) {
152 int padding = -2 * (*it)->builtin_padding + 206 int padding = -2 * (*it)->builtin_padding +
153 (first_visible ? (*it)->edge_item_padding : (*it)->item_padding); 207 (first_visible ? (*it)->edge_item_padding : (*it)->item_padding);
154 // Try preferred size, if it fails try minimum size, if it fails collapse. 208 // Try preferred size, if it fails try minimum size, if it fails collapse.
155 (*it)->computed_width = (*it)->view->GetPreferredSize().width(); 209 (*it)->computed_width = (*it)->view->GetPreferredSize().width();
156 if ((*it)->computed_width + padding > *available_width) 210 if ((*it)->computed_width + padding > *available_width)
157 (*it)->computed_width = (*it)->view->GetMinimumSize().width(); 211 (*it)->computed_width = (*it)->view->GetMinimumSize().width();
158 if ((*it)->computed_width + padding > *available_width) { 212 if ((*it)->computed_width + padding > *available_width) {
159 (*it)->computed_width = 0; 213 (*it)->computed_width = 0;
160 (*it)->view->SetVisible(false); 214 (*it)->view->SetVisible(false);
161 } else { 215 } else {
162 (*it)->view->SetVisible(true); 216 (*it)->view->SetVisible(true);
163 (*available_width) -= (*it)->computed_width + padding; 217 (*available_width) -= (*it)->computed_width + padding;
218 DetermineSeparatorVisibility(it, first_visible, padding,
219 available_width);
164 } 220 }
165 } else { 221 } else {
166 (*it)->view->SetVisible(true); 222 (*it)->view->SetVisible(true);
167 } 223 }
224
168 // Layout visible decorations. 225 // Layout visible decorations.
169 if ((*it)->view->visible()) { 226 if ((*it)->view->visible()) {
170 int padding = -(*it)->builtin_padding + 227 int padding = -(*it)->builtin_padding +
171 (first_visible ? (*it)->edge_item_padding : (*it)->item_padding); 228 (first_visible ? (*it)->edge_item_padding : (*it)->item_padding);
172 first_visible = false; 229 first_visible = false;
230 int height = (*it)->height == 0 ?
231 (*it)->view->GetPreferredSize().height() : (*it)->height;
232
233 if ((*it)->separator == SEPARATOR_BEFORE &&
234 // If separator bounds was set successfully or this decoration is
235 // sharing the separator of the previous decoration, this decoration
236 // should use the padding between itself and its separator.
237 (SetSeparatorBounds(it, padding, height, bounds) ||
238 (*it)->share_separator)) {
239 padding = (*it)->separator_padding;
240 }
beaudoin 2013/01/09 20:36:52 I would layout separators normally here, however,
kuan 2013/01/11 21:21:20 Done.
241
173 int x; 242 int x;
174 if (position_ == LEFT_EDGE) 243 if (position_ == LEFT_EDGE)
175 x = bounds->x() + padding; 244 x = bounds->x() + padding;
176 else 245 else
177 x = bounds->x() + bounds->width() - padding - (*it)->computed_width; 246 x = bounds->right() - padding - (*it)->computed_width;
178 int height = (*it)->height == 0 ?
179 (*it)->view->GetPreferredSize().height() : (*it)->height;
180 (*it)->view->SetBounds(x, (*it)->y, (*it)->computed_width, height); 247 (*it)->view->SetBounds(x, (*it)->y, (*it)->computed_width, height);
181 bounds->set_width(bounds->width() - padding - (*it)->computed_width + 248 bounds->set_width(bounds->width() - padding - (*it)->computed_width +
182 (*it)->builtin_padding); 249 (*it)->builtin_padding);
183 if (position_ == LEFT_EDGE) { 250 if (position_ == LEFT_EDGE) {
184 bounds->set_x(bounds->x() + padding + (*it)->computed_width - 251 bounds->set_x(bounds->x() + padding + (*it)->computed_width -
185 (*it)->builtin_padding); 252 (*it)->builtin_padding);
186 } 253 }
254
255 if ((*it)->separator == SEPARATOR_AFTER)
256 SetSeparatorBounds(it, (*it)->separator_padding, height, bounds);
187 } 257 }
188 } 258 }
189 int final_padding = first_visible ? edge_edit_padding_ : item_edit_padding_; 259 int final_padding = first_visible ? edge_edit_padding_ : item_edit_padding_;
190 bounds->set_width(bounds->width() - final_padding); 260 bounds->set_width(bounds->width() - final_padding);
191 if (position_ == LEFT_EDGE) 261 if (position_ == LEFT_EDGE)
192 bounds->set_x(bounds->x() + final_padding); 262 bounds->set_x(bounds->x() + final_padding);
193 } 263 }
264
265 void LocationBarLayout::DetermineSeparatorVisibility(
266 ScopedVector<LocationBarDecoration>::iterator it,
267 bool first_visible,
268 int item_padding,
269 int* available_width) {
270 Separator separator = (*it)->separator;
271 if (separator == SEPARATOR_NONE)
272 return;
273
274 (*it)->separator_view->SetVisible(false);
275
276 // Hide separator if auto-collapsing decoration is not visible or visible
277 // decoration is by the edge with a separator before it; before means
278 // separator is left of decoration for LEFT position and separator is right of
279 // decoration for RIGHT position.
280 if (((*it)->auto_collapse && !(*it)->view->visible()) ||
beaudoin 2013/01/09 20:36:52 Checking (*it)->auto_collapse is not needed.
kuan 2013/01/11 21:21:20 removed, based on new design.
281 (separator == SEPARATOR_BEFORE && first_visible)) {
282 return;
283 }
284
285 // If 2 side-by-side decorations want separators at the same position (i.e.
286 // 1st decoration has separator after while 2nd decoration has separator
287 // before), the 2nd decoration hide its separator and uses that of the 1st
288 // decoration.
289 if (!first_visible && (*it)->separator == SEPARATOR_BEFORE) {
290 ScopedVector<LocationBarDecoration>::iterator prev_it = it - 1;
291 if ((*prev_it)->separator == SEPARATOR_AFTER &&
292 (*prev_it)->separator_view->visible()) {
293 // Subtract the separator padding and add back the item padding subtracted
294 // earlier.
295 (*available_width) -= (*it)->separator_padding - item_padding;
296 (*it)->share_separator = true;
297 return;
298 }
299 }
300
301 int separator_width = (*it)->separator_view->GetPreferredSize().width();
302 if ((*it)->auto_collapse) {
303 if (separator_width + (*it)->separator_padding <= *available_width) {
304 (*it)->separator_view->SetVisible(true);
305 (*available_width) -= separator_width + (*it)->separator_padding;
306 } else {
307 // Hide auto-collapsing decoration since its separator is not visible.
308 (*it)->view->SetVisible(false);
309 // Add back what was subtracted when this view was made visible.
310 (*available_width) += (*it)->computed_width + item_padding;
311 }
312 } else {
313 (*it)->separator_view->SetVisible(true);
314 (*available_width) -= separator_width + (*it)->separator_padding;
315 }
316 }
317
318 bool LocationBarLayout::SetSeparatorBounds(
319 ScopedVector<LocationBarDecoration>::iterator it,
320 int padding,
321 int item_height,
322 gfx::Rect* bounds) {
323 if (!((*it)->view->visible() && (*it)->separator_view &&
324 (*it)->separator_view->visible())) {
325 return false;
326 }
327
328 int separator_width = (*it)->separator_view->GetPreferredSize().width();
329 int x;
330 if (position_ == LEFT_EDGE)
331 x = bounds->x() + padding;
332 else
333 x = bounds->right() - padding - separator_width;
334 int separator_height = (*it)->separator_height == 0 ?
335 item_height : (*it)->separator_height;
336 // Vertically center separator.
337 int y = (*it)->y + ((item_height - separator_height) / 2);
338 (*it)->separator_view->SetBounds(x, y, separator_width, separator_height);
339 bounds->set_width(bounds->width() - padding - separator_width);
340 if (position_ == LEFT_EDGE)
341 bounds->set_x(bounds->x() + padding + separator_width);
342 return true;
343 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698