Merge branch 'dvc-virtual-has-value'

Allow overriding wxDataViewModel::HasValue() to specify which cells
should, and should not, show anything.

Closes https://github.com/wxWidgets/wxWidgets/pull/1792

Closes #18724.
This commit is contained in:
Vadim Zeitlin
2020-05-02 18:10:54 +02:00
8 changed files with 258 additions and 91 deletions

View File

@@ -170,6 +170,9 @@ private:
enum Lang { Lang_English, Lang_French };
void FillIndexList(Lang lang);
// HasValue page.
void OnHasValueValueChanged(wxDataViewEvent& event);
wxNotebook* m_notebook;
@@ -182,6 +185,7 @@ private:
Page_TreeStore,
Page_VarHeight,
Page_IndexList,
Page_HasValue,
Page_Max
};
@@ -713,6 +717,16 @@ MyFrame::MyFrame(wxFrame *frame, const wxString &title, int x, int y, int w, int
sixthPanelSz->Add(button_sizer6);
sixthPanel->SetSizerAndFit(sixthPanelSz);
// page showing that some columns don't have values for some items
// ---------------------------------------------------------------
wxPanel *seventhPanel = new wxPanel( m_notebook, wxID_ANY );
BuildDataViewCtrl(seventhPanel, Page_HasValue);
wxSizer *seventhPanelSz = new wxBoxSizer( wxVERTICAL );
seventhPanelSz->Add(m_ctrl[Page_HasValue], 1, wxGROW|wxALL, 5);
seventhPanel->SetSizerAndFit(seventhPanelSz);
// complete GUI
// ------------
@@ -723,6 +737,7 @@ MyFrame::MyFrame(wxFrame *frame, const wxString &title, int x, int y, int w, int
m_notebook->AddPage(fourthPanel, "wxDataViewTreeCtrl");
m_notebook->AddPage(fifthPanel, "Variable line height");
m_notebook->AddPage(sixthPanel, "MyIndexListModel");
m_notebook->AddPage(seventhPanel, "MyDataViewHasValue");
wxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
@@ -987,7 +1002,50 @@ void MyFrame::BuildDataViewCtrl(wxPanel* parent, unsigned int nPanel, unsigned l
this);
}
break;
case Page_HasValue:
{
wxDataViewListCtrl* lc =
new wxDataViewListCtrl( parent, wxID_ANY, wxDefaultPosition,
wxDefaultSize, style );
m_ctrl[Page_HasValue] = lc;
MyListStoreDerivedModel* page7_model = new MyListStoreHasValueModel();
lc->AssociateModel(page7_model);
page7_model->DecRef();
lc->AppendToggleColumn( "Toggle" );
// We're not limited to convenience column-appending functions, it
// can also be done fully manually, which allows us to customize
// the renderer being used.
wxDataViewToggleRenderer* const rendererRadio =
new wxDataViewToggleRenderer("bool", wxDATAVIEW_CELL_ACTIVATABLE);
rendererRadio->ShowAsRadio();
wxDataViewColumn* const colRadio =
new wxDataViewColumn("Radio", rendererRadio, 1);
lc->AppendColumn(colRadio, "bool");
lc->AppendTextColumn( "Text" );
lc->AppendProgressColumn( "Progress" )->SetMinWidth(FromDIP(100));
wxVector<wxVariant> data;
for (unsigned int i=0; i<10; i++)
{
data.clear();
data.push_back( (i%3) == 0 );
data.push_back( i == 7 ); // select a single (random) radio item
data.push_back( wxString::Format("row %d", i) );
data.push_back( long(5*i) );
lc->AppendItem( data );
}
lc->Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, &MyFrame::OnHasValueValueChanged, this);
}
break;
}
}
@@ -1717,3 +1775,45 @@ void MyFrame::OnIndexListSelectionChanged(wxDataViewEvent& event)
wxLogMessage("Selected week day: %s", weekday);
}
// ----------------------------------------------------------------------------
// MyFrame - event handlers for the HasValue (wxDataViewListCtrl) page
// ----------------------------------------------------------------------------
void MyFrame::OnHasValueValueChanged(wxDataViewEvent& event)
{
// Ignore changes coming from our own SetToggleValue() calls below.
if ( m_eventFromProgram )
{
m_eventFromProgram = false;
return;
}
wxDataViewListCtrl* const lc = static_cast<wxDataViewListCtrl*>(m_ctrl[Page_HasValue]);
const int columnToggle = 1;
// Handle selecting a radio button by unselecting all the other ones.
if ( event.GetColumn() == columnToggle )
{
const int rowChanged = lc->ItemToRow(event.GetItem());
if ( lc->GetToggleValue(rowChanged, columnToggle) )
{
for ( int row = 0; row < lc->GetItemCount(); ++row )
{
if ( row != rowChanged )
{
m_eventFromProgram = true;
lc->SetToggleValue(false, row, columnToggle);
}
}
}
else // The item was cleared.
{
// Explicitly check it back, we want to always have exactly one
// checked radio item in this column.
m_eventFromProgram = true;
lc->SetToggleValue(true, rowChanged, columnToggle);
}
}
}

View File

@@ -626,3 +626,15 @@ bool MyListStoreDerivedModel::IsEnabledByRow(unsigned int row, unsigned int col)
// disabled the last two checkboxes
return !(col == 0 && 8 <= row && row <= 9);
}
// ----------------------------------------------------------------------------
// MyListStoreHasValueModel
// ----------------------------------------------------------------------------
bool MyListStoreHasValueModel::HasValue(const wxDataViewItem &item, unsigned int col) const
{
unsigned int row = GetRow( item );
// the diagonal entries don't have values. This is just a silly example to demonstrate the
// usage of overriding HasValue to specify that some columns don't have values for some items
return row != col;
}

View File

@@ -266,6 +266,16 @@ public:
virtual bool IsEnabledByRow(unsigned int row, unsigned int col) const wxOVERRIDE;
};
// ----------------------------------------------------------------------------
// MyListStoreHasValueModel
// ----------------------------------------------------------------------------
class MyListStoreHasValueModel : public MyListStoreDerivedModel
{
public:
virtual bool HasValue(const wxDataViewItem &item, unsigned int col) const wxOVERRIDE;
};
// ----------------------------------------------------------------------------
// MyIndexListModel
// ----------------------------------------------------------------------------