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.
4
5#include "ui/views/layout/grid_layout.h"
6
7#include "base/compiler_specific.h"
8#include "testing/gtest/include/gtest/gtest.h"
9#include "ui/views/view.h"
10
11namespace views {
12
13void ExpectViewBoundsEquals(int x, int y, int w, int h,
14                            const View* view) {
15  EXPECT_EQ(x, view->x());
16  EXPECT_EQ(y, view->y());
17  EXPECT_EQ(w, view->width());
18  EXPECT_EQ(h, view->height());
19}
20
21class SettableSizeView : public View {
22 public:
23  explicit SettableSizeView(const gfx::Size& pref) {
24    pref_ = pref;
25  }
26
27  virtual gfx::Size GetPreferredSize() const OVERRIDE {
28    return pref_;
29  }
30
31 private:
32   gfx::Size pref_;
33};
34
35// A view with fixed circumference that trades height for width.
36class FlexibleView : public View {
37 public:
38  explicit FlexibleView(int circumference) {
39    circumference_ = circumference;
40  }
41
42  virtual gfx::Size GetPreferredSize() const OVERRIDE {
43    return gfx::Size(0, circumference_ / 2);
44  }
45
46  virtual int GetHeightForWidth(int width) const OVERRIDE {
47    return std::max(0, circumference_ / 2 - width);
48  }
49
50 private:
51   int circumference_;
52};
53
54class GridLayoutTest : public testing::Test {
55 public:
56  GridLayoutTest() : layout(&host) {}
57
58  void RemoveAll() {
59    for (int i = host.child_count() - 1; i >= 0; i--)
60      host.RemoveChildView(host.child_at(i));
61  }
62
63  void GetPreferredSize() {
64    pref = layout.GetPreferredSize(&host);
65  }
66
67  gfx::Size pref;
68  gfx::Rect bounds;
69  View host;
70  GridLayout layout;
71};
72
73class GridLayoutAlignmentTest : public testing::Test {
74 public:
75   GridLayoutAlignmentTest()
76       : v1(gfx::Size(10, 20)),
77         layout(&host) {}
78
79  void RemoveAll() {
80    for (int i = host.child_count() - 1; i >= 0; i--)
81      host.RemoveChildView(host.child_at(i));
82  }
83
84  void TestAlignment(GridLayout::Alignment alignment, gfx::Rect* bounds) {
85    ColumnSet* c1 = layout.AddColumnSet(0);
86    c1->AddColumn(alignment, alignment, 1, GridLayout::USE_PREF, 0, 0);
87    layout.StartRow(1, 0);
88    layout.AddView(&v1);
89    gfx::Size pref = layout.GetPreferredSize(&host);
90    EXPECT_EQ(gfx::Size(10, 20), pref);
91    host.SetBounds(0, 0, 100, 100);
92    layout.Layout(&host);
93    *bounds = v1.bounds();
94    RemoveAll();
95  }
96
97  View host;
98  SettableSizeView v1;
99  GridLayout layout;
100};
101
102TEST_F(GridLayoutAlignmentTest, Fill) {
103  gfx::Rect bounds;
104  TestAlignment(GridLayout::FILL, &bounds);
105  EXPECT_EQ(gfx::Rect(0, 0, 100, 100), bounds);
106}
107
108TEST_F(GridLayoutAlignmentTest, Leading) {
109  gfx::Rect bounds;
110  TestAlignment(GridLayout::LEADING, &bounds);
111  EXPECT_EQ(gfx::Rect(0, 0, 10, 20), bounds);
112}
113
114TEST_F(GridLayoutAlignmentTest, Center) {
115  gfx::Rect bounds;
116  TestAlignment(GridLayout::CENTER, &bounds);
117  EXPECT_EQ(gfx::Rect(45, 40, 10, 20), bounds);
118}
119
120TEST_F(GridLayoutAlignmentTest, Trailing) {
121  gfx::Rect bounds;
122  TestAlignment(GridLayout::TRAILING, &bounds);
123  EXPECT_EQ(gfx::Rect(90, 80, 10, 20), bounds);
124}
125
126TEST_F(GridLayoutTest, TwoColumns) {
127  SettableSizeView v1(gfx::Size(10, 20));
128  SettableSizeView v2(gfx::Size(20, 20));
129  ColumnSet* c1 = layout.AddColumnSet(0);
130  c1->AddColumn(GridLayout::LEADING, GridLayout::LEADING,
131                0, GridLayout::USE_PREF, 0, 0);
132  c1->AddColumn(GridLayout::LEADING, GridLayout::LEADING,
133                0, GridLayout::USE_PREF, 0, 0);
134  layout.StartRow(0, 0);
135  layout.AddView(&v1);
136  layout.AddView(&v2);
137
138  GetPreferredSize();
139  EXPECT_EQ(gfx::Size(30, 20), pref);
140
141  host.SetBounds(0, 0, pref.width(), pref.height());
142  layout.Layout(&host);
143  ExpectViewBoundsEquals(0, 0, 10, 20, &v1);
144  ExpectViewBoundsEquals(10, 0, 20, 20, &v2);
145
146  RemoveAll();
147}
148
149TEST_F(GridLayoutTest, ColSpan1) {
150  SettableSizeView v1(gfx::Size(100, 20));
151  SettableSizeView v2(gfx::Size(10, 40));
152  ColumnSet* c1 = layout.AddColumnSet(0);
153  c1->AddColumn(GridLayout::LEADING, GridLayout::LEADING,
154                0, GridLayout::USE_PREF, 0, 0);
155  c1->AddColumn(GridLayout::LEADING, GridLayout::LEADING,
156                1, GridLayout::USE_PREF, 0, 0);
157  layout.StartRow(0, 0);
158  layout.AddView(&v1, 2, 1);
159  layout.StartRow(0, 0);
160  layout.AddView(&v2);
161
162  GetPreferredSize();
163  EXPECT_EQ(gfx::Size(100, 60), pref);
164
165  host.SetBounds(0, 0, pref.width(), pref.height());
166  layout.Layout(&host);
167  ExpectViewBoundsEquals(0, 0, 100, 20, &v1);
168  ExpectViewBoundsEquals(0, 20, 10, 40, &v2);
169
170  RemoveAll();
171}
172
173TEST_F(GridLayoutTest, ColSpan2) {
174  SettableSizeView v1(gfx::Size(100, 20));
175  SettableSizeView v2(gfx::Size(10, 20));
176  ColumnSet* c1 = layout.AddColumnSet(0);
177  c1->AddColumn(GridLayout::LEADING, GridLayout::LEADING,
178                1, GridLayout::USE_PREF, 0, 0);
179  c1->AddColumn(GridLayout::LEADING, GridLayout::LEADING,
180                0, GridLayout::USE_PREF, 0, 0);
181  layout.StartRow(0, 0);
182  layout.AddView(&v1, 2, 1);
183  layout.StartRow(0, 0);
184  layout.SkipColumns(1);
185  layout.AddView(&v2);
186
187  GetPreferredSize();
188  EXPECT_EQ(gfx::Size(100, 40), pref);
189
190  host.SetBounds(0, 0, pref.width(), pref.height());
191  layout.Layout(&host);
192  ExpectViewBoundsEquals(0, 0, 100, 20, &v1);
193  ExpectViewBoundsEquals(90, 20, 10, 20, &v2);
194
195  RemoveAll();
196}
197
198TEST_F(GridLayoutTest, ColSpan3) {
199  SettableSizeView v1(gfx::Size(100, 20));
200  SettableSizeView v2(gfx::Size(10, 20));
201  SettableSizeView v3(gfx::Size(10, 20));
202  ColumnSet* c1 = layout.AddColumnSet(0);
203  c1->AddColumn(GridLayout::LEADING, GridLayout::LEADING,
204                0, GridLayout::USE_PREF, 0, 0);
205  c1->AddColumn(GridLayout::LEADING, GridLayout::LEADING,
206                0, GridLayout::USE_PREF, 0, 0);
207  layout.StartRow(0, 0);
208  layout.AddView(&v1, 2, 1);
209  layout.StartRow(0, 0);
210  layout.AddView(&v2);
211  layout.AddView(&v3);
212
213  GetPreferredSize();
214  EXPECT_EQ(gfx::Size(100, 40), pref);
215
216  host.SetBounds(0, 0, pref.width(), pref.height());
217  layout.Layout(&host);
218  ExpectViewBoundsEquals(0, 0, 100, 20, &v1);
219  ExpectViewBoundsEquals(0, 20, 10, 20, &v2);
220  ExpectViewBoundsEquals(50, 20, 10, 20, &v3);
221
222  RemoveAll();
223}
224
225
226TEST_F(GridLayoutTest, ColSpan4) {
227  ColumnSet* set = layout.AddColumnSet(0);
228
229  set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 0,
230                 GridLayout::USE_PREF, 0, 0);
231  set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 0,
232                 GridLayout::USE_PREF, 0, 0);
233
234  SettableSizeView v1(gfx::Size(10, 10));
235  SettableSizeView v2(gfx::Size(10, 10));
236  SettableSizeView v3(gfx::Size(25, 20));
237  layout.StartRow(0, 0);
238  layout.AddView(&v1);
239  layout.AddView(&v2);
240  layout.StartRow(0, 0);
241  layout.AddView(&v3, 2, 1);
242
243  GetPreferredSize();
244  EXPECT_EQ(gfx::Size(25, 30), pref);
245
246  host.SetBounds(0, 0, pref.width(), pref.height());
247  layout.Layout(&host);
248  ExpectViewBoundsEquals(0, 0, 10, 10, &v1);
249  ExpectViewBoundsEquals(12, 0, 10, 10, &v2);
250  ExpectViewBoundsEquals(0, 10, 25, 20, &v3);
251
252  RemoveAll();
253}
254
255// Verifies the sizing of a view that doesn't start in the first column
256// and has a column span > 1 (crbug.com/254092).
257TEST_F(GridLayoutTest, ColSpanStartSecondColumn) {
258  ColumnSet* set = layout.AddColumnSet(0);
259
260  set->AddColumn(GridLayout::FILL, GridLayout::FILL, 0,
261                 GridLayout::USE_PREF, 0, 0);
262  set->AddColumn(GridLayout::FILL, GridLayout::FILL, 0,
263                 GridLayout::USE_PREF, 0, 0);
264  set->AddColumn(GridLayout::FILL, GridLayout::FILL, 0,
265                 GridLayout::FIXED, 10, 0);
266
267  SettableSizeView v1(gfx::Size(10, 10));
268  SettableSizeView v2(gfx::Size(20, 10));
269
270  layout.StartRow(0, 0);
271  layout.AddView(&v1);
272  layout.AddView(&v2, 2, 1);
273
274  GetPreferredSize();
275  EXPECT_EQ(gfx::Size(30, 10), pref);
276
277  host.SetBounds(0, 0, pref.width(), pref.height());
278  layout.Layout(&host);
279  ExpectViewBoundsEquals(0, 0, 10, 10, &v1);
280  ExpectViewBoundsEquals(10, 0, 20, 10, &v2);
281
282  RemoveAll();
283}
284
285TEST_F(GridLayoutTest, SameSizeColumns) {
286  SettableSizeView v1(gfx::Size(50, 20));
287  SettableSizeView v2(gfx::Size(10, 10));
288  ColumnSet* c1 = layout.AddColumnSet(0);
289  c1->AddColumn(GridLayout::LEADING, GridLayout::LEADING,
290                0, GridLayout::USE_PREF, 0, 0);
291  c1->AddColumn(GridLayout::LEADING, GridLayout::LEADING,
292                0, GridLayout::USE_PREF, 0, 0);
293  c1->LinkColumnSizes(0, 1, -1);
294  layout.StartRow(0, 0);
295  layout.AddView(&v1);
296  layout.AddView(&v2);
297
298  gfx::Size pref = layout.GetPreferredSize(&host);
299  EXPECT_EQ(gfx::Size(100, 20), pref);
300
301  host.SetBounds(0, 0, pref.width(), pref.height());
302  layout.Layout(&host);
303  ExpectViewBoundsEquals(0, 0, 50, 20, &v1);
304  ExpectViewBoundsEquals(50, 0, 10, 10, &v2);
305
306  RemoveAll();
307}
308
309TEST_F(GridLayoutTest, HorizontalResizeTest1) {
310  SettableSizeView v1(gfx::Size(50, 20));
311  SettableSizeView v2(gfx::Size(10, 10));
312  ColumnSet* c1 = layout.AddColumnSet(0);
313  c1->AddColumn(GridLayout::FILL, GridLayout::LEADING,
314                1, GridLayout::USE_PREF, 0, 0);
315  c1->AddColumn(GridLayout::LEADING, GridLayout::LEADING,
316                0, GridLayout::USE_PREF, 0, 0);
317  layout.StartRow(0, 0);
318  layout.AddView(&v1);
319  layout.AddView(&v2);
320
321  host.SetBounds(0, 0, 110, 20);
322  layout.Layout(&host);
323  ExpectViewBoundsEquals(0, 0, 100, 20, &v1);
324  ExpectViewBoundsEquals(100, 0, 10, 10, &v2);
325
326  RemoveAll();
327}
328
329TEST_F(GridLayoutTest, HorizontalResizeTest2) {
330  SettableSizeView v1(gfx::Size(50, 20));
331  SettableSizeView v2(gfx::Size(10, 10));
332  ColumnSet* c1 = layout.AddColumnSet(0);
333  c1->AddColumn(GridLayout::FILL, GridLayout::LEADING,
334                1, GridLayout::USE_PREF, 0, 0);
335  c1->AddColumn(GridLayout::TRAILING, GridLayout::LEADING,
336                1, GridLayout::USE_PREF, 0, 0);
337  layout.StartRow(0, 0);
338  layout.AddView(&v1);
339  layout.AddView(&v2);
340
341  host.SetBounds(0, 0, 120, 20);
342  layout.Layout(&host);
343  ExpectViewBoundsEquals(0, 0, 80, 20, &v1);
344  ExpectViewBoundsEquals(110, 0, 10, 10, &v2);
345
346  RemoveAll();
347}
348
349// Tests that space leftover due to rounding is distributed to the last
350// resizable column.
351TEST_F(GridLayoutTest, HorizontalResizeTest3) {
352  SettableSizeView v1(gfx::Size(10, 10));
353  SettableSizeView v2(gfx::Size(10, 10));
354  SettableSizeView v3(gfx::Size(10, 10));
355  ColumnSet* c1 = layout.AddColumnSet(0);
356  c1->AddColumn(GridLayout::FILL, GridLayout::LEADING,
357                1, GridLayout::USE_PREF, 0, 0);
358  c1->AddColumn(GridLayout::FILL, GridLayout::LEADING,
359                1, GridLayout::USE_PREF, 0, 0);
360  c1->AddColumn(GridLayout::TRAILING, GridLayout::LEADING,
361                0, GridLayout::USE_PREF, 0, 0);
362  layout.StartRow(0, 0);
363  layout.AddView(&v1);
364  layout.AddView(&v2);
365  layout.AddView(&v3);
366
367  host.SetBounds(0, 0, 31, 10);
368  layout.Layout(&host);
369  ExpectViewBoundsEquals(0, 0, 10, 10, &v1);
370  ExpectViewBoundsEquals(10, 0, 11, 10, &v2);
371  ExpectViewBoundsEquals(21, 0, 10, 10, &v3);
372
373  RemoveAll();
374}
375
376TEST_F(GridLayoutTest, TestVerticalResize1) {
377  SettableSizeView v1(gfx::Size(50, 20));
378  SettableSizeView v2(gfx::Size(10, 10));
379  ColumnSet* c1 = layout.AddColumnSet(0);
380  c1->AddColumn(GridLayout::FILL, GridLayout::FILL,
381                1, GridLayout::USE_PREF, 0, 0);
382  layout.StartRow(1, 0);
383  layout.AddView(&v1);
384  layout.StartRow(0, 0);
385  layout.AddView(&v2);
386
387  GetPreferredSize();
388  EXPECT_EQ(gfx::Size(50, 30), pref);
389
390  host.SetBounds(0, 0, 50, 100);
391  layout.Layout(&host);
392  ExpectViewBoundsEquals(0, 0, 50, 90, &v1);
393  ExpectViewBoundsEquals(0, 90, 50, 10, &v2);
394
395  RemoveAll();
396}
397
398TEST_F(GridLayoutTest, Insets) {
399  SettableSizeView v1(gfx::Size(10, 20));
400  ColumnSet* c1 = layout.AddColumnSet(0);
401  layout.SetInsets(1, 2, 3, 4);
402  c1->AddColumn(GridLayout::LEADING, GridLayout::LEADING,
403                0, GridLayout::USE_PREF, 0, 0);
404  layout.StartRow(0, 0);
405  layout.AddView(&v1);
406
407  GetPreferredSize();
408  EXPECT_EQ(gfx::Size(16, 24), pref);
409
410  host.SetBounds(0, 0, pref.width(), pref.height());
411  layout.Layout(&host);
412  ExpectViewBoundsEquals(2, 1, 10, 20, &v1);
413
414  RemoveAll();
415}
416
417TEST_F(GridLayoutTest, FixedSize) {
418  layout.SetInsets(2, 2, 2, 2);
419
420  ColumnSet* set = layout.AddColumnSet(0);
421
422  int column_count = 4;
423  int title_width = 100;
424  int row_count = 2;
425  int pref_width = 10;
426  int pref_height = 20;
427
428  for (int i = 0; i < column_count; ++i) {
429    set->AddColumn(GridLayout::CENTER,
430                   GridLayout::CENTER,
431                   0,
432                   GridLayout::FIXED,
433                   title_width,
434                   title_width);
435  }
436
437  for (int row = 0; row < row_count; ++row) {
438    layout.StartRow(0, 0);
439    for (int col = 0; col < column_count; ++col) {
440      layout.AddView(new SettableSizeView(gfx::Size(pref_width, pref_height)));
441    }
442  }
443
444  layout.Layout(&host);
445
446  for (int i = 0; i < column_count; ++i) {
447    for (int row = 0; row < row_count; ++row) {
448      View* view = host.child_at(row * column_count + i);
449      ExpectViewBoundsEquals(
450          2 + title_width * i + (title_width - pref_width) / 2,
451          2 + pref_height * row,
452          pref_width,
453          pref_height, view);
454    }
455  }
456
457  GetPreferredSize();
458  EXPECT_EQ(gfx::Size(column_count * title_width + 4,
459                      row_count * pref_height + 4), pref);
460}
461
462TEST_F(GridLayoutTest, RowSpanWithPaddingRow) {
463  ColumnSet* set = layout.AddColumnSet(0);
464
465  set->AddColumn(GridLayout::CENTER,
466                 GridLayout::CENTER,
467                 0,
468                 GridLayout::FIXED,
469                 10,
470                 10);
471
472  layout.StartRow(0, 0);
473  layout.AddView(new SettableSizeView(gfx::Size(10, 10)), 1, 2);
474  layout.AddPaddingRow(0, 10);
475}
476
477TEST_F(GridLayoutTest, RowSpan) {
478  ColumnSet* set = layout.AddColumnSet(0);
479
480  set->AddColumn(GridLayout::LEADING,
481                 GridLayout::LEADING,
482                 0,
483                 GridLayout::USE_PREF,
484                 0,
485                 0);
486  set->AddColumn(GridLayout::LEADING,
487                 GridLayout::LEADING,
488                 0,
489                 GridLayout::USE_PREF,
490                 0,
491                 0);
492
493  layout.StartRow(0, 0);
494  layout.AddView(new SettableSizeView(gfx::Size(20, 10)));
495  layout.AddView(new SettableSizeView(gfx::Size(20, 40)), 1, 2);
496  layout.StartRow(1, 0);
497  View* s3 = new SettableSizeView(gfx::Size(20, 10));
498  layout.AddView(s3);
499
500  GetPreferredSize();
501  EXPECT_EQ(gfx::Size(40, 40), pref);
502
503  host.SetBounds(0, 0, pref.width(), pref.height());
504  layout.Layout(&host);
505  ExpectViewBoundsEquals(0, 10, 20, 10, s3);
506}
507
508TEST_F(GridLayoutTest, RowSpan2) {
509  ColumnSet* set = layout.AddColumnSet(0);
510
511  set->AddColumn(GridLayout::LEADING, GridLayout::LEADING,
512                 0, GridLayout::USE_PREF, 0, 0);
513  set->AddColumn(GridLayout::LEADING, GridLayout::LEADING,
514                 0,GridLayout::USE_PREF, 0, 0);
515
516  layout.StartRow(0, 0);
517  layout.AddView(new SettableSizeView(gfx::Size(20, 20)));
518  View* s3 = new SettableSizeView(gfx::Size(64, 64));
519  layout.AddView(s3, 1, 3);
520
521  layout.AddPaddingRow(0, 10);
522
523  layout.StartRow(0, 0);
524  layout.AddView(new SettableSizeView(gfx::Size(10, 20)));
525
526  GetPreferredSize();
527  EXPECT_EQ(gfx::Size(84, 64), pref);
528
529  host.SetBounds(0, 0, pref.width(), pref.height());
530  layout.Layout(&host);
531  ExpectViewBoundsEquals(20, 0, 64, 64, s3);
532}
533
534TEST_F(GridLayoutTest, FixedViewWidth) {
535  ColumnSet* set = layout.AddColumnSet(0);
536
537  set->AddColumn(GridLayout::LEADING, GridLayout::LEADING,
538                 0, GridLayout::USE_PREF, 0, 0);
539  set->AddColumn(GridLayout::LEADING, GridLayout::LEADING,
540                 0,GridLayout::USE_PREF, 0, 0);
541
542  layout.StartRow(0, 0);
543  View* view = new SettableSizeView(gfx::Size(30, 40));
544  layout.AddView(view, 1, 1, GridLayout::LEADING, GridLayout::LEADING, 10, 0);
545
546  GetPreferredSize();
547  EXPECT_EQ(10, pref.width());
548  EXPECT_EQ(40, pref.height());
549
550  host.SetBounds(0, 0, pref.width(), pref.height());
551  layout.Layout(&host);
552  ExpectViewBoundsEquals(0, 0, 10, 40, view);
553}
554
555TEST_F(GridLayoutTest, FixedViewHeight) {
556  ColumnSet* set = layout.AddColumnSet(0);
557
558  set->AddColumn(GridLayout::LEADING, GridLayout::LEADING,
559                 0, GridLayout::USE_PREF, 0, 0);
560  set->AddColumn(GridLayout::LEADING, GridLayout::LEADING,
561                 0,GridLayout::USE_PREF, 0, 0);
562
563  layout.StartRow(0, 0);
564  View* view = new SettableSizeView(gfx::Size(30, 40));
565  layout.AddView(view, 1, 1, GridLayout::LEADING, GridLayout::LEADING, 0, 10);
566
567  GetPreferredSize();
568  EXPECT_EQ(30, pref.width());
569  EXPECT_EQ(10, pref.height());
570
571  host.SetBounds(0, 0, pref.width(), pref.height());
572  layout.Layout(&host);
573  ExpectViewBoundsEquals(0, 0, 30, 10, view);
574}
575
576// Make sure that for views that span columns the underlying columns are resized
577// based on the resize percent of the column.
578TEST_F(GridLayoutTest, ColumnSpanResizing) {
579  ColumnSet* set = layout.AddColumnSet(0);
580
581  set->AddColumn(GridLayout::FILL, GridLayout::CENTER,
582                 2, GridLayout::USE_PREF, 0, 0);
583  set->AddColumn(GridLayout::FILL, GridLayout::CENTER,
584                 4, GridLayout::USE_PREF, 0, 0);
585
586  layout.StartRow(0, 0);
587  // span_view spans two columns and is twice as big the views added below.
588  View* span_view = new SettableSizeView(gfx::Size(12, 40));
589  layout.AddView(span_view, 2, 1, GridLayout::LEADING, GridLayout::LEADING);
590
591  layout.StartRow(0, 0);
592  View* view1 = new SettableSizeView(gfx::Size(2, 40));
593  View* view2 = new SettableSizeView(gfx::Size(4, 40));
594  layout.AddView(view1);
595  layout.AddView(view2);
596
597  host.SetBounds(0, 0, 12, 80);
598  layout.Layout(&host);
599
600  ExpectViewBoundsEquals(0, 0, 12, 40, span_view);
601
602  // view1 should be 4 pixels wide
603  // column_pref + (remaining_width * column_resize / total_column_resize) =
604  // 2 + (6 * 2 / 6).
605  ExpectViewBoundsEquals(0, 40, 4, 40, view1);
606
607  // And view2 should be 8 pixels wide:
608  // 4 + (6 * 4 / 6).
609  ExpectViewBoundsEquals(4, 40, 8, 40, view2);
610}
611
612// Check that GetPreferredSize() takes resizing of columns into account when
613// there is additional space in the case we have column sets of different
614// preferred sizes.
615TEST_F(GridLayoutTest, ColumnResizingOnGetPreferredSize) {
616  ColumnSet* set = layout.AddColumnSet(0);
617  set->AddColumn(GridLayout::FILL, GridLayout::CENTER,
618                 1, GridLayout::USE_PREF, 0, 0);
619
620  set = layout.AddColumnSet(1);
621  set->AddColumn(GridLayout::FILL, GridLayout::CENTER,
622                 1, GridLayout::USE_PREF, 0, 0);
623
624  set = layout.AddColumnSet(2);
625  set->AddColumn(GridLayout::FILL, GridLayout::CENTER,
626                 1, GridLayout::USE_PREF, 0, 0);
627
628  // Make a row containing a flexible view that trades width for height.
629  layout.StartRow(0, 0);
630  View* view1 = new FlexibleView(100);
631  layout.AddView(view1, 1, 1, GridLayout::FILL, GridLayout::LEADING);
632
633  // The second row contains a view of fixed size that will enforce a column
634  // width of 20 pixels.
635  layout.StartRow(0, 1);
636  View* view2 = new SettableSizeView(gfx::Size(20, 20));
637  layout.AddView(view2, 1, 1, GridLayout::FILL, GridLayout::LEADING);
638
639  // Add another flexible view in row three in order to ensure column set
640  // ordering doesn't influence sizing behaviour.
641  layout.StartRow(0, 2);
642  View* view3 = new FlexibleView(40);
643  layout.AddView(view3, 1, 1, GridLayout::FILL, GridLayout::LEADING);
644
645  // We expect a height of 50: 30 from the variable width view in the first row
646  // plus 20 from the statically sized view in the second row. The flexible
647  // view in the third row should contribute no height.
648  EXPECT_EQ(gfx::Size(20, 50), layout.GetPreferredSize(&host));
649}
650
651TEST_F(GridLayoutTest, MinimumPreferredSize) {
652  SettableSizeView v1(gfx::Size(10, 20));
653  ColumnSet* set = layout.AddColumnSet(0);
654  set->AddColumn(GridLayout::FILL, GridLayout::FILL,
655                 0, GridLayout::USE_PREF, 0, 0);
656  layout.StartRow(0, 0);
657  layout.AddView(&v1);
658
659  GetPreferredSize();
660  EXPECT_EQ(gfx::Size(10, 20), pref);
661
662  layout.set_minimum_size(gfx::Size(40, 40));
663  GetPreferredSize();
664  EXPECT_EQ(gfx::Size(40, 40), pref);
665
666  RemoveAll();
667}
668
669}  // namespace views
670