X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8907154c1a8a6882c6797d1f16393ddfb23e7f3a..11bf9fea53d75b460aaa4028a591917b6dd6fe54:/src/common/gbsizer.cpp diff --git a/src/common/gbsizer.cpp b/src/common/gbsizer.cpp index a3ad1e92a8..7f91a1c40d 100644 --- a/src/common/gbsizer.cpp +++ b/src/common/gbsizer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: gbsizer.cpp +// Name: src/common/gbsizer.cpp // Purpose: wxGridBagSizer: A sizer that can lay out items in a grid, // with items at specified cells, and with the option of row // and/or column spanning @@ -76,7 +76,6 @@ wxGBSizerItem::wxGBSizerItem( wxSizer *sizer, wxGBSizerItem::wxGBSizerItem() : wxSizerItem(), m_pos(-1,-1), - m_span(-1,-1), m_gbsizer(NULL) { } @@ -187,7 +186,7 @@ wxSizerItem* wxGridBagSizer::Add( wxWindow *window, else { delete item; - return (wxSizerItem*)NULL; + return NULL; } } @@ -201,7 +200,7 @@ wxSizerItem* wxGridBagSizer::Add( wxSizer *sizer, else { delete item; - return (wxSizerItem*)NULL; + return NULL; } } @@ -215,7 +214,7 @@ wxSizerItem* wxGridBagSizer::Add( int width, int height, else { delete item; - return (wxSizerItem*)NULL; + return NULL; } } @@ -228,6 +227,18 @@ wxSizerItem* wxGridBagSizer::Add( wxGBSizerItem *item ) if ( item->GetWindow() ) item->GetWindow()->SetContainingSizer( this ); + // extend the number of rows/columns of the underlying wxFlexGridSizer if + // necessary + int row, col; + item->GetEndPos(row, col); + row++; + col++; + + if ( row > GetRows() ) + SetRows(row); + if ( col > GetCols() ) + SetCols(col); + return item; } @@ -266,7 +277,7 @@ wxGBPosition wxGridBagSizer::GetItemPosition(size_t index) { wxGBPosition badpos(-1,-1); wxSizerItemList::compatibility_iterator node = m_children.Item( index ); - wxCHECK_MSG( node, badpos, _T("Failed to find item.") ); + wxCHECK_MSG( node, badpos, wxT("Failed to find item.") ); wxGBSizerItem* item = (wxGBSizerItem*)node->GetData(); return item->GetPos(); } @@ -292,7 +303,7 @@ bool wxGridBagSizer::SetItemPosition(wxSizer *sizer, const wxGBPosition& pos) bool wxGridBagSizer::SetItemPosition(size_t index, const wxGBPosition& pos) { wxSizerItemList::compatibility_iterator node = m_children.Item( index ); - wxCHECK_MSG( node, false, _T("Failed to find item.") ); + wxCHECK_MSG( node, false, wxT("Failed to find item.") ); wxGBSizerItem* item = (wxGBSizerItem*)node->GetData(); return item->SetPos(pos); } @@ -301,27 +312,24 @@ bool wxGridBagSizer::SetItemPosition(size_t index, const wxGBPosition& pos) wxGBSpan wxGridBagSizer::GetItemSpan(wxWindow *window) { - wxGBSpan badspan(-1,-1); wxGBSizerItem* item = FindItem(window); - wxCHECK_MSG( item, badspan, _T("Failed to find item.") ); + wxCHECK_MSG( item, wxGBSpan::Invalid(), wxT("Failed to find item.") ); return item->GetSpan(); } wxGBSpan wxGridBagSizer::GetItemSpan(wxSizer *sizer) { - wxGBSpan badspan(-1,-1); wxGBSizerItem* item = FindItem(sizer); - wxCHECK_MSG( item, badspan, _T("Failed to find item.") ); + wxCHECK_MSG( item, wxGBSpan::Invalid(), wxT("Failed to find item.") ); return item->GetSpan(); } wxGBSpan wxGridBagSizer::GetItemSpan(size_t index) { - wxGBSpan badspan(-1,-1); wxSizerItemList::compatibility_iterator node = m_children.Item( index ); - wxCHECK_MSG( node, badspan, _T("Failed to find item.") ); + wxCHECK_MSG( node, wxGBSpan::Invalid(), wxT("Failed to find item.") ); wxGBSizerItem* item = (wxGBSizerItem*)node->GetData(); return item->GetSpan(); } @@ -347,7 +355,7 @@ bool wxGridBagSizer::SetItemSpan(wxSizer *sizer, const wxGBSpan& span) bool wxGridBagSizer::SetItemSpan(size_t index, const wxGBSpan& span) { wxSizerItemList::compatibility_iterator node = m_children.Item( index ); - wxCHECK_MSG( node, false, _T("Failed to find item.") ); + wxCHECK_MSG( node, false, wxT("Failed to find item.") ); wxGBSizerItem* item = (wxGBSizerItem*)node->GetData(); return item->SetSpan(span); } @@ -409,7 +417,7 @@ wxGBSizerItem* wxGridBagSizer::FindItemAtPoint(const wxPoint& pt) wxGBSizerItem* item = (wxGBSizerItem*)node->GetData(); wxRect rect(item->GetPosition(), item->GetSize()); rect.Inflate(m_hgap, m_vgap); - if ( rect.Inside(pt) ) + if ( rect.Contains(pt) ) return item; node = node->GetNext(); } @@ -460,10 +468,10 @@ wxSize wxGridBagSizer::CalcMin() item->GetPos(row, col); item->GetEndPos(endrow, endcol); - // fill heights and widths upto this item if needed - while ( m_rowHeights.GetCount() <= (size_t)endrow ) + // fill heights and widths up to this item if needed + while ( (int)m_rowHeights.GetCount() <= endrow ) m_rowHeights.Add(m_emptyCellSize.GetHeight()); - while ( m_colWidths.GetCount() <= (size_t)endcol ) + while ( (int)m_colWidths.GetCount() <= endcol ) m_colWidths.Add(m_emptyCellSize.GetWidth()); // See if this item increases the size of its row(s) or col(s) @@ -476,6 +484,7 @@ wxSize wxGridBagSizer::CalcMin() node = node->GetNext(); } + AdjustForOverflow(); AdjustForFlexDirection(); // Now traverse the heights and widths arrays calcing the totals, including gaps @@ -507,7 +516,7 @@ void wxGridBagSizer::RecalcSizes() m_cols = m_colWidths.GetCount(); int idx, width, height; - AdjustForGrowables(sz, m_calculatedMinSize, m_rows, m_cols); + AdjustForGrowables(sz); // Find the start positions on the window of the rows and columns wxArrayInt rowpos; @@ -537,26 +546,122 @@ void wxGridBagSizer::RecalcSizes() { int row, col, endrow, endcol; wxGBSizerItem* item = (wxGBSizerItem*)node->GetData(); - item->GetPos(row, col); - item->GetEndPos(endrow, endcol); - height = 0; - for(idx=row; idx <= endrow; idx++) - height += m_rowHeights[idx]; - height += (endrow - row) * m_vgap; // add a vgap for every row spanned + if ( item->IsShown() ) + { + item->GetPos(row, col); + item->GetEndPos(endrow, endcol); - width = 0; - for (idx=col; idx <= endcol; idx++) - width += m_colWidths[idx]; - width += (endcol - col) * m_hgap; // add a hgap for every col spanned + height = 0; + for(idx=row; idx <= endrow; idx++) + height += m_rowHeights[idx]; + height += (endrow - row) * m_vgap; // add a vgap for every row spanned - SetItemBounds(item, colpos[col], rowpos[row], width, height); + width = 0; + for (idx=col; idx <= endcol; idx++) + width += m_colWidths[idx]; + width += (endcol - col) * m_hgap; // add a hgap for every col spanned + + SetItemBounds(item, colpos[col], rowpos[row], width, height); + } node = node->GetNext(); } } +// Sometimes CalcMin can result in some rows or cols having too much space in +// them because as it traverses the items it makes some assumptions when +// items span to other cells. But those assumptions can become invalid later +// on when other items are fitted into the same rows or columns that the +// spanning item occupies. This method tries to find those situations and +// fixes them. +void wxGridBagSizer::AdjustForOverflow() +{ + int row, col; + + for (row=0; row<(int)m_rowHeights.GetCount(); row++) + { + int rowExtra=INT_MAX; + int rowHeight = m_rowHeights[row]; + for (col=0; col<(int)m_colWidths.GetCount(); col++) + { + wxGBPosition pos(row,col); + wxGBSizerItem* item = FindItemAtPosition(pos); + if ( !item || !item->IsShown() ) + continue; + + int endrow, endcol; + item->GetEndPos(endrow, endcol); + + // If the item starts in this position and doesn't span rows, then + // just look at the whole item height + if ( item->GetPos() == pos && endrow == row ) + { + int itemHeight = item->CalcMin().GetHeight(); + rowExtra = wxMin(rowExtra, rowHeight - itemHeight); + continue; + } + + // Otherwise, only look at spanning items if they end on this row + if ( endrow == row ) + { + // first deduct the portions of the item that are on prior rows + int itemHeight = item->CalcMin().GetHeight(); + for (int r=item->GetPos().GetRow(); rIsShown() ) + continue; + + int endrow, endcol; + item->GetEndPos(endrow, endcol); + + if ( item->GetPos() == pos && endcol == col ) + { + int itemWidth = item->CalcMin().GetWidth(); + colExtra = wxMin(colExtra, colWidth - itemWidth); + continue; + } + + if ( endcol == col ) + { + int itemWidth = item->CalcMin().GetWidth(); + for (int c=item->GetPos().GetCol(); c