Move radio group navigation functions to wxRadioButtonBase
Now that this class is not a template any longer, we can have the code for radio button group navigation directly in it, without making it inline, so move the existing functions bodies into the new methods and remove the old functions entirely. No real changes, this is just a refactoring.
This commit is contained in:
parent
bcb016613e
commit
09060ed262
@ -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<const wxRadioButton*>(this));
|
||||
}
|
||||
|
||||
wxRadioButton* GetLastInGroup() const
|
||||
{
|
||||
return wxPrivate::wxGetLastButtonInGroup(static_cast<const wxRadioButton*>(this));
|
||||
}
|
||||
|
||||
wxRadioButton* GetPreviousInGroup() const
|
||||
{
|
||||
return wxPrivate::wxGetPreviousButtonInGroup(static_cast<const wxRadioButton*>(this));
|
||||
}
|
||||
|
||||
wxRadioButton* GetNextInGroup() const
|
||||
{
|
||||
return wxPrivate::wxGetNextButtonInGroup(static_cast<const wxRadioButton*>(this));
|
||||
}
|
||||
wxRadioButton* GetFirstInGroup() const;
|
||||
wxRadioButton* GetLastInGroup() const;
|
||||
wxRadioButton* GetPreviousInGroup() const;
|
||||
wxRadioButton* GetNextInGroup() const;
|
||||
|
||||
private:
|
||||
wxDECLARE_NO_COPY_CLASS(wxRadioButtonBase);
|
||||
|
@ -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<wxRadioButton*>(btn);
|
||||
|
||||
btn = prevBtn;
|
||||
}
|
||||
}
|
||||
|
||||
wxRadioButton* wxGetLastButtonInGroup(const wxRadioButton *btn)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
wxRadioButton* nextBtn = wxGetNextButtonInGroup(btn);
|
||||
if (!nextBtn)
|
||||
return const_cast<wxRadioButton*>(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<wxRadioButton*>(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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<wxRadioButton*>(const_cast<wxRadioButtonBase*>(this));
|
||||
while (true)
|
||||
{
|
||||
wxRadioButton* prevBtn = btn->GetPreviousInGroup();
|
||||
if (!prevBtn)
|
||||
return btn;
|
||||
|
||||
btn = prevBtn;
|
||||
}
|
||||
}
|
||||
|
||||
wxRadioButton* wxRadioButtonBase::GetLastInGroup() const
|
||||
{
|
||||
wxRadioButton*
|
||||
btn = static_cast<wxRadioButton*>(const_cast<wxRadioButtonBase*>(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
|
||||
|
Loading…
Reference in New Issue
Block a user