Reduce number of calls to GetLineStart() in generic wxDVC

GetLineStart() is very expensive when using wxDV_VARIABLE_LINE_HEIGHT
style, so don't call it again unnecessarily if we already have the
result.
This commit is contained in:
Jens Göpfert
2017-03-17 16:10:40 +01:00
committed by Vadim Zeitlin
parent 198adec748
commit 57bdd372fb

View File

@@ -2005,6 +2005,10 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
(int)(GetRowCount( ) - item_start)); (int)(GetRowCount( ) - item_start));
unsigned int item_last = item_start + item_count; unsigned int item_last = item_start + item_count;
unsigned int line_start = GetLineStart(item_start);
unsigned int cell_height;
unsigned int ty;
// Send the event to wxDataViewCtrl itself. // Send the event to wxDataViewCtrl itself.
wxDataViewEvent cache_event(wxEVT_DATAVIEW_CACHE_HINT, m_owner, NULL); wxDataViewEvent cache_event(wxEVT_DATAVIEW_CACHE_HINT, m_owner, NULL);
cache_event.SetCache(item_start, item_last - 1); cache_event.SetCache(item_start, item_last - 1);
@@ -2070,15 +2074,18 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
// We only need to draw the visible part, so limit the rectangle to it. // We only need to draw the visible part, so limit the rectangle to it.
const int xRect = m_owner->CalcUnscrolledPosition(wxPoint(0, 0)).x; const int xRect = m_owner->CalcUnscrolledPosition(wxPoint(0, 0)).x;
const int widthRect = size.x; const int widthRect = size.x;
ty = line_start;
for (unsigned int item = item_start; item < item_last; item++) for (unsigned int item = item_start; item < item_last; item++)
{ {
cell_height = GetLineHeight(item);
if ( item % 2 ) if ( item % 2 )
{ {
dc.DrawRectangle(xRect, dc.DrawRectangle(xRect,
GetLineStart(item), ty,
widthRect, widthRect,
GetLineHeight(item)); GetLineHeight(item));
} }
ty += cell_height;
} }
} }
@@ -2088,10 +2095,12 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
dc.SetPen(m_penRule); dc.SetPen(m_penRule);
dc.SetBrush(*wxTRANSPARENT_BRUSH); dc.SetBrush(*wxTRANSPARENT_BRUSH);
ty = line_start;
for (unsigned int i = item_start; i <= item_last; i++) for (unsigned int i = item_start; i <= item_last; i++)
{ {
int y = GetLineStart( i ); cell_height = GetLineHeight(i);
dc.DrawLine(x_start, y, x_last, y); dc.DrawLine(x_start, ty, x_last, ty);
ty += cell_height;
} }
} }
@@ -2107,6 +2116,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
// rule at the most-left side of the control. // rule at the most-left side of the control.
int x = x_start - 1; int x = x_start - 1;
int line_last = GetLineStart(item_last);
for (unsigned int i = col_start; i < col_last; i++) for (unsigned int i = col_start; i < col_last; i++)
{ {
wxDataViewColumn *col = GetOwner()->GetColumnAt(i); wxDataViewColumn *col = GetOwner()->GetColumnAt(i);
@@ -2115,20 +2125,22 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
x += col->GetWidth(); x += col->GetWidth();
dc.DrawLine(x, GetLineStart( item_start ), dc.DrawLine(x, line_start,
x, GetLineStart( item_last ) ); x, line_last);
} }
} }
// redraw the background for the items which are selected/current // redraw the background for the items which are selected/current
ty = line_start;
for (unsigned int item = item_start; item < item_last; item++) for (unsigned int item = item_start; item < item_last; item++)
{ {
bool selected = m_selection.IsSelected(item); bool selected = m_selection.IsSelected(item);
cell_height = GetLineHeight(item);
if (selected || item == m_currentRow) if (selected || item == m_currentRow)
{ {
wxRect rowRect( x_start, GetLineStart( item ), wxRect rowRect( x_start, ty,
x_last - x_start, GetLineHeight( item ) ); x_last - x_start, cell_height );
bool renderColumnFocus = false; bool renderColumnFocus = false;
@@ -2227,6 +2239,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
); );
} }
} }
ty += cell_height;
} }
#if wxUSE_DRAG_AND_DROP #if wxUSE_DRAG_AND_DROP
@@ -2255,17 +2268,21 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
if ( col->IsHidden() || cell_rect.width <= 0 ) if ( col->IsHidden() || cell_rect.width <= 0 )
continue; // skip it! continue; // skip it!
cell_rect.y = line_start;
for (unsigned int item = item_start; item < item_last; item++) for (unsigned int item = item_start; item < item_last; item++)
{ {
// get the cell value and set it into the renderer // get the cell value and set it into the renderer
wxDataViewTreeNode *node = NULL; wxDataViewTreeNode *node = NULL;
wxDataViewItem dataitem; wxDataViewItem dataitem;
cell_height = GetLineHeight(item);
if (!IsVirtualList()) if (!IsVirtualList())
{ {
node = GetTreeNodeByRow(item); node = GetTreeNodeByRow(item);
if( node == NULL ) if (node == NULL) {
cell_rect.y += cell_height;
continue; continue;
}
dataitem = node->GetItem(); dataitem = node->GetItem();
@@ -2273,17 +2290,18 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
// column itself unless HasContainerColumns() overrides this. // column itself unless HasContainerColumns() overrides this.
if ( col != expander && if ( col != expander &&
model->IsContainer(dataitem) && model->IsContainer(dataitem) &&
!model->HasContainerColumns(dataitem) ) !model->HasContainerColumns(dataitem) ) {
cell_rect.y += cell_height;
continue; continue;
} }
}
else else
{ {
dataitem = wxDataViewItem( wxUIntToPtr(item+1) ); dataitem = wxDataViewItem( wxUIntToPtr(item+1) );
} }
// update cell_rect // update cell_rect
cell_rect.y = GetLineStart( item ); cell_rect.height = cell_height;
cell_rect.height = GetLineHeight( item );
bool selected = m_selection.IsSelected(item); bool selected = m_selection.IsSelected(item);
@@ -2347,8 +2365,10 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
item_rect.x += indent; item_rect.x += indent;
item_rect.width -= indent; item_rect.width -= indent;
if ( item_rect.width <= 0 ) if ( item_rect.width <= 0 ) {
cell_rect.y += cell_height;
continue; continue;
}
// TODO: it would be much more efficient to create a clipping // TODO: it would be much more efficient to create a clipping
// region for the entire column being rendered (in the OnPaint // region for the entire column being rendered (in the OnPaint
@@ -2360,6 +2380,8 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
wxDCClipper clip(dc, item_rect); wxDCClipper clip(dc, item_rect);
cell->WXCallRender(item_rect, &dc, state); cell->WXCallRender(item_rect, &dc, state);
cell_rect.y += cell_height;
} }
cell_rect.x += cell_rect.width; cell_rect.x += cell_rect.width;