From 26022721e88892446ebcfc34bc34384492952fa9 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 18 Mar 2010 15:07:14 +0000 Subject: [PATCH] Ensure that size in the major direction of box sizer doesn't exceed the total. After fixing the problem with "growing items by negative proportion" in r56010 (which still was the correct thing to do as it fixed such indefensibly broken behaviour as shrinking items with larger proportion by more than "smaller" items when there was not enough space) the items in a box sizer could become larger than the total space allocated to the sizer resulting in only parts of them being visible. Fix this by truncating the items to the (remaining) total size even if this means making them less than their minimal sizes -- because there is nothing else we can do when the total space is smaller than the sum of minimal sizes anyhow. Closes #10008. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@63704 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/sizer.cpp | 25 ++++++++++++++++++++----- tests/sizers/boxsizer.cpp | 6 ++++++ 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/common/sizer.cpp b/src/common/sizer.cpp index 64ffc0877f..ad0abd60ed 100644 --- a/src/common/sizer.cpp +++ b/src/common/sizer.cpp @@ -1993,10 +1993,11 @@ void wxBoxSizer::RecalcSizes() return; const wxCoord totalMinorSize = GetSizeInMinorDir(m_size); + const wxCoord totalMajorSize = GetSizeInMajorDir(m_size); // the amount of free space which we should redistribute among the // stretchable items (i.e. those with non zero proportion) - int delta = GetSizeInMajorDir(m_size) - GetSizeInMajorDir(m_minSize); + int delta = totalMajorSize - GetSizeInMajorDir(m_minSize); // Inform child items about the size in minor direction, that can @@ -2029,11 +2030,14 @@ void wxBoxSizer::RecalcSizes() // might have a new delta now - delta = GetSizeInMajorDir(m_size) - GetSizeInMajorDir(m_minSize); + delta = totalMajorSize - GetSizeInMajorDir(m_minSize); // the position at which we put the next child wxPoint pt(m_position); + // space remaining for the items + wxCoord majorRemaining = totalMajorSize; + int totalProportion = m_totalProportion; for ( i = m_children.begin(); i != m_children.end(); @@ -2049,11 +2053,10 @@ void wxBoxSizer::RecalcSizes() // adjust the size in the major direction using the proportion wxCoord majorSize = GetSizeInMajorDir(sizeThis); - // if there is not enough space, don't try to distribute negative space - // among the children, this would result in overlapping windows which - // we don't want if ( delta > 0 ) { + // distribute extra space among the items respecting their + // proportions const int propItem = item->GetProportion(); if ( propItem ) { @@ -2065,6 +2068,18 @@ void wxBoxSizer::RecalcSizes() totalProportion -= propItem; } } + else // delta < 0 + { + // we're not going to have enough space for making all items even + // of their minimal size, check if this item still fits at all and + // truncate it if it doesn't -- even if it means giving it 0 size + // and thus making it invisible because we just can't do anything + // else + if ( majorSize > majorRemaining ) + majorSize = majorRemaining; + + majorRemaining -= majorSize; + } // apply the alignment in the minor direction diff --git a/tests/sizers/boxsizer.cpp b/tests/sizers/boxsizer.cpp index e4dbbec1df..e7916a1841 100644 --- a/tests/sizers/boxsizer.cpp +++ b/tests/sizers/boxsizer.cpp @@ -103,5 +103,11 @@ void BoxSizerTestCase::Size1() m_sizer->Add(child, wxSizerFlags(1).Expand()); m_win->Layout(); CPPUNIT_ASSERT_EQUAL( sizeTotal, child->GetSize() ); + + m_sizer->Clear(); + m_sizer->Add(child, wxSizerFlags().Expand()); + m_sizer->SetItemMinSize(child, sizeTotal*2); + m_win->Layout(); + CPPUNIT_ASSERT_EQUAL( sizeTotal, child->GetSize() ); } -- 2.49.0