optimize wxGrid::BlockToDeviceRect() to avoid iterating over all cells, it's enough to only iterate over the visible ones (#9527)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@54175 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -11018,34 +11018,33 @@ void wxGrid::ClearSelection()
|
|||||||
wxRect wxGrid::BlockToDeviceRect( const wxGridCellCoords& topLeft,
|
wxRect wxGrid::BlockToDeviceRect( const wxGridCellCoords& topLeft,
|
||||||
const wxGridCellCoords& bottomRight ) const
|
const wxGridCellCoords& bottomRight ) const
|
||||||
{
|
{
|
||||||
wxRect rect( wxGridNoCellRect );
|
wxRect resultRect;
|
||||||
wxRect cellRect;
|
wxRect tempCellRect = CellToRect(topLeft);
|
||||||
|
if ( tempCellRect != wxGridNoCellRect )
|
||||||
cellRect = CellToRect( topLeft );
|
|
||||||
if ( cellRect != wxGridNoCellRect )
|
|
||||||
{
|
{
|
||||||
rect = cellRect;
|
resultRect = tempCellRect;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rect = wxRect(0, 0, 0, 0);
|
resultRect = wxRect(0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
cellRect = CellToRect( bottomRight );
|
tempCellRect = CellToRect(bottomRight);
|
||||||
if ( cellRect != wxGridNoCellRect )
|
if ( tempCellRect != wxGridNoCellRect )
|
||||||
{
|
{
|
||||||
rect += cellRect;
|
resultRect += tempCellRect;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// If both inputs were "wxGridNoCellRect," then there's nothing to do.
|
||||||
return wxGridNoCellRect;
|
return wxGridNoCellRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i, j;
|
// Ensure that left/right and top/bottom pairs are in order.
|
||||||
int left = rect.GetLeft();
|
int left = resultRect.GetLeft();
|
||||||
int top = rect.GetTop();
|
int top = resultRect.GetTop();
|
||||||
int right = rect.GetRight();
|
int right = resultRect.GetRight();
|
||||||
int bottom = rect.GetBottom();
|
int bottom = resultRect.GetBottom();
|
||||||
|
|
||||||
int leftCol = topLeft.GetCol();
|
int leftCol = topLeft.GetCol();
|
||||||
int topRow = topLeft.GetRow();
|
int topRow = topLeft.GetRow();
|
||||||
@@ -11054,65 +11053,89 @@ wxRect wxGrid::BlockToDeviceRect( const wxGridCellCoords &topLeft,
|
|||||||
|
|
||||||
if (left > right)
|
if (left > right)
|
||||||
{
|
{
|
||||||
i = left;
|
int tmp = left;
|
||||||
left = right;
|
left = right;
|
||||||
right = i;
|
right = tmp;
|
||||||
i = leftCol;
|
|
||||||
|
tmp = leftCol;
|
||||||
leftCol = rightCol;
|
leftCol = rightCol;
|
||||||
rightCol = i;
|
rightCol = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (top > bottom)
|
if (top > bottom)
|
||||||
{
|
{
|
||||||
i = top;
|
int tmp = top;
|
||||||
top = bottom;
|
top = bottom;
|
||||||
bottom = i;
|
bottom = tmp;
|
||||||
i = topRow;
|
|
||||||
|
tmp = topRow;
|
||||||
topRow = bottomRow;
|
topRow = bottomRow;
|
||||||
bottomRow = i;
|
bottomRow = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( j = topRow; j <= bottomRow; j++ )
|
// The following loop is ONLY necessary to detect and handle merged cells.
|
||||||
{
|
int cw, ch;
|
||||||
for ( i = leftCol; i <= rightCol; i++ )
|
m_gridWin->GetClientSize( &cw, &ch );
|
||||||
{
|
|
||||||
if ((j == topRow) || (j == bottomRow) || (i == leftCol) || (i == rightCol))
|
|
||||||
{
|
|
||||||
cellRect = CellToRect( j, i );
|
|
||||||
|
|
||||||
if (cellRect.x < left)
|
// Get the origin coordinates: notice that they will be negative if the
|
||||||
left = cellRect.x;
|
// grid is scrolled downwards/to the right.
|
||||||
if (cellRect.y < top)
|
int gridOriginX = 0;
|
||||||
top = cellRect.y;
|
int gridOriginY = 0;
|
||||||
if (cellRect.x + cellRect.width > right)
|
CalcScrolledPosition(gridOriginX, gridOriginY, &gridOriginX, &gridOriginY);
|
||||||
right = cellRect.x + cellRect.width;
|
|
||||||
if (cellRect.y + cellRect.height > bottom)
|
int onScreenLeftmostCol = internalXToCol(-gridOriginX);
|
||||||
bottom = cellRect.y + cellRect.height;
|
int onScreenUppermostRow = internalYToRow(-gridOriginY);
|
||||||
|
|
||||||
|
int onScreenRightmostCol = internalXToCol(-gridOriginX + cw);
|
||||||
|
int onScreenBottommostRow = internalYToRow(-gridOriginY + ch);
|
||||||
|
|
||||||
|
// Bound our loop so that we only examine the portion of the selected block
|
||||||
|
// that is shown on screen. Therefore, we compare the Top-Left block values
|
||||||
|
// to the Top-Left screen values, and the Bottom-Right block values to the
|
||||||
|
// Bottom-Right screen values, choosing appropriately.
|
||||||
|
const int visibleTopRow = wxMax(topRow, onScreenUppermostRow);
|
||||||
|
const int visibleBottomRow = wxMin(bottomRow, onScreenBottommostRow);
|
||||||
|
const int visibleLeftCol = wxMax(leftCol, onScreenLeftmostCol);
|
||||||
|
const int visibleRightCol = wxMin(rightCol, onScreenRightmostCol);
|
||||||
|
|
||||||
|
for ( int j = visibleTopRow; j <= visibleBottomRow; j++ )
|
||||||
|
{
|
||||||
|
for ( int i = visibleLeftCol; i <= visibleRightCol; i++ )
|
||||||
|
{
|
||||||
|
if ( (j == visibleTopRow) || (j == visibleBottomRow) ||
|
||||||
|
(i == visibleLeftCol) || (i == visibleRightCol) )
|
||||||
|
{
|
||||||
|
tempCellRect = CellToRect( j, i );
|
||||||
|
|
||||||
|
if (tempCellRect.x < left)
|
||||||
|
left = tempCellRect.x;
|
||||||
|
if (tempCellRect.y < top)
|
||||||
|
top = tempCellRect.y;
|
||||||
|
if (tempCellRect.x + tempCellRect.width > right)
|
||||||
|
right = tempCellRect.x + tempCellRect.width;
|
||||||
|
if (tempCellRect.y + tempCellRect.height > bottom)
|
||||||
|
bottom = tempCellRect.y + tempCellRect.height;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
i = rightCol; // jump over inner cells.
|
i = visibleRightCol; // jump over inner cells.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert to scrolled coords
|
// Convert to scrolled coords
|
||||||
//
|
|
||||||
CalcScrolledPosition( left, top, &left, &top );
|
CalcScrolledPosition( left, top, &left, &top );
|
||||||
CalcScrolledPosition( right, bottom, &right, &bottom );
|
CalcScrolledPosition( right, bottom, &right, &bottom );
|
||||||
|
|
||||||
int cw, ch;
|
|
||||||
m_gridWin->GetClientSize( &cw, &ch );
|
|
||||||
|
|
||||||
if (right < 0 || bottom < 0 || left > cw || top > ch)
|
if (right < 0 || bottom < 0 || left > cw || top > ch)
|
||||||
return wxRect(0,0,0,0);
|
return wxRect(0,0,0,0);
|
||||||
|
|
||||||
rect.SetLeft( wxMax(0, left) );
|
resultRect.SetLeft( wxMax(0, left) );
|
||||||
rect.SetTop( wxMax(0, top) );
|
resultRect.SetTop( wxMax(0, top) );
|
||||||
rect.SetRight( wxMin(cw, right) );
|
resultRect.SetRight( wxMin(cw, right) );
|
||||||
rect.SetBottom( wxMin(ch, bottom) );
|
resultRect.SetBottom( wxMin(ch, bottom) );
|
||||||
|
|
||||||
return rect;
|
return resultRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
Reference in New Issue
Block a user