Chromium Code Reviews| Index: chrome/browser/ui/views/location_bar/location_bar_layout.cc |
| diff --git a/chrome/browser/ui/views/location_bar/location_bar_layout.cc b/chrome/browser/ui/views/location_bar/location_bar_layout.cc |
| index b328772cd19548af81d15a76d770644efa37359c..31933ba18d5ccc483cac83036060c62aed029d86 100644 |
| --- a/chrome/browser/ui/views/location_bar/location_bar_layout.cc |
| +++ b/chrome/browser/ui/views/location_bar/location_bar_layout.cc |
| @@ -1,4 +1,4 @@ |
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| +// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| @@ -18,7 +18,11 @@ struct LocationBarDecoration { |
| int edge_item_padding, |
| int item_padding, |
| int builtin_padding, |
| - views::View* view); |
| + LocationBarLayout::Separator separator, |
| + int separator_padding, |
| + int separator_height, |
| + views::View* view, |
| + views::View* separator_view); |
| // The y position of the view inside its parent. |
| int y; |
| @@ -46,20 +50,41 @@ struct LocationBarDecoration { |
| // both sides, during layout. |
| int builtin_padding; |
| + // Indicates if decoration needs a separator, and where if so. |
| + LocationBarLayout::Separator separator; |
| + |
| + // Padding to use between decoration and separator. |
| + int separator_padding; |
| + |
| + // If 0, use the final height of the |view|. |
| + int separator_height; |
| + |
| views::View* view; |
| + views::View* separator_view; |
| + |
| // The width computed by the layout process. |
| double computed_width; |
| + |
| + // Determined by the layout process if this decoration is sharing a separator |
| + // with a previous decoration in the stack; if true, this view uses the |
| + // neighbor's separator and doesn't show its own. |
| + bool share_separator; |
| }; |
| -LocationBarDecoration::LocationBarDecoration(int y, |
| - int height, |
| - bool auto_collapse, |
| - double max_fraction, |
| - int edge_item_padding, |
| - int item_padding, |
| - int builtin_padding, |
| - views::View* view) |
| +LocationBarDecoration::LocationBarDecoration( |
| + int y, |
| + int height, |
| + bool auto_collapse, |
| + double max_fraction, |
| + int edge_item_padding, |
| + int item_padding, |
| + int builtin_padding, |
| + LocationBarLayout::Separator separator, |
| + int separator_padding, |
| + int separator_height, |
| + views::View* view, |
| + 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.
|
| : y(y), |
| height(height), |
| auto_collapse(auto_collapse), |
| @@ -67,13 +92,18 @@ LocationBarDecoration::LocationBarDecoration(int y, |
| edge_item_padding(edge_item_padding), |
| item_padding(item_padding), |
| builtin_padding(builtin_padding), |
| + separator(separator), |
| + separator_padding(separator_padding), |
| + separator_height(separator_height), |
| view(view), |
| - computed_width(0) { |
| + separator_view(separator_view), |
| + computed_width(0), |
| + share_separator(false) { |
| DCHECK(!auto_collapse || max_fraction == 0.0); |
| DCHECK(max_fraction >= 0.0); |
| + DCHECK(separator == LocationBarLayout::SEPARATOR_NONE || separator_view); |
| } |
| - |
| // LocationBarLayout --------------------------------------------------------- |
| LocationBarLayout::LocationBarLayout(Position position, |
| @@ -96,7 +126,8 @@ void LocationBarLayout::AddDecoration(int y, |
| int builtin_padding, |
| views::View* view) { |
| decorations_.push_back(new LocationBarDecoration(y, height, auto_collapse, |
| - max_fraction, edge_item_padding, item_padding, builtin_padding, view)); |
| + max_fraction, edge_item_padding, item_padding, builtin_padding, |
| + SEPARATOR_NONE, 0, 0, view, NULL)); |
| } |
| void LocationBarLayout::AddDecoration(int height, |
| @@ -105,11 +136,28 @@ void LocationBarLayout::AddDecoration(int height, |
| decorations_.push_back(new LocationBarDecoration( |
| LocationBarView::kVerticalEdgeThickness, height, false, 0, |
| LocationBarView::GetEdgeItemPadding(), LocationBarView::GetItemPadding(), |
| - builtin_padding, view)); |
| + builtin_padding, SEPARATOR_NONE, 0, 0, view, NULL)); |
| } |
| -void LocationBarLayout::LayoutPass1(int* entry_width) { |
| +void LocationBarLayout::AddDecorationWithSeparator( |
| + int y, |
| + int height, |
| + bool auto_collapse, |
| + double max_fraction, |
| + int edge_item_padding, |
| + int item_padding, |
| + int builtin_padding, |
| + Separator separator, |
| + int separator_padding, |
| + int separator_height, |
| + views::View* view, |
| + views::View* separator_view) { |
| + decorations_.push_back(new LocationBarDecoration(y, height, auto_collapse, |
| + max_fraction, edge_item_padding, item_padding, builtin_padding, |
| + separator, separator_padding, separator_height, view, separator_view)); |
| +} |
| +void LocationBarLayout::LayoutPass1(int* entry_width) { |
| bool first_item = true; |
| bool at_least_one_visible = false; |
| for (ScopedVector<LocationBarDecoration>::iterator it(decorations_.begin()); |
| @@ -120,18 +168,21 @@ void LocationBarLayout::LayoutPass1(int* entry_width) { |
| *entry_width -= -2 * (*it)->builtin_padding + |
| (first_item ? (*it)->edge_item_padding : (*it)->item_padding); |
| } |
| - first_item = false; |
| // Resizing decorations are ignored in this pass. |
| if (!(*it)->auto_collapse && (*it)->max_fraction == 0.0) { |
| (*it)->computed_width = (*it)->view->GetPreferredSize().width(); |
| *entry_width -= (*it)->computed_width; |
| + DetermineSeparatorVisibility(it, first_item, 0 /* not used */, |
| + 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.
|
| } |
| + first_item = false; |
| } |
| *entry_width -= at_least_one_visible ? item_edit_padding_ : |
| edge_edit_padding_; |
| } |
| void LocationBarLayout::LayoutPass2(int *entry_width) { |
| + bool first_item = true; |
| for (ScopedVector<LocationBarDecoration>::iterator it(decorations_.begin()); |
| it != decorations_.end(); ++it) { |
| if ((*it)->max_fraction > 0.0) { |
| @@ -139,7 +190,10 @@ void LocationBarLayout::LayoutPass2(int *entry_width) { |
| (*it)->computed_width = std::min((*it)->view->GetPreferredSize().width(), |
| std::max((*it)->view->GetMinimumSize().width(), max_width)); |
| *entry_width -= (*it)->computed_width; |
| + DetermineSeparatorVisibility(it, first_item, 0 /* not used */, |
| + entry_width); |
| } |
| + first_item = false; |
| } |
| } |
| @@ -161,22 +215,35 @@ void LocationBarLayout::LayoutPass3(gfx::Rect* bounds, int* available_width) { |
| } else { |
| (*it)->view->SetVisible(true); |
| (*available_width) -= (*it)->computed_width + padding; |
| + DetermineSeparatorVisibility(it, first_visible, padding, |
| + available_width); |
| } |
| } else { |
| (*it)->view->SetVisible(true); |
| } |
| + |
| // Layout visible decorations. |
| if ((*it)->view->visible()) { |
| int padding = -(*it)->builtin_padding + |
| (first_visible ? (*it)->edge_item_padding : (*it)->item_padding); |
| first_visible = false; |
| + int height = (*it)->height == 0 ? |
| + (*it)->view->GetPreferredSize().height() : (*it)->height; |
| + |
| + if ((*it)->separator == SEPARATOR_BEFORE && |
| + // If separator bounds was set successfully or this decoration is |
| + // sharing the separator of the previous decoration, this decoration |
| + // should use the padding between itself and its separator. |
| + (SetSeparatorBounds(it, padding, height, bounds) || |
| + (*it)->share_separator)) { |
| + padding = (*it)->separator_padding; |
| + } |
|
beaudoin
2013/01/09 20:36:52
I would layout separators normally here, however,
kuan
2013/01/11 21:21:20
Done.
|
| + |
| int x; |
| if (position_ == LEFT_EDGE) |
| x = bounds->x() + padding; |
| else |
| - x = bounds->x() + bounds->width() - padding - (*it)->computed_width; |
| - int height = (*it)->height == 0 ? |
| - (*it)->view->GetPreferredSize().height() : (*it)->height; |
| + x = bounds->right() - padding - (*it)->computed_width; |
| (*it)->view->SetBounds(x, (*it)->y, (*it)->computed_width, height); |
| bounds->set_width(bounds->width() - padding - (*it)->computed_width + |
| (*it)->builtin_padding); |
| @@ -184,6 +251,9 @@ void LocationBarLayout::LayoutPass3(gfx::Rect* bounds, int* available_width) { |
| bounds->set_x(bounds->x() + padding + (*it)->computed_width - |
| (*it)->builtin_padding); |
| } |
| + |
| + if ((*it)->separator == SEPARATOR_AFTER) |
| + SetSeparatorBounds(it, (*it)->separator_padding, height, bounds); |
| } |
| } |
| int final_padding = first_visible ? edge_edit_padding_ : item_edit_padding_; |
| @@ -191,3 +261,83 @@ void LocationBarLayout::LayoutPass3(gfx::Rect* bounds, int* available_width) { |
| if (position_ == LEFT_EDGE) |
| bounds->set_x(bounds->x() + final_padding); |
| } |
| + |
| +void LocationBarLayout::DetermineSeparatorVisibility( |
| + ScopedVector<LocationBarDecoration>::iterator it, |
| + bool first_visible, |
| + int item_padding, |
| + int* available_width) { |
| + Separator separator = (*it)->separator; |
| + if (separator == SEPARATOR_NONE) |
| + return; |
| + |
| + (*it)->separator_view->SetVisible(false); |
| + |
| + // Hide separator if auto-collapsing decoration is not visible or visible |
| + // decoration is by the edge with a separator before it; before means |
| + // separator is left of decoration for LEFT position and separator is right of |
| + // decoration for RIGHT position. |
| + 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.
|
| + (separator == SEPARATOR_BEFORE && first_visible)) { |
| + return; |
| + } |
| + |
| + // If 2 side-by-side decorations want separators at the same position (i.e. |
| + // 1st decoration has separator after while 2nd decoration has separator |
| + // before), the 2nd decoration hide its separator and uses that of the 1st |
| + // decoration. |
| + if (!first_visible && (*it)->separator == SEPARATOR_BEFORE) { |
| + ScopedVector<LocationBarDecoration>::iterator prev_it = it - 1; |
| + if ((*prev_it)->separator == SEPARATOR_AFTER && |
| + (*prev_it)->separator_view->visible()) { |
| + // Subtract the separator padding and add back the item padding subtracted |
| + // earlier. |
| + (*available_width) -= (*it)->separator_padding - item_padding; |
| + (*it)->share_separator = true; |
| + return; |
| + } |
| + } |
| + |
| + int separator_width = (*it)->separator_view->GetPreferredSize().width(); |
| + if ((*it)->auto_collapse) { |
| + if (separator_width + (*it)->separator_padding <= *available_width) { |
| + (*it)->separator_view->SetVisible(true); |
| + (*available_width) -= separator_width + (*it)->separator_padding; |
| + } else { |
| + // Hide auto-collapsing decoration since its separator is not visible. |
| + (*it)->view->SetVisible(false); |
| + // Add back what was subtracted when this view was made visible. |
| + (*available_width) += (*it)->computed_width + item_padding; |
| + } |
| + } else { |
| + (*it)->separator_view->SetVisible(true); |
| + (*available_width) -= separator_width + (*it)->separator_padding; |
| + } |
| +} |
| + |
| +bool LocationBarLayout::SetSeparatorBounds( |
| + ScopedVector<LocationBarDecoration>::iterator it, |
| + int padding, |
| + int item_height, |
| + gfx::Rect* bounds) { |
| + if (!((*it)->view->visible() && (*it)->separator_view && |
| + (*it)->separator_view->visible())) { |
| + return false; |
| + } |
| + |
| + int separator_width = (*it)->separator_view->GetPreferredSize().width(); |
| + int x; |
| + if (position_ == LEFT_EDGE) |
| + x = bounds->x() + padding; |
| + else |
| + x = bounds->right() - padding - separator_width; |
| + int separator_height = (*it)->separator_height == 0 ? |
| + item_height : (*it)->separator_height; |
| + // Vertically center separator. |
| + int y = (*it)->y + ((item_height - separator_height) / 2); |
| + (*it)->separator_view->SetBounds(x, y, separator_width, separator_height); |
| + bounds->set_width(bounds->width() - padding - separator_width); |
| + if (position_ == LEFT_EDGE) |
| + bounds->set_x(bounds->x() + padding + separator_width); |
| + return true; |
| +} |