Page 2 of 2
Re: wxDataViewListCtrl and wxVariant
Posted: Thu Feb 07, 2019 9:07 am
by refaelsh
doublemax wrote:When does it crash? Directly at the start?
I tested with this code and it worked fine:
Code: Select all
#include <wx/wxprec.h>
#include <wx/dataview.h>
#include <wx/wx.h>
class MyCustomRenderer : public wxDataViewCustomRenderer
{
public:
MyCustomRenderer(const wxString &varianttype = "string", wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT, int align = wxDVR_DEFAULT_ALIGNMENT )
:wxDataViewCustomRenderer(varianttype, mode, align )
{
};
bool SetValue(const wxVariant& value)
{
if (value.IsNull() == true)
{
return false;
}
return true;
}
bool GetValue(wxVariant& value) const
{
return true;
}
wxSize GetSize() const
{
return wxSize(42, 42);
}
bool Render(wxRect cell, wxDC* dc, int state)
{
// Do lots of stuff here ...
return true;
}
};
class MyApp : public wxApp
{
public:
virtual bool OnInit();
};
class MyFrame : public wxFrame
{
public:
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
};
wxIMPLEMENT_APP(MyApp);
bool MyApp::OnInit()
{
MyFrame* frame = new MyFrame("Hello World", wxPoint(50, 50), wxSize(450, 340));
frame->Show(true);
return true;
}
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
: wxFrame(NULL, wxID_ANY, title, pos, size)
{
wxDataViewListCtrl* data_view_list_ctrl = new wxDataViewListCtrl(this, wxID_ANY, wxDefaultPosition, wxSize(-1, -1), wxDV_ROW_LINES | wxDV_SINGLE);
MyCustomRenderer* custom_renderer = new MyCustomRenderer();
wxDataViewColumn* data_view_column = new wxDataViewColumn("Some title goes here", custom_renderer,0);
data_view_list_ctrl->AppendColumn(data_view_column);
data_view_list_ctrl->AppendTextColumn("Some cool column title goes here");
wxVector<wxVariant> data;
data.push_back(wxVariant(42));
data.push_back(wxVariant("row 1"));
data_view_list_ctrl->AppendItem(data);
data.clear();
data.push_back(wxVariant(43));
data.push_back(wxVariant("row 3"));
data_view_list_ctrl->AppendItem(data);
}
In `MyCustomRenderer::SetValue()`, the statement `value.IsNull()` is always true. In the original code (I simplified it for the mcve), this part looked like this:
Code: Select all
bool MyCustomRenderer::SetValue(const wxVariant& value)
{
MyClass* temp = static_cast<MyClass*>(value.GetWxObjectPtr());
m_my_class = MyClass(temp->m_nodes, m_radius);
return true;
}
It would crash on the first line `MyClass* temp = static_cast<MyClass*>(value.GetWxObjectPtr());`.
Re: wxDataViewListCtrl and wxVariant
Posted: Thu Feb 07, 2019 9:39 am
by doublemax
I don't have a working sample that uses a wxObject type (do you actually need this?).
But here's one that uses void* as data, maybe this helps:
Code: Select all
#include <wx/wxprec.h>
#include <wx/dataview.h>
#include <wx/wx.h>
class MyCustomRenderer : public wxDataViewCustomRenderer
{
public:
MyCustomRenderer(const wxString &varianttype = "void*", wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT, int align = wxDVR_DEFAULT_ALIGNMENT )
:wxDataViewCustomRenderer(varianttype, mode, align )
{
};
bool SetValue(const wxVariant& value)
{
m_value = static_cast<void *>(value.GetVoidPtr());
wxLogDebug("temp=%p", m_value );
return true;
}
bool GetValue(wxVariant& value) const
{
value = (void*)NULL;
return true;
}
wxSize GetSize() const
{
return wxSize(42, 42);
}
bool Render(wxRect rect, wxDC* dc, int state)
{
dc->SetBrush( *wxLIGHT_GREY_BRUSH );
dc->SetPen( *wxTRANSPARENT_PEN );
rect.Deflate(2);
dc->DrawRoundedRectangle( rect, 5 );
wxString s;
s.Printf("%p", m_value );
RenderText(s,
0, // no offset
wxRect(dc->GetTextExtent(s)).CentreIn(rect),
dc,
state);
return true;
}
protected:
void *m_value;
};
class MyApp : public wxApp
{
public:
virtual bool OnInit();
};
class MyFrame : public wxFrame
{
public:
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
};
wxIMPLEMENT_APP(MyApp);
bool MyApp::OnInit()
{
MyFrame* frame = new MyFrame("Hello World", wxPoint(50, 50), wxSize(450, 340));
frame->Show(true);
return true;
}
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
: wxFrame(NULL, wxID_ANY, title, pos, size)
{
wxDataViewListCtrl* data_view_list_ctrl = new wxDataViewListCtrl(this, wxID_ANY, wxDefaultPosition, wxSize(-1, -1), wxDV_ROW_LINES | wxDV_SINGLE);
MyCustomRenderer* custom_renderer = new MyCustomRenderer();
wxDataViewColumn* data_view_column = new wxDataViewColumn("Some title goes here", custom_renderer,0);
data_view_list_ctrl->AppendColumn(data_view_column);
data_view_list_ctrl->AppendTextColumn("Some cool column title goes here");
wxVector<wxVariant> data;
data.push_back(wxVariant((void*)0x12345678));
data.push_back(wxVariant("row 1"));
data_view_list_ctrl->AppendItem(data);
data.clear();
data.push_back(wxVariant((void*)0x87654321));
data.push_back(wxVariant("row 3"));
data_view_list_ctrl->AppendItem(data);
}
Re: wxDataViewListCtrl and wxVariant
Posted: Thu Feb 07, 2019 2:40 pm
by refaelsh
doublemax wrote:I don't have a working sample that uses a wxObject type (do you actually need this?).
But here's one that uses void* as data, maybe this helps:
Code: Select all
#include <wx/wxprec.h>
#include <wx/dataview.h>
#include <wx/wx.h>
class MyCustomRenderer : public wxDataViewCustomRenderer
{
public:
MyCustomRenderer(const wxString &varianttype = "void*", wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT, int align = wxDVR_DEFAULT_ALIGNMENT )
:wxDataViewCustomRenderer(varianttype, mode, align )
{
};
bool SetValue(const wxVariant& value)
{
m_value = static_cast<void *>(value.GetVoidPtr());
wxLogDebug("temp=%p", m_value );
return true;
}
bool GetValue(wxVariant& value) const
{
value = (void*)NULL;
return true;
}
wxSize GetSize() const
{
return wxSize(42, 42);
}
bool Render(wxRect rect, wxDC* dc, int state)
{
dc->SetBrush( *wxLIGHT_GREY_BRUSH );
dc->SetPen( *wxTRANSPARENT_PEN );
rect.Deflate(2);
dc->DrawRoundedRectangle( rect, 5 );
wxString s;
s.Printf("%p", m_value );
RenderText(s,
0, // no offset
wxRect(dc->GetTextExtent(s)).CentreIn(rect),
dc,
state);
return true;
}
protected:
void *m_value;
};
class MyApp : public wxApp
{
public:
virtual bool OnInit();
};
class MyFrame : public wxFrame
{
public:
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
};
wxIMPLEMENT_APP(MyApp);
bool MyApp::OnInit()
{
MyFrame* frame = new MyFrame("Hello World", wxPoint(50, 50), wxSize(450, 340));
frame->Show(true);
return true;
}
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
: wxFrame(NULL, wxID_ANY, title, pos, size)
{
wxDataViewListCtrl* data_view_list_ctrl = new wxDataViewListCtrl(this, wxID_ANY, wxDefaultPosition, wxSize(-1, -1), wxDV_ROW_LINES | wxDV_SINGLE);
MyCustomRenderer* custom_renderer = new MyCustomRenderer();
wxDataViewColumn* data_view_column = new wxDataViewColumn("Some title goes here", custom_renderer,0);
data_view_list_ctrl->AppendColumn(data_view_column);
data_view_list_ctrl->AppendTextColumn("Some cool column title goes here");
wxVector<wxVariant> data;
data.push_back(wxVariant((void*)0x12345678));
data.push_back(wxVariant("row 1"));
data_view_list_ctrl->AppendItem(data);
data.clear();
data.push_back(wxVariant((void*)0x87654321));
data.push_back(wxVariant("row 3"));
data_view_list_ctrl->AppendItem(data);
}
That worked!
I've made the following changes:
Code: Select all
MyCustomRenderer::MyCustomRenderer() : wxDataViewCustomRenderer("void*", wxDATAVIEW_CELL_INERT, wxALIGN_CENTER)
And this:
Code: Select all
item.push_back(wxVariant(static_cast<void*>(/*Raw pointer to an instance of MyClass*/)));
And now it works in version 3.1.2.
Thank you and every other responder very much!