Add wxDataViewToggleRenderer::ShowAsRadio()
This allows showing radio buttons in wxDataViewCtrl easily and natively. Notice that this approach, adding an extra function to the existing renderer class instead of creating some new wxDataViewRadioRenderer (see https://github.com/wxWidgets/wxWidgets/pull/809), was finally chosen because it is simpler to implement and, more importantly, because it will be more natural to generalize if/when we also add a 3-state check/radio renderer. Closes https://github.com/wxWidgets/wxWidgets/pull/853
This commit is contained in:
@@ -94,6 +94,7 @@ All:
|
||||
|
||||
All (GUI):
|
||||
|
||||
- Add wxDataViewToggleRenderer::ShowAsRadio().
|
||||
- Improve stock items consistency and aesthetics (dhowland).
|
||||
- Fix bug with missing items in overflowing AUI toolbar (Maarten Bent).
|
||||
- Revert to left-aligning wxSpinCtrl contents by default.
|
||||
|
@@ -132,6 +132,8 @@ public:
|
||||
wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT,
|
||||
int align = wxDVR_DEFAULT_ALIGNMENT );
|
||||
|
||||
void ShowAsRadio() { m_radio = true; }
|
||||
|
||||
virtual bool SetValue( const wxVariant &value ) wxOVERRIDE;
|
||||
virtual bool GetValue( wxVariant &value ) const wxOVERRIDE;
|
||||
#if wxUSE_ACCESSIBILITY
|
||||
@@ -149,6 +151,7 @@ public:
|
||||
const wxMouseEvent *mouseEvent) wxOVERRIDE;
|
||||
private:
|
||||
bool m_toggle;
|
||||
bool m_radio;
|
||||
|
||||
protected:
|
||||
wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxDataViewToggleRenderer);
|
||||
|
@@ -107,6 +107,8 @@ public:
|
||||
wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT,
|
||||
int align = wxDVR_DEFAULT_ALIGNMENT );
|
||||
|
||||
void ShowAsRadio();
|
||||
|
||||
bool SetValue( const wxVariant &value ) wxOVERRIDE;
|
||||
bool GetValue( wxVariant &value ) const wxOVERRIDE;
|
||||
|
||||
|
@@ -198,6 +198,8 @@ public:
|
||||
wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT,
|
||||
int align = wxDVR_DEFAULT_ALIGNMENT);
|
||||
|
||||
void ShowAsRadio();
|
||||
|
||||
virtual bool MacRender();
|
||||
|
||||
virtual void OSXOnCellChanged(NSObject *value,
|
||||
|
@@ -2272,6 +2272,9 @@ public:
|
||||
|
||||
This class is used by wxDataViewCtrl to render toggle controls.
|
||||
|
||||
Note that "toggles" can be represented either by check boxes (default) or
|
||||
radio buttons.
|
||||
|
||||
@see wxDataViewCheckIconTextRenderer
|
||||
@library{wxadv}
|
||||
@category{dvc}
|
||||
@@ -2292,6 +2295,24 @@ public:
|
||||
wxDataViewToggleRenderer(const wxString& varianttype = GetDefaultType(),
|
||||
wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT,
|
||||
int align = wxDVR_DEFAULT_ALIGNMENT);
|
||||
|
||||
/**
|
||||
Switch to using radiobutton-like appearance instead of the default
|
||||
checkbox-like one.
|
||||
|
||||
By default, this renderer uses checkboxes to represent the boolean
|
||||
values, but using this method its appearance can be changed to use
|
||||
radio buttons instead.
|
||||
|
||||
Notice that only the appearance is changed, the cells don't really
|
||||
start behaving as radio buttons after a call to ShowAsRadio(), i.e. the
|
||||
application code also needs to react to selecting one of the cells
|
||||
shown by this renderer and clearing all the other ones in the same row
|
||||
or column to actually implement radio button-like behaviour.
|
||||
|
||||
@since 3.1.2
|
||||
*/
|
||||
void ShowAsRadio();
|
||||
};
|
||||
|
||||
|
||||
|
@@ -108,6 +108,10 @@ private:
|
||||
|
||||
void OnPrependList(wxCommandEvent& event);
|
||||
void OnDeleteList(wxCommandEvent& event);
|
||||
|
||||
// Third (wxDataViewListCtrl) page.
|
||||
void OnListValueChanged(wxDataViewEvent& event);
|
||||
|
||||
// Fourth page.
|
||||
void OnDeleteTreeItem(wxCommandEvent& event);
|
||||
void OnDeleteAllTreeItems(wxCommandEvent& event);
|
||||
@@ -176,6 +180,9 @@ private:
|
||||
wxLog *m_logOld;
|
||||
|
||||
private:
|
||||
// Flag used by OnListValueChanged(), see there.
|
||||
bool m_eventFromProgram;
|
||||
|
||||
wxDECLARE_EVENT_TABLE();
|
||||
};
|
||||
|
||||
@@ -450,6 +457,8 @@ MyFrame::MyFrame(wxFrame *frame, const wxString &title, int x, int y, int w, int
|
||||
m_ctrl[2] = NULL;
|
||||
m_ctrl[3] = NULL;
|
||||
|
||||
m_eventFromProgram = false;
|
||||
|
||||
SetIcon(wxICON(sample));
|
||||
|
||||
|
||||
@@ -759,6 +768,17 @@ void MyFrame::BuildDataViewCtrl(wxPanel* parent, unsigned int nPanel, unsigned l
|
||||
page2_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" );
|
||||
|
||||
@@ -767,11 +787,14 @@ void MyFrame::BuildDataViewCtrl(wxPanel* parent, unsigned int nPanel, unsigned l
|
||||
{
|
||||
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::OnListValueChanged, this);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1390,6 +1413,48 @@ void MyFrame::OnShowAttributes(wxCommandEvent& WXUNUSED(event))
|
||||
m_attributes->SetHidden(false);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// MyFrame - event handlers for the third (wxDataViewListCtrl) page
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void MyFrame::OnListValueChanged(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[2]);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// MyFrame - event handlers for the fourth page
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@@ -1260,6 +1260,7 @@ wxDataViewToggleRenderer::wxDataViewToggleRenderer( const wxString &varianttype,
|
||||
wxDataViewRenderer( varianttype, mode, align )
|
||||
{
|
||||
m_toggle = false;
|
||||
m_radio = false;
|
||||
}
|
||||
|
||||
bool wxDataViewToggleRenderer::SetValue( const wxVariant &value )
|
||||
@@ -1301,11 +1302,12 @@ bool wxDataViewToggleRenderer::Render( wxRect cell, wxDC *dc, int WXUNUSED(state
|
||||
size.IncTo(GetSize());
|
||||
cell.SetSize(size);
|
||||
|
||||
wxRendererNative::Get().DrawCheckBox(
|
||||
GetOwner()->GetOwner(),
|
||||
*dc,
|
||||
cell,
|
||||
flags );
|
||||
wxRendererNative& renderer = wxRendererNative::Get();
|
||||
wxWindow* const win = GetOwner()->GetOwner();
|
||||
if ( m_radio )
|
||||
renderer.DrawRadioBitmap(win, *dc, cell, flags);
|
||||
else
|
||||
renderer.DrawCheckBox(win, *dc, cell, flags);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@@ -2539,6 +2539,11 @@ wxDataViewToggleRenderer::wxDataViewToggleRenderer( const wxString &varianttype,
|
||||
SetAlignment(align);
|
||||
}
|
||||
|
||||
void wxDataViewToggleRenderer::ShowAsRadio()
|
||||
{
|
||||
gtk_cell_renderer_toggle_set_radio(GTK_CELL_RENDERER_TOGGLE(m_renderer), TRUE);
|
||||
}
|
||||
|
||||
bool wxDataViewToggleRenderer::SetValue( const wxVariant &value )
|
||||
{
|
||||
bool tmp = value;
|
||||
|
@@ -3326,6 +3326,11 @@ wxDataViewToggleRenderer::wxDataViewToggleRenderer(const wxString& varianttype,
|
||||
[cell release];
|
||||
}
|
||||
|
||||
void wxDataViewToggleRenderer::ShowAsRadio()
|
||||
{
|
||||
[GetNativeData()->GetItemCell() setButtonType:NSRadioButton];
|
||||
}
|
||||
|
||||
bool wxDataViewToggleRenderer::MacRender()
|
||||
{
|
||||
[GetNativeData()->GetItemCell() setIntValue:GetValue().GetLong()];
|
||||
|
Reference in New Issue
Block a user