X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7d83595849b8c014f6b975c3d2acc9a8465d2bc4..205bdf2069b93743848d69a39c0bd4a32e9ff8b7:/src/generic/datavgen.cpp diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index 8be7c4781d..bdeadffd36 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -70,7 +70,7 @@ static const int EXPANDER_OFFSET = 1; #endif // Below is the compare stuff. -// For the generic implementation, both the leaf nodes and the nodes are sorted for +// For the generic implementation, both the leaf nodes and the nodes are sorted for // fast search when needed static wxDataViewModel* g_model; static int g_column = -2; @@ -99,6 +99,7 @@ protected: return *(GetOwner()->GetColumn(idx)); } + // FIXME: currently unused virtual bool UpdateColumnWidthToFit(unsigned int idx, int widthTitle) { wxDataViewCtrl * const owner = GetOwner(); @@ -229,7 +230,7 @@ class wxDataViewTreeNode; WX_DEFINE_ARRAY( wxDataViewTreeNode *, wxDataViewTreeNodes ); WX_DEFINE_ARRAY( void* , wxDataViewTreeLeaves); -int LINKAGEMODE wxGenericTreeModelNodeCmp( wxDataViewTreeNode ** node1, +int LINKAGEMODE wxGenericTreeModelNodeCmp( wxDataViewTreeNode ** node1, wxDataViewTreeNode ** node2); int LINKAGEMODE wxGenericTreeModelItemCmp( void ** id1, void ** id2); @@ -350,7 +351,7 @@ private: int m_subTreeCount; }; -int LINKAGEMODE wxGenericTreeModelNodeCmp( wxDataViewTreeNode ** node1, +int LINKAGEMODE wxGenericTreeModelNodeCmp( wxDataViewTreeNode ** node1, wxDataViewTreeNode ** node2) { return g_model->Compare( (*node1)->GetItem(), (*node2)->GetItem(), g_column, g_asending ); @@ -450,15 +451,15 @@ public: int GetEndOfLastCol() const; unsigned int GetFirstVisibleRow() const; - // I change this method to un const because in the tree view, - // the displaying number of the tree are changing along with the + // I change this method to un const because in the tree view, + // the displaying number of the tree are changing along with the // expanding/collapsing of the tree nodes unsigned int GetLastVisibleRow(); unsigned int GetRowCount(); wxDataViewItem GetSelection() const; wxDataViewSelection GetSelections(){ return m_selection; } - void SetSelections( const wxDataViewSelection & sel ) + void SetSelections( const wxDataViewSelection & sel ) { m_selection = sel; UpdateDisplay(); } void Select( const wxArrayInt& aSelections ); void SelectAllRows( bool on ); @@ -494,9 +495,10 @@ public: void HitTest( const wxPoint & point, wxDataViewItem & item, wxDataViewColumn* &column ); wxRect GetItemRect( const wxDataViewItem & item, const wxDataViewColumn* column ); - void Expand( unsigned int row ) { OnExpanding( row ); } - void Collapse( unsigned int row ) { OnCollapsing( row ); } + void Expand( unsigned int row ); + void Collapse( unsigned int row ); bool IsExpanded( unsigned int row ) const; + bool HasChildren( unsigned int row ) const; #if wxUSE_DRAG_AND_DROP bool EnableDragSource( const wxDataFormat &format ); @@ -517,8 +519,6 @@ private: int RecalculateCount(); wxDataViewEvent SendExpanderEvent( wxEventType type, const wxDataViewItem & item ); - void OnExpanding( unsigned int row ); - void OnCollapsing( unsigned int row ); wxDataViewTreeNode * FindNode( const wxDataViewItem & item ); @@ -612,8 +612,6 @@ wxDataViewRenderer::wxDataViewRenderer( const wxString &varianttype, m_dc = NULL; m_align = align; m_mode = mode; - m_wantsAttr = false; - m_hasAttr = false; } wxDataViewRenderer::~wxDataViewRenderer() @@ -622,6 +620,54 @@ wxDataViewRenderer::~wxDataViewRenderer() delete m_dc; } +bool +wxDataViewRenderer::RenderWithAttr(wxDC& dc, + const wxRect& cell_rect, + int align, + const wxDataViewItemAttr *WXUNUSED(attr), + int state) +{ + // adjust the rectangle ourselves to account for the alignment + + wxRect item_rect = cell_rect; + if ( align ) + { + const wxSize size = GetSize(); + + // take alignment into account only if there is enough space, otherwise + // show as much contents as possible + // + // notice that many existing renderers (e.g. wxDataViewSpinRenderer) + // return hard-coded size which can be more than they need and if we + // trusted their GetSize() we'd draw the text out of cell bounds + // entirely + + if ( size.x < cell_rect.width ) + { + if (align & wxALIGN_CENTER_HORIZONTAL) + item_rect.x += (cell_rect.width - size.x)/2; + else if (align & wxALIGN_RIGHT) + item_rect.x += cell_rect.width - size.x; + // else: wxALIGN_LEFT is the default + + item_rect.width = size.x; + } + + if ( size.y < cell_rect.height ) + { + if (align & wxALIGN_CENTER_VERTICAL) + item_rect.y += (cell_rect.height - size.y)/2; + else if (align & wxALIGN_BOTTOM) + item_rect.y += cell_rect.height - size.y; + // else: wxALIGN_TOP is the default + + item_rect.height = size.y; + } + } + + return Render(item_rect, &dc, state); +} + wxDC *wxDataViewRenderer::GetDC() { if (m_dc == NULL) @@ -671,17 +717,42 @@ wxDataViewCustomRenderer::wxDataViewCustomRenderer( const wxString &varianttype, { } -void wxDataViewCustomRenderer::RenderText( const wxString &text, int xoffset, - wxRect cell, wxDC *dc, int state ) +void +wxDataViewCustomRenderer::RenderText(wxDC& dc, + const wxRect& rect, + int align, + const wxString& text, + const wxDataViewItemAttr *attr, + int state, + int xoffset) { - wxDataViewCtrl *view = GetOwner()->GetOwner(); - wxColour col = (state & wxDATAVIEW_CELL_SELECTED) ? - wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT) : - view->GetForegroundColour(); - dc->SetTextForeground(col); - dc->DrawText( text, - cell.x + xoffset, - cell.y + ((cell.height - dc->GetCharHeight()) / 2)); + wxColour col; + if ( attr && attr->HasColour() ) + col = attr->GetColour(); + else if ( state & wxDATAVIEW_CELL_SELECTED ) + col = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT); + else // use default foreground + col = GetOwner()->GetOwner()->GetForegroundColour(); + + wxDCTextColourChanger changeFg(dc, col); + + wxDCFontChanger changeFont(dc); + if ( attr && attr->HasFont() ) + { + wxFont font(dc.GetFont()); + if ( attr->GetBold() ) + font.MakeBold(); + if ( attr->GetItalic() ) + font.MakeItalic(); + + changeFont.Set(font); + } + + wxRect rectText = rect; + rectText.x += xoffset; + rectText.width -= xoffset; + + dc.DrawLabel(text, rectText, align); } // --------------------------------------------------------- @@ -716,9 +787,15 @@ bool wxDataViewTextRenderer::HasEditorCtrl() const wxControl* wxDataViewTextRenderer::CreateEditorCtrl( wxWindow *parent, wxRect labelRect, const wxVariant &value ) { - return new wxTextCtrl( parent, wxID_ANY, value, - wxPoint(labelRect.x,labelRect.y), - wxSize(labelRect.width,labelRect.height) ); + wxTextCtrl* ctrl = new wxTextCtrl( parent, wxID_ANY, value, + wxPoint(labelRect.x,labelRect.y), + wxSize(labelRect.width,labelRect.height) ); + + // select the text in the control an place the cursor at the end + ctrl->SetInsertionPointEnd(); + ctrl->SelectAll(); + + return ctrl; } bool wxDataViewTextRenderer::GetValueFromEditorCtrl( wxControl *editor, wxVariant &value ) @@ -728,9 +805,14 @@ bool wxDataViewTextRenderer::GetValueFromEditorCtrl( wxControl *editor, wxVarian return true; } -bool wxDataViewTextRenderer::Render( wxRect cell, wxDC *dc, int state ) +bool +wxDataViewTextRenderer::RenderWithAttr(wxDC& dc, + const wxRect& rect, + int align, + const wxDataViewItemAttr *attr, + int state) { - RenderText( m_text, 0, cell, dc, state ); + RenderText(dc, rect, align, m_text, attr, state); return true; } @@ -738,68 +820,10 @@ wxSize wxDataViewTextRenderer::GetSize() const { const wxDataViewCtrl *view = GetView(); if (!m_text.empty()) - { - int x,y; - view->GetTextExtent( m_text, &x, &y ); - return wxSize( x, y ); - } - return wxSize(80,20); + return view->wxWindowBase::GetTextExtent( m_text ); + return wxSize(wxDVC_DEFAULT_RENDERER_SIZE,wxDVC_DEFAULT_RENDERER_SIZE); } -// --------------------------------------------------------- -// wxDataViewTextRendererAttr -// --------------------------------------------------------- - -IMPLEMENT_CLASS(wxDataViewTextRendererAttr, wxDataViewTextRenderer) - -wxDataViewTextRendererAttr::wxDataViewTextRendererAttr( const wxString &varianttype, - wxDataViewCellMode mode, int align ) : - wxDataViewTextRenderer( varianttype, mode, align ) -{ - m_wantsAttr = true; -} - -bool wxDataViewTextRendererAttr::Render( wxRect cell, wxDC *dc, int WXUNUSED(state) ) -{ - wxFont font; - wxColour colour; - - if (m_hasAttr) - { - if (m_attr.HasColour()) - { - colour = dc->GetTextForeground(); - dc->SetTextForeground( m_attr.GetColour() ); - } - - if (m_attr.GetBold() || m_attr.GetItalic()) - { - font = dc->GetFont(); - wxFont myfont = font; - if (m_attr.GetBold()) - myfont.SetWeight( wxFONTWEIGHT_BOLD ); - if (m_attr.GetItalic()) - myfont.SetStyle( wxFONTSTYLE_ITALIC ); - dc->SetFont( myfont ); - } - } - - dc->DrawText( m_text, cell.x, cell.y + ((cell.height - dc->GetCharHeight()) / 2)); - - // restore dc - if (m_hasAttr) - { - if (m_attr.HasColour()) - dc->SetTextForeground( colour ); - - if (m_attr.GetBold() || m_attr.GetItalic()) - dc->SetFont( font ); - } - - return true; -} - - // --------------------------------------------------------- // wxDataViewBitmapRenderer // --------------------------------------------------------- @@ -844,7 +868,7 @@ wxSize wxDataViewBitmapRenderer::GetSize() const else if (m_icon.Ok()) return wxSize( m_icon.GetWidth(), m_icon.GetHeight() ); - return wxSize(16,16); + return wxSize(wxDVC_DEFAULT_RENDERER_SIZE,wxDVC_DEFAULT_RENDERER_SIZE); } // --------------------------------------------------------- @@ -921,10 +945,6 @@ wxDataViewProgressRenderer::wxDataViewProgressRenderer( const wxString &label, m_value = 0; } -wxDataViewProgressRenderer::~wxDataViewProgressRenderer() -{ -} - bool wxDataViewProgressRenderer::SetValue( const wxVariant &value ) { m_value = (long) value; @@ -941,18 +961,24 @@ bool wxDataViewProgressRenderer::GetValue( wxVariant &value ) const return true; } -bool wxDataViewProgressRenderer::Render( wxRect cell, wxDC *dc, int WXUNUSED(state) ) +bool wxDataViewProgressRenderer::RenderWithAttr(wxDC& dc, + const wxRect& rect, + int WXUNUSED(align), + const wxDataViewItemAttr *attr, + int WXUNUSED(state)) { - double pct = (double)m_value / 100.0; - wxRect bar = cell; - bar.width = (int)(cell.width * pct); - dc->SetPen( *wxTRANSPARENT_PEN ); - dc->SetBrush( *wxBLUE_BRUSH ); - dc->DrawRectangle( bar ); + // deflat the rect to leave a small border between bars in adjacent rows + wxRect bar = rect.Deflate(0, 1); - dc->SetBrush( *wxTRANSPARENT_BRUSH ); - dc->SetPen( *wxBLACK_PEN ); - dc->DrawRectangle( cell ); + dc.SetBrush( *wxTRANSPARENT_BRUSH ); + dc.SetPen( *wxBLACK_PEN ); + dc.DrawRectangle( bar ); + + bar.width = (int)(bar.width * m_value / 100.); + dc.SetPen( *wxTRANSPARENT_PEN ); + dc.SetBrush( attr && attr->HasColour() ? wxBrush(attr->GetColour()) + : *wxBLUE_BRUSH ); + dc.DrawRectangle( bar ); return true; } @@ -1089,10 +1115,6 @@ const wxString &varianttype, wxDataViewCellMode mode, int align ) : SetAlignment(align); } -wxDataViewIconTextRenderer::~wxDataViewIconTextRenderer() -{ -} - bool wxDataViewIconTextRenderer::SetValue( const wxVariant &value ) { m_value << value; @@ -1104,17 +1126,23 @@ bool wxDataViewIconTextRenderer::GetValue( wxVariant& WXUNUSED(value) ) const return false; } -bool wxDataViewIconTextRenderer::Render( wxRect cell, wxDC *dc, int state ) +bool +wxDataViewIconTextRenderer::RenderWithAttr(wxDC& dc, + const wxRect& rect, + int align, + const wxDataViewItemAttr *attr, + int state) { int xoffset = 0; - const wxIcon &icon = m_value.GetIcon(); - if (icon.IsOk()) + + const wxIcon& icon = m_value.GetIcon(); + if ( icon.IsOk() ) { - dc->DrawIcon( icon, cell.x, cell.y + ((cell.height - icon.GetHeight()) / 2)); - xoffset = icon.GetWidth()+4; + dc.DrawIcon(icon, rect.x, rect.y + (rect.height - icon.GetHeight())/2); + xoffset = icon.GetWidth()+4; } - RenderText( m_value.GetText(), xoffset, cell, dc, state ); + RenderText(dc, rect, align, m_value.GetText(), attr, state, xoffset); return true; } @@ -1134,19 +1162,39 @@ wxSize wxDataViewIconTextRenderer::GetSize() const return wxSize(80,20); } -wxControl * -wxDataViewIconTextRenderer::CreateEditorCtrl(wxWindow * WXUNUSED(parent), - wxRect WXUNUSED(labelRect), - const wxVariant& WXUNUSED(value)) +wxControl* wxDataViewIconTextRenderer::CreateEditorCtrl(wxWindow *parent, wxRect labelRect, const wxVariant& value) { - return NULL; + wxDataViewIconText iconText; + iconText << value; + + wxString text = iconText.GetText(); + + // adjust the label rect to take the width of the icon into account + if (iconText.GetIcon().IsOk()) + { + int w = iconText.GetIcon().GetWidth() + 4; + labelRect.x += w; + labelRect.width -= w; + } + + wxTextCtrl* ctrl = new wxTextCtrl( parent, wxID_ANY, text, + wxPoint(labelRect.x,labelRect.y), + wxSize(labelRect.width,labelRect.height) ); + + // select the text in the control an place the cursor at the end + ctrl->SetInsertionPointEnd(); + ctrl->SelectAll(); + + return ctrl; } -bool -wxDataViewIconTextRenderer::GetValueFromEditorCtrl(wxControl* WXUNUSED(editor), - wxVariant& WXUNUSED(value)) +bool wxDataViewIconTextRenderer::GetValueFromEditorCtrl( wxControl *editor, wxVariant& value ) { - return false; + wxTextCtrl *text = (wxTextCtrl*) editor; + + wxDataViewIconText iconText(text->GetValue(), m_value.GetIcon()); + value << iconText; + return true; } //----------------------------------------------------------------------------- @@ -1242,30 +1290,30 @@ public: } virtual wxDragResult OnDragOver( wxCoord x, wxCoord y, wxDragResult def ) - { + { wxDataFormat format = GetMatchingPair(); if (format == wxDF_INVALID) return wxDragNone; return m_win->OnDragOver( format, x, y, def); - } + } virtual bool OnDrop( wxCoord x, wxCoord y ) - { + { wxDataFormat format = GetMatchingPair(); if (format == wxDF_INVALID) return false; return m_win->OnDrop( format, x, y ); - } + } virtual wxDragResult OnData( wxCoord x, wxCoord y, wxDragResult def ) - { + { wxDataFormat format = GetMatchingPair(); if (format == wxDF_INVALID) return wxDragNone; if (!GetData()) return wxDragNone; return m_win->OnData( format, x, y, def ); - } + } virtual void OnLeave() { m_win->OnLeave(); } @@ -1294,7 +1342,7 @@ void wxDataViewRenameTimer::Notify() //----------------------------------------------------------------------------- // The tree building helper, declared firstly -static void BuildTreeHelper( wxDataViewModel * model, wxDataViewItem & item, +static void BuildTreeHelper( wxDataViewModel * model, wxDataViewItem & item, wxDataViewTreeNode * node); int LINKAGEMODE wxDataViewSelectionCmp( unsigned int row1, unsigned int row2 ) @@ -1304,7 +1352,6 @@ int LINKAGEMODE wxDataViewSelectionCmp( unsigned int row1, unsigned int row2 ) return -1; } - IMPLEMENT_ABSTRACT_CLASS(wxDataViewMainWindow, wxWindow) BEGIN_EVENT_TABLE(wxDataViewMainWindow,wxWindow) @@ -1404,7 +1451,7 @@ void wxDataViewMainWindow::RemoveDropHint() } } -wxDragResult wxDataViewMainWindow::OnDragOver( wxDataFormat format, wxCoord x, +wxDragResult wxDataViewMainWindow::OnDragOver( wxDataFormat format, wxCoord x, wxCoord y, wxDragResult def ) { int xx = x; @@ -1479,7 +1526,7 @@ bool wxDataViewMainWindow::OnDrop( wxDataFormat format, wxCoord x, wxCoord y ) return true; } -wxDragResult wxDataViewMainWindow::OnData( wxDataFormat format, wxCoord x, wxCoord y, +wxDragResult wxDataViewMainWindow::OnData( wxDataFormat format, wxCoord x, wxCoord y, wxDragResult def ) { int xx = x; @@ -1536,7 +1583,7 @@ wxBitmap wxDataViewMainWindow::CreateItemBitmap( unsigned int row, int &indent ) { wxDataViewTreeNode *node = GetTreeNodeByRow(row); indent = GetOwner()->GetIndent() * node->GetIndentLevel(); - indent = indent + m_lineHeight; + indent = indent + m_lineHeight; // try to use the m_lineHeight as the expander space if(!node->HasChildren()) @@ -1581,43 +1628,15 @@ wxBitmap wxDataViewMainWindow::CreateItemBitmap( unsigned int row, int &indent ) model->GetValue( value, item, column->GetModelColumn()); cell->SetValue( value ); - if (cell->GetWantsAttr()) - { - wxDataViewItemAttr attr; - bool ret = model->GetAttr( item, column->GetModelColumn(), attr ); - if (ret) - cell->SetAttr( attr ); - cell->SetHasAttr( ret ); - } - - wxSize size = cell->GetSize(); - size.x = wxMin( 2*PADDING_RIGHTLEFT + size.x, width ); - size.y = height; - wxRect item_rect(x, 0, size.x, size.y); - - int align = cell->CalculateAlignment(); - // horizontal alignment: - item_rect.x = x; - if (align & wxALIGN_CENTER_HORIZONTAL) - item_rect.x = x + (width / 2) - (size.x / 2); - else if (align & wxALIGN_RIGHT) - item_rect.x = x + width - size.x; - // else: wxALIGN_LEFT is the default - - // vertical alignment: - item_rect.y = 0; - if (align & wxALIGN_CENTER_VERTICAL) - item_rect.y = (height / 2) - (size.y / 2); - else if (align & wxALIGN_BOTTOM) - item_rect.y = height - size.y; - // else: wxALIGN_TOP is the default - - // add padding - item_rect.x += PADDING_RIGHTLEFT; - item_rect.width = size.x - 2 * PADDING_RIGHTLEFT; + wxRect item_rect(x, 0, width, height); + item_rect.Deflate(PADDING_RIGHTLEFT, 0); // dc.SetClippingRegion( item_rect ); - cell->Render( item_rect, &dc, 0 ); + wxDataViewItemAttr attr; + const bool + hasAttr = model->GetAttr(item, column->GetModelColumn(), attr); + cell->RenderWithAttr(dc, item_rect, cell->CalculateAlignment(), + hasAttr ? &attr : NULL, 0); // dc.DestroyClippingRegion(); x += width; @@ -1635,11 +1654,9 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) wxAutoBufferedPaintDC dc( this ); #ifdef __WXMSW__ + dc.SetBrush(GetOwner()->GetBackgroundColour()); dc.SetPen( *wxTRANSPARENT_PEN ); - dc.SetBrush( wxBrush( GetBackgroundColour()) ); - dc.SetBrush( *wxWHITE_BRUSH ); - wxSize size( GetClientSize() ); - dc.DrawRectangle( 0,0,size.x,size.y ); + dc.DrawRectangle(GetClientSize()); #endif // prepare the DC @@ -1655,6 +1672,12 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) wxMin( (int)( GetLineAt( wxMax(0,update.y+update.height) ) - item_start + 1), (int)(GetRowCount( ) - item_start)); unsigned int item_last = item_start + item_count; + // Get the parent of DataViewCtrl + wxWindow *parent = GetParent()->GetParent(); + wxDataViewEvent cache_event(wxEVT_COMMAND_DATAVIEW_CACHE_HINT, parent->GetId()); + cache_event.SetEventObject(GetParent()); + cache_event.SetCache(item_start, item_last - 1); + parent->ProcessWindowEvent(cache_event); // compute which columns needs to be redrawn unsigned int cols = GetOwner()->GetColumnCount(); @@ -1771,7 +1794,6 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) cell_rect.x = x_start; for (unsigned int i = col_start; i < col_last; i++) { - wxDataViewColumn *col = GetOwner()->GetColumnAt( i ); wxDataViewRenderer *cell = col->GetRenderer(); cell_rect.width = col->GetWidth(); @@ -1794,27 +1816,18 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) dataitem = node->GetItem(); - if ((i > 0) && model->IsContainer(dataitem) && + if ((i > 0) && model->IsContainer(dataitem) && !model->HasContainerColumns(dataitem)) continue; } else { - dataitem = wxDataViewItem( wxUIntToPtr(item) ); + dataitem = wxDataViewItem( wxUIntToPtr(item+1) ); } model->GetValue( value, dataitem, col->GetModelColumn()); cell->SetValue( value ); - if (cell->GetWantsAttr()) - { - wxDataViewItemAttr attr; - bool ret = model->GetAttr( dataitem, col->GetModelColumn(), attr ); - if (ret) - cell->SetAttr( attr ); - cell->SetHasAttr( ret ); - } - // update cell_rect cell_rect.y = GetLineStart( item ); cell_rect.height = GetLineHeight( item ); @@ -1832,10 +1845,10 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) // change the cell_rect.x to the appropriate pos int expander_x = indent + EXPANDER_MARGIN; - int expander_y = cell_rect.y + EXPANDER_MARGIN + (GetLineHeight(item) / 2) + int expander_y = cell_rect.y + EXPANDER_MARGIN + (GetLineHeight(item) / 2) - (expander_width/2) - EXPANDER_OFFSET; - indent = indent + m_lineHeight; + indent = indent + m_lineHeight; // try to use the m_lineHeight as the expander space dc.SetPen( m_penExpander ); @@ -1849,7 +1862,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) flag |= wxCONTROL_CURRENT; } if( node->IsOpen() ) - wxRendererNative::Get().DrawTreeItemButton( this, dc, rect, + wxRendererNative::Get().DrawTreeItemButton( this, dc, rect, flag|wxCONTROL_EXPANDED ); else wxRendererNative::Get().DrawTreeItemButton( this, dc, rect, flag); @@ -1865,40 +1878,12 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) wxDELETE(node); } - // 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, cell_rect.height ); - size.y = cell_rect.height; - - wxRect item_rect(cell_rect.GetTopLeft(), size); - int align = cell->CalculateAlignment(); - - // 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.width = size.x - 2 * PADDING_RIGHTLEFT; + wxRect item_rect = cell_rect; + item_rect.Deflate(PADDING_RIGHTLEFT, 0); - // Here we add the tree indent + // account for the tree indent (harmless if we're not indented) item_rect.x += indent; + item_rect.width -= indent; int state = 0; if (m_hasFocus && (m_selection.Index(item) != wxNOT_FOUND)) @@ -1911,9 +1896,13 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) // 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(); + wxDCClipper clip(dc, item_rect); + + wxDataViewItemAttr attr; + const bool + hasAttr = model->GetAttr(dataitem, col->GetModelColumn(), attr); + cell->RenderWithAttr(dc, item_rect, cell->CalculateAlignment(), + hasAttr ? &attr : NULL, state); } cell_rect.x += cell_rect.width; @@ -1931,42 +1920,10 @@ void wxDataViewMainWindow::OnRenameTimer() wxSafeYield(); } - int xpos = 0; - unsigned int cols = GetOwner()->GetColumnCount(); - unsigned int i; - for (i = 0; i < cols; i++) - { - wxDataViewColumn *c = GetOwner()->GetColumnAt( i ); - if (c->IsHidden()) - continue; // skip it! - - if (c == m_currentCol) - break; - xpos += c->GetWidth(); - } - - // we have to take an expander column into account and compute its indentation - // to get the editor at the correct x position where the actual text is - int indent = 0; - if (!IsVirtualList() && GetOwner()->GetExpanderColumn() == m_currentCol) - { - wxDataViewTreeNode* node = GetTreeNodeByRow(m_currentRow); - indent = GetOwner()->GetIndent() * node->GetIndentLevel(); - indent = indent + m_lineHeight; - - if(!node->HasChildren()) - delete node; - } - - wxRect labelRect( xpos + indent, - GetLineStart( m_currentRow ), - m_currentCol->GetWidth() - indent, - GetLineHeight( m_currentRow ) ); + wxDataViewItem item = GetItemByRow( m_currentRow ); - GetOwner()->CalcScrolledPosition( labelRect.x, labelRect.y, - &labelRect.x, &labelRect.y); + wxRect labelRect = GetItemRect(item, m_currentCol); - wxDataViewItem item = GetItemByRow( m_currentRow ); m_currentCol->GetRenderer()->StartEditing( item, labelRect ); } @@ -2040,9 +1997,11 @@ bool Walker( wxDataViewTreeNode * node, DoJob & func ) bool wxDataViewMainWindow::ItemAdded(const wxDataViewItem & parent, const wxDataViewItem & item) { - if (!m_root) + if (IsVirtualList()) { - m_count++; + wxDataViewVirtualListModel *list_model = + (wxDataViewVirtualListModel*) GetOwner()->GetModel(); + m_count = list_model->GetCount(); UpdateDisplay(); return true; } @@ -2078,14 +2037,18 @@ bool wxDataViewMainWindow::ItemAdded(const wxDataViewItem & parent, const wxData static void DestroyTreeHelper( wxDataViewTreeNode * node); bool wxDataViewMainWindow::ItemDeleted(const wxDataViewItem& parent, - const wxDataViewItem& item) + const wxDataViewItem& item) { - if (!m_root) + if (IsVirtualList()) { - m_count--; + wxDataViewVirtualListModel *list_model = + (wxDataViewVirtualListModel*) GetOwner()->GetModel(); + m_count = list_model->GetCount(); + if( m_currentRow > GetRowCount() ) m_currentRow = m_count - 1; + // TODO: why empty the entire selection? m_selection.Empty(); UpdateDisplay(); @@ -2096,7 +2059,7 @@ bool wxDataViewMainWindow::ItemDeleted(const wxDataViewItem& parent, wxDataViewTreeNode * node = FindNode(parent); wxCHECK_MSG( node != NULL, false, "item not found" ); - wxCHECK_MSG( node->GetChildren().Index( item.GetID() ) != wxNOT_FOUND, + wxCHECK_MSG( node->GetChildren().Index( item.GetID() ) != wxNOT_FOUND, false, "item not found" ); int sub = -1; @@ -2498,7 +2461,7 @@ void wxDataViewMainWindow::RefreshRowsAfter( unsigned int firstRow ) void wxDataViewMainWindow::OnArrowChar(unsigned int newCurrent, const wxKeyEvent& event) { wxCHECK_RET( newCurrent < GetRowCount(), - _T("invalid item index in OnArrowChar()") ); + wxT("invalid item index in OnArrowChar()") ); // if there is no selection, we cannot move it anywhere if (!HasCurrentRow()) @@ -2592,18 +2555,20 @@ int wxDataViewMainWindow::GetLineStart( unsigned int row ) const if (column->IsHidden()) continue; // skip it! - if ((col != 0) && model->IsContainer(item) && !model->HasContainerColumns(item)) + if ((col != 0) && + model->IsContainer(item) && + !model->HasContainerColumns(item)) continue; // skip it! - const wxDataViewRenderer *renderer = column->GetRenderer(); wxVariant value; model->GetValue( value, item, column->GetModelColumn() ); - wxDataViewRenderer *renderer2 = const_cast(renderer); - renderer2->SetValue( value ); + + wxDataViewRenderer *renderer = + const_cast(column->GetRenderer()); + renderer->SetValue( value ); height = wxMax( height, renderer->GetSize().y ); } - start += height; } @@ -2628,14 +2593,14 @@ int wxDataViewMainWindow::GetLineAt( unsigned int y ) const unsigned int yy = 0; for (;;) { - const wxDataViewTreeNode* node = GetTreeNodeByRow(row); - if (!node) - { - // not really correct... - return row + ((y-yy) / m_lineHeight); - } + const wxDataViewTreeNode* node = GetTreeNodeByRow(row); + if (!node) + { + // not really correct... + return row + ((y-yy) / m_lineHeight); + } - wxDataViewItem item = node->GetItem(); + wxDataViewItem item = node->GetItem(); if (node && !node->HasChildren()) { @@ -2644,31 +2609,34 @@ int wxDataViewMainWindow::GetLineAt( unsigned int y ) const wxDELETE(node); } - unsigned int cols = GetOwner()->GetColumnCount(); - unsigned int col; - int height = m_lineHeight; - for (col = 0; col < cols; col++) - { + unsigned int cols = GetOwner()->GetColumnCount(); + unsigned int col; + int height = m_lineHeight; + for (col = 0; col < cols; col++) + { const wxDataViewColumn *column = GetOwner()->GetColumn(col); if (column->IsHidden()) continue; // skip it! - if ((col != 0) && model->IsContainer(item) && !model->HasContainerColumns(item)) + if ((col != 0) && + model->IsContainer(item) && + !model->HasContainerColumns(item)) continue; // skip it! - const wxDataViewRenderer *renderer = column->GetRenderer(); wxVariant value; model->GetValue( value, item, column->GetModelColumn() ); - wxDataViewRenderer *renderer2 = const_cast(renderer); - renderer2->SetValue( value ); + + wxDataViewRenderer *renderer = + const_cast(column->GetRenderer()); + renderer->SetValue( value ); height = wxMax( height, renderer->GetSize().y ); - } + } - yy += height; - if (y < yy) - return row; + yy += height; + if (y < yy) + return row; - row++; + row++; } } @@ -2703,14 +2671,17 @@ int wxDataViewMainWindow::GetLineHeight( unsigned int row ) const if (column->IsHidden()) continue; // skip it! - if ((col != 0) && model->IsContainer(item) && !model->HasContainerColumns(item)) + if ((col != 0) && + model->IsContainer(item) && + !model->HasContainerColumns(item)) continue; // skip it! - const wxDataViewRenderer *renderer = column->GetRenderer(); wxVariant value; model->GetValue( value, item, column->GetModelColumn() ); - wxDataViewRenderer *renderer2 = const_cast(renderer); - renderer2->SetValue( value ); + + wxDataViewRenderer *renderer = + const_cast(column->GetRenderer()); + renderer->SetValue( value ); height = wxMax( height, renderer->GetSize().y ); } @@ -2725,7 +2696,7 @@ int wxDataViewMainWindow::GetLineHeight( unsigned int row ) const class RowToItemJob: public DoJob { public: - RowToItemJob( unsigned int row , int current ) + RowToItemJob( unsigned int row , int current ) { this->row = row; this->current = current; } virtual ~RowToItemJob() {} @@ -2745,9 +2716,9 @@ public: } else { - // If the current has no child node, we can find the desired item of the row + // If the current has no child node, we can find the desired item of the row // number directly. - // This if can speed up finding in some case, and will has a very good effect + // This if can speed up finding in some case, and will has a very good effect // when it comes to list view if( node->GetNodes().GetCount() == 0) { @@ -2781,9 +2752,9 @@ private: wxDataViewItem wxDataViewMainWindow::GetItemByRow(unsigned int row) const { - if (!m_root) + if (IsVirtualList()) { - return wxDataViewItem( wxUIntToPtr(row) ); + return wxDataViewItem( wxUIntToPtr(row+1) ); } else { @@ -2823,9 +2794,9 @@ public: { parent = node; - // If the current node has no children, we can find the desired item of the + // If the current node has no children, we can find the desired item of the // row number directly. - // This if can speed up finding in some case, and will have a very good + // This if can speed up finding in some case, and will have a very good // effect for list views. if( node->GetNodes().GetCount() == 0) { @@ -2873,7 +2844,7 @@ wxDataViewTreeNode * wxDataViewMainWindow::GetTreeNodeByRow(unsigned int row) co return job.GetResult(); } -wxDataViewEvent wxDataViewMainWindow::SendExpanderEvent( wxEventType type, +wxDataViewEvent wxDataViewMainWindow::SendExpanderEvent( wxEventType type, const wxDataViewItem & item ) { wxWindow *parent = GetParent(); @@ -2905,20 +2876,42 @@ bool wxDataViewMainWindow::IsExpanded( unsigned int row ) const return node->IsOpen(); } +bool wxDataViewMainWindow::HasChildren( unsigned int row ) const +{ + if (IsVirtualList()) + return false; + + wxDataViewTreeNode * node = GetTreeNodeByRow(row); + if (!node) + return false; -void wxDataViewMainWindow::OnExpanding( unsigned int row ) + if (!node->HasChildren()) + { + delete node; + return false; + } + + return true; +} + +void wxDataViewMainWindow::Expand( unsigned int row ) { if (IsVirtualList()) return; wxDataViewTreeNode * node = GetTreeNodeByRow(row); - if( node != NULL ) + if (!node) + return; + + if (!node->HasChildren()) { - if( node->HasChildren()) - { - if( !node->IsOpen()) + delete node; + return; + } + + if (!node->IsOpen()) { - wxDataViewEvent e = + wxDataViewEvent e = SendExpanderEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING, node->GetItem()); // Check if the user prevent expanding @@ -2955,23 +2948,9 @@ void wxDataViewMainWindow::OnExpanding( unsigned int row ) // Send the expanded event SendExpanderEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDED,node->GetItem()); } - else - { -#if 0 - // Why should we select the next row here??? - SelectRow( row, false ); - SelectRow( row + 1, true ); - ChangeCurrentRow( row + 1 ); - SendSelectionChangedEvent( GetItemByRow(row+1)); -#endif - } - } - else - delete node; - } } -void wxDataViewMainWindow::OnCollapsing(unsigned int row) +void wxDataViewMainWindow::Collapse(unsigned int row) { if (IsVirtualList()) return; @@ -2979,16 +2958,16 @@ void wxDataViewMainWindow::OnCollapsing(unsigned int row) wxDataViewTreeNode *node = GetTreeNodeByRow(row); if (!node) return; - - if( !node->HasChildren()) + + if (!node->HasChildren()) { delete node; return; } - if( node->HasChildren() && node->IsOpen() ) + if (node->IsOpen()) { - wxDataViewEvent e = + wxDataViewEvent e = SendExpanderEvent(wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSING,node->GetItem()); if( e.GetSkipped() ) return; @@ -3023,7 +3002,7 @@ void wxDataViewMainWindow::OnCollapsing(unsigned int row) { // if there were no selected items below our node we still need to "fix" the // selection list to adjust for the changing of the row indices. - // We actually do the opposite of what we are doing in OnExpanding(). + // We actually do the opposite of what we are doing in Expand(). for(unsigned i=0; iGetItem()); } - else - { - node = node->GetParent(); - if( node != NULL ) - { - int parent = GetRowByItem( node->GetItem() ); - if( parent >= 0 ) - { - SelectRow( row, false); - SelectRow(parent , true ); - ChangeCurrentRow( parent ); - SendSelectionChangedEvent( node->GetItem() ); - } - } - } } wxDataViewTreeNode * wxDataViewMainWindow::FindNode( const wxDataViewItem & item ) @@ -3120,7 +3084,7 @@ wxDataViewTreeNode * wxDataViewMainWindow::FindNode( const wxDataViewItem & item return NULL; } -void wxDataViewMainWindow::HitTest( const wxPoint & point, wxDataViewItem & item, +void wxDataViewMainWindow::HitTest( const wxPoint & point, wxDataViewItem & item, wxDataViewColumn* &column ) { wxDataViewColumn *col = NULL; @@ -3145,37 +3109,77 @@ void wxDataViewMainWindow::HitTest( const wxPoint & point, wxDataViewItem & item item = GetItemByRow( GetLineAt( y ) ); } -wxRect wxDataViewMainWindow::GetItemRect( const wxDataViewItem & item, +wxRect wxDataViewMainWindow::GetItemRect( const wxDataViewItem & item, const wxDataViewColumn* column ) { + int xpos = 0; + int width = 0; + + unsigned int cols = GetOwner()->GetColumnCount(); + // If column is null the loop will compute the combined width of all columns. + // Otherwise, it will compute the x position of the column we are looking for. + for (unsigned int i = 0; i < cols; i++) + { + wxDataViewColumn* col = GetOwner()->GetColumnAt( i ); + + if (col == column) + break; + + if (col->IsHidden()) + continue; // skip it! + + xpos += col->GetWidth(); + width += col->GetWidth(); + } + + if(column != 0) + { + // If we have a column, we need can get its width directly. + if(column->IsHidden()) + width = 0; + else + width = column->GetWidth(); + + } + else + { + // If we have no column, we reset the x position back to zero. + xpos = 0; + } + + // we have to take an expander column into account and compute its indentation + // to get the correct x position where the actual text is + int indent = 0; int row = GetRowByItem(item); - int y = GetLineStart( row ); - int h = GetLineHeight( m_lineHeight ); - int x = 0; - wxDataViewColumn *col = NULL; - for( int i = 0, cols = GetOwner()->GetColumnCount(); i < cols; i ++ ) + if (!IsVirtualList() && (column == 0 || GetOwner()->GetExpanderColumn() == column) ) { - col = GetOwner()->GetColumnAt( i ); - x += col->GetWidth(); - if( GetOwner()->GetColumnAt(i+1) == column ) - break; + wxDataViewTreeNode* node = GetTreeNodeByRow(row); + indent = GetOwner()->GetIndent() * node->GetIndentLevel(); + indent = indent + m_lineHeight; // use m_lineHeight as the width of the expander + + if(!node->HasChildren()) + delete node; } - int w = col->GetWidth(); - m_owner->CalcScrolledPosition( x, y, &x, &y ); - return wxRect(x, y, w, h); + + wxRect itemRect( xpos + indent, + GetLineStart( row ), + width - indent, + GetLineHeight( row ) ); + + GetOwner()->CalcScrolledPosition( itemRect.x, itemRect.y, + &itemRect.x, &itemRect.y ); + + return itemRect; } int wxDataViewMainWindow::RecalculateCount() { - if (!m_root) + if (IsVirtualList()) { - wxDataViewIndexListModel *list_model = - (wxDataViewIndexListModel*) GetOwner()->GetModel(); -#ifndef __WXMAC__ - return list_model->GetLastIndex() + 1; -#else - return list_model->GetLastIndex() - 1; -#endif + wxDataViewVirtualListModel *list_model = + (wxDataViewVirtualListModel*) GetOwner()->GetModel(); + + return list_model->GetCount(); } else { @@ -3240,9 +3244,9 @@ int wxDataViewMainWindow::GetRowByItem(const wxDataViewItem & item) const if( model == NULL ) return -1; - if (!m_root) + if (IsVirtualList()) { - return wxPtrToUInt( item.GetID() ); + return wxPtrToUInt( item.GetID() ) -1; } else { @@ -3269,7 +3273,7 @@ int wxDataViewMainWindow::GetRowByItem(const wxDataViewItem & item) const } } -static void BuildTreeHelper( wxDataViewModel * model, wxDataViewItem & item, +static void BuildTreeHelper( wxDataViewModel * model, wxDataViewItem & item, wxDataViewTreeNode * node) { if( !model->IsContainer( item ) ) @@ -3357,16 +3361,15 @@ void wxDataViewMainWindow::OnChar( wxKeyEvent &event ) // don't use m_linesPerPage directly as it might not be computed yet const int pageSize = GetCountPerPage(); - wxCHECK_RET( pageSize, _T("should have non zero page size") ); + wxCHECK_RET( pageSize, wxT("should have non zero page size") ); switch ( event.GetKeyCode() ) { case WXK_RETURN: - { - if (m_currentRow >= 0) { wxWindow *parent = GetParent(); - wxDataViewEvent le(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, parent->GetId()); + wxDataViewEvent le(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, + parent->GetId()); le.SetItem( GetItemByRow(m_currentRow) ); le.SetEventObject(parent); le.SetModel(GetOwner()->GetModel()); @@ -3374,7 +3377,7 @@ void wxDataViewMainWindow::OnChar( wxKeyEvent &event ) parent->GetEventHandler()->ProcessEvent(le); } break; - } + case WXK_UP: if ( m_currentRow > 0 ) OnArrowChar( m_currentRow - 1, event ); @@ -3386,16 +3389,62 @@ void wxDataViewMainWindow::OnChar( wxKeyEvent &event ) break; // Add the process for tree expanding/collapsing case WXK_LEFT: - OnCollapsing(m_currentRow); - break; - case WXK_RIGHT: - OnExpanding( m_currentRow); - break; + { + if (IsVirtualList()) + break; + + wxDataViewTreeNode* node = GetTreeNodeByRow(m_currentRow); + if (!node) + break; + + if (node->HasChildren() && node->IsOpen()) + { + Collapse(m_currentRow); + } + else // if the node is already closed we move the selection to its parent + { + wxDataViewTreeNode *parent_node = node->GetParent(); + + if(!node->HasChildren()) + delete node; + + if (parent_node) + { + int parent = GetRowByItem( parent_node->GetItem() ); + if ( parent >= 0 ) + { + unsigned int row = m_currentRow; + SelectRow( row, false); + SelectRow( parent, true ); + ChangeCurrentRow( parent ); + GetOwner()->EnsureVisible( parent, -1 ); + SendSelectionChangedEvent( parent_node->GetItem() ); + } + } + } + break; + } + case WXK_RIGHT: + { + if (!IsExpanded( m_currentRow )) + Expand( m_currentRow ); + else + { + unsigned int row = m_currentRow; + SelectRow( row, false ); + SelectRow( row + 1, true ); + ChangeCurrentRow( row + 1 ); + GetOwner()->EnsureVisible( row + 1, -1 ); + SendSelectionChangedEvent( GetItemByRow(row+1) ); + } + break; + } case WXK_END: + { if (!IsEmpty()) OnArrowChar( GetRowCount() - 1, event ); break; - + } case WXK_HOME: if (!IsEmpty()) OnArrowChar( 0, event ); @@ -3424,6 +3473,16 @@ void wxDataViewMainWindow::OnChar( wxKeyEvent &event ) } break; + case WXK_F2: + { + if(m_selection.size() == 1) + { + // TODO: we need to revise that when we have a concept for a 'current column' + GetOwner()->StartEditor(GetItemByRow(m_selection[0]), 0); + } + } + break; + default: event.Skip(); } @@ -3535,7 +3594,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) if (event.LeftIsDown()) { - m_owner->CalcUnscrolledPosition( m_dragStart.x, m_dragStart.y, + m_owner->CalcUnscrolledPosition( m_dragStart.x, m_dragStart.y, &m_dragStart.x, &m_dragStart.y ); unsigned int drag_item_row = GetLineAt( m_dragStart.y ); wxDataViewItem item = GetItemByRow( drag_item_row ); @@ -3630,7 +3689,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) SendSelectionChangedEvent( GetItemByRow(m_lineSelectSingleOnUp) ); } - // If the user click the expander, we do not do editing even if the column + // If the user click the expander, we do not do editing even if the column // with expander are editable if (m_lastOnSame && !ignore_other_columns) { @@ -3667,7 +3726,9 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) SelectRow(m_currentRow,true); SendSelectionChangedEvent(GetItemByRow( m_currentRow ) ); } - + } + else if (event.RightUp()) + { wxVariant value; model->GetValue( value, item, col->GetModelColumn() ); wxWindow *parent = GetParent(); @@ -3686,13 +3747,13 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) { wxDataViewTreeNode* node = GetTreeNodeByRow(current); - // hoverOverExpander being true tells us that our node must be + // hoverOverExpander being true tells us that our node must be // valid and have children. // So we don't need any extra checks. if( node->IsOpen() ) - OnCollapsing(current); + Collapse(current); else - OnExpanding(current); + Expand(current); } else if ((event.LeftDown() || simulateClick) && !hoverOverExpander) { @@ -3747,7 +3808,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) else // !ctrl, !shift { // test in the enclosing if should make it impossible - wxFAIL_MSG( _T("how did we get here?") ); + wxFAIL_MSG( wxT("how did we get here?") ); } } @@ -3771,7 +3832,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) cell->SetValue( value ); wxRect cell_rect( xpos, GetLineStart( current ), col->GetWidth(), GetLineHeight( current ) ); - /* ignore ret */ cell->LeftClick( event.GetPosition(), cell_rect, + /* ignore ret */ cell->LeftClick( event.GetPosition(), cell_rect, model, item, col->GetModelColumn()); } } @@ -4286,13 +4347,13 @@ void wxDataViewCtrl::EnsureVisible( const wxDataViewItem & item, const wxDataVie } -void wxDataViewCtrl::HitTest( const wxPoint & point, wxDataViewItem & item, +void wxDataViewCtrl::HitTest( const wxPoint & point, wxDataViewItem & item, wxDataViewColumn* &column ) const { m_clientArea->HitTest(point, item, column); } -wxRect wxDataViewCtrl::GetItemRect( const wxDataViewItem & item, +wxRect wxDataViewCtrl::GetItemRect( const wxDataViewItem & item, const wxDataViewColumn* column ) const { return m_clientArea->GetItemRect(item, column); @@ -4318,7 +4379,6 @@ void wxDataViewCtrl::Expand( const wxDataViewItem & item ) void wxDataViewCtrl::Collapse( const wxDataViewItem & item ) { int row = m_clientArea->GetRowByItem( item ); - wxPrintf( "row %d\n", row ); if (row != -1) m_clientArea->Collapse(row); } @@ -4331,8 +4391,17 @@ bool wxDataViewCtrl::IsExpanded( const wxDataViewItem & item ) const return false; } -#endif - // !wxUSE_GENERICDATAVIEWCTRL +void wxDataViewCtrl::StartEditor( const wxDataViewItem & item, unsigned int column ) +{ + wxDataViewColumn* col = GetColumn( column ); + if (!col) + return; -#endif - // wxUSE_DATAVIEWCTRL + wxRect itemRect = GetItemRect(item, col); + wxDataViewRenderer* renderer = col->GetRenderer(); + renderer->StartEditing(item, itemRect); +} + +#endif // !wxUSE_GENERICDATAVIEWCTRL + +#endif // wxUSE_DATAVIEWCTRL