From 0274a7973da59746c55bc91ebceac64f622b6a34 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 23 Aug 2009 22:24:48 +0000 Subject: [PATCH] Added wxGridSize::GetEffective{Cols,Rows}Count(). These functions return the number of columns or rows being currently used and not 0, unlike the existing Get{Cols,Rows}(), if the corresponding number is determined dynamically. Closes #10254. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@61750 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/sizer.h | 31 ++++++++++++++++++++++++ interface/wx/sizer.h | 27 +++++++++++++++++---- src/common/sizer.cpp | 56 +++++++++++++------------------------------- 3 files changed, 69 insertions(+), 45 deletions(-) diff --git a/include/wx/sizer.h b/include/wx/sizer.h index ffd8442e98..289b765d80 100644 --- a/include/wx/sizer.h +++ b/include/wx/sizer.h @@ -757,18 +757,49 @@ public: int GetVGap() const { return m_vgap; } int GetHGap() const { return m_hgap; } + int GetEffectiveColsCount() const { return m_cols ? m_cols : CalcCols(); } + int GetEffectiveRowsCount() const { return m_rows ? m_rows : CalcRows(); } + // return the number of total items and the number of columns and rows // (for internal use only) int CalcRowsCols(int& rows, int& cols) const; protected: + // the number of rows/columns in the sizer, if 0 then it is determined + // dynamically depending on the total number of items int m_rows; int m_cols; + + // gaps between rows and columns int m_vgap; int m_hgap; void SetItemBounds( wxSizerItem *item, int x, int y, int w, int h ); + // returns the number of columns/rows needed for the current total number + // of children (and the fixed number of rows/columns) + int CalcCols() const + { + wxCHECK_MSG + ( + m_rows, 0, + "Can't calculate number of cols if number of rows is not specified" + ); + + return (m_children.GetCount() + m_rows - 1) / m_rows; + } + + int CalcRows() const + { + wxCHECK_MSG + ( + m_cols, 0, + "Can't calculate number of cols if number of rows is not specified" + ); + + return (m_children.GetCount() + m_cols - 1) / m_cols; + } + private: DECLARE_CLASS(wxGridSizer) }; diff --git a/interface/wx/sizer.h b/interface/wx/sizer.h index 31e66cb38d..1423c6d485 100644 --- a/interface/wx/sizer.h +++ b/interface/wx/sizer.h @@ -1604,20 +1604,37 @@ public: wxGridSizer( int rows, int cols, const wxSize& gap ); //@} + //@{ /** - Returns the number of columns in the sizer. + Returns the number of columns or rows that has been specified for the + sizer. + + Returns zero if the sizer is automatically adjusting the number of + columns/rows depending on number of its children. To get the effective + number of columns or rows being currently used, see + GetEffectiveColsCount() and GetEffectiveRowsCount(). */ int GetCols() const; + int GetRows() const; + //@} + //@{ /** - Returns the horizontal gap (in pixels) between cells in the sizer. + Returns the number of columns or rows currently used by the sizer. + + This will depend on the number of children the sizer has if + the sizer is automatically adjusting the number of columns/rows. + + @since 2.9.1 */ - int GetHGap() const; + int GetEffectiveColsCount() const; + int GetEffectiveRowsCount() const; + //@} /** - Returns the number of rows in the sizer. + Returns the horizontal gap (in pixels) between cells in the sizer. */ - int GetRows() const; + int GetHGap() const; /** Returns the vertical gap (in pixels) between the cells in the sizer. diff --git a/src/common/sizer.cpp b/src/common/sizer.cpp index 31ca5342f5..01180b5374 100644 --- a/src/common/sizer.cpp +++ b/src/common/sizer.cpp @@ -1369,7 +1369,7 @@ wxSizerItem *wxGridSizer::Insert(size_t index, wxSizerItem *item) // 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 + // 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 @@ -1385,32 +1385,13 @@ wxSizerItem *wxGridSizer::Insert(size_t index, wxSizerItem *item) int wxGridSizer::CalcRowsCols(int& nrows, int& ncols) const { const int nitems = m_children.GetCount(); - if ( m_cols && m_rows ) - { - ncols = m_cols; - nrows = m_rows; - // 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 ) - { - ncols = m_cols; - nrows = (nitems + m_cols - 1) / m_cols; - } - else if ( m_rows ) - { - ncols = (nitems + m_rows - 1) / m_rows; - nrows = m_rows; - } - else // 0 columns, 0 rows? - { - wxFAIL_MSG( wxT("grid sizer must have either rows or columns fixed") ); + ncols = GetEffectiveColsCount(); + nrows = GetEffectiveRowsCount(); - nrows = - ncols = 0; - } + // Since Insert() checks for overpopulation, the following + // should only assert if the grid was shrunk via SetRows() / SetCols() + wxASSERT_MSG( nitems <= ncols*nrows, "logic error in wxGridSizer" ); return nitems; } @@ -1850,11 +1831,10 @@ void wxFlexGridSizer::AdjustForGrowables(const wxSize& sz) // comments in AddGrowableCol/Row()) if ( !m_rows || !m_cols ) { - int nrows, ncols; - CalcRowsCols(nrows, ncols); - if ( !m_rows ) { + int nrows = CalcRows(); + for ( size_t n = 0; n < m_growableRows.size(); n++ ) { wxASSERT_MSG( m_growableRows[n] < nrows, @@ -1864,6 +1844,8 @@ void wxFlexGridSizer::AdjustForGrowables(const wxSize& sz) if ( !m_cols ) { + int ncols = CalcCols(); + for ( size_t n = 0; n < m_growableCols.size(); n++ ) { wxASSERT_MSG( m_growableCols[n] < ncols, @@ -1888,17 +1870,17 @@ void wxFlexGridSizer::AdjustForGrowables(const wxSize& sz) // This gives nested objects that benefit from knowing one size // component in advance the chance to use that. bool didAdjustMinSize = false; - int nrows, ncols; - CalcRowsCols(nrows, ncols); // Iterate over all items and inform about column width - size_t n = 0; + const int ncols = GetEffectiveColsCount(); + int col = 0; for ( wxSizerItemList::iterator i = m_children.begin(); i != m_children.end(); - ++i, ++n ) + ++i ) { - const int col = n % ncols; didAdjustMinSize |= (*i)->InformFirstDirection(wxHORIZONTAL, m_colWidths[col], sz.y - m_calculatedMinSize.y); + if ( ++col == ncols ) + col = 0; } // Only redo if info was actually used @@ -1942,9 +1924,6 @@ bool wxFlexGridSizer::IsColGrowable( size_t idx ) void wxFlexGridSizer::AddGrowableRow( size_t idx, int proportion ) { - int nrows, ncols; - CalcRowsCols(nrows, ncols); - wxASSERT_MSG( !IsRowGrowable( idx ), "AddGrowableRow() called for growable row" ); @@ -1960,15 +1939,12 @@ void wxFlexGridSizer::AddGrowableRow( size_t idx, int proportion ) void wxFlexGridSizer::AddGrowableCol( size_t idx, int proportion ) { - int nrows, ncols; - CalcRowsCols(nrows, ncols); - 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" ); + wxCHECK_RET( !m_cols || idx < (size_t)m_cols, "invalid column index" ); m_growableCols.Add( idx ); m_growableColsProportions.Add( proportion ); -- 2.45.2