]> git.saurik.com Git - wxWidgets.git/commitdiff
Ensure that size in the major direction of box sizer doesn't exceed the total.
authorVadim Zeitlin <vadim@wxwidgets.org>
Thu, 18 Mar 2010 15:07:14 +0000 (15:07 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Thu, 18 Mar 2010 15:07:14 +0000 (15:07 +0000)
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
tests/sizers/boxsizer.cpp

index 64ffc0877feee12d68a85df6f88ed5609d6cb6e7..ad0abd60edaa85ea3f8e3c965b531194cfd0ec6b 100644 (file)
@@ -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
index e4dbbec1df7618dc6e53a20f7ff2a933d1b053ac..e7916a1841d9137144d24bfeb70e3d522949b850 100644 (file)
@@ -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() );
 }