diff --git a/include/wx/radiobut.h b/include/wx/radiobut.h index 90217847a5..f4cf3b1a09 100644 --- a/include/wx/radiobut.h +++ b/include/wx/radiobut.h @@ -19,14 +19,6 @@ class WXDLLIMPEXP_FWD_CORE wxRadioButton; -namespace wxPrivate -{ - WXDLLIMPEXP_CORE wxRadioButton* wxGetNextButtonInGroup(const wxRadioButton *btn); - WXDLLIMPEXP_CORE wxRadioButton* wxGetPreviousButtonInGroup(const wxRadioButton *btn); - WXDLLIMPEXP_CORE wxRadioButton* wxGetFirstButtonInGroup(const wxRadioButton *btn); - WXDLLIMPEXP_CORE wxRadioButton* wxGetLastButtonInGroup(const wxRadioButton *btn); -} // namespace wxPrivate - // TODO: In wxUniv, wxRadioButton must derive from wxCheckBox as it reuses // much of its code. This should be fixed by refactoring wxCheckBox to allow // this class to reuse its functionality without inheriting from it, but for @@ -50,25 +42,10 @@ public: // Methods implemented by this class itself. - wxRadioButton* GetFirstInGroup() const - { - return wxPrivate::wxGetFirstButtonInGroup(static_cast(this)); - } - - wxRadioButton* GetLastInGroup() const - { - return wxPrivate::wxGetLastButtonInGroup(static_cast(this)); - } - - wxRadioButton* GetPreviousInGroup() const - { - return wxPrivate::wxGetPreviousButtonInGroup(static_cast(this)); - } - - wxRadioButton* GetNextInGroup() const - { - return wxPrivate::wxGetNextButtonInGroup(static_cast(this)); - } + wxRadioButton* GetFirstInGroup() const; + wxRadioButton* GetLastInGroup() const; + wxRadioButton* GetPreviousInGroup() const; + wxRadioButton* GetNextInGroup() const; private: wxDECLARE_NO_COPY_CLASS(wxRadioButtonBase); diff --git a/src/common/containr.cpp b/src/common/containr.cpp index 52b808a29f..d20098f869 100644 --- a/src/common/containr.cpp +++ b/src/common/containr.cpp @@ -233,103 +233,15 @@ void wxControlContainer::SetLastFocus(wxWindow *win) } } -#endif // !wxHAS_NATIVE_TAB_TRAVERSAL - // -------------------------------------------------------------------- -// The following four functions are used to find other radio buttons -// within the same group. Used by wxSetFocusToChild() and to implement -// wxRadioButtonBase public API. +// The following functions is used by wxSetFocusToChild() // -------------------------------------------------------------------- #if wxUSE_RADIOBTN -namespace wxPrivate +namespace { -wxRadioButton* wxGetPreviousButtonInGroup(const wxRadioButton *btn) -{ - if ( btn->HasFlag(wxRB_GROUP) || btn->HasFlag(wxRB_SINGLE) ) - return NULL; - - const wxWindowList& siblings = btn->GetParent()->GetChildren(); - wxWindowList::compatibility_iterator nodeThis = siblings.Find(btn); - wxCHECK_MSG( nodeThis, NULL, wxT("radio button not a child of its parent?") ); - - // Iterate over all previous siblings until we find the next radio button - wxWindowList::compatibility_iterator nodeBefore = nodeThis->GetPrevious(); - wxRadioButton *prevBtn = 0; - while (nodeBefore) - { - prevBtn = wxDynamicCast(nodeBefore->GetData(), wxRadioButton); - if (prevBtn) - break; - - nodeBefore = nodeBefore->GetPrevious(); - } - - if (!prevBtn || prevBtn->HasFlag(wxRB_SINGLE)) - { - // no more buttons in group - return NULL; - } - - return prevBtn; -} - -wxRadioButton* wxGetNextButtonInGroup(const wxRadioButton *btn) -{ - if (btn->HasFlag(wxRB_SINGLE)) - return NULL; - - const wxWindowList& siblings = btn->GetParent()->GetChildren(); - wxWindowList::compatibility_iterator nodeThis = siblings.Find(btn); - wxCHECK_MSG( nodeThis, NULL, wxT("radio button not a child of its parent?") ); - - // Iterate over all previous siblings until we find the next radio button - wxWindowList::compatibility_iterator nodeNext = nodeThis->GetNext(); - wxRadioButton *nextBtn = 0; - while (nodeNext) - { - nextBtn = wxDynamicCast(nodeNext->GetData(), wxRadioButton); - if (nextBtn) - break; - - nodeNext = nodeNext->GetNext(); - } - - if ( !nextBtn || nextBtn->HasFlag(wxRB_GROUP) || nextBtn->HasFlag(wxRB_SINGLE) ) - { - // no more buttons or the first button of the next group - return NULL; - } - - return nextBtn; -} - -wxRadioButton* wxGetFirstButtonInGroup(const wxRadioButton *btn) -{ - while (true) - { - wxRadioButton* prevBtn = wxGetPreviousButtonInGroup(btn); - if (!prevBtn) - return const_cast(btn); - - btn = prevBtn; - } -} - -wxRadioButton* wxGetLastButtonInGroup(const wxRadioButton *btn) -{ - while (true) - { - wxRadioButton* nextBtn = wxGetNextButtonInGroup(btn); - if (!nextBtn) - return const_cast(btn); - - btn = nextBtn; - } -} - wxRadioButton* wxGetSelectedButtonInGroup(const wxRadioButton *btn) { // Find currently selected button @@ -342,26 +254,22 @@ wxRadioButton* wxGetSelectedButtonInGroup(const wxRadioButton *btn) wxRadioButton *selBtn; // First check all previous buttons - for (selBtn = wxGetPreviousButtonInGroup(btn); selBtn; selBtn = wxGetPreviousButtonInGroup(selBtn)) + for (selBtn = btn->GetPreviousInGroup(); selBtn; selBtn = selBtn->GetPreviousInGroup()) if (selBtn->GetValue()) return selBtn; // Now all following buttons - for (selBtn = wxGetNextButtonInGroup(btn); selBtn; selBtn = wxGetNextButtonInGroup(selBtn)) + for (selBtn = btn->GetNextInGroup(); selBtn; selBtn = selBtn->GetNextInGroup()) if (selBtn->GetValue()) return selBtn; return NULL; } -} // namespace wxPrivate - -using namespace wxPrivate; +} // anonymous namespace #endif // wxUSE_RADIOBTN -#ifndef wxHAS_NATIVE_TAB_TRAVERSAL - // ---------------------------------------------------------------------------- // Keyboard handling - this is the place where the TAB traversal logic is // implemented. As this code is common to all ports, this ensures consistent @@ -480,7 +388,7 @@ void wxControlContainer::HandleOnNavigationKey( wxNavigationKeyEvent& event ) // If we are in a radio button group, start from the first item in the // group if ( event.IsFromTab() && wxIsKindOf(winFocus, wxRadioButton ) ) - winFocus = wxGetFirstButtonInGroup((wxRadioButton*)winFocus); + winFocus = static_cast(winFocus)->GetFirstInGroup(); #endif // USE_RADIOBTN_NAV // ok, we found the focus - now is it our child? start_node = children.Find( winFocus ); @@ -598,20 +506,20 @@ void wxControlContainer::HandleOnNavigationKey( wxNavigationKeyEvent& event ) // find the correct radio button to focus if ( forward ) { - child = wxGetNextButtonInGroup(lastBtn); + child = lastBtn->GetNextInGroup(); if ( !child ) { // no next button in group, set it to the first button - child = wxGetFirstButtonInGroup(lastBtn); + child = lastBtn->GetFirstInGroup(); } } else { - child = wxGetPreviousButtonInGroup(lastBtn); + child = lastBtn->GetPreviousInGroup(); if ( !child ) { // no previous button in group, set it to the last button - child = wxGetLastButtonInGroup(lastBtn); + child = lastBtn->GetLastInGroup(); } } diff --git a/src/common/radiobtncmn.cpp b/src/common/radiobtncmn.cpp index dc2bd09240..5e847c7ab9 100644 --- a/src/common/radiobtncmn.cpp +++ b/src/common/radiobtncmn.cpp @@ -92,4 +92,96 @@ wxCONSTRUCTOR_6( wxRadioButton, wxWindow*, Parent, wxWindowID, Id, \ wxString, Label, wxPoint, Position, wxSize, Size, long, WindowStyle ) +// ---------------------------------------------------------------------------- +// wxRadioButton group navigation +// ---------------------------------------------------------------------------- + +wxRadioButton* wxRadioButtonBase::GetFirstInGroup() const +{ + wxRadioButton* + btn = static_cast(const_cast(this)); + while (true) + { + wxRadioButton* prevBtn = btn->GetPreviousInGroup(); + if (!prevBtn) + return btn; + + btn = prevBtn; + } +} + +wxRadioButton* wxRadioButtonBase::GetLastInGroup() const +{ + wxRadioButton* + btn = static_cast(const_cast(this)); + while (true) + { + wxRadioButton* nextBtn = btn->GetNextInGroup(); + if (!nextBtn) + return btn; + + btn = nextBtn; + } +} + +wxRadioButton* wxRadioButtonBase::GetPreviousInGroup() const +{ + if ( HasFlag(wxRB_GROUP) || HasFlag(wxRB_SINGLE) ) + return NULL; + + const wxWindowList& siblings = GetParent()->GetChildren(); + wxWindowList::compatibility_iterator nodeThis = siblings.Find(this); + wxCHECK_MSG( nodeThis, NULL, wxT("radio button not a child of its parent?") ); + + // Iterate over all previous siblings until we find the next radio button + wxWindowList::compatibility_iterator nodeBefore = nodeThis->GetPrevious(); + wxRadioButton *prevBtn = 0; + while (nodeBefore) + { + prevBtn = wxDynamicCast(nodeBefore->GetData(), wxRadioButton); + if (prevBtn) + break; + + nodeBefore = nodeBefore->GetPrevious(); + } + + if (!prevBtn || prevBtn->HasFlag(wxRB_SINGLE)) + { + // no more buttons in group + return NULL; + } + + return prevBtn; +} + +wxRadioButton* wxRadioButtonBase::GetNextInGroup() const +{ + if ( HasFlag(wxRB_SINGLE) ) + return NULL; + + const wxWindowList& siblings = GetParent()->GetChildren(); + wxWindowList::compatibility_iterator nodeThis = siblings.Find(this); + wxCHECK_MSG( nodeThis, NULL, wxT("radio button not a child of its parent?") ); + + // Iterate over all previous siblings until we find the next radio button + wxWindowList::compatibility_iterator nodeNext = nodeThis->GetNext(); + wxRadioButton *nextBtn = 0; + while (nodeNext) + { + nextBtn = wxDynamicCast(nodeNext->GetData(), wxRadioButton); + if (nextBtn) + break; + + nodeNext = nodeNext->GetNext(); + } + + if ( !nextBtn || nextBtn->HasFlag(wxRB_GROUP) || nextBtn->HasFlag(wxRB_SINGLE) ) + { + // no more buttons or the first button of the next group + return NULL; + } + + return nextBtn; +} + #endif // wxUSE_RADIOBTN