X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/aa5973eef45ad0353175ee79a763ce9db8d53e05..0a2f5c7bc59906224f8ff93940e0bda33214c963:/src/common/sizer.cpp diff --git a/src/common/sizer.cpp b/src/common/sizer.cpp index 5a9c11a99f..3650a7b5b7 100644 --- a/src/common/sizer.cpp +++ b/src/common/sizer.cpp @@ -94,10 +94,16 @@ wxSizerItem::wxSizerItem( wxSizer *sizer, int proportion, int flag, int border, wxSizerItem::~wxSizerItem() { - if (m_userData) - delete m_userData; - if (m_sizer) + delete m_userData; + + if ( m_window ) + { + m_window->SetContainingSizer(NULL); + } + else // we must be a sizer + { delete m_sizer; + } } @@ -277,12 +283,11 @@ int wxSizerItem::GetOption() const wxSizer::wxSizer() : m_minSize( wxSize( 0, 0 ) ) { - m_children.DeleteContents( true ); } wxSizer::~wxSizer() { - Clear(); + WX_CLEAR_LIST(wxSizerItemList, m_children); } void wxSizer::Add( wxWindow *window, int proportion, int flag, int border, wxObject* userData ) @@ -385,13 +390,17 @@ bool wxSizer::Remove( wxSizer *sizer ) { wxASSERT_MSG( sizer, _T("Removing NULL sizer") ); - wxSizerItemList::Node *node = m_children.GetFirst(); + wxSizerItemList::compatibility_iterator node = m_children.GetFirst(); while (node) { wxSizerItem *item = node->GetData(); if (item->GetSizer() == sizer) - return m_children.DeleteNode( node ); + { + delete item; + m_children.Erase( node ); + return true; + } node = node->GetNext(); } @@ -405,7 +414,7 @@ bool wxSizer::Remove( int index ) false, _T("Remove index is out of range") ); - wxSizerItemList::Node *node = m_children.Item( index ); + wxSizerItemList::compatibility_iterator node = m_children.Item( index ); wxCHECK_MSG( node, false, _T("Failed to find child node") ); @@ -414,14 +423,16 @@ bool wxSizer::Remove( int index ) if( item->IsWindow() ) item->GetWindow()->SetContainingSizer( NULL ); - return m_children.DeleteNode( node ); + delete item; + m_children.Erase( node ); + return true; } bool wxSizer::Detach( wxSizer *sizer ) { wxASSERT_MSG( sizer, _T("Detaching NULL sizer") ); - wxSizerItemList::Node *node = m_children.GetFirst(); + wxSizerItemList::compatibility_iterator node = m_children.GetFirst(); while (node) { wxSizerItem *item = node->GetData(); @@ -429,7 +440,9 @@ bool wxSizer::Detach( wxSizer *sizer ) if (item->GetSizer() == sizer) { item->DetachSizer(); - return m_children.DeleteNode( node ); + delete item; + m_children.Erase( node ); + return true; } node = node->GetNext(); } @@ -441,7 +454,7 @@ bool wxSizer::Detach( wxWindow *window ) { wxASSERT_MSG( window, _T("Detaching NULL window") ); - wxSizerItemList::Node *node = m_children.GetFirst(); + wxSizerItemList::compatibility_iterator node = m_children.GetFirst(); while (node) { wxSizerItem *item = node->GetData(); @@ -449,7 +462,9 @@ bool wxSizer::Detach( wxWindow *window ) if (item->GetWindow() == window) { item->GetWindow()->SetContainingSizer( NULL ); - return m_children.DeleteNode( node ); + delete item; + m_children.Erase( node ); + return true; } node = node->GetNext(); } @@ -463,7 +478,7 @@ bool wxSizer::Detach( int index ) false, _T("Detach index is out of range") ); - wxSizerItemList::Node *node = m_children.Item( index ); + wxSizerItemList::compatibility_iterator node = m_children.Item( index ); wxCHECK_MSG( node, false, _T("Failed to find child node") ); @@ -474,13 +489,15 @@ bool wxSizer::Detach( int index ) else if( item->IsWindow() ) item->GetWindow()->SetContainingSizer( NULL ); - return m_children.DeleteNode( node ); + delete item; + m_children.Erase( node ); + return true; } void wxSizer::Clear( bool delete_windows ) { // First clear the ContainingSizer pointers - wxSizerItemList::Node *node = m_children.GetFirst(); + wxSizerItemList::compatibility_iterator node = m_children.GetFirst(); while (node) { wxSizerItem *item = node->GetData(); @@ -495,12 +512,12 @@ void wxSizer::Clear( bool delete_windows ) DeleteWindows(); // Now empty the list - m_children.Clear(); + WX_CLEAR_LIST(wxSizerItemList, m_children); } void wxSizer::DeleteWindows() { - wxSizerItemList::Node *node = m_children.GetFirst(); + wxSizerItemList::compatibility_iterator node = m_children.GetFirst(); while (node) { wxSizerItem *item = node->GetData(); @@ -662,7 +679,7 @@ bool wxSizer::DoSetItemMinSize( wxWindow *window, int width, int height ) // Is it our immediate child? - wxSizerItemList::Node *node = m_children.GetFirst(); + wxSizerItemList::compatibility_iterator node = m_children.GetFirst(); while (node) { wxSizerItem *item = node->GetData(); @@ -700,7 +717,7 @@ bool wxSizer::DoSetItemMinSize( wxSizer *sizer, int width, int height ) // Is it our immediate child? - wxSizerItemList::Node *node = m_children.GetFirst(); + wxSizerItemList::compatibility_iterator node = m_children.GetFirst(); while (node) { wxSizerItem *item = node->GetData(); @@ -734,7 +751,7 @@ bool wxSizer::DoSetItemMinSize( wxSizer *sizer, int width, int height ) bool wxSizer::DoSetItemMinSize( size_t index, int width, int height ) { - wxSizerItemList::Node *node = m_children.Item( index ); + wxSizerItemList::compatibility_iterator node = m_children.Item( index ); wxCHECK_MSG( node, false, _T("Failed to find child node") ); @@ -758,7 +775,7 @@ void wxSizer::Show( wxWindow *window, bool show ) { wxASSERT_MSG( window, _T("Show for NULL window") ); - wxSizerItemList::Node *node = m_children.GetFirst(); + wxSizerItemList::compatibility_iterator node = m_children.GetFirst(); while (node) { wxSizerItem *item = node->GetData(); @@ -776,7 +793,7 @@ void wxSizer::Show( wxSizer *sizer, bool show ) { wxASSERT_MSG( sizer, _T("Show for NULL sizer") ); - wxSizerItemList::Node *node = m_children.GetFirst(); + wxSizerItemList::compatibility_iterator node = m_children.GetFirst(); while (node) { wxSizerItem *item = node->GetData(); @@ -800,7 +817,7 @@ void wxSizer::Show( size_t index, bool show ) void wxSizer::ShowItems( bool show ) { - wxSizerItemList::Node *node = m_children.GetFirst(); + wxSizerItemList::compatibility_iterator node = m_children.GetFirst(); while (node) { node->GetData()->Show( show ); @@ -810,7 +827,7 @@ void wxSizer::ShowItems( bool show ) bool wxSizer::IsShown( wxWindow *window ) const { - wxSizerItemList::Node *node = m_children.GetFirst(); + wxSizerItemList::compatibility_iterator node = m_children.GetFirst(); while (node) { wxSizerItem *item = node->GetData(); @@ -829,7 +846,7 @@ bool wxSizer::IsShown( wxWindow *window ) const bool wxSizer::IsShown( wxSizer *sizer ) const { - wxSizerItemList::Node *node = m_children.GetFirst(); + wxSizerItemList::compatibility_iterator node = m_children.GetFirst(); while (node) { wxSizerItem *item = node->GetData(); @@ -923,7 +940,7 @@ void wxGridSizer::RecalcSizes() int i = r * ncols + c; if (i < nitems) { - wxSizerItemList::Node *node = m_children.Item( i ); + wxSizerItemList::compatibility_iterator node = m_children.Item( i ); wxASSERT_MSG( node, _T("Failed to find SizerItemList node") ); @@ -945,7 +962,7 @@ wxSize wxGridSizer::CalcMin() int w = 0; int h = 0; - wxSizerItemList::Node *node = m_children.GetFirst(); + wxSizerItemList::compatibility_iterator node = m_children.GetFirst(); while (node) { wxSizerItem *item = node->GetData(); @@ -1026,50 +1043,48 @@ void wxFlexGridSizer::RecalcSizes() wxSize sz( GetSize() ); wxSize minsz( CalcMin() ); wxPoint pt( GetPosition() ); - int delta; - size_t idx, num; - wxArrayInt temp; - wxArrayInt temp_proportions; - int sum_proportions = 0; - int growable_space = 0; // what to do with the rows? by default, resize them proportionally - if ( (m_flexDirection & wxVERTICAL) || - (m_growMode == wxFLEX_GROWMODE_SPECIFIED) ) + if ( sz.y > minsz.y && ( (m_flexDirection & wxVERTICAL) || (m_growMode == wxFLEX_GROWMODE_SPECIFIED) ) ) { - // Transfer only those rows into temp which exist in the sizer - // ignoring the superfluous ones. This prevents a segfault when - // calling AddGrowableRow( 3 ) if the sizer only has 2 rows. + int sum_proportions = 0; + int growable_space = 0; + int num = 0; + size_t idx; for (idx = 0; idx < m_growableRows.GetCount(); idx++) { - if (m_growableRows[idx] < nrows) - { - temp.Add( m_growableRows[idx] ); - temp_proportions.Add( m_growableRowsProportions[idx] ); - sum_proportions += m_growableRowsProportions[idx]; - growable_space += m_rowHeights[ temp[idx] ]; - } + // Since the number of rows/columns can change as items are inserted/deleted, we need + // to verify at runtime that the requested growable rows/columns are still valid. + if (m_growableRows[idx] >= nrows) + continue; + // If all items in a row/column are hidden, that row/column will have a dimension of -1. + // This causes the row/column to be hidden completely. + if (m_rowHeights[ m_growableRows[idx] ] == -1) + continue; + sum_proportions += m_growableRowsProportions[idx]; + growable_space += m_rowHeights[ m_growableRows[idx] ]; + num++; } - num = temp.GetCount(); - - if ((num > 0) && (sz.y > minsz.y)) + if (num > 0) { - for (idx = 0; idx < num; idx++) + for (idx = 0; idx < m_growableRows.GetCount(); idx++) { - delta = (sz.y - minsz.y); - if (sum_proportions == 0) - delta = (delta/num) + m_rowHeights[ temp[idx] ]; + if (m_growableRows[idx] >= nrows ) + continue; + if (m_rowHeights[ m_growableRows[idx] ] == -1) + m_rowHeights[ m_growableRows[idx] ] = 0; else - delta = ((delta+growable_space)*temp_proportions[idx])/ - sum_proportions; - m_rowHeights[ temp[idx] ] = delta; + { + int delta = (sz.y - minsz.y); + if (sum_proportions == 0) + delta = (delta/num) + m_rowHeights[ m_growableRows[idx] ]; + else + delta = ((delta+growable_space)*m_growableRowsProportions[idx]) / sum_proportions; + m_rowHeights[ m_growableRows[idx] ] = delta; + } } } - temp.Empty(); - temp_proportions.Empty(); - sum_proportions = 0; - growable_space = 0; } else if ( (m_growMode == wxFLEX_GROWMODE_ALL) && (sz.y > minsz.y) ) { @@ -1079,34 +1094,45 @@ void wxFlexGridSizer::RecalcSizes() } // the same logic as above but for the columns - if ( (m_flexDirection & wxHORIZONTAL) || - (m_growMode == wxFLEX_GROWMODE_SPECIFIED) ) + if ( sz.x > minsz.x && ( (m_flexDirection & wxHORIZONTAL) || (m_growMode == wxFLEX_GROWMODE_SPECIFIED) ) ) { - // See above + int sum_proportions = 0; + int growable_space = 0; + int num = 0; + size_t idx; for (idx = 0; idx < m_growableCols.GetCount(); idx++) { - if (m_growableCols[idx] < ncols) - { - temp.Add( m_growableCols[idx] ); - temp_proportions.Add( m_growableColsProportions[idx] ); - sum_proportions += m_growableColsProportions[idx]; - growable_space += m_colWidths[idx]; - } + // Since the number of rows/columns can change as items are inserted/deleted, we need + // to verify at runtime that the requested growable rows/columns are still valid. + if (m_growableCols[idx] >= ncols) + continue; + // If all items in a row/column are hidden, that row/column will have a dimension of -1. + // This causes the column to be hidden completely. + if (m_colWidths[ m_growableCols[idx] ] == -1) + continue; + sum_proportions += m_growableColsProportions[idx]; + // wtb 5/12/02 bugfix - was m_ColWidths[idx]!! + growable_space += m_colWidths[ m_growableCols[idx] ]; + num++; } - num = temp.GetCount(); - - if ((num > 0) && (sz.x > minsz.x)) + if (num > 0) { - for (idx = 0; idx < num; idx++) + for (idx = 0; idx < m_growableCols.GetCount(); idx++) { - delta = (sz.x - minsz.x); - if (sum_proportions == 0) - delta = (delta/num) + m_colWidths[ temp[idx] ]; - else - delta = ((delta+growable_space)*temp_proportions[idx])/ - sum_proportions; - m_colWidths[ temp[idx] ] = delta; + if (m_growableCols[idx] >= ncols ) + continue; + if (m_colWidths[ m_growableCols[idx] ] == -1) + m_colWidths[ m_growableCols[idx] ] = 0; + else + { + int delta = (sz.x - minsz.x); + if (sum_proportions == 0) + delta = (delta/num) + m_colWidths[ m_growableCols[idx] ]; + else + delta = ((delta+growable_space)*m_growableColsProportions[idx])/sum_proportions; + m_colWidths[ m_growableCols[idx] ] = delta; + } } } } @@ -1127,7 +1153,7 @@ void wxFlexGridSizer::RecalcSizes() int i = r * ncols + c; if (i < nitems) { - wxSizerItemList::Node *node = m_children.Item( i ); + wxSizerItemList::compatibility_iterator node = m_children.Item( i ); wxASSERT_MSG( node, _T("Failed to find node") ); @@ -1148,34 +1174,37 @@ wxSize wxFlexGridSizer::CalcMin() 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); - // We have to clear the old sizes out if any item has wxADJUST_MINSIZE - // set on it. Its probably quicker to just always do it than test for - // that though. At least do it before resizing the arrays, SetCount will - // initialise new elements to zero. - for( s = m_rowHeights.GetCount(), i = 0; i < s; ++i ) - m_rowHeights[ i ] = 0; - - for( s = m_colWidths.GetCount(), i = 0; i < s; ++i ) - m_colWidths[ i ] = 0; - m_rowHeights.SetCount(nrows); m_colWidths.SetCount(ncols); - wxSizerItemList::Node *node = m_children.GetFirst(); + // We have to recalcuate the sizes in case an item has wxADJUST_MINSIZE, has changed + // minimum size since the previous layout, or 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(); - wxSize sz( item->CalcMin() ); - int row = i / ncols; - int col = i % ncols; + if ( item->IsShown() ) + { + wxSize sz( item->CalcMin() ); + int row = i / ncols; + int col = i % ncols; - m_rowHeights[ row ] = wxMax( sz.y, m_rowHeights[ row ] ); - m_colWidths[ col ] = wxMax( sz.x, m_colWidths[ col ] ); + 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++; @@ -1193,8 +1222,7 @@ wxSize wxFlexGridSizer::CalcMin() const int count = array.GetCount(); // find the largest value in this array - int n, - largest = 0; + int n, largest = 0; for ( n = 0; n < count; ++n ) { if ( array[n] > largest ) @@ -1208,17 +1236,19 @@ wxSize wxFlexGridSizer::CalcMin() } } - + // Sum total minimum size, including gaps between rows/columns. + // -1 is used as a magic number meaning empty column. int width = 0; for (int col = 0; col < ncols; col++) - width += m_colWidths[ col ]; + if ( m_colWidths[ col ] != -1 ) + width += m_colWidths[ col ] + ( col == ncols-1 ? 0 : m_hgap ); int height = 0; for (int row = 0; row < nrows; row++) - height += m_rowHeights[ row ]; + if ( m_rowHeights[ row ] != -1 ) + height += m_rowHeights[ row ] + ( row == nrows-1 ? 0 : m_vgap ); - return wxSize( width + (ncols-1) * m_hgap, - height + (nrows-1) * m_vgap); + return wxSize( width, height ); } void wxFlexGridSizer::AddGrowableRow( size_t idx, int proportion ) @@ -1273,7 +1303,7 @@ void wxBoxSizer::RecalcSizes() wxPoint pt( m_position ); - wxSizerItemList::Node *node = m_children.GetFirst(); + wxSizerItemList::compatibility_iterator node = m_children.GetFirst(); while (node) { wxSizerItem *item = node->GetData(); @@ -1355,7 +1385,7 @@ wxSize wxBoxSizer::CalcMin() // Find how long each stretch unit needs to be int stretchSize = 1; - wxSizerItemList::Node *node = m_children.GetFirst(); + wxSizerItemList::compatibility_iterator node = m_children.GetFirst(); while (node) { @@ -1446,6 +1476,9 @@ static void GetStaticBoxBorders( wxStaticBox *box, { // this has to be done platform by platform as there is no way to // guess the thickness of a wxStaticBox border +#ifdef __WXCOCOA__ + box->GetBordersForSizer(borderTop,borderOther); +#else // __WXCOCOA__ #ifdef __WXGTK__ if ( box->GetLabel().IsEmpty() ) *borderTop = 5; @@ -1454,6 +1487,7 @@ static void GetStaticBoxBorders( wxStaticBox *box, *borderTop = box->GetCharHeight(); *borderOther = 5; +#endif // __WXCOCOA__ } void wxStaticBoxSizer::RecalcSizes() @@ -1522,7 +1556,7 @@ wxSize wxNotebookSizer::CalcMin() int maxX = 0; int maxY = 0; - wxWindowList::Node *node = m_notebook->GetChildren().GetFirst(); + wxWindowList::compatibility_iterator node = m_notebook->GetChildren().GetFirst(); while (node) { wxWindow *item = node->GetData();