summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-15 07:38:39 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-15 07:38:39 +0000
commitb3c1185aa4baa0fb007830d0350fc8e8af61144a (patch)
tree35dd500c143725303cd86416cc5242dc28212c16 /ui
parentede53873904fc261bd171df9de822a33227e1b03 (diff)
downloadchromium_src-b3c1185aa4baa0fb007830d0350fc8e8af61144a.zip
chromium_src-b3c1185aa4baa0fb007830d0350fc8e8af61144a.tar.gz
chromium_src-b3c1185aa4baa0fb007830d0350fc8e8af61144a.tar.bz2
make BoxLayout use and respect GetHeightForWidth() (for vertical layouts).
BUG=none Review URL: https://chromiumcodereview.appspot.com/12575005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@188288 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/views/layout/box_layout.cc105
-rw-r--r--ui/views/layout/box_layout.h12
-rw-r--r--ui/views/layout/box_layout_unittest.cc38
3 files changed, 121 insertions, 34 deletions
diff --git a/ui/views/layout/box_layout.cc b/ui/views/layout/box_layout.cc
index 319efa7..0111485 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
diff --git a/ui/views/layout/box_layout.h b/ui/views/layout/box_layout.h
index b592cc6..7670d8c 100644
--- a/ui/views/layout/box_layout.h
+++ b/ui/views/layout/box_layout.h
@@ -7,6 +7,7 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "ui/gfx/insets.h"
#include "ui/views/layout/layout_manager.h"
namespace gfx {
@@ -46,13 +47,20 @@ class VIEWS_EXPORT BoxLayout : public LayoutManager {
// Overridden from views::LayoutManager:
virtual void Layout(View* host) OVERRIDE;
virtual gfx::Size GetPreferredSize(View* host) OVERRIDE;
+ virtual int GetPreferredHeightForWidth(View* host, int width) OVERRIDE;
private:
+ // The preferred size for the dialog given the width of the child area.
+ gfx::Size GetPreferredSizeForChildWidth(View* host, int child_area_width);
+
+ // The amount of space the layout requires in addition to any space for the
+ // child views.
+ gfx::Size NonChildSize(View* host);
+
const Orientation orientation_;
// Spacing between child views and host view border.
- const int inside_border_horizontal_spacing_;
- const int inside_border_vertical_spacing_;
+ gfx::Insets inside_border_insets_;
// Spacing to put in between child views.
const int between_child_spacing_;
diff --git a/ui/views/layout/box_layout_unittest.cc b/ui/views/layout/box_layout_unittest.cc
index 017120d..130e14d 100644
--- a/ui/views/layout/box_layout_unittest.cc
+++ b/ui/views/layout/box_layout_unittest.cc
@@ -16,13 +16,33 @@ class StaticSizedView : public View {
explicit StaticSizedView(const gfx::Size& size)
: size_(size) {
}
+ virtual ~StaticSizedView() {}
- virtual gfx::Size GetPreferredSize() OVERRIDE{
+ virtual gfx::Size GetPreferredSize() OVERRIDE {
return size_;
}
private:
gfx::Size size_;
+
+ DISALLOW_COPY_AND_ASSIGN(StaticSizedView);
+};
+
+class ProportionallySizedView : public View {
+ public:
+ explicit ProportionallySizedView(int factor) : factor_(factor) {}
+ virtual ~ProportionallySizedView() {}
+
+ virtual int GetHeightForWidth(int w) OVERRIDE {
+ return w * factor_;
+ }
+
+ private:
+ // The multiplicative factor between width and height, i.e.
+ // height = width * factor_.
+ int factor_;
+
+ DISALLOW_COPY_AND_ASSIGN(ProportionallySizedView);
};
class BoxLayoutTest : public testing::Test {
@@ -131,4 +151,20 @@ TEST_F(BoxLayoutTest, DistributeEmptySpace) {
EXPECT_EQ(gfx::Rect(60, 10, 30, 20).ToString(), v2->bounds().ToString());
}
+TEST_F(BoxLayoutTest, UseHeightForWidth) {
+ layout_.reset(new BoxLayout(BoxLayout::kVertical, 0, 0, 0));
+ View* v1 = new StaticSizedView(gfx::Size(20, 10));
+ host_->AddChildView(v1);
+ View* v2 = new ProportionallySizedView(2);
+ host_->AddChildView(v2);
+ EXPECT_EQ(gfx::Size(20, 50), layout_->GetPreferredSize(host_.get()));
+
+ host_->SetBounds(0, 0, 20, 50);
+ layout_->Layout(host_.get());
+ EXPECT_EQ(gfx::Rect(0, 0, 20, 10), v1->bounds());
+ EXPECT_EQ(gfx::Rect(0, 10, 20, 40), v2->bounds());
+
+ EXPECT_EQ(110, layout_->GetPreferredHeightForWidth(host_.get(), 50));
+}
+
} // namespace views