Add support for custom radio button controls in wxFileDialog
Update the dialogs sample to show using them too.
This commit is contained in:
parent
bf5ddc200b
commit
07d7dd19f8
@ -15,6 +15,7 @@
|
||||
class wxFileDialogCustomControlImpl;
|
||||
class wxFileDialogButtonImpl;
|
||||
class wxFileDialogCheckBoxImpl;
|
||||
class wxFileDialogRadioButtonImpl;
|
||||
class wxFileDialogTextCtrlImpl;
|
||||
class wxFileDialogStaticTextImpl;
|
||||
class wxFileDialogCustomizeImpl;
|
||||
@ -90,6 +91,25 @@ private:
|
||||
wxDECLARE_NO_COPY_CLASS(wxFileDialogCheckBox);
|
||||
};
|
||||
|
||||
// A class representing a custom radio button.
|
||||
class WXDLLIMPEXP_CORE wxFileDialogRadioButton : public wxFileDialogCustomControl
|
||||
{
|
||||
public:
|
||||
bool GetValue() const;
|
||||
void SetValue(bool value);
|
||||
|
||||
// Ctor is only used by wxWidgets itself.
|
||||
explicit wxFileDialogRadioButton(wxFileDialogRadioButtonImpl* impl);
|
||||
|
||||
protected:
|
||||
virtual bool OnDynamicBind(wxDynamicEventTableEntry& entry) wxOVERRIDE;
|
||||
|
||||
private:
|
||||
wxFileDialogRadioButtonImpl* GetImpl() const;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(wxFileDialogRadioButton);
|
||||
};
|
||||
|
||||
// A class representing a custom text control.
|
||||
class WXDLLIMPEXP_CORE wxFileDialogTextCtrl : public wxFileDialogCustomControl
|
||||
{
|
||||
@ -130,6 +150,7 @@ class WXDLLIMPEXP_CORE wxFileDialogCustomize
|
||||
public:
|
||||
wxFileDialogButton* AddButton(const wxString& label);
|
||||
wxFileDialogCheckBox* AddCheckBox(const wxString& label);
|
||||
wxFileDialogRadioButton* AddRadioButton(const wxString& label);
|
||||
wxFileDialogTextCtrl* AddTextCtrl(const wxString& label = wxString());
|
||||
wxFileDialogStaticText* AddStaticText(const wxString& label);
|
||||
|
||||
|
@ -38,6 +38,13 @@ public:
|
||||
virtual void SetValue(bool value) = 0;
|
||||
};
|
||||
|
||||
class wxFileDialogRadioButtonImpl : public wxFileDialogCustomControlImpl
|
||||
{
|
||||
public:
|
||||
virtual bool GetValue() = 0;
|
||||
virtual void SetValue(bool value) = 0;
|
||||
};
|
||||
|
||||
class wxFileDialogTextCtrlImpl : public wxFileDialogCustomControlImpl
|
||||
{
|
||||
public:
|
||||
@ -60,6 +67,7 @@ class wxFileDialogCustomizeImpl
|
||||
public:
|
||||
virtual wxFileDialogButtonImpl* AddButton(const wxString& label) = 0;
|
||||
virtual wxFileDialogCheckBoxImpl* AddCheckBox(const wxString& label) = 0;
|
||||
virtual wxFileDialogRadioButtonImpl* AddRadioButton(const wxString& label) = 0;
|
||||
virtual wxFileDialogTextCtrlImpl* AddTextCtrl(const wxString& label) = 0;
|
||||
virtual wxFileDialogStaticTextImpl* AddStaticText(const wxString& label) = 0;
|
||||
|
||||
|
@ -1605,7 +1605,8 @@ public:
|
||||
MyExtraPanel(wxWindow *parent);
|
||||
wxString GetInfo() const
|
||||
{
|
||||
return wxString::Format("checkbox=%d, text=\"%s\"", m_checked, m_str);
|
||||
return wxString::Format("paper=%s, enabled=%d, text=\"%s\"",
|
||||
m_paperSize, m_checked, m_str);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -1615,6 +1616,16 @@ private:
|
||||
m_btn->Enable(m_checked);
|
||||
}
|
||||
|
||||
void OnRadioButton(wxCommandEvent& event)
|
||||
{
|
||||
if ( event.GetEventObject() == m_radioA4 )
|
||||
m_paperSize = "A4";
|
||||
else if ( event.GetEventObject() == m_radioLetter )
|
||||
m_paperSize = "Letter";
|
||||
else
|
||||
m_paperSize = "Unknown";
|
||||
}
|
||||
|
||||
void OnText(wxCommandEvent& event)
|
||||
{
|
||||
m_str = event.GetString();
|
||||
@ -1632,9 +1643,12 @@ private:
|
||||
|
||||
wxString m_str;
|
||||
bool m_checked;
|
||||
wxString m_paperSize;
|
||||
|
||||
wxButton *m_btn;
|
||||
wxCheckBox *m_cb;
|
||||
wxRadioButton *m_radioA4;
|
||||
wxRadioButton *m_radioLetter;
|
||||
wxStaticText *m_label;
|
||||
wxTextCtrl *m_text;
|
||||
};
|
||||
@ -1648,6 +1662,11 @@ MyExtraPanel::MyExtraPanel(wxWindow *parent)
|
||||
m_btn->Enable(false);
|
||||
m_cb = new wxCheckBox(this, -1, "Enable Custom Button");
|
||||
m_cb->Bind(wxEVT_CHECKBOX, &MyExtraPanel::OnCheckBox, this);
|
||||
m_radioA4 = new wxRadioButton(this, wxID_ANY, "A4",
|
||||
wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
|
||||
m_radioA4->Bind(wxEVT_RADIOBUTTON, &MyExtraPanel::OnRadioButton, this);
|
||||
m_radioLetter = new wxRadioButton(this, wxID_ANY, "Letter");
|
||||
m_radioLetter->Bind(wxEVT_RADIOBUTTON, &MyExtraPanel::OnRadioButton, this);
|
||||
m_label = new wxStaticText(this, wxID_ANY, "Nothing selected");
|
||||
m_label->Bind(wxEVT_UPDATE_UI, &MyExtraPanel::OnUpdateLabelUI, this);
|
||||
|
||||
@ -1660,6 +1679,8 @@ MyExtraPanel::MyExtraPanel(wxWindow *parent)
|
||||
wxSizerFlags().Centre().Border());
|
||||
sizerTop->Add(m_text, wxSizerFlags(1).Centre().Border());
|
||||
sizerTop->AddSpacer(10);
|
||||
sizerTop->Add(m_radioA4, wxSizerFlags().Centre().Border());
|
||||
sizerTop->Add(m_radioLetter, wxSizerFlags().Centre().Border());
|
||||
sizerTop->Add(m_cb, wxSizerFlags().Centre().Border());
|
||||
sizerTop->AddSpacer(5);
|
||||
sizerTop->Add(m_btn, wxSizerFlags().Centre().Border());
|
||||
@ -1695,6 +1716,8 @@ public:
|
||||
// ShowModal() returns, TransferDataFromCustomControls() is the latest
|
||||
// moment when they can still be used.
|
||||
m_text = customizer.AddTextCtrl("Just some extra text:");
|
||||
m_radioA4 = customizer.AddRadioButton("A4");
|
||||
m_radioLetter = customizer.AddRadioButton("Letter");
|
||||
m_cb = customizer.AddCheckBox("Enable Custom Button");
|
||||
m_cb->Bind(wxEVT_CHECKBOX, &MyCustomizeHook::OnCheckBox, this);
|
||||
m_btn = customizer.AddButton("Custom Button");
|
||||
@ -1715,7 +1738,8 @@ public:
|
||||
// And another one called when the dialog is accepted.
|
||||
virtual void TransferDataFromCustomControls() wxOVERRIDE
|
||||
{
|
||||
m_info.Printf("checkbox=%d, text=\"%s\"",
|
||||
m_info.Printf("paper=%s, enabled=%d, text=\"%s\"",
|
||||
m_radioA4->GetValue() ? "A4" : "Letter",
|
||||
m_cb->GetValue(), m_text->GetValue());
|
||||
}
|
||||
|
||||
@ -1740,6 +1764,8 @@ private:
|
||||
|
||||
wxFileDialogButton* m_btn;
|
||||
wxFileDialogCheckBox* m_cb;
|
||||
wxFileDialogRadioButton* m_radioA4;
|
||||
wxFileDialogRadioButton* m_radioLetter;
|
||||
wxFileDialogTextCtrl* m_text;
|
||||
wxFileDialogStaticText* m_label;
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#include "wx/button.h"
|
||||
#include "wx/checkbox.h"
|
||||
#include "wx/radiobut.h"
|
||||
#include "wx/stattext.h"
|
||||
#include "wx/textctrl.h"
|
||||
#endif // WX_PRECOMP
|
||||
@ -143,6 +144,34 @@ void wxFileDialogCheckBox::SetValue(bool value)
|
||||
GetImpl()->SetValue(value);
|
||||
}
|
||||
|
||||
wxFileDialogRadioButton::wxFileDialogRadioButton(wxFileDialogRadioButtonImpl* impl)
|
||||
: wxFileDialogCustomControl(impl)
|
||||
{
|
||||
}
|
||||
|
||||
bool wxFileDialogRadioButton::OnDynamicBind(wxDynamicEventTableEntry& entry)
|
||||
{
|
||||
if ( entry.m_eventType == wxEVT_RADIOBUTTON )
|
||||
return GetImpl()->DoBind(this);
|
||||
|
||||
return wxFileDialogCustomControl::OnDynamicBind(entry);
|
||||
}
|
||||
|
||||
wxFileDialogRadioButtonImpl* wxFileDialogRadioButton::GetImpl() const
|
||||
{
|
||||
return static_cast<wxFileDialogRadioButtonImpl*>(m_impl);
|
||||
}
|
||||
|
||||
bool wxFileDialogRadioButton::GetValue() const
|
||||
{
|
||||
return GetImpl()->GetValue();
|
||||
}
|
||||
|
||||
void wxFileDialogRadioButton::SetValue(bool value)
|
||||
{
|
||||
GetImpl()->SetValue(value);
|
||||
}
|
||||
|
||||
wxFileDialogTextCtrl::wxFileDialogTextCtrl(wxFileDialogTextCtrlImpl* impl)
|
||||
: wxFileDialogCustomControl(impl)
|
||||
{
|
||||
@ -222,6 +251,12 @@ wxFileDialogCustomize::AddCheckBox(const wxString& label)
|
||||
return StoreAndReturn(new wxFileDialogCheckBox(m_impl->AddCheckBox(label)));
|
||||
}
|
||||
|
||||
wxFileDialogRadioButton*
|
||||
wxFileDialogCustomize::AddRadioButton(const wxString& label)
|
||||
{
|
||||
return StoreAndReturn(new wxFileDialogRadioButton(m_impl->AddRadioButton(label)));
|
||||
}
|
||||
|
||||
wxFileDialogTextCtrl*
|
||||
wxFileDialogCustomize::AddTextCtrl(const wxString& label)
|
||||
{
|
||||
@ -374,6 +409,58 @@ private:
|
||||
wxEvtHandler* m_handler;
|
||||
};
|
||||
|
||||
class RadioButtonImpl : public ControlImplBase<wxFileDialogRadioButtonImpl>
|
||||
{
|
||||
public:
|
||||
RadioButtonImpl(wxWindow* parent, const wxString& label)
|
||||
: ControlImplBase<wxFileDialogRadioButtonImpl>
|
||||
(
|
||||
new wxRadioButton(parent, wxID_ANY, label)
|
||||
)
|
||||
{
|
||||
m_handler = NULL;
|
||||
}
|
||||
|
||||
virtual bool GetValue() wxOVERRIDE
|
||||
{
|
||||
return GetRadioButton()->GetValue();
|
||||
}
|
||||
|
||||
virtual void SetValue(bool value) wxOVERRIDE
|
||||
{
|
||||
GetRadioButton()->SetValue(value);
|
||||
}
|
||||
|
||||
virtual bool DoBind(wxEvtHandler* handler) wxOVERRIDE
|
||||
{
|
||||
if ( !m_handler )
|
||||
{
|
||||
m_handler = handler;
|
||||
m_win->Bind(wxEVT_RADIOBUTTON, &RadioButtonImpl::OnRadioButton, this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
wxRadioButton* GetRadioButton() const
|
||||
{
|
||||
return static_cast<wxRadioButton*>(m_win);
|
||||
}
|
||||
|
||||
void OnRadioButton(wxCommandEvent& event)
|
||||
{
|
||||
// See comments in OnButton() above, they also apply here.
|
||||
|
||||
wxCommandEvent eventCopy(event);
|
||||
eventCopy.SetEventObject(m_handler);
|
||||
|
||||
m_handler->ProcessEvent(eventCopy);
|
||||
}
|
||||
|
||||
wxEvtHandler* m_handler;
|
||||
};
|
||||
|
||||
class TextCtrlImpl : public ControlImplBase<wxFileDialogTextCtrlImpl>
|
||||
{
|
||||
public:
|
||||
@ -441,7 +528,8 @@ public:
|
||||
Panel(wxWindow* parent, wxFileDialogCustomizeHook& customizeHook)
|
||||
: wxPanel(parent),
|
||||
wxFileDialogCustomize(this),
|
||||
m_customizeHook(customizeHook)
|
||||
m_customizeHook(customizeHook),
|
||||
m_lastWasRadio(false)
|
||||
{
|
||||
// Use a simple horizontal sizer to layout all the controls for now.
|
||||
wxBoxSizer* const sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
@ -467,16 +555,36 @@ public:
|
||||
// Implement wxFileDialogCustomizeImpl pure virtual methods.
|
||||
wxFileDialogButtonImpl* AddButton(const wxString& label) wxOVERRIDE
|
||||
{
|
||||
m_lastWasRadio = false;
|
||||
|
||||
return AddToLayoutAndReturn<ButtonImpl>(label);
|
||||
}
|
||||
|
||||
wxFileDialogCheckBoxImpl* AddCheckBox(const wxString& label) wxOVERRIDE
|
||||
{
|
||||
m_lastWasRadio = false;
|
||||
|
||||
return AddToLayoutAndReturn<CheckBoxImpl>(label);
|
||||
}
|
||||
|
||||
wxFileDialogRadioButtonImpl* AddRadioButton(const wxString& label) wxOVERRIDE
|
||||
{
|
||||
RadioButtonImpl* const impl = AddToLayoutAndReturn<RadioButtonImpl>(label);
|
||||
if ( !m_lastWasRadio )
|
||||
{
|
||||
// Select the first button of a new radio group.
|
||||
impl->SetValue(true);
|
||||
|
||||
m_lastWasRadio = true;
|
||||
}
|
||||
|
||||
return impl;
|
||||
}
|
||||
|
||||
wxFileDialogTextCtrlImpl* AddTextCtrl(const wxString& label) wxOVERRIDE
|
||||
{
|
||||
m_lastWasRadio = false;
|
||||
|
||||
if ( !label.empty() )
|
||||
{
|
||||
AddToLayout(new wxStaticText(this, wxID_ANY, label));
|
||||
@ -487,6 +595,8 @@ public:
|
||||
|
||||
wxFileDialogStaticTextImpl* AddStaticText(const wxString& label) wxOVERRIDE
|
||||
{
|
||||
m_lastWasRadio = false;
|
||||
|
||||
return AddToLayoutAndReturn<StaticTextImpl>(label);
|
||||
}
|
||||
|
||||
@ -509,6 +619,8 @@ private:
|
||||
|
||||
wxFileDialogCustomizeHook& m_customizeHook;
|
||||
|
||||
bool m_lastWasRadio;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(Panel);
|
||||
};
|
||||
|
||||
|
@ -57,6 +57,7 @@
|
||||
|
||||
#include "wx/button.h"
|
||||
#include "wx/checkbox.h"
|
||||
#include "wx/radiobut.h"
|
||||
#include "wx/stattext.h"
|
||||
#include "wx/textctrl.h"
|
||||
|
||||
@ -332,6 +333,47 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class wxFileDialogRadioButtonImplFDC
|
||||
: public wxFileDialogImplFDC<wxFileDialogRadioButtonImpl>
|
||||
{
|
||||
public:
|
||||
wxFileDialogRadioButtonImplFDC(IFileDialogCustomize* fdc, DWORD id, DWORD item)
|
||||
: wxFileDialogImplFDC<wxFileDialogRadioButtonImpl>(fdc, id),
|
||||
m_item(item)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool GetValue() wxOVERRIDE
|
||||
{
|
||||
DWORD selected = 0;
|
||||
HRESULT hr = m_fdc->GetSelectedControlItem(m_id, &selected);
|
||||
if ( FAILED(hr) )
|
||||
wxLogApiError(wxS("IFileDialogCustomize::GetSelectedControlItem"), hr);
|
||||
|
||||
return selected == m_item;
|
||||
}
|
||||
|
||||
virtual void SetValue(bool value) wxOVERRIDE
|
||||
{
|
||||
// We can't implement it using the available API and this shouldn't be
|
||||
// ever needed anyhow.
|
||||
wxCHECK_RET( value, wxS("clearing radio buttons not supported") );
|
||||
|
||||
HRESULT hr = m_fdc->SetSelectedControlItem(m_id, m_item);
|
||||
if ( FAILED(hr) )
|
||||
wxLogApiError(wxS("IFileDialogCustomize::SetSelectedControlItem"), hr);
|
||||
}
|
||||
|
||||
virtual bool DoBind(wxEvtHandler* WXUNUSED(handler)) wxOVERRIDE
|
||||
{
|
||||
// We don't need to do anything special to get the events here.
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
const DWORD m_item;
|
||||
};
|
||||
|
||||
class wxFileDialogTextCtrlImplFDC
|
||||
: public wxFileDialogImplFDC<wxFileDialogTextCtrlImpl>
|
||||
{
|
||||
@ -391,7 +433,8 @@ public:
|
||||
: wxFileDialogCustomize(this)
|
||||
{
|
||||
m_lastId =
|
||||
m_lastAuxId = 0;
|
||||
m_lastAuxId =
|
||||
m_radioListId = 0;
|
||||
}
|
||||
|
||||
bool Initialize(IFileDialog* fileDialog)
|
||||
@ -424,6 +467,8 @@ public:
|
||||
// Implement wxFileDialogCustomizeImpl pure virtual methods.
|
||||
wxFileDialogButtonImpl* AddButton(const wxString& label) wxOVERRIDE
|
||||
{
|
||||
m_radioListId = 0;
|
||||
|
||||
HRESULT hr = m_fdc->AddPushButton(++m_lastId, label.wc_str());
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
@ -436,6 +481,8 @@ public:
|
||||
|
||||
wxFileDialogCheckBoxImpl* AddCheckBox(const wxString& label) wxOVERRIDE
|
||||
{
|
||||
m_radioListId = 0;
|
||||
|
||||
HRESULT hr = m_fdc->AddCheckButton(++m_lastId, label.wc_str(), FALSE);
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
@ -446,8 +493,45 @@ public:
|
||||
return new wxFileDialogCheckBoxImplFDC(m_fdc, m_lastId);
|
||||
}
|
||||
|
||||
wxFileDialogRadioButtonImpl* AddRadioButton(const wxString& label) wxOVERRIDE
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
bool firstButton = false;
|
||||
if ( !m_radioListId )
|
||||
{
|
||||
hr = m_fdc->AddRadioButtonList(--m_lastAuxId);
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
wxLogApiError(wxS("IFileDialogCustomize::AddRadioButtonList"), hr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
m_radioListId = m_lastAuxId;
|
||||
firstButton = true;
|
||||
}
|
||||
|
||||
hr = m_fdc->AddControlItem(m_radioListId, ++m_lastId, label.wc_str());
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
wxLogApiError(wxS("IFileDialogCustomize::AddControlItem"), hr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wxFileDialogRadioButtonImplFDC* const
|
||||
impl = new wxFileDialogRadioButtonImplFDC(m_fdc, m_radioListId, m_lastId);
|
||||
|
||||
// Select the first button of a new radio group.
|
||||
if ( firstButton )
|
||||
impl->SetValue(true);
|
||||
|
||||
return impl;
|
||||
}
|
||||
|
||||
wxFileDialogTextCtrlImpl* AddTextCtrl(const wxString& label) wxOVERRIDE
|
||||
{
|
||||
m_radioListId = 0;
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
if ( !label.empty() )
|
||||
@ -476,6 +560,8 @@ public:
|
||||
|
||||
wxFileDialogStaticTextImpl* AddStaticText(const wxString& label) wxOVERRIDE
|
||||
{
|
||||
m_radioListId = 0;
|
||||
|
||||
HRESULT hr = m_fdc->AddText(++m_lastId, label.wc_str());
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
@ -497,6 +583,10 @@ private:
|
||||
// IDs used for any other controls, they're negative (which means they
|
||||
// decrement from USHORT_MAX down).
|
||||
DWORD m_lastAuxId;
|
||||
|
||||
// ID of the current radio button list, i.e. the one to which the next call
|
||||
// to AddRadioButton() would add a radio button. 0 if none.
|
||||
DWORD m_radioListId;
|
||||
};
|
||||
|
||||
#endif // wxUSE_IFILEOPENDIALOG
|
||||
@ -638,8 +728,20 @@ public:
|
||||
wxSTDMETHODIMP
|
||||
OnItemSelected(IFileDialogCustomize*,
|
||||
DWORD WXUNUSED(dwIDCtl),
|
||||
DWORD WXUNUSED(dwIDItem)) wxOVERRIDE
|
||||
DWORD dwIDItem) wxOVERRIDE
|
||||
{
|
||||
// Note that we don't use dwIDCtl here because we use unique item IDs
|
||||
// for all controls.
|
||||
if ( wxFileDialogCustomControl* const
|
||||
control = m_customize.FindControl(dwIDItem) )
|
||||
{
|
||||
wxCommandEvent event(wxEVT_RADIOBUTTON, dwIDItem);
|
||||
event.SetEventObject(control);
|
||||
event.SetInt(true); // Ensure IsChecked() returns true.
|
||||
|
||||
control->SafelyProcessEvent(event);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user