Fix box sizer layout algorithm to respect both proportions and min sizes.
The new version of the algorithm tries to distribute the entire space allocated to the sizer among its children, just as the version in 2.8 did, while still respecting minimal children sizes first and foremost. This means that the space allocated to the item will always be at least its minimal size if the total space is at least equal to the sum of minimal sizes of the children but that if there is enough space, the proportions will be respected too. Extended the unit test to check that laying out various combinations of three elements results in the expected results. Closes #11311. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@63706 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -42,9 +42,11 @@ public:
|
||||
private:
|
||||
CPPUNIT_TEST_SUITE( BoxSizerTestCase );
|
||||
CPPUNIT_TEST( Size1 );
|
||||
CPPUNIT_TEST( Size3 );
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
void Size1();
|
||||
void Size3();
|
||||
|
||||
wxWindow *m_win;
|
||||
wxSizer *m_sizer;
|
||||
@@ -93,7 +95,7 @@ void BoxSizerTestCase::Size1()
|
||||
m_sizer->Add(child);
|
||||
m_win->Layout();
|
||||
CPPUNIT_ASSERT_EQUAL( sizeChild, child->GetSize() );
|
||||
;
|
||||
|
||||
m_sizer->Clear();
|
||||
m_sizer->Add(child, wxSizerFlags(1));
|
||||
m_win->Layout();
|
||||
@@ -117,3 +119,131 @@ void BoxSizerTestCase::Size1()
|
||||
CPPUNIT_ASSERT_EQUAL( sizeTotal, child->GetSize() );
|
||||
}
|
||||
|
||||
void BoxSizerTestCase::Size3()
|
||||
{
|
||||
// check that various combinations of minimal sizes and proportions work as
|
||||
// expected for different window sizes
|
||||
static const struct LayoutTestData
|
||||
{
|
||||
// proportions of the elements
|
||||
int prop[3];
|
||||
|
||||
// minimal sizes of the elements in the sizer direction
|
||||
int minsize[3];
|
||||
|
||||
// total size and the expected sizes of the elements
|
||||
int x,
|
||||
sizes[3];
|
||||
|
||||
// if true, don't try the permutations of our test data
|
||||
bool dontPermute;
|
||||
|
||||
|
||||
// Add the given window to the sizer with the corresponding parameters
|
||||
void AddToSizer(wxSizer *sizer, wxWindow *win, int n) const
|
||||
{
|
||||
sizer->Add(win, wxSizerFlags(prop[n]));
|
||||
sizer->SetItemMinSize(win, wxSize(minsize[n], -1));
|
||||
}
|
||||
|
||||
} layoutTestData[] =
|
||||
{
|
||||
// some really simple cases (no need to permute those, they're
|
||||
// symmetrical anyhow)
|
||||
{ { 1, 1, 1, }, { 50, 50, 50, }, 150, { 50, 50, 50, }, true },
|
||||
{ { 2, 2, 2, }, { 50, 50, 50, }, 600, { 200, 200, 200, }, true },
|
||||
|
||||
// items with different proportions and min sizes when there is enough
|
||||
// space to lay them out
|
||||
{ { 1, 2, 3, }, { 0, 0, 0, }, 600, { 100, 200, 300, } },
|
||||
{ { 1, 2, 3, }, { 100, 100, 100, }, 600, { 100, 200, 300, } },
|
||||
{ { 1, 2, 3, }, { 100, 50, 50, }, 600, { 100, 200, 300, } },
|
||||
{ { 0, 1, 1, }, { 200, 100, 100, }, 600, { 200, 200, 200, } },
|
||||
{ { 0, 1, 2, }, { 300, 100, 100, }, 600, { 300, 100, 200, } },
|
||||
{ { 0, 1, 1, }, { 100, 50, 50, }, 300, { 100, 100, 100, } },
|
||||
{ { 0, 1, 2, }, { 100, 50, 50, }, 400, { 100, 100, 200, } },
|
||||
|
||||
// cases when there is not enough space to lay out the items correctly
|
||||
// while still respecting their min sizes
|
||||
{ { 0, 1, 1, }, { 100, 150, 50, }, 300, { 100, 150, 50, } },
|
||||
{ { 1, 2, 3, }, { 100, 100, 100, }, 300, { 100, 100, 100, } },
|
||||
{ { 1, 2, 3, }, { 100, 50, 50, }, 300, { 100, 80, 120, } },
|
||||
{ { 1, 2, 3, }, { 100, 10, 10, }, 150, { 100, 20, 30, } },
|
||||
|
||||
// cases when there is not enough space even for the min sizes (don't
|
||||
// permute in these cases as the layout does depend on the item order
|
||||
// because the first ones have priority)
|
||||
{ { 1, 2, 3, }, { 100, 50, 50, }, 150, { 100, 50, 0, }, true },
|
||||
{ { 1, 2, 3, }, { 100, 100, 100, }, 200, { 100, 100, 0, }, true },
|
||||
{ { 1, 2, 3, }, { 100, 100, 100, }, 150, { 100, 50, 0, }, true },
|
||||
{ { 1, 2, 3, }, { 100, 100, 100, }, 50, { 50, 0, 0, }, true },
|
||||
{ { 1, 2, 3, }, { 100, 100, 100, }, 0, { 0, 0, 0, }, true },
|
||||
};
|
||||
|
||||
wxWindow *child[3];
|
||||
child[0] = new wxWindow(m_win, wxID_ANY);
|
||||
child[1] = new wxWindow(m_win, wxID_ANY);
|
||||
child[2] = new wxWindow(m_win, wxID_ANY);
|
||||
|
||||
int j;
|
||||
for ( unsigned i = 0; i < WXSIZEOF(layoutTestData); i++ )
|
||||
{
|
||||
LayoutTestData ltd = layoutTestData[i];
|
||||
|
||||
// the results shouldn't depend on the order of items except in the
|
||||
// case when there is not enough space for even the fixed width items
|
||||
// (in which case the first ones might get enough of it but not the
|
||||
// last ones) so test a couple of permutations of test data unless
|
||||
// specifically disabled for this test case
|
||||
for ( unsigned p = 0; p < 3; p++)
|
||||
{
|
||||
switch ( p )
|
||||
{
|
||||
case 0:
|
||||
// nothing to do, use original data
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// exchange first and last elements
|
||||
wxSwap(ltd.prop[0], ltd.prop[2]);
|
||||
wxSwap(ltd.minsize[0], ltd.minsize[2]);
|
||||
wxSwap(ltd.sizes[0], ltd.sizes[2]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// exchange the original third and second elements
|
||||
wxSwap(ltd.prop[0], ltd.prop[1]);
|
||||
wxSwap(ltd.minsize[0], ltd.minsize[1]);
|
||||
wxSwap(ltd.sizes[0], ltd.sizes[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
m_sizer->Clear();
|
||||
for ( j = 0; j < WXSIZEOF(child); j++ )
|
||||
ltd.AddToSizer(m_sizer, child[j], j);
|
||||
|
||||
m_win->SetClientSize(ltd.x, -1);
|
||||
m_win->Layout();
|
||||
|
||||
for ( j = 0; j < WXSIZEOF(child); j++ )
|
||||
{
|
||||
WX_ASSERT_EQUAL_MESSAGE
|
||||
(
|
||||
(
|
||||
"test %lu, permutation #%d: wrong size for child #%d "
|
||||
"for total size %d",
|
||||
static_cast<unsigned long>(i),
|
||||
static_cast<unsigned long>(p),
|
||||
j,
|
||||
ltd.x
|
||||
),
|
||||
ltd.sizes[j], child[j]->GetSize().x
|
||||
);
|
||||
}
|
||||
|
||||
// don't try other permutations if explicitly disabled
|
||||
if ( ltd.dontPermute )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user