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