Improve wxDataViewMainWindow::RefreshRow speed
RefreshRow() is called very frequently, and in particular after every
ItemChanged notification. Calling GetEndOfLastCol() in it repeatedly is
extremely inefficient in presence of auto-sizing columns, and doesn't
make much sense anyway - controls with significant space unoccupied by
columns are rare, and rendering of such unused space is efficient (just
background erase). It is therefore more performant to simply refresh
the entire row instead of repeatedly and expensively calculating the
smallest rectangle that needs repainting.
Fixes previously wrong calculation of the refreshed rectangle in
RefreshRows() in the process.
Fixes major performance regression introduced in
77c7c80696
.
Closes https://github.com/wxWidgets/wxWidgets/pull/970
This commit is contained in:
committed by
Vadim Zeitlin
parent
6fff1c37b5
commit
e5beb4e93f
@@ -806,7 +806,7 @@ public:
|
||||
bool IsRowSelected( unsigned int row );
|
||||
void SendSelectionChangedEvent( const wxDataViewItem& item);
|
||||
|
||||
void RefreshRow( unsigned int row );
|
||||
void RefreshRow( unsigned int row ) { RefreshRows(row, row); }
|
||||
void RefreshRows( unsigned int from, unsigned int to );
|
||||
void RefreshRowsAfter( unsigned int firstRow );
|
||||
|
||||
@@ -816,7 +816,7 @@ public:
|
||||
return wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT);
|
||||
}
|
||||
|
||||
wxRect GetLineRect( unsigned int row ) const;
|
||||
wxRect GetLinesRect( unsigned int rowFrom, unsigned int rowTo ) const;
|
||||
|
||||
int GetLineStart( unsigned int row ) const; // row * m_lineHeight in fixed mode
|
||||
int GetLineHeight( unsigned int row ) const; // m_lineHeight in fixed mode
|
||||
@@ -3275,34 +3275,16 @@ void wxDataViewMainWindow::SendSelectionChangedEvent( const wxDataViewItem& item
|
||||
m_owner->ProcessWindowEvent(le);
|
||||
}
|
||||
|
||||
void wxDataViewMainWindow::RefreshRow( unsigned int row )
|
||||
{
|
||||
wxRect rect( 0, GetLineStart( row ), GetEndOfLastCol(), GetLineHeight( row ) );
|
||||
m_owner->CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y );
|
||||
|
||||
wxSize client_size = GetClientSize();
|
||||
wxRect client_rect( 0, 0, client_size.x, client_size.y );
|
||||
wxRect intersect_rect = client_rect.Intersect( rect );
|
||||
if (intersect_rect.width > 0)
|
||||
Refresh( true, &intersect_rect );
|
||||
}
|
||||
|
||||
void wxDataViewMainWindow::RefreshRows( unsigned int from, unsigned int to )
|
||||
{
|
||||
if (from > to)
|
||||
{
|
||||
unsigned int tmp = to;
|
||||
to = from;
|
||||
from = tmp;
|
||||
}
|
||||
wxRect rect = GetLinesRect(from, to);
|
||||
|
||||
wxRect rect( 0, GetLineStart( from ), GetEndOfLastCol(), GetLineStart( (to-from+1) ) );
|
||||
m_owner->CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y );
|
||||
m_owner->CalcScrolledPosition(rect.x, rect.y, &rect.x, &rect.y);
|
||||
|
||||
wxSize client_size = GetClientSize();
|
||||
wxRect client_rect( 0, 0, client_size.x, client_size.y );
|
||||
wxRect intersect_rect = client_rect.Intersect( rect );
|
||||
if (intersect_rect.width > 0)
|
||||
if (!intersect_rect.IsEmpty())
|
||||
Refresh( true, &intersect_rect );
|
||||
}
|
||||
|
||||
@@ -3318,14 +3300,22 @@ void wxDataViewMainWindow::RefreshRowsAfter( unsigned int firstRow )
|
||||
Refresh( true, &rect );
|
||||
}
|
||||
|
||||
wxRect wxDataViewMainWindow::GetLineRect( unsigned int row ) const
|
||||
wxRect wxDataViewMainWindow::GetLinesRect( unsigned int rowFrom, unsigned int rowTo ) const
|
||||
{
|
||||
if (rowFrom > rowTo)
|
||||
wxSwap(rowFrom, rowTo);
|
||||
|
||||
wxRect rect;
|
||||
rect.x = 0;
|
||||
rect.y = GetLineStart( row );
|
||||
rect.width = GetEndOfLastCol();
|
||||
rect.height = GetLineHeight( row );
|
||||
|
||||
rect.y = GetLineStart(rowFrom);
|
||||
// Don't calculate exact width of the row, because GetEndOfLastCol() is
|
||||
// expensive to call, and controls with rows not spanning entire width rare.
|
||||
// It is more efficient to e.g. repaint empty parts of the window needlessly.
|
||||
rect.width = INT_MAX;
|
||||
if (rowFrom == rowTo)
|
||||
rect.height = GetLineHeight(rowFrom);
|
||||
else
|
||||
rect.height = GetLineStart(rowTo) - rect.y + GetLineHeight(rowTo);
|
||||
return rect;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user