-                SetItemBounds( node->GetData(), x, y, w, h);
-            }
-            if (m_rowHeights[r] != -1)
-                y = y + m_rowHeights[r] + m_vgap;
+        const int hrow = m_rowHeights[r];
+        int h = sz.y - y; // max remaining height, don't overflow it
+        if ( hrow < h )
+            h = hrow;
+
+        int x = 0;
+        for ( int c = 0; c < ncols && i != end; c++, ++i )
+        {
+            const int wcol = m_colWidths[c];
+
+            if ( wcol == -1 )
+                continue;
+
+            int w = sz.x - x; // max possible value, ensure we don't overflow
+            if ( wcol < w )
+                w = wcol;
+
+            SetItemBounds(*i, pt.x + x, pt.y + y, w, h);
+
+            x += wcol + m_hgap;
+        }
+
+        if ( i == end )
+            return;
+
+        y += hrow + m_vgap;
+    }
+}
+
+// helper function used in CalcMin() to sum up the sizes of non-hidden items
+static int SumArraySizes(const wxArrayInt& sizes, int gap)
+{
+    // Sum total minimum size, including gaps between rows/columns.
+    // -1 is used as a magic number meaning empty row/column.
+    int total = 0;
+
+    const size_t count = sizes.size();
+    for ( size_t n = 0; n < count; n++ )
+    {
+        if ( sizes[n] != -1 )
+        {
+            if ( total )
+                total += gap; // separate from the previous column
+
+            total += sizes[n];