]> git.saurik.com Git - wxWidgets.git/blob - tests/sizers/boxsizer.cpp
313dafa3de2cb30e39a03d36d2cd11ce9a4e6964
[wxWidgets.git] / tests / sizers / boxsizer.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/sizers/boxsizer.cpp
3 // Purpose: Unit tests for wxBoxSizer
4 // Author: Vadim Zeitlin
5 // Created: 2010-03-06
6 // RCS-ID: $Id$
7 // Copyright: (c) 2010 Vadim Zeitlin <vadim@wxwidgets.org>
8 ///////////////////////////////////////////////////////////////////////////////
9
10 // ----------------------------------------------------------------------------
11 // headers
12 // ----------------------------------------------------------------------------
13
14 #include "testprec.h"
15
16 #ifdef __BORLANDC__
17 #pragma hdrstop
18 #endif
19
20 #ifndef WX_PRECOMP
21 #include "wx/app.h"
22 #include "wx/sizer.h"
23 #endif // WX_PRECOMP
24
25 #include "asserthelper.h"
26
27 // ----------------------------------------------------------------------------
28 // test class
29 // ----------------------------------------------------------------------------
30
31 class BoxSizerTestCase : public CppUnit::TestCase
32 {
33 public:
34 BoxSizerTestCase() { }
35
36 virtual void setUp();
37 virtual void tearDown();
38
39 private:
40 CPPUNIT_TEST_SUITE( BoxSizerTestCase );
41 CPPUNIT_TEST( Size1 );
42 CPPUNIT_TEST( Size3 );
43 CPPUNIT_TEST( CalcMin );
44 CPPUNIT_TEST_SUITE_END();
45
46 void Size1();
47 void Size3();
48 void CalcMin();
49
50 wxWindow *m_win;
51 wxSizer *m_sizer;
52
53 DECLARE_NO_COPY_CLASS(BoxSizerTestCase)
54 };
55
56 // register in the unnamed registry so that these tests are run by default
57 CPPUNIT_TEST_SUITE_REGISTRATION( BoxSizerTestCase );
58
59 // also include in it's own registry so that these tests can be run alone
60 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( BoxSizerTestCase, "BoxSizerTestCase" );
61
62 // ----------------------------------------------------------------------------
63 // test initialization
64 // ----------------------------------------------------------------------------
65
66 void BoxSizerTestCase::setUp()
67 {
68 m_win = new wxWindow(wxTheApp->GetTopWindow(), wxID_ANY);
69 m_win->SetClientSize(127, 35);
70
71 m_sizer = new wxBoxSizer(wxHORIZONTAL);
72 m_win->SetSizer(m_sizer);
73 }
74
75 void BoxSizerTestCase::tearDown()
76 {
77 delete m_win;
78 m_win = NULL;
79
80 m_sizer = NULL;
81 }
82
83 // ----------------------------------------------------------------------------
84 // tests themselves
85 // ----------------------------------------------------------------------------
86
87 void BoxSizerTestCase::Size1()
88 {
89 const wxSize sizeTotal = m_win->GetClientSize();
90 const wxSize sizeChild = sizeTotal / 2;
91
92 wxWindow * const
93 child = new wxWindow(m_win, wxID_ANY, wxDefaultPosition, sizeChild);
94 m_sizer->Add(child);
95 m_win->Layout();
96 CPPUNIT_ASSERT_EQUAL( sizeChild, child->GetSize() );
97
98 m_sizer->Clear();
99 m_sizer->Add(child, wxSizerFlags(1));
100 m_win->Layout();
101 CPPUNIT_ASSERT_EQUAL( wxSize(sizeTotal.x, sizeChild.y), child->GetSize() );
102
103 m_sizer->Clear();
104 m_sizer->Add(child, wxSizerFlags(1).Expand());
105 m_win->Layout();
106 CPPUNIT_ASSERT_EQUAL( sizeTotal, child->GetSize() );
107
108 m_sizer->Clear();
109 m_sizer->Add(child, wxSizerFlags());
110 m_sizer->SetItemMinSize(child, sizeTotal*2);
111 m_win->Layout();
112 CPPUNIT_ASSERT_EQUAL( sizeTotal, child->GetSize() );
113
114 m_sizer->Clear();
115 m_sizer->Add(child, wxSizerFlags().Expand());
116 m_sizer->SetItemMinSize(child, sizeTotal*2);
117 m_win->Layout();
118 CPPUNIT_ASSERT_EQUAL( sizeTotal, child->GetSize() );
119 }
120
121 void BoxSizerTestCase::Size3()
122 {
123 // check that various combinations of minimal sizes and proportions work as
124 // expected for different window sizes
125 static const struct LayoutTestData
126 {
127 // proportions of the elements
128 int prop[3];
129
130 // minimal sizes of the elements in the sizer direction
131 int minsize[3];
132
133 // total size and the expected sizes of the elements
134 int x,
135 sizes[3];
136
137 // if true, don't try the permutations of our test data
138 bool dontPermute;
139
140
141 // Add the given window to the sizer with the corresponding parameters
142 void AddToSizer(wxSizer *sizer, wxWindow *win, int n) const
143 {
144 sizer->Add(win, wxSizerFlags(prop[n]));
145 sizer->SetItemMinSize(win, wxSize(minsize[n], -1));
146 }
147
148 } layoutTestData[] =
149 {
150 // some really simple cases (no need to permute those, they're
151 // symmetrical anyhow)
152 { { 1, 1, 1, }, { 50, 50, 50, }, 150, { 50, 50, 50, }, true },
153 { { 2, 2, 2, }, { 50, 50, 50, }, 600, { 200, 200, 200, }, true },
154
155 // items with different proportions and min sizes when there is enough
156 // space to lay them out
157 { { 1, 2, 3, }, { 0, 0, 0, }, 600, { 100, 200, 300, } },
158 { { 1, 2, 3, }, { 100, 100, 100, }, 600, { 100, 200, 300, } },
159 { { 1, 2, 3, }, { 100, 50, 50, }, 600, { 100, 200, 300, } },
160 { { 0, 1, 1, }, { 200, 100, 100, }, 600, { 200, 200, 200, } },
161 { { 0, 1, 2, }, { 300, 100, 100, }, 600, { 300, 100, 200, } },
162 { { 0, 1, 1, }, { 100, 50, 50, }, 300, { 100, 100, 100, } },
163 { { 0, 1, 2, }, { 100, 50, 50, }, 400, { 100, 100, 200, } },
164
165 // cases when there is not enough space to lay out the items correctly
166 // while still respecting their min sizes
167 { { 0, 1, 1, }, { 100, 150, 50, }, 300, { 100, 150, 50, } },
168 { { 1, 2, 3, }, { 100, 100, 100, }, 300, { 100, 100, 100, } },
169 { { 1, 2, 3, }, { 100, 50, 50, }, 300, { 100, 80, 120, } },
170 { { 1, 2, 3, }, { 100, 10, 10, }, 150, { 100, 20, 30, } },
171
172 // cases when there is not enough space even for the min sizes (don't
173 // permute in these cases as the layout does depend on the item order
174 // because the first ones have priority)
175 { { 1, 2, 3, }, { 100, 50, 50, }, 150, { 100, 50, 0, }, true },
176 { { 1, 2, 3, }, { 100, 100, 100, }, 200, { 100, 100, 0, }, true },
177 { { 1, 2, 3, }, { 100, 100, 100, }, 150, { 100, 50, 0, }, true },
178 { { 1, 2, 3, }, { 100, 100, 100, }, 50, { 50, 0, 0, }, true },
179 { { 1, 2, 3, }, { 100, 100, 100, }, 0, { 0, 0, 0, }, true },
180 };
181
182 wxWindow *child[3];
183 child[0] = new wxWindow(m_win, wxID_ANY);
184 child[1] = new wxWindow(m_win, wxID_ANY);
185 child[2] = new wxWindow(m_win, wxID_ANY);
186
187 for ( unsigned i = 0; i < WXSIZEOF(layoutTestData); i++ )
188 {
189 LayoutTestData ltd = layoutTestData[i];
190
191 // the results shouldn't depend on the order of items except in the
192 // case when there is not enough space for even the fixed width items
193 // (in which case the first ones might get enough of it but not the
194 // last ones) so test a couple of permutations of test data unless
195 // specifically disabled for this test case
196 for ( unsigned p = 0; p < 3; p++)
197 {
198 switch ( p )
199 {
200 case 0:
201 // nothing to do, use original data
202 break;
203
204 case 1:
205 // exchange first and last elements
206 wxSwap(ltd.prop[0], ltd.prop[2]);
207 wxSwap(ltd.minsize[0], ltd.minsize[2]);
208 wxSwap(ltd.sizes[0], ltd.sizes[2]);
209 break;
210
211 case 2:
212 // exchange the original third and second elements
213 wxSwap(ltd.prop[0], ltd.prop[1]);
214 wxSwap(ltd.minsize[0], ltd.minsize[1]);
215 wxSwap(ltd.sizes[0], ltd.sizes[1]);
216 break;
217 }
218
219 m_sizer->Clear();
220
221 unsigned j;
222 for ( j = 0; j < WXSIZEOF(child); j++ )
223 ltd.AddToSizer(m_sizer, child[j], j);
224
225 m_win->SetClientSize(ltd.x, -1);
226 m_win->Layout();
227
228 for ( j = 0; j < WXSIZEOF(child); j++ )
229 {
230 WX_ASSERT_EQUAL_MESSAGE
231 (
232 (
233 "test %lu, permutation #%lu: wrong size for child #%d "
234 "for total size %d",
235 static_cast<unsigned long>(i),
236 static_cast<unsigned long>(p),
237 j,
238 ltd.x
239 ),
240 ltd.sizes[j], child[j]->GetSize().x
241 );
242 }
243
244 // don't try other permutations if explicitly disabled
245 if ( ltd.dontPermute )
246 break;
247 }
248 }
249 }
250
251 void BoxSizerTestCase::CalcMin()
252 {
253 static const unsigned NUM_TEST_ITEM = 3;
254
255 static const struct CalcMinTestData
256 {
257 // proportions of the elements, if one of them is -1 it means to not
258 // use this window at all in this test
259 int prop[NUM_TEST_ITEM];
260
261 // minimal sizes of the elements in the sizer direction
262 int minsize[NUM_TEST_ITEM];
263
264 // the expected minimal sizer size
265 int total;
266 } calcMinTestData[] =
267 {
268 { { 1, 1, -1 }, { 30, 50, 0 }, 100 },
269 { { 1, 1, 0 }, { 30, 50, 20 }, 120 },
270 { { 10, 10, -1 }, { 30, 50, 0 }, 100 },
271 { { 1, 2, 2 }, { 50, 50, 80 }, 250 },
272 { { 1, 2, 2 }, { 100, 50, 80 }, 500 },
273 };
274
275 unsigned n;
276 wxWindow *child[NUM_TEST_ITEM];
277 for ( n = 0; n < NUM_TEST_ITEM; n++ )
278 child[n] = new wxWindow(m_win, wxID_ANY);
279
280 for ( unsigned i = 0; i < WXSIZEOF(calcMinTestData); i++ )
281 {
282 m_sizer->Clear();
283
284 const CalcMinTestData& cmtd = calcMinTestData[i];
285 for ( n = 0; n < NUM_TEST_ITEM; n++ )
286 {
287 if ( cmtd.prop[n] != -1 )
288 {
289 child[n]->SetInitialSize(wxSize(cmtd.minsize[n], -1));
290 m_sizer->Add(child[n], wxSizerFlags(cmtd.prop[n]));
291 }
292 }
293
294 WX_ASSERT_EQUAL_MESSAGE
295 (
296 ("In test #%u", i),
297 cmtd.total, m_sizer->CalcMin().x
298 );
299 }
300 }