| Index: ui/views/layout/box_layout.cc
|
| diff --git a/ui/views/layout/box_layout.cc b/ui/views/layout/box_layout.cc
|
| index 319efa770c3677a9a9a97fa545f9854be201be17..011148597553ceac4d8da64bebbf9c75fb1e69b9 100644
|
| --- a/ui/views/layout/box_layout.cc
|
| +++ b/ui/views/layout/box_layout.cc
|
| @@ -4,7 +4,6 @@
|
|
|
| #include "ui/views/layout/box_layout.h"
|
|
|
| -#include "ui/gfx/insets.h"
|
| #include "ui/gfx/rect.h"
|
| #include "ui/views/view.h"
|
|
|
| @@ -15,8 +14,10 @@ BoxLayout::BoxLayout(BoxLayout::Orientation orientation,
|
| int inside_border_vertical_spacing,
|
| int between_child_spacing)
|
| : orientation_(orientation),
|
| - inside_border_horizontal_spacing_(inside_border_horizontal_spacing),
|
| - inside_border_vertical_spacing_(inside_border_vertical_spacing),
|
| + inside_border_insets_(inside_border_vertical_spacing,
|
| + inside_border_horizontal_spacing,
|
| + inside_border_vertical_spacing,
|
| + inside_border_horizontal_spacing),
|
| between_child_spacing_(between_child_spacing),
|
| spread_blank_space_(false) {
|
| }
|
| @@ -27,8 +28,7 @@ BoxLayout::~BoxLayout() {
|
| void BoxLayout::Layout(View* host) {
|
| gfx::Rect child_area(host->GetLocalBounds());
|
| child_area.Inset(host->GetInsets());
|
| - child_area.Inset(inside_border_horizontal_spacing_,
|
| - inside_border_vertical_spacing_);
|
| + child_area.Inset(inside_border_insets_);
|
| int x = child_area.x();
|
| int y = child_area.y();
|
|
|
| @@ -40,10 +40,12 @@ void BoxLayout::Layout(View* host) {
|
| View* child = host->child_at(i);
|
| if (!child->visible())
|
| continue;
|
| - if (orientation_ == kHorizontal)
|
| + if (orientation_ == kHorizontal) {
|
| total += child->GetPreferredSize().width() + between_child_spacing_;
|
| - else
|
| - total += child->GetPreferredSize().height() + between_child_spacing_;
|
| + } else {
|
| + total += child->GetHeightForWidth(child_area.width()) +
|
| + between_child_spacing_;
|
| + }
|
| ++visible;
|
| }
|
|
|
| @@ -63,13 +65,12 @@ void BoxLayout::Layout(View* host) {
|
| View* child = host->child_at(i);
|
| if (child->visible()) {
|
| gfx::Rect bounds(x, y, child_area.width(), child_area.height());
|
| - gfx::Size size(child->GetPreferredSize());
|
| if (orientation_ == kHorizontal) {
|
| - bounds.set_width(size.width() + padding);
|
| - x += size.width() + between_child_spacing_ + padding;
|
| + bounds.set_width(child->GetPreferredSize().width() + padding);
|
| + x += bounds.width() + between_child_spacing_;
|
| } else {
|
| - bounds.set_height(size.height() + padding);
|
| - y += size.height() + between_child_spacing_ + padding;
|
| + bounds.set_height(child->GetHeightForWidth(bounds.width()) + padding);
|
| + y += bounds.height() + between_child_spacing_;
|
| }
|
| // Clamp child view bounds to |child_area|.
|
| bounds.Intersect(child_area);
|
| @@ -79,28 +80,70 @@ void BoxLayout::Layout(View* host) {
|
| }
|
|
|
| gfx::Size BoxLayout::GetPreferredSize(View* host) {
|
| - gfx::Rect bounds;
|
| - int position = 0;
|
| - for (int i = 0; i < host->child_count(); ++i) {
|
| - View* child = host->child_at(i);
|
| - if (child->visible()) {
|
| + // Calculate the child views' preferred width.
|
| + int width = 0;
|
| + if (orientation_ == kVertical) {
|
| + for (int i = 0; i < host->child_count(); ++i) {
|
| + View* child = host->child_at(i);
|
| + if (!child->visible())
|
| + continue;
|
| +
|
| + width = std::max(width, child->GetPreferredSize().width());
|
| + }
|
| + }
|
| +
|
| + return GetPreferredSizeForChildWidth(host, width);
|
| +}
|
| +
|
| +int BoxLayout::GetPreferredHeightForWidth(View* host, int width) {
|
| + int child_width = width - NonChildSize(host).width();
|
| + return GetPreferredSizeForChildWidth(host, child_width).height();
|
| +}
|
| +
|
| +gfx::Size BoxLayout::GetPreferredSizeForChildWidth(View* host,
|
| + int child_area_width) {
|
| + gfx::Rect child_area_bounds;
|
| +
|
| + if (orientation_ == kHorizontal) {
|
| + // Horizontal layouts ignore |child_area_width|, meaning they mimic the
|
| + // default behavior of GridLayout::GetPreferredHeightForWidth().
|
| + // TODO(estade): fix this if it ever becomes a problem.
|
| + int position = 0;
|
| + for (int i = 0; i < host->child_count(); ++i) {
|
| + View* child = host->child_at(i);
|
| + if (!child->visible())
|
| + continue;
|
| +
|
| gfx::Size size(child->GetPreferredSize());
|
| - if (orientation_ == kHorizontal) {
|
| - gfx::Rect child_bounds(position, 0, size.width(), size.height());
|
| - bounds.Union(child_bounds);
|
| - position += size.width();
|
| - } else {
|
| - gfx::Rect child_bounds(0, position, size.width(), size.height());
|
| - bounds.Union(child_bounds);
|
| - position += size.height();
|
| - }
|
| - position += between_child_spacing_;
|
| + gfx::Rect child_bounds(position, 0, size.width(), size.height());
|
| + child_area_bounds.Union(child_bounds);
|
| + position += size.width() + between_child_spacing_;
|
| }
|
| + } else {
|
| + int height = 0;
|
| + for (int i = 0; i < host->child_count(); ++i) {
|
| + View* child = host->child_at(i);
|
| + if (!child->visible())
|
| + continue;
|
| +
|
| + height += child->GetHeightForWidth(child_area_width);
|
| + if (i != 0)
|
| + height += between_child_spacing_;
|
| + }
|
| +
|
| + child_area_bounds.set_width(child_area_width);
|
| + child_area_bounds.set_height(height);
|
| }
|
| +
|
| + gfx::Size non_child_size = NonChildSize(host);
|
| + return gfx::Size(child_area_bounds.width() + non_child_size.width(),
|
| + child_area_bounds.height() + non_child_size.height());
|
| +}
|
| +
|
| +gfx::Size BoxLayout::NonChildSize(View* host) {
|
| gfx::Insets insets(host->GetInsets());
|
| - return gfx::Size(
|
| - bounds.width() + insets.width() + 2 * inside_border_horizontal_spacing_,
|
| - bounds.height() + insets.height() + 2 * inside_border_vertical_spacing_);
|
| + return gfx::Size(insets.width() + inside_border_insets_.width(),
|
| + insets.height() + inside_border_insets_.height());
|
| }
|
|
|
| } // namespace views
|
|
|