+
+ return false;
+}
+
+bool wxSizer::DoSetItemMinSize( wxSizer *sizer, int width, int height )
+{
+ wxASSERT_MSG( sizer, _T("SetMinSize for NULL sizer") );
+
+ // Is it our immediate child?
+
+ wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
+ while (node)
+ {
+ wxSizerItem *item = node->GetData();
+
+ if (item->GetSizer() == sizer)
+ {
+ item->GetSizer()->DoSetMinSize( width, height );
+ return true;
+ }
+ node = node->GetNext();
+ }
+
+ // No? Search any subsizers we own then
+
+ node = m_children.GetFirst();
+ while (node)
+ {
+ wxSizerItem *item = node->GetData();
+
+ if ( item->GetSizer() &&
+ item->GetSizer()->DoSetItemMinSize( sizer, width, height ) )
+ {
+ // A child found the requested sizer, exit.
+ return true;
+ }
+ node = node->GetNext();
+ }
+
+ return false;
+}
+
+bool wxSizer::DoSetItemMinSize( size_t index, int width, int height )
+{
+ wxSizerItemList::compatibility_iterator node = m_children.Item( index );
+
+ wxCHECK_MSG( node, false, _T("Failed to find child node") );
+
+ wxSizerItem *item = node->GetData();
+
+ if (item->GetSizer())
+ {
+ // Sizers contains the minimal size in them, if not calculated ...
+ item->GetSizer()->DoSetMinSize( width, height );
+ }
+ else
+ {
+ // ... but the minimal size of spacers and windows is stored via the item
+ item->SetMinSize( width, height );
+ }
+
+ return true;
+}
+
+void wxSizer::Show( wxWindow *window, bool show )
+{
+ wxASSERT_MSG( window, _T("Show for NULL window") );
+
+ wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
+ while (node)
+ {
+ wxSizerItem *item = node->GetData();
+
+ if (item->GetWindow() == window)
+ {
+ item->Show( show );
+ break;
+ }
+ node = node->GetNext();
+ }
+}
+
+void wxSizer::Show( wxSizer *sizer, bool show )
+{
+ wxASSERT_MSG( sizer, _T("Show for NULL sizer") );
+
+ wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
+ while (node)
+ {
+ wxSizerItem *item = node->GetData();
+
+ if (item->GetSizer() == sizer)
+ {
+ item->Show( show );
+ break;
+ }
+ node = node->GetNext();
+ }
+}
+
+void wxSizer::Show( size_t index, bool show )
+{
+ wxCHECK_RET( index < m_children.GetCount(),
+ _T("Show index is out of range") );
+
+ m_children.Item( index )->GetData()->Show( show );
+}
+
+void wxSizer::ShowItems( bool show )
+{
+ wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
+ while (node)
+ {
+ node->GetData()->Show( show );
+ node = node->GetNext();
+ }
+}
+
+bool wxSizer::IsShown( wxWindow *window ) const
+{
+ wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
+ while (node)
+ {
+ wxSizerItem *item = node->GetData();
+
+ if (item->GetWindow() == window)
+ {
+ return item->IsShown();
+ }
+ node = node->GetNext();
+ }
+
+ wxFAIL_MSG( _T("IsShown failed to find sizer item") );
+
+ return false;
+}
+
+bool wxSizer::IsShown( wxSizer *sizer ) const
+{
+ wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
+ while (node)
+ {
+ wxSizerItem *item = node->GetData();
+
+ if (item->GetSizer() == sizer)
+ {
+ return item->IsShown();
+ }
+ node = node->GetNext();
+ }
+
+ wxFAIL_MSG( _T("IsShown failed to find sizer item") );
+
+ return false;
+}
+
+bool wxSizer::IsShown( size_t index ) const
+{
+ wxCHECK_MSG( index < m_children.GetCount(),
+ false,
+ _T("IsShown index is out of range") );
+
+ return m_children.Item( index )->GetData()->IsShown();
+}
+
+
+//---------------------------------------------------------------------------
+// wxGridSizer
+//---------------------------------------------------------------------------
+
+wxGridSizer::wxGridSizer( int rows, int cols, int vgap, int hgap )
+ : m_rows( rows )
+ , m_cols( cols )
+ , m_vgap( vgap )
+ , m_hgap( hgap )
+{
+ if (m_rows == 0 && m_cols == 0)
+ m_rows = 1;
+}
+
+wxGridSizer::wxGridSizer( int cols, int vgap, int hgap )
+ : m_rows( 0 )
+ , m_cols( cols )
+ , m_vgap( vgap )
+ , m_hgap( hgap )
+{
+ if (m_rows == 0 && m_cols == 0)
+ m_rows = 1;
+}
+
+int wxGridSizer::CalcRowsCols(int& nrows, int& ncols) const
+{
+ int nitems = m_children.GetCount();
+ if ( nitems)
+ {
+ 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( _T("grid sizer must have either rows or columns fixed") );
+
+ nrows = ncols = 0;
+ }
+ }
+
+ return nitems;
+}
+
+void wxGridSizer::RecalcSizes()
+{
+ int nitems, nrows, ncols;
+ if ( (nitems = CalcRowsCols(nrows, ncols)) == 0 )
+ return;
+
+ wxSize sz( GetSize() );
+ wxPoint pt( GetPosition() );
+
+ int w = (sz.x - (ncols - 1) * m_hgap) / ncols;
+ int h = (sz.y - (nrows - 1) * m_vgap) / nrows;
+
+ int x = pt.x;
+ for (int c = 0; c < ncols; c++)
+ {
+ int y = pt.y;
+ for (int r = 0; r < nrows; r++)
+ {
+ int i = r * ncols + c;
+ if (i < nitems)
+ {
+ wxSizerItemList::compatibility_iterator node = m_children.Item( i );
+
+ wxASSERT_MSG( node, _T("Failed to find SizerItemList node") );
+
+ SetItemBounds( node->GetData(), x, y, w, h);
+ }
+ y = y + h + m_vgap;
+ }
+ x = x + w + m_hgap;
+ }
+}
+
+wxSize wxGridSizer::CalcMin()
+{
+ int nrows, ncols;
+ if ( CalcRowsCols(nrows, ncols) == 0 )
+ return wxSize(10, 10);
+
+ // Find the max width and height for any component
+ int w = 0;
+ int h = 0;
+
+ wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
+ while (node)
+ {
+ wxSizerItem *item = node->GetData();
+ wxSize sz( item->CalcMin() );
+
+ w = wxMax( w, sz.x );
+ h = wxMax( h, sz.y );
+
+ node = node->GetNext();
+ }
+
+ return wxSize( ncols * w + (ncols-1) * m_hgap,
+ nrows * h + (nrows-1) * m_vgap );
+}
+
+void wxGridSizer::SetItemBounds( wxSizerItem *item, int x, int y, int w, int h )
+{
+ wxPoint pt( x,y );
+ wxSize sz( item->GetMinSizeWithBorder() );
+ int flag = item->GetFlag();
+
+ if ((flag & wxEXPAND) || (flag & wxSHAPED))
+ {
+ sz = wxSize(w, h);
+ }
+ else
+ {
+ if (flag & wxALIGN_CENTER_HORIZONTAL)
+ {
+ pt.x = x + (w - sz.x) / 2;
+ }
+ else if (flag & wxALIGN_RIGHT)
+ {
+ pt.x = x + (w - sz.x);
+ }
+
+ if (flag & wxALIGN_CENTER_VERTICAL)
+ {
+ pt.y = y + (h - sz.y) / 2;
+ }
+ else if (flag & wxALIGN_BOTTOM)
+ {
+ pt.y = y + (h - sz.y);
+ }
+ }
+
+ item->SetDimension(pt, sz);
+}
+
+//---------------------------------------------------------------------------
+// wxFlexGridSizer
+//---------------------------------------------------------------------------
+
+wxFlexGridSizer::wxFlexGridSizer( int rows, int cols, int vgap, int hgap )
+ : wxGridSizer( rows, cols, vgap, hgap ),
+ m_flexDirection(wxBOTH),
+ m_growMode(wxFLEX_GROWMODE_SPECIFIED)
+{
+}
+
+wxFlexGridSizer::wxFlexGridSizer( int cols, int vgap, int hgap )
+ : wxGridSizer( cols, vgap, hgap ),
+ m_flexDirection(wxBOTH),
+ m_growMode(wxFLEX_GROWMODE_SPECIFIED)
+{
+}
+
+wxFlexGridSizer::~wxFlexGridSizer()
+{
+}
+
+void wxFlexGridSizer::RecalcSizes()
+{
+ int nitems, nrows, ncols;
+ if ( (nitems = CalcRowsCols(nrows, ncols)) == 0 )
+ return;
+
+ wxPoint pt( GetPosition() );
+ wxSize sz( GetSize() );
+
+ AdjustForGrowables(sz, m_calculatedMinSize, nrows, ncols);
+
+ sz = wxSize( pt.x + sz.x, pt.y + sz.y );
+
+ int x = pt.x;
+ for (int c = 0; c < ncols; c++)
+ {
+ int y = pt.y;
+ for (int r = 0; r < nrows; r++)
+ {
+ int i = r * ncols + c;
+ if (i < nitems)
+ {
+ wxSizerItemList::compatibility_iterator node = m_children.Item( i );
+
+ wxASSERT_MSG( node, _T("Failed to find node") );
+
+ int w = wxMax( 0, wxMin( m_colWidths[c], sz.x - x ) );
+ int h = wxMax( 0, wxMin( m_rowHeights[r], sz.y - y ) );
+
+ SetItemBounds( node->GetData(), x, y, w, h);
+ }
+ y = y + m_rowHeights[r] + m_vgap;
+ }
+ x = x + m_colWidths[c] + m_hgap;
+ }
+}
+
+wxSize wxFlexGridSizer::CalcMin()
+{
+ int nrows,
+ ncols;
+ size_t i, s;
+
+ // Number of rows/columns can change as items are added or removed.
+ if ( !CalcRowsCols(nrows, ncols) )
+ return wxSize(10, 10);
+
+ m_rowHeights.SetCount(nrows);
+ m_colWidths.SetCount(ncols);
+
+ // We have to recalcuate the sizes in case the item minimum size has
+ // changed since the previous layout, or the item has been hidden using
+ // wxSizer::Show(). If all the items in a row/column are hidden, the final
+ // dimension of the row/column will be -1, indicating that the column
+ // itself is hidden.
+ for( s = m_rowHeights.GetCount(), i = 0; i < s; ++i )
+ m_rowHeights[ i ] = -1;
+ for( s = m_colWidths.GetCount(), i = 0; i < s; ++i )
+ m_colWidths[ i ] = -1;
+
+ wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
+
+ i = 0;
+ while (node)
+ {
+ wxSizerItem *item = node->GetData();
+ if ( item->IsShown() )
+ {
+ wxSize sz( item->CalcMin() );
+ int row = i / ncols;
+ int col = i % ncols;
+
+ m_rowHeights[ row ] = wxMax( wxMax( 0, sz.y ), m_rowHeights[ row ] );
+ m_colWidths[ col ] = wxMax( wxMax( 0, sz.x ), m_colWidths[ col ] );
+ }
+
+ node = node->GetNext();
+ i++;
+ }
+
+ AdjustForFlexDirection();