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 |