| 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..14ac0b2bf31685e53216f317a706358699f284d7 100644
|
| --- a/chrome/browser/ui/views/location_bar/location_bar_layout.cc
|
| +++ b/chrome/browser/ui/views/location_bar/location_bar_layout.cc
|
| @@ -8,32 +8,48 @@
|
| #include "ui/gfx/rect.h"
|
| #include "ui/views/view.h"
|
|
|
| +namespace {
|
| +
|
| +enum DecorationType {
|
| + // Decoration is always visible.
|
| + NORMAL = 0,
|
| + // If there is not enough available space in the location bar, the decoration
|
| + // will reduce its width either to its minimal width or to zero (making it
|
| + // invisible), whichever fits. |LocationBarDecoration::max_fraction| must be
|
| + // 0.
|
| + AUTO_COLLAPSE,
|
| + // Decoration is a separator, only visible if it's not leading, or not
|
| + // trailing, or not next to another separator.
|
| + SEPARATOR,
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +
|
| // Description of a decoration to be added inside the location bar, either to
|
| // the left or to the right.
|
| struct LocationBarDecoration {
|
| - LocationBarDecoration(int y,
|
| + LocationBarDecoration(DecorationType type,
|
| + int y,
|
| int height,
|
| - bool auto_collapse,
|
| double max_fraction,
|
| int edge_item_padding,
|
| int item_padding,
|
| int builtin_padding,
|
| views::View* view);
|
|
|
| + // The type of decoration.
|
| + DecorationType type;
|
| +
|
| // The y position of the view inside its parent.
|
| int y;
|
|
|
| // If 0, will use the preferred height of the view.
|
| int height;
|
|
|
| - // True means that, if there is not enough available space in the location
|
| - // bar, the view will reduce its width either to its minimal width or to zero
|
| - // (making it invisible), whichever fits. If true, |max_fraction| must be 0.
|
| - bool auto_collapse;
|
| -
|
| // Used for resizeable decorations, indicates the maximum fraction of the
|
| // location bar that can be taken by this decoration, 0 for non-resizable
|
| - // decorations. If non-zero, |auto_collapse| must be false.
|
| + // decorations. If non-zero, |type| must not be AUTO_COLLAPSE.
|
| double max_fraction;
|
|
|
| // Padding to use if the decoration is the first element next to the edge.
|
| @@ -52,25 +68,28 @@ struct LocationBarDecoration {
|
| double computed_width;
|
| };
|
|
|
| -LocationBarDecoration::LocationBarDecoration(int y,
|
| +LocationBarDecoration::LocationBarDecoration(DecorationType type,
|
| + int y,
|
| int height,
|
| - bool auto_collapse,
|
| double max_fraction,
|
| int edge_item_padding,
|
| int item_padding,
|
| int builtin_padding,
|
| views::View* view)
|
| - : y(y),
|
| + : type(type),
|
| + y(y),
|
| height(height),
|
| - auto_collapse(auto_collapse),
|
| max_fraction(max_fraction),
|
| edge_item_padding(edge_item_padding),
|
| item_padding(item_padding),
|
| builtin_padding(builtin_padding),
|
| view(view),
|
| computed_width(0) {
|
| - DCHECK(!auto_collapse || max_fraction == 0.0);
|
| - DCHECK(max_fraction >= 0.0);
|
| + if (type == NORMAL) {
|
| + DCHECK_GE(max_fraction, 0.0);
|
| + } else {
|
| + DCHECK_EQ(0.0, max_fraction);
|
| + }
|
| }
|
|
|
|
|
| @@ -95,34 +114,44 @@ void LocationBarLayout::AddDecoration(int y,
|
| int item_padding,
|
| 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));
|
| + decorations_.push_back(new LocationBarDecoration(
|
| + auto_collapse ? AUTO_COLLAPSE : NORMAL, y, height, max_fraction,
|
| + edge_item_padding, item_padding, builtin_padding, view));
|
| }
|
|
|
| void LocationBarLayout::AddDecoration(int height,
|
| int builtin_padding,
|
| views::View* view) {
|
| decorations_.push_back(new LocationBarDecoration(
|
| - LocationBarView::kVerticalEdgeThickness, height, false, 0,
|
| + NORMAL, LocationBarView::kVerticalEdgeThickness, height, 0,
|
| LocationBarView::GetEdgeItemPadding(), LocationBarView::GetItemPadding(),
|
| builtin_padding, view));
|
| }
|
|
|
| -void LocationBarLayout::LayoutPass1(int* entry_width) {
|
| +void LocationBarLayout::AddSeparator(int y,
|
| + int height,
|
| + int padding_from_previous_item,
|
| + views::View* separator) {
|
| + // Edge item padding won't apply since a separator won't be by the edge, so
|
| + // use 0 for more accurate evaluation of |entry_width| in LayoutPass1().
|
| + decorations_.push_back(new LocationBarDecoration(
|
| + SEPARATOR, y, height, 0, 0, padding_from_previous_item, 0, separator));
|
| +}
|
|
|
| +void LocationBarLayout::LayoutPass1(int* entry_width) {
|
| bool first_item = true;
|
| bool at_least_one_visible = false;
|
| - for (ScopedVector<LocationBarDecoration>::iterator it(decorations_.begin());
|
| - it != decorations_.end(); ++it) {
|
| + for (Decorations::iterator it(decorations_.begin()); it != decorations_.end();
|
| + ++it) {
|
| // Autocollapsing decorations are ignored in this pass.
|
| - if (!(*it)->auto_collapse) {
|
| + if ((*it)->type != AUTO_COLLAPSE) {
|
| at_least_one_visible = true;
|
| *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) {
|
| + if (((*it)->type != AUTO_COLLAPSE) && ((*it)->max_fraction == 0.0)) {
|
| (*it)->computed_width = (*it)->view->GetPreferredSize().width();
|
| *entry_width -= (*it)->computed_width;
|
| }
|
| @@ -132,8 +161,8 @@ void LocationBarLayout::LayoutPass1(int* entry_width) {
|
| }
|
|
|
| void LocationBarLayout::LayoutPass2(int *entry_width) {
|
| - for (ScopedVector<LocationBarDecoration>::iterator it(decorations_.begin());
|
| - it != decorations_.end(); ++it) {
|
| + for (Decorations::iterator it(decorations_.begin()); it != decorations_.end();
|
| + ++it) {
|
| if ((*it)->max_fraction > 0.0) {
|
| int max_width = static_cast<int>(*entry_width * (*it)->max_fraction);
|
| (*it)->computed_width = std::min((*it)->view->GetPreferredSize().width(),
|
| @@ -144,14 +173,21 @@ void LocationBarLayout::LayoutPass2(int *entry_width) {
|
| }
|
|
|
| void LocationBarLayout::LayoutPass3(gfx::Rect* bounds, int* available_width) {
|
| + SetVisibilityForDecorations(available_width);
|
| + HideUnneededSeparators(available_width);
|
| + SetBoundsForDecorations(bounds);
|
| +}
|
| +
|
| +void LocationBarLayout::SetVisibilityForDecorations(int* available_width) {
|
| bool first_visible = true;
|
| - for (ScopedVector<LocationBarDecoration>::iterator it(decorations_.begin());
|
| - it != decorations_.end(); ++it) {
|
| + for (Decorations::iterator it(decorations_.begin()); it != decorations_.end();
|
| + ++it) {
|
| // Collapse decorations if needed.
|
| - if ((*it)->auto_collapse) {
|
| + if ((*it)->type == AUTO_COLLAPSE) {
|
| int padding = -2 * (*it)->builtin_padding +
|
| (first_visible ? (*it)->edge_item_padding : (*it)->item_padding);
|
| - // Try preferred size, if it fails try minimum size, if it fails collapse.
|
| + // Try preferred size, if it fails try minimum size, if it fails
|
| + // collapse.
|
| (*it)->computed_width = (*it)->view->GetPreferredSize().width();
|
| if ((*it)->computed_width + padding > *available_width)
|
| (*it)->computed_width = (*it)->view->GetMinimumSize().width();
|
| @@ -165,25 +201,61 @@ void LocationBarLayout::LayoutPass3(gfx::Rect* bounds, int* 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);
|
| +
|
| + if ((*it)->view->visible())
|
| first_visible = false;
|
| - 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;
|
| - (*it)->view->SetBounds(x, (*it)->y, (*it)->computed_width, height);
|
| - bounds->set_width(bounds->width() - padding - (*it)->computed_width +
|
| - (*it)->builtin_padding);
|
| - if (position_ == LEFT_EDGE) {
|
| - bounds->set_x(bounds->x() + padding + (*it)->computed_width -
|
| - (*it)->builtin_padding);
|
| + }
|
| +}
|
| +
|
| +void LocationBarLayout::HideUnneededSeparators(int* available_width) {
|
| + // Initialize |trailing_separator| to first decoration so that any leading
|
| + // separator will be hidden.
|
| + Decorations::iterator trailing_separator = decorations_.begin();
|
| + for (Decorations::iterator it(decorations_.begin()); it != decorations_.end();
|
| + ++it) {
|
| + if ((*it)->type == SEPARATOR) {
|
| + if (trailing_separator != decorations_.end()) {
|
| + (*it)->view->SetVisible(false);
|
| + // Add back what was subtracted when setting this separator visible in
|
| + // LayoutPass1().
|
| + (*available_width) += (*it)->item_padding + (*it)->computed_width;
|
| + } else {
|
| + trailing_separator = it;
|
| }
|
| + } else if ((*it)->view->visible()) {
|
| + trailing_separator = decorations_.end();
|
| + }
|
| + }
|
| + // If there's a trailing separator, hide it.
|
| + if (trailing_separator != decorations_.end()) {
|
| + (*trailing_separator)->view->SetVisible(false);
|
| + // Add back what was subtracted when setting this separator visible in
|
| + // LayoutPass1().
|
| + (*available_width) += (*trailing_separator)->item_padding +
|
| + (*trailing_separator)->computed_width;
|
| + }
|
| +}
|
| +
|
| +void LocationBarLayout::SetBoundsForDecorations(gfx::Rect* bounds) {
|
| + bool first_visible = true;
|
| + for (Decorations::iterator it(decorations_.begin()); it != decorations_.end();
|
| + ++it) {
|
| + LocationBarDecoration* curr = *it;
|
| + if (!curr->view->visible())
|
| + continue;
|
| + int padding = -curr->builtin_padding +
|
| + (first_visible ? curr->edge_item_padding : curr->item_padding);
|
| + first_visible = false;
|
| + int x = (position_ == LEFT_EDGE) ? (bounds->x() + padding) :
|
| + (bounds->right() - padding - curr->computed_width);
|
| + int height = curr->height == 0 ?
|
| + curr->view->GetPreferredSize().height() : curr->height;
|
| + curr->view->SetBounds(x, curr->y, curr->computed_width, height);
|
| + bounds->set_width(bounds->width() - padding - curr->computed_width +
|
| + curr->builtin_padding);
|
| + if (position_ == LEFT_EDGE) {
|
| + bounds->set_x(
|
| + bounds->x() + padding + curr->computed_width - curr->builtin_padding);
|
| }
|
| }
|
| int final_padding = first_visible ? edge_edit_padding_ : item_edit_padding_;
|
|
|