This source file includes following definitions.
- SetPreferredSize
 
- GetPreferredSize
 
- Layout
 
- TEST
 
- TEST
 
- TEST
 
- TEST
 
- TEST
 
- TEST
 
- TEST
 
- TEST
 
- TEST
 
- TEST
 
#include "ui/views/controls/scroll_view.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/views/controls/scrollbar/overlay_scroll_bar.h"
#include "ui/views/test/test_views.h"
namespace views {
namespace {
const int kWidth = 100;
const int kMinHeight = 50;
const int kMaxHeight = 100;
class CustomView : public View {
 public:
  CustomView() {}
  void SetPreferredSize(const gfx::Size& size) {
    preferred_size_ = size;
    PreferredSizeChanged();
  }
  virtual gfx::Size GetPreferredSize() OVERRIDE { return preferred_size_; }
  virtual void Layout() OVERRIDE {
    gfx::Size pref = GetPreferredSize();
    int width = pref.width();
    int height = pref.height();
    if (parent()) {
      width = std::max(parent()->width(), width);
      height = std::max(parent()->height(), height);
    }
    SetBounds(x(), y(), width, height);
  }
 private:
  gfx::Size preferred_size_;
  DISALLOW_COPY_AND_ASSIGN(CustomView);
};
}  
TEST(ScrollViewTest, ViewportSizedToFit) {
  ScrollView scroll_view;
  View* contents = new View;
  scroll_view.SetContents(contents);
  scroll_view.SetBoundsRect(gfx::Rect(0, 0, 100, 100));
  scroll_view.Layout();
  EXPECT_EQ("0,0 100x100", contents->parent()->bounds().ToString());
}
TEST(ScrollViewTest, ScrollBars) {
  ScrollView scroll_view;
  View* contents = new View;
  scroll_view.SetContents(contents);
  scroll_view.SetBoundsRect(gfx::Rect(0, 0, 100, 100));
  
  contents->SetBounds(0, 0, 50, 400);
  scroll_view.Layout();
  EXPECT_EQ(100 - scroll_view.GetScrollBarWidth(), contents->parent()->width());
  EXPECT_EQ(100, contents->parent()->height());
  EXPECT_TRUE(!scroll_view.horizontal_scroll_bar() ||
              !scroll_view.horizontal_scroll_bar()->visible());
  ASSERT_TRUE(scroll_view.vertical_scroll_bar() != NULL);
  EXPECT_TRUE(scroll_view.vertical_scroll_bar()->visible());
  
  contents->SetBounds(0, 0, 400, 50);
  scroll_view.Layout();
  EXPECT_EQ(100, contents->parent()->width());
  EXPECT_EQ(100 - scroll_view.GetScrollBarHeight(),
            contents->parent()->height());
  ASSERT_TRUE(scroll_view.horizontal_scroll_bar() != NULL);
  EXPECT_TRUE(scroll_view.horizontal_scroll_bar()->visible());
  EXPECT_TRUE(!scroll_view.vertical_scroll_bar() ||
              !scroll_view.vertical_scroll_bar()->visible());
  
  contents->SetBounds(0, 0, 300, 400);
  scroll_view.Layout();
  EXPECT_EQ(100 - scroll_view.GetScrollBarWidth(), contents->parent()->width());
  EXPECT_EQ(100 - scroll_view.GetScrollBarHeight(),
            contents->parent()->height());
  ASSERT_TRUE(scroll_view.horizontal_scroll_bar() != NULL);
  EXPECT_TRUE(scroll_view.horizontal_scroll_bar()->visible());
  ASSERT_TRUE(scroll_view.vertical_scroll_bar() != NULL);
  EXPECT_TRUE(scroll_view.vertical_scroll_bar()->visible());
}
TEST(ScrollViewTest, Header) {
  ScrollView scroll_view;
  View* contents = new View;
  CustomView* header = new CustomView;
  scroll_view.SetHeader(header);
  View* header_parent = header->parent();
  scroll_view.SetContents(contents);
  scroll_view.SetBoundsRect(gfx::Rect(0, 0, 100, 100));
  scroll_view.Layout();
  
  
  EXPECT_EQ("0,0 100x0", header->parent()->bounds().ToString());
  EXPECT_EQ("0,0 100x100", contents->parent()->bounds().ToString());
  
  header->SetPreferredSize(gfx::Size(10, 20));
  EXPECT_EQ("0,0 100x20", header->parent()->bounds().ToString());
  EXPECT_EQ("0,20 100x80", contents->parent()->bounds().ToString());
  
  scroll_view.SetHeader(NULL);
  
  header = NULL;
  EXPECT_EQ("0,0 100x0", header_parent->bounds().ToString());
  EXPECT_EQ("0,0 100x100", contents->parent()->bounds().ToString());
}
TEST(ScrollViewTest, ScrollBarsWithHeader) {
  ScrollView scroll_view;
  View* contents = new View;
  scroll_view.SetContents(contents);
  CustomView* header = new CustomView;
  scroll_view.SetHeader(header);
  scroll_view.SetBoundsRect(gfx::Rect(0, 0, 100, 100));
  header->SetPreferredSize(gfx::Size(10, 20));
  
  contents->SetBounds(0, 0, 50, 400);
  scroll_view.Layout();
  EXPECT_EQ(0, contents->parent()->x());
  EXPECT_EQ(20, contents->parent()->y());
  EXPECT_EQ(100 - scroll_view.GetScrollBarWidth(), contents->parent()->width());
  EXPECT_EQ(80, contents->parent()->height());
  EXPECT_EQ(0, header->parent()->x());
  EXPECT_EQ(0, header->parent()->y());
  EXPECT_EQ(100 - scroll_view.GetScrollBarWidth(), header->parent()->width());
  EXPECT_EQ(20, header->parent()->height());
  EXPECT_TRUE(!scroll_view.horizontal_scroll_bar() ||
              !scroll_view.horizontal_scroll_bar()->visible());
  ASSERT_TRUE(scroll_view.vertical_scroll_bar() != NULL);
  EXPECT_TRUE(scroll_view.vertical_scroll_bar()->visible());
  
  contents->SetBounds(0, 0, 400, 50);
  scroll_view.Layout();
  EXPECT_EQ(0, contents->parent()->x());
  EXPECT_EQ(20, contents->parent()->y());
  EXPECT_EQ(100, contents->parent()->width());
  EXPECT_EQ(100 - scroll_view.GetScrollBarHeight() - 20,
            contents->parent()->height());
  EXPECT_EQ(0, header->parent()->x());
  EXPECT_EQ(0, header->parent()->y());
  EXPECT_EQ(100, header->parent()->width());
  EXPECT_EQ(20, header->parent()->height());
  ASSERT_TRUE(scroll_view.horizontal_scroll_bar() != NULL);
  EXPECT_TRUE(scroll_view.horizontal_scroll_bar()->visible());
  EXPECT_TRUE(!scroll_view.vertical_scroll_bar() ||
              !scroll_view.vertical_scroll_bar()->visible());
  
  contents->SetBounds(0, 0, 300, 400);
  scroll_view.Layout();
  EXPECT_EQ(0, contents->parent()->x());
  EXPECT_EQ(20, contents->parent()->y());
  EXPECT_EQ(100 - scroll_view.GetScrollBarWidth(), contents->parent()->width());
  EXPECT_EQ(100 - scroll_view.GetScrollBarHeight() - 20,
            contents->parent()->height());
  EXPECT_EQ(0, header->parent()->x());
  EXPECT_EQ(0, header->parent()->y());
  EXPECT_EQ(100 - scroll_view.GetScrollBarWidth(), header->parent()->width());
  EXPECT_EQ(20, header->parent()->height());
  ASSERT_TRUE(scroll_view.horizontal_scroll_bar() != NULL);
  EXPECT_TRUE(scroll_view.horizontal_scroll_bar()->visible());
  ASSERT_TRUE(scroll_view.vertical_scroll_bar() != NULL);
  EXPECT_TRUE(scroll_view.vertical_scroll_bar()->visible());
}
TEST(ScrollViewTest, HeaderScrollsWithContent) {
  ScrollView scroll_view;
  CustomView* contents = new CustomView;
  scroll_view.SetContents(contents);
  contents->SetPreferredSize(gfx::Size(500, 500));
  CustomView* header = new CustomView;
  scroll_view.SetHeader(header);
  header->SetPreferredSize(gfx::Size(500, 20));
  scroll_view.SetBoundsRect(gfx::Rect(0, 0, 100, 100));
  EXPECT_EQ("0,0", contents->bounds().origin().ToString());
  EXPECT_EQ("0,0", header->bounds().origin().ToString());
  
  ASSERT_TRUE(scroll_view.horizontal_scroll_bar());
  scroll_view.ScrollToPosition(
      const_cast<ScrollBar*>(scroll_view.horizontal_scroll_bar()), 1);
  EXPECT_EQ("-1,0", contents->bounds().origin().ToString());
  EXPECT_EQ("-1,0", header->bounds().origin().ToString());
  
  ASSERT_TRUE(scroll_view.vertical_scroll_bar());
  scroll_view.ScrollToPosition(
      const_cast<ScrollBar*>(scroll_view.vertical_scroll_bar()), 1);
  EXPECT_EQ("-1,-1", contents->bounds().origin().ToString());
  EXPECT_EQ("-1,0", header->bounds().origin().ToString());
}
TEST(ScrollViewTest, ScrollRectToVisible) {
  ScrollView scroll_view;
  CustomView* contents = new CustomView;
  scroll_view.SetContents(contents);
  contents->SetPreferredSize(gfx::Size(500, 1000));
  scroll_view.SetBoundsRect(gfx::Rect(0, 0, 100, 100));
  scroll_view.Layout();
  EXPECT_EQ("0,0", contents->bounds().origin().ToString());
  
  
  contents->ScrollRectToVisible(gfx::Rect(0, 405, 10, 10));
  const int viewport_height = contents->parent()->height();
  EXPECT_EQ(-(415 - viewport_height), contents->y());
  
  contents->ScrollRectToVisible(gfx::Rect(0, -contents->y(), 10, 10));
  EXPECT_EQ(-(415 - viewport_height), contents->y());
}
TEST(ScrollViewTest, ClipHeightToNormalContentHeight) {
  ScrollView scroll_view;
  scroll_view.ClipHeightTo(kMinHeight, kMaxHeight);
  const int kNormalContentHeight = 75;
  scroll_view.SetContents(
      new views::StaticSizedView(gfx::Size(kWidth, kNormalContentHeight)));
  EXPECT_EQ(gfx::Size(kWidth, kNormalContentHeight),
            scroll_view.GetPreferredSize());
  scroll_view.SizeToPreferredSize();
  scroll_view.Layout();
  EXPECT_EQ(gfx::Size(kWidth, kNormalContentHeight),
            scroll_view.contents()->size());
  EXPECT_EQ(gfx::Size(kWidth, kNormalContentHeight), scroll_view.size());
}
TEST(ScrollViewTest, ClipHeightToShortContentHeight) {
  ScrollView scroll_view;
  scroll_view.ClipHeightTo(kMinHeight, kMaxHeight);
  const int kShortContentHeight = 10;
  scroll_view.SetContents(
      new views::StaticSizedView(gfx::Size(kWidth, kShortContentHeight)));
  EXPECT_EQ(gfx::Size(kWidth, kMinHeight), scroll_view.GetPreferredSize());
  scroll_view.SizeToPreferredSize();
  scroll_view.Layout();
  EXPECT_EQ(gfx::Size(kWidth, kShortContentHeight),
            scroll_view.contents()->size());
  EXPECT_EQ(gfx::Size(kWidth, kMinHeight), scroll_view.size());
}
TEST(ScrollViewTest, ClipHeightToTallContentHeight) {
  ScrollView scroll_view;
  
  
  scroll_view.SetVerticalScrollBar(new views::OverlayScrollBar(false));
  scroll_view.ClipHeightTo(kMinHeight, kMaxHeight);
  const int kTallContentHeight = 1000;
  scroll_view.SetContents(
      new views::StaticSizedView(gfx::Size(kWidth, kTallContentHeight)));
  EXPECT_EQ(gfx::Size(kWidth, kMaxHeight), scroll_view.GetPreferredSize());
  scroll_view.SizeToPreferredSize();
  scroll_view.Layout();
  EXPECT_EQ(gfx::Size(kWidth, kTallContentHeight),
            scroll_view.contents()->size());
  EXPECT_EQ(gfx::Size(kWidth, kMaxHeight), scroll_view.size());
}
TEST(ScrollViewTest, ClipHeightToScrollbarUsesWidth) {
  ScrollView scroll_view;
  scroll_view.ClipHeightTo(kMinHeight, kMaxHeight);
  
  scroll_view.SetContents(new views::ProportionallySizedView(1000));
  
  scroll_view.SizeToPreferredSize();
  EXPECT_EQ(gfx::Size(0, kMinHeight), scroll_view.GetPreferredSize());
  gfx::Size new_size(kWidth, scroll_view.GetHeightForWidth(kWidth));
  scroll_view.SetSize(new_size);
  scroll_view.Layout();
  int scroll_bar_width = scroll_view.GetScrollBarWidth();
  int expected_width = kWidth - scroll_bar_width;
  EXPECT_EQ(scroll_view.contents()->size().width(), expected_width);
  EXPECT_EQ(scroll_view.contents()->size().height(), 1000 * expected_width);
  EXPECT_EQ(gfx::Size(kWidth, kMaxHeight), scroll_view.size());
}
}