diff --git a/include/wx/valgen.h b/include/wx/valgen.h index c3d0faaab8..2c769ee8a8 100644 --- a/include/wx/valgen.h +++ b/include/wx/valgen.h @@ -76,6 +76,10 @@ public: // Called to transfer data to the window virtual bool TransferFromWindow() override; + // Called when the validator is associated with a window, is used to check + // that the validator is not being associated with a wrong window. + virtual void SetWindow(wxWindow* win) override; + protected: void Initialize(); diff --git a/interface/wx/valgen.h b/interface/wx/valgen.h index 3dc150713b..960cc63bf0 100644 --- a/interface/wx/valgen.h +++ b/interface/wx/valgen.h @@ -25,6 +25,9 @@ A wxLB_SINGLE wxListBox can also use an int. wxColourPickerCtrl support. A 3-state wxCheckBox can use wxCheckBoxState. + @since 3.3.0 + A group of wxRadioButton controls can also be associated with an int. + For more information, please see @ref overview_validator. @library{wxcore} @@ -79,7 +82,7 @@ public: wxGenericValidator(int* valPtr); /** Constructor taking a wxArrayInt pointer. This will be used for - wxListBox, wxCheckListBox. + wxListBox, wxCheckListBox, and groups of wxRadioButton. @param valPtr A pointer to a variable that contains the value. This variable diff --git a/src/common/valgen.cpp b/src/common/valgen.cpp index f73516d27a..8655e03c88 100644 --- a/src/common/valgen.cpp +++ b/src/common/valgen.cpp @@ -172,6 +172,26 @@ bool wxGenericValidator::TransferToWindow() pControl->SetValue(*m_pBool) ; return true; } + else if (m_pInt) + { + const auto last = pControl->GetLastInGroup(); + for (int i = 0 ; ; ++i) + { + if (i == *m_pInt) + { + pControl->SetValue(true); + return true; + } + + if (pControl == last) + { + wxFAIL_MSG("value out of range or not enough radio buttons"); + return false; + } + + pControl = pControl->GetNextInGroup(); + } + } } else #endif @@ -499,6 +519,29 @@ bool wxGenericValidator::TransferFromWindow() *m_pBool = pControl->GetValue() ; return true; } + else if (m_pInt) + { + const auto last = pControl->GetLastInGroup(); + for (int i = 0 ; ; ++i) + { + if (pControl->GetValue()) + { + *m_pInt = i; + return true; + } + + if (pControl == last) + { + // This really should never happen. + wxFAIL_MSG("no selected radio button?"); + + *m_pInt = wxNOT_FOUND; + return false; + } + + pControl = pControl->GetNextInGroup(); + } + } } else #endif #if wxUSE_TOGGLEBTN @@ -795,6 +838,21 @@ bool wxGenericValidator::TransferFromWindow() return false; } +void wxGenericValidator::SetWindow(wxWindow* win) +{ +#if wxUSE_RADIOBTN + if (m_pInt) + { + if (wxRadioButton* pControl = wxDynamicCast(win, wxRadioButton)) + { + wxCHECK_RET(pControl == pControl->GetFirstInGroup(), + "wxRadioButton group validator must be on first item in group"); + } + } +#endif + wxValidator::SetWindow(win); +} + /* Called by constructors to initialize ALL data members */