Merge branch 'reduce-dvc-getlinestart'
Reduce the number of calls to GetLineStart() in generic wxDataViewCtrl code and thus slightly improve its performance when variable line height is used. See https://github.com/wxWidgets/wxWidgets/pull/438
This commit is contained in:
@@ -2048,6 +2048,13 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
|
|||||||
x_last += col->GetWidth();
|
x_last += col->GetWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Instead of calling GetLineStart() for each line from the first to the
|
||||||
|
// last one, we will compute the starts of the lines as we iterate over
|
||||||
|
// them starting from this one, as this is much more efficient when using
|
||||||
|
// wxDV_VARIABLE_LINE_HEIGHT (and doesn't really change anything when not
|
||||||
|
// using it, so there is no need to use two different approaches).
|
||||||
|
const unsigned int first_line_start = GetLineStart(item_start);
|
||||||
|
|
||||||
// Draw background of alternate rows specially if required
|
// Draw background of alternate rows specially if required
|
||||||
if ( m_owner->HasFlag(wxDV_ROW_LINES) )
|
if ( m_owner->HasFlag(wxDV_ROW_LINES) )
|
||||||
{
|
{
|
||||||
@@ -2070,15 +2077,15 @@ 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;
|
||||||
|
unsigned int cur_line_start = first_line_start;
|
||||||
for (unsigned int item = item_start; item < item_last; item++)
|
for (unsigned int item = item_start; item < item_last; item++)
|
||||||
{
|
{
|
||||||
|
const int h = GetLineHeight(item);
|
||||||
if ( item % 2 )
|
if ( item % 2 )
|
||||||
{
|
{
|
||||||
dc.DrawRectangle(xRect,
|
dc.DrawRectangle(xRect, cur_line_start, widthRect, h);
|
||||||
GetLineStart(item),
|
|
||||||
widthRect,
|
|
||||||
GetLineHeight(item));
|
|
||||||
}
|
}
|
||||||
|
cur_line_start += h;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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);
|
||||||
|
|
||||||
|
unsigned int cur_line_start = first_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 );
|
const int h = GetLineHeight(i);
|
||||||
dc.DrawLine(x_start, y, x_last, y);
|
dc.DrawLine(x_start, cur_line_start, x_last, cur_line_start);
|
||||||
|
cur_line_start += h;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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, first_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
|
||||||
|
unsigned int cur_line_start = first_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);
|
||||||
|
const int line_height = GetLineHeight(item);
|
||||||
|
|
||||||
if (selected || item == m_currentRow)
|
if (selected || item == m_currentRow)
|
||||||
{
|
{
|
||||||
wxRect rowRect( x_start, GetLineStart( item ),
|
wxRect rowRect( x_start, cur_line_start,
|
||||||
x_last - x_start, GetLineHeight( item ) );
|
x_last - x_start, line_height );
|
||||||
|
|
||||||
bool renderColumnFocus = false;
|
bool renderColumnFocus = false;
|
||||||
|
|
||||||
@@ -2227,6 +2239,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
cur_line_start += line_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if wxUSE_DRAG_AND_DROP
|
#if wxUSE_DRAG_AND_DROP
|
||||||
@@ -2255,17 +2268,22 @@ 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 = first_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;
|
||||||
|
const int line_height = GetLineHeight(item);
|
||||||
|
|
||||||
if (!IsVirtualList())
|
if (!IsVirtualList())
|
||||||
{
|
{
|
||||||
node = GetTreeNodeByRow(item);
|
node = GetTreeNodeByRow(item);
|
||||||
if( node == NULL )
|
if (node == NULL)
|
||||||
|
{
|
||||||
|
cell_rect.y += line_height;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
dataitem = node->GetItem();
|
dataitem = node->GetItem();
|
||||||
|
|
||||||
@@ -2274,7 +2292,10 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
|
|||||||
if ( col != expander &&
|
if ( col != expander &&
|
||||||
model->IsContainer(dataitem) &&
|
model->IsContainer(dataitem) &&
|
||||||
!model->HasContainerColumns(dataitem) )
|
!model->HasContainerColumns(dataitem) )
|
||||||
|
{
|
||||||
|
cell_rect.y += line_height;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -2282,8 +2303,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update cell_rect
|
// update cell_rect
|
||||||
cell_rect.y = GetLineStart( item );
|
cell_rect.height = line_height;
|
||||||
cell_rect.height = GetLineHeight( item );
|
|
||||||
|
|
||||||
bool selected = m_selection.IsSelected(item);
|
bool selected = m_selection.IsSelected(item);
|
||||||
|
|
||||||
@@ -2348,7 +2368,10 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
|
|||||||
item_rect.width -= indent;
|
item_rect.width -= indent;
|
||||||
|
|
||||||
if ( item_rect.width <= 0 )
|
if ( item_rect.width <= 0 )
|
||||||
|
{
|
||||||
|
cell_rect.y += line_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 +2383,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 += line_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
cell_rect.x += cell_rect.width;
|
cell_rect.x += cell_rect.width;
|
||||||
|
Reference in New Issue
Block a user