Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / ui / views / controls / scroll_view_unittest.cc
bloba2cba6ffe6d2ddfce054d3b4348b61e27b6f63cb
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/views/controls/scroll_view.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "ui/views/controls/scrollbar/overlay_scroll_bar.h"
9 #include "ui/views/test/test_views.h"
11 namespace views {
13 namespace {
15 const int kWidth = 100;
16 const int kMinHeight = 50;
17 const int kMaxHeight = 100;
19 // View implementation that allows setting the preferred size.
20 class CustomView : public View {
21 public:
22 CustomView() {}
24 void SetPreferredSize(const gfx::Size& size) {
25 preferred_size_ = size;
26 PreferredSizeChanged();
29 virtual gfx::Size GetPreferredSize() const OVERRIDE {
30 return preferred_size_;
33 virtual void Layout() OVERRIDE {
34 gfx::Size pref = GetPreferredSize();
35 int width = pref.width();
36 int height = pref.height();
37 if (parent()) {
38 width = std::max(parent()->width(), width);
39 height = std::max(parent()->height(), height);
41 SetBounds(x(), y(), width, height);
44 private:
45 gfx::Size preferred_size_;
47 DISALLOW_COPY_AND_ASSIGN(CustomView);
50 } // namespace
52 // Verifies the viewport is sized to fit the available space.
53 TEST(ScrollViewTest, ViewportSizedToFit) {
54 ScrollView scroll_view;
55 View* contents = new View;
56 scroll_view.SetContents(contents);
57 scroll_view.SetBoundsRect(gfx::Rect(0, 0, 100, 100));
58 scroll_view.Layout();
59 EXPECT_EQ("0,0 100x100", contents->parent()->bounds().ToString());
62 // Verifies the scrollbars are added as necessary.
63 TEST(ScrollViewTest, ScrollBars) {
64 ScrollView scroll_view;
65 View* contents = new View;
66 scroll_view.SetContents(contents);
67 scroll_view.SetBoundsRect(gfx::Rect(0, 0, 100, 100));
69 // Size the contents such that vertical scrollbar is needed.
70 contents->SetBounds(0, 0, 50, 400);
71 scroll_view.Layout();
72 EXPECT_EQ(100 - scroll_view.GetScrollBarWidth(), contents->parent()->width());
73 EXPECT_EQ(100, contents->parent()->height());
74 EXPECT_TRUE(!scroll_view.horizontal_scroll_bar() ||
75 !scroll_view.horizontal_scroll_bar()->visible());
76 ASSERT_TRUE(scroll_view.vertical_scroll_bar() != NULL);
77 EXPECT_TRUE(scroll_view.vertical_scroll_bar()->visible());
79 // Size the contents such that horizontal scrollbar is needed.
80 contents->SetBounds(0, 0, 400, 50);
81 scroll_view.Layout();
82 EXPECT_EQ(100, contents->parent()->width());
83 EXPECT_EQ(100 - scroll_view.GetScrollBarHeight(),
84 contents->parent()->height());
85 ASSERT_TRUE(scroll_view.horizontal_scroll_bar() != NULL);
86 EXPECT_TRUE(scroll_view.horizontal_scroll_bar()->visible());
87 EXPECT_TRUE(!scroll_view.vertical_scroll_bar() ||
88 !scroll_view.vertical_scroll_bar()->visible());
90 // Both horizontal and vertical.
91 contents->SetBounds(0, 0, 300, 400);
92 scroll_view.Layout();
93 EXPECT_EQ(100 - scroll_view.GetScrollBarWidth(), contents->parent()->width());
94 EXPECT_EQ(100 - scroll_view.GetScrollBarHeight(),
95 contents->parent()->height());
96 ASSERT_TRUE(scroll_view.horizontal_scroll_bar() != NULL);
97 EXPECT_TRUE(scroll_view.horizontal_scroll_bar()->visible());
98 ASSERT_TRUE(scroll_view.vertical_scroll_bar() != NULL);
99 EXPECT_TRUE(scroll_view.vertical_scroll_bar()->visible());
102 // Assertions around adding a header.
103 TEST(ScrollViewTest, Header) {
104 ScrollView scroll_view;
105 View* contents = new View;
106 CustomView* header = new CustomView;
107 scroll_view.SetHeader(header);
108 View* header_parent = header->parent();
109 scroll_view.SetContents(contents);
110 scroll_view.SetBoundsRect(gfx::Rect(0, 0, 100, 100));
111 scroll_view.Layout();
112 // |header|s preferred size is empty, which should result in all space going
113 // to contents.
114 EXPECT_EQ("0,0 100x0", header->parent()->bounds().ToString());
115 EXPECT_EQ("0,0 100x100", contents->parent()->bounds().ToString());
117 // Get the header a height of 20.
118 header->SetPreferredSize(gfx::Size(10, 20));
119 EXPECT_EQ("0,0 100x20", header->parent()->bounds().ToString());
120 EXPECT_EQ("0,20 100x80", contents->parent()->bounds().ToString());
122 // Remove the header.
123 scroll_view.SetHeader(NULL);
124 // SetHeader(NULL) deletes header.
125 header = NULL;
126 EXPECT_EQ("0,0 100x0", header_parent->bounds().ToString());
127 EXPECT_EQ("0,0 100x100", contents->parent()->bounds().ToString());
130 // Verifies the scrollbars are added as necessary when a header is present.
131 TEST(ScrollViewTest, ScrollBarsWithHeader) {
132 ScrollView scroll_view;
133 View* contents = new View;
134 scroll_view.SetContents(contents);
135 CustomView* header = new CustomView;
136 scroll_view.SetHeader(header);
137 scroll_view.SetBoundsRect(gfx::Rect(0, 0, 100, 100));
139 header->SetPreferredSize(gfx::Size(10, 20));
141 // Size the contents such that vertical scrollbar is needed.
142 contents->SetBounds(0, 0, 50, 400);
143 scroll_view.Layout();
144 EXPECT_EQ(0, contents->parent()->x());
145 EXPECT_EQ(20, contents->parent()->y());
146 EXPECT_EQ(100 - scroll_view.GetScrollBarWidth(), contents->parent()->width());
147 EXPECT_EQ(80, contents->parent()->height());
148 EXPECT_EQ(0, header->parent()->x());
149 EXPECT_EQ(0, header->parent()->y());
150 EXPECT_EQ(100 - scroll_view.GetScrollBarWidth(), header->parent()->width());
151 EXPECT_EQ(20, header->parent()->height());
152 EXPECT_TRUE(!scroll_view.horizontal_scroll_bar() ||
153 !scroll_view.horizontal_scroll_bar()->visible());
154 ASSERT_TRUE(scroll_view.vertical_scroll_bar() != NULL);
155 EXPECT_TRUE(scroll_view.vertical_scroll_bar()->visible());
157 // Size the contents such that horizontal scrollbar is needed.
158 contents->SetBounds(0, 0, 400, 50);
159 scroll_view.Layout();
160 EXPECT_EQ(0, contents->parent()->x());
161 EXPECT_EQ(20, contents->parent()->y());
162 EXPECT_EQ(100, contents->parent()->width());
163 EXPECT_EQ(100 - scroll_view.GetScrollBarHeight() - 20,
164 contents->parent()->height());
165 EXPECT_EQ(0, header->parent()->x());
166 EXPECT_EQ(0, header->parent()->y());
167 EXPECT_EQ(100, header->parent()->width());
168 EXPECT_EQ(20, header->parent()->height());
169 ASSERT_TRUE(scroll_view.horizontal_scroll_bar() != NULL);
170 EXPECT_TRUE(scroll_view.horizontal_scroll_bar()->visible());
171 EXPECT_TRUE(!scroll_view.vertical_scroll_bar() ||
172 !scroll_view.vertical_scroll_bar()->visible());
174 // Both horizontal and vertical.
175 contents->SetBounds(0, 0, 300, 400);
176 scroll_view.Layout();
177 EXPECT_EQ(0, contents->parent()->x());
178 EXPECT_EQ(20, contents->parent()->y());
179 EXPECT_EQ(100 - scroll_view.GetScrollBarWidth(), contents->parent()->width());
180 EXPECT_EQ(100 - scroll_view.GetScrollBarHeight() - 20,
181 contents->parent()->height());
182 EXPECT_EQ(0, header->parent()->x());
183 EXPECT_EQ(0, header->parent()->y());
184 EXPECT_EQ(100 - scroll_view.GetScrollBarWidth(), header->parent()->width());
185 EXPECT_EQ(20, header->parent()->height());
186 ASSERT_TRUE(scroll_view.horizontal_scroll_bar() != NULL);
187 EXPECT_TRUE(scroll_view.horizontal_scroll_bar()->visible());
188 ASSERT_TRUE(scroll_view.vertical_scroll_bar() != NULL);
189 EXPECT_TRUE(scroll_view.vertical_scroll_bar()->visible());
192 // Verifies the header scrolls horizontally with the content.
193 TEST(ScrollViewTest, HeaderScrollsWithContent) {
194 ScrollView scroll_view;
195 CustomView* contents = new CustomView;
196 scroll_view.SetContents(contents);
197 contents->SetPreferredSize(gfx::Size(500, 500));
199 CustomView* header = new CustomView;
200 scroll_view.SetHeader(header);
201 header->SetPreferredSize(gfx::Size(500, 20));
203 scroll_view.SetBoundsRect(gfx::Rect(0, 0, 100, 100));
204 EXPECT_EQ("0,0", contents->bounds().origin().ToString());
205 EXPECT_EQ("0,0", header->bounds().origin().ToString());
207 // Scroll the horizontal scrollbar.
208 ASSERT_TRUE(scroll_view.horizontal_scroll_bar());
209 scroll_view.ScrollToPosition(
210 const_cast<ScrollBar*>(scroll_view.horizontal_scroll_bar()), 1);
211 EXPECT_EQ("-1,0", contents->bounds().origin().ToString());
212 EXPECT_EQ("-1,0", header->bounds().origin().ToString());
214 // Scrolling the vertical scrollbar shouldn't effect the header.
215 ASSERT_TRUE(scroll_view.vertical_scroll_bar());
216 scroll_view.ScrollToPosition(
217 const_cast<ScrollBar*>(scroll_view.vertical_scroll_bar()), 1);
218 EXPECT_EQ("-1,-1", contents->bounds().origin().ToString());
219 EXPECT_EQ("-1,0", header->bounds().origin().ToString());
222 // Verifies ScrollRectToVisible() on the child works.
223 TEST(ScrollViewTest, ScrollRectToVisible) {
224 ScrollView scroll_view;
225 CustomView* contents = new CustomView;
226 scroll_view.SetContents(contents);
227 contents->SetPreferredSize(gfx::Size(500, 1000));
229 scroll_view.SetBoundsRect(gfx::Rect(0, 0, 100, 100));
230 scroll_view.Layout();
231 EXPECT_EQ("0,0", contents->bounds().origin().ToString());
233 // Scroll to y=405 height=10, this should make the y position of the content
234 // at (405 + 10) - viewport_height (scroll region bottom aligned).
235 contents->ScrollRectToVisible(gfx::Rect(0, 405, 10, 10));
236 const int viewport_height = contents->parent()->height();
237 EXPECT_EQ(-(415 - viewport_height), contents->y());
239 // Scroll to the current y-location and 10x10; should do nothing.
240 contents->ScrollRectToVisible(gfx::Rect(0, -contents->y(), 10, 10));
241 EXPECT_EQ(-(415 - viewport_height), contents->y());
244 // Verifies ClipHeightTo() uses the height of the content when it is between the
245 // minimum and maximum height values.
246 TEST(ScrollViewTest, ClipHeightToNormalContentHeight) {
247 ScrollView scroll_view;
249 scroll_view.ClipHeightTo(kMinHeight, kMaxHeight);
251 const int kNormalContentHeight = 75;
252 scroll_view.SetContents(
253 new views::StaticSizedView(gfx::Size(kWidth, kNormalContentHeight)));
255 EXPECT_EQ(gfx::Size(kWidth, kNormalContentHeight),
256 scroll_view.GetPreferredSize());
258 scroll_view.SizeToPreferredSize();
259 scroll_view.Layout();
261 EXPECT_EQ(gfx::Size(kWidth, kNormalContentHeight),
262 scroll_view.contents()->size());
263 EXPECT_EQ(gfx::Size(kWidth, kNormalContentHeight), scroll_view.size());
266 // Verifies ClipHeightTo() uses the minimum height when the content is shorter
267 // thamn the minimum height value.
268 TEST(ScrollViewTest, ClipHeightToShortContentHeight) {
269 ScrollView scroll_view;
271 scroll_view.ClipHeightTo(kMinHeight, kMaxHeight);
273 const int kShortContentHeight = 10;
274 scroll_view.SetContents(
275 new views::StaticSizedView(gfx::Size(kWidth, kShortContentHeight)));
277 EXPECT_EQ(gfx::Size(kWidth, kMinHeight), scroll_view.GetPreferredSize());
279 scroll_view.SizeToPreferredSize();
280 scroll_view.Layout();
282 EXPECT_EQ(gfx::Size(kWidth, kShortContentHeight),
283 scroll_view.contents()->size());
284 EXPECT_EQ(gfx::Size(kWidth, kMinHeight), scroll_view.size());
287 // Verifies ClipHeightTo() uses the maximum height when the content is longer
288 // thamn the maximum height value.
289 TEST(ScrollViewTest, ClipHeightToTallContentHeight) {
290 ScrollView scroll_view;
292 // Use a scrollbar that is disabled by default, so the width of the content is
293 // not affected.
294 scroll_view.SetVerticalScrollBar(new views::OverlayScrollBar(false));
296 scroll_view.ClipHeightTo(kMinHeight, kMaxHeight);
298 const int kTallContentHeight = 1000;
299 scroll_view.SetContents(
300 new views::StaticSizedView(gfx::Size(kWidth, kTallContentHeight)));
302 EXPECT_EQ(gfx::Size(kWidth, kMaxHeight), scroll_view.GetPreferredSize());
304 scroll_view.SizeToPreferredSize();
305 scroll_view.Layout();
307 EXPECT_EQ(gfx::Size(kWidth, kTallContentHeight),
308 scroll_view.contents()->size());
309 EXPECT_EQ(gfx::Size(kWidth, kMaxHeight), scroll_view.size());
312 // Verifies that when ClipHeightTo() produces a scrollbar, it reduces the width
313 // of the inner content of the ScrollView.
314 TEST(ScrollViewTest, ClipHeightToScrollbarUsesWidth) {
315 ScrollView scroll_view;
317 scroll_view.ClipHeightTo(kMinHeight, kMaxHeight);
319 // Create a view that will be much taller than it is wide.
320 scroll_view.SetContents(new views::ProportionallySizedView(1000));
322 // Without any width, it will default to 0,0 but be overridden by min height.
323 scroll_view.SizeToPreferredSize();
324 EXPECT_EQ(gfx::Size(0, kMinHeight), scroll_view.GetPreferredSize());
326 gfx::Size new_size(kWidth, scroll_view.GetHeightForWidth(kWidth));
327 scroll_view.SetSize(new_size);
328 scroll_view.Layout();
330 int scroll_bar_width = scroll_view.GetScrollBarWidth();
331 int expected_width = kWidth - scroll_bar_width;
332 EXPECT_EQ(scroll_view.contents()->size().width(), expected_width);
333 EXPECT_EQ(scroll_view.contents()->size().height(), 1000 * expected_width);
334 EXPECT_EQ(gfx::Size(kWidth, kMaxHeight), scroll_view.size());
337 TEST(ScrollViewTest, CornerViewVisibility) {
338 ScrollView scroll_view;
339 View* contents = new View;
340 scroll_view.SetContents(contents);
341 scroll_view.SetBoundsRect(gfx::Rect(0, 0, 100, 100));
342 View* corner_view = scroll_view.corner_view_;
344 // Corner view should be visible when both scrollbars are visible.
345 contents->SetBounds(0, 0, 200, 200);
346 scroll_view.Layout();
347 EXPECT_EQ(&scroll_view, corner_view->parent());
348 EXPECT_TRUE(corner_view->visible());
350 // Corner view should be aligned to the scrollbars.
351 EXPECT_EQ(scroll_view.vertical_scroll_bar()->x(), corner_view->x());
352 EXPECT_EQ(scroll_view.horizontal_scroll_bar()->y(), corner_view->y());
353 EXPECT_EQ(scroll_view.GetScrollBarWidth(), corner_view->width());
354 EXPECT_EQ(scroll_view.GetScrollBarHeight(), corner_view->height());
356 // Corner view should be removed when only the vertical scrollbar is visible.
357 contents->SetBounds(0, 0, 50, 200);
358 scroll_view.Layout();
359 EXPECT_FALSE(corner_view->parent());
361 // ... or when only the horizontal scrollbar is visible.
362 contents->SetBounds(0, 0, 200, 50);
363 scroll_view.Layout();
364 EXPECT_FALSE(corner_view->parent());
366 // ... or when no scrollbar is visible.
367 contents->SetBounds(0, 0, 50, 50);
368 scroll_view.Layout();
369 EXPECT_FALSE(corner_view->parent());
371 // Corner view should reappear when both scrollbars reappear.
372 contents->SetBounds(0, 0, 200, 200);
373 scroll_view.Layout();
374 EXPECT_EQ(&scroll_view, corner_view->parent());
375 EXPECT_TRUE(corner_view->visible());
378 } // namespace views