- // get the cell value and set it into the renderer
- wxVariant value;
- wxDataViewTreeNode * node = GetTreeNodeByRow(item);
- if( node == NULL )
- {
- continue;
- }
-
- wxDataViewItem dataitem = node->GetItem();
- model->GetValue( value, dataitem, col->GetModelColumn());
- cell->SetValue( value );
-
- // update the y offset
- cell_rect.y = item * m_lineHeight;
-
- //Draw the expander here.
- int indent = node->GetIndentLevel();
- if( col->GetModelColumn() == GetOwner()->GetExpanderColumn() )
- {
- //Calculate the indent first
- indent = cell_rect.x + GetOwner()->GetIndent() * indent;
-
- int expander_width = m_lineHeight - 2*EXPANDER_MARGIN;
- // change the cell_rect.x to the appropriate pos
- int expander_x = indent + EXPANDER_MARGIN , expander_y = cell_rect.y + EXPANDER_MARGIN ;
- indent = indent + m_lineHeight ; //try to use the m_lineHeight as the expander space
- dc.SetPen( m_penExpander );
- dc.SetBrush( wxNullBrush );
- if( node->HasChildren() )
- {
- //dc.DrawRoundedRectangle( expander_x,expander_y,expander_width,expander_width, 1.0);
- //dc.DrawLine( expander_x + 2 , expander_y + expander_width/2, expander_x + expander_width - 2, expander_y + expander_width/2 );
- wxRect rect( expander_x , expander_y, expander_width, expander_width);
- if( node->IsOpen() )
- wxRendererNative::Get().DrawTreeItemButton( this, dc, rect, wxCONTROL_EXPANDED );
- else
- wxRendererNative::Get().DrawTreeItemButton( this, dc, rect );
- }
- else
- {
- // I am wandering whether we should draw dot lines between tree nodes
- delete node;
- //Yes, if the node does not have any child, it must be a leaf which mean that it is a temporarily created by GetTreeNodeByRow
- }
-
- //force the expander column to left-center align
- cell->SetAlignment( wxALIGN_CENTER_VERTICAL );
- }
-
-
- // cannot be bigger than allocated space
- wxSize size = cell->GetSize();
- // Because of the tree structure indent, here we should minus the width of the cell for drawing
- size.x = wxMin( size.x + 2*PADDING_RIGHTLEFT, cell_rect.width - indent );
- size.y = wxMin( size.y + 2*PADDING_TOPBOTTOM, cell_rect.height );
-
- wxRect item_rect(cell_rect.GetTopLeft(), size);
- int align = cell->GetAlignment();
-
- // horizontal alignment:
- item_rect.x = cell_rect.x;
- if (align & wxALIGN_CENTER_HORIZONTAL)
- item_rect.x = cell_rect.x + (cell_rect.width / 2) - (size.x / 2);
- else if (align & wxALIGN_RIGHT)
- item_rect.x = cell_rect.x + cell_rect.width - size.x;
- //else: wxALIGN_LEFT is the default
-
- // vertical alignment:
- item_rect.y = cell_rect.y;
- if (align & wxALIGN_CENTER_VERTICAL)
- item_rect.y = cell_rect.y + (cell_rect.height / 2) - (size.y / 2);
- else if (align & wxALIGN_BOTTOM)
- item_rect.y = cell_rect.y + cell_rect.height - size.y;
- //else: wxALIGN_TOP is the default
-
- // add padding
- item_rect.x += PADDING_RIGHTLEFT;
- item_rect.y += PADDING_TOPBOTTOM;
- item_rect.width = size.x - 2 * PADDING_RIGHTLEFT;
- item_rect.height = size.y - 2 * PADDING_TOPBOTTOM;
-
- //Here we add the tree indent
- item_rect.x += indent;
-
- int state = 0;
- if (m_selection.Index(item) != wxNOT_FOUND)
- state |= wxDATAVIEW_CELL_SELECTED;
-
- // TODO: it would be much more efficient to create a clipping
- // region for the entire column being rendered (in the OnPaint
- // of wxDataViewMainWindow) instead of a single clip region for
- // each cell. However it would mean that each renderer should
- // respect the given wxRect's top & bottom coords, eventually
- // violating only the left & right coords - however the user can
- // make its own renderer and thus we cannot be sure of that.
- dc.SetClippingRegion( item_rect );
- cell->Render( item_rect, &dc, state );
- dc.DestroyClippingRegion();