X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c084a1ac064cff672b777e1e6a3624fd838387e7..ab9df4fb452e785836de38712af84d209113b5af:/src/common/sizer.cpp?ds=sidebyside diff --git a/src/common/sizer.cpp b/src/common/sizer.cpp index c5efdf4e36..a4c17f8b8c 100644 --- a/src/common/sizer.cpp +++ b/src/common/sizer.cpp @@ -1333,18 +1333,50 @@ wxGridSizer::wxGridSizer( int cols, int vgap, int hgap ) { } +wxSizerItem *wxGridSizer::Insert(size_t index, wxSizerItem *item) +{ + // if only the number of columns or the number of rows is specified for a + // sizer, arbitrarily many items can be added to it but if both of them are + // fixed, then the sizer can't have more than that many items -- check for + // this here to ensure that we detect errors as soon as possible + if ( m_cols && m_rows ) + { + const int nitems = m_children.GetCount(); + if ( nitems == m_cols*m_rows ) + { + wxFAIL_MSG( + wxString::Format( + "too many items (%d > %d*%d) in grid sizer (maybe you " + "should omit the number of either rows or columns?)", + nitems + 1, m_cols, m_rows) + ); + + // additionally, continuing to use the specified number of columns + // and rows is not a good idea as callers of CalcRowsCols() expect + // that all sizer items can fit into m_cols/m_rows-sized arrays + // which is not the case if there are too many items and results in + // crashes, so let it compute the number of rows automatically by + // forgetting the (wrong) number of rows specified (this also has a + // nice side effect of giving only one assert even if there are + // many more items than allowed in this sizer) + m_rows = 0; + } + } + + return wxSizer::Insert(index, item); +} + int wxGridSizer::CalcRowsCols(int& nrows, int& ncols) const { const int nitems = m_children.GetCount(); if ( m_cols && m_rows ) { - // if both rows and columns are specified by user, use the provided - // values even if we don't have enough items but check that we don't - // have too many of them as this is going to result in problems later ncols = m_cols; nrows = m_rows; - wxASSERT_MSG( ncols*nrows >= nitems, "too many items in grid sizer" ); + // this should be impossible because the too high number of items + // should have been detected by Insert() above + wxASSERT_MSG( nitems <= ncols*nrows, "logic error in wxGridSizer" ); } else if ( m_cols ) { @@ -1781,6 +1813,37 @@ DoAdjustForGrowables(int delta, void wxFlexGridSizer::AdjustForGrowables(const wxSize& sz) { +#ifdef __WXDEBUG__ + // by the time this function is called, the sizer should be already fully + // initialized and hence the number of its columns and rows is known and we + // can check that all indices in m_growableCols/Rows are valid (see also + // comments in AddGrowableCol/Row()) + if ( !m_rows || !m_cols ) + { + int nrows, ncols; + CalcRowsCols(nrows, ncols); + + if ( !m_rows ) + { + for ( size_t n = 0; n < m_growableRows.size(); n++ ) + { + wxASSERT_MSG( m_growableRows[n] < nrows, + "invalid growable row index" ); + } + } + + if ( !m_cols ) + { + for ( size_t n = 0; n < m_growableCols.size(); n++ ) + { + wxASSERT_MSG( m_growableCols[n] < ncols, + "invalid growable column index" ); + } + } + } +#endif // __WXDEBUG__ + + if ( (m_flexDirection & wxHORIZONTAL) || (m_growMode != wxFLEX_GROWMODE_NONE) ) { DoAdjustForGrowables @@ -1851,10 +1914,16 @@ void wxFlexGridSizer::AddGrowableRow( size_t idx, int proportion ) { int nrows, ncols; CalcRowsCols(nrows, ncols); - wxCHECK_RET( idx < (size_t)nrows, "invalid row index" ); wxASSERT_MSG( !IsRowGrowable( idx ), "AddGrowableRow() called for growable row" ); + + // notice that we intentionally don't check the index validity here in (the + // common) case when the number of rows was not specified in the ctor -- in + // this case it will be computed only later, when all items are added to + // the sizer, and the check will be done in AdjustForGrowables() + wxCHECK_RET( !m_rows || idx < (size_t)m_rows, "invalid row index" ); + m_growableRows.Add( idx ); m_growableRowsProportions.Add( proportion ); } @@ -1863,10 +1932,14 @@ void wxFlexGridSizer::AddGrowableCol( size_t idx, int proportion ) { int nrows, ncols; CalcRowsCols(nrows, ncols); - wxCHECK_RET( idx < (size_t)ncols, "invalid column index" ); wxASSERT_MSG( !IsColGrowable( idx ), "AddGrowableCol() called for growable column" ); + + // see comment in AddGrowableRow(): although it's less common to omit the + // specification of the number of columns, it still can also happen + wxCHECK_RET( !m_cols || idx < (size_t)ncols, "invalid column index" ); + m_growableCols.Add( idx ); m_growableColsProportions.Add( proportion ); } @@ -2078,19 +2151,10 @@ wxStaticBoxSizer::~wxStaticBoxSizer() delete m_staticBox; } -static void GetStaticBoxBorders( wxStaticBox *box, - int *borderTop, - int *borderOther) -{ - // this has to be done platform by platform as there is no way to - // guess the thickness of a wxStaticBox border - box->GetBordersForSizer(borderTop, borderOther); -} - void wxStaticBoxSizer::RecalcSizes() { int top_border, other_border; - GetStaticBoxBorders(m_staticBox, &top_border, &other_border); + m_staticBox->GetBordersForSizer(&top_border, &other_border); m_staticBox->SetSize( m_position.x, m_position.y, m_size.x, m_size.y ); @@ -2110,10 +2174,17 @@ void wxStaticBoxSizer::RecalcSizes() wxSize wxStaticBoxSizer::CalcMin() { int top_border, other_border; - GetStaticBoxBorders(m_staticBox, &top_border, &other_border); + m_staticBox->GetBordersForSizer(&top_border, &other_border); wxSize ret( wxBoxSizer::CalcMin() ); ret.x += 2*other_border; + + // ensure that we're wide enough to show the static box label (there is no + // need to check for the static box best size in vertical direction though) + const int boxWidth = m_staticBox->GetBestSize().x; + if ( ret.x < boxWidth ) + ret.x = boxWidth; + ret.y += other_border + top_border; return ret; @@ -2248,7 +2319,7 @@ void wxStdDialogButtonSizer::Realize() } // Extra space around and at the right - Add(12, 24); + Add(12, 40); #elif defined(__WXGTK20__) Add(0, 0, 0, wxLEFT, 9); if (m_buttonHelp)