diff options
author | Caolán McNamara <caolanm@redhat.com> | 2012-11-22 17:14:23 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2012-11-22 20:11:52 +0000 |
commit | df0cef5bc7b15c40caa9b3224d5f033063856afb (patch) | |
tree | 12779d3c500566a3f6acedfd7aba55271963301b /vcl | |
parent | 1b329fd5ccc0ff270d776dfd03571da3f4d6f34d (diff) |
make left-right traverse through radiobutton groups
lets preserve the traversal order from the initial
grouping order, so convert the radio group set to a vector
Change-Id: If057f0c5d5f2eac2e8866a8a39efde8035c4fc4a
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/inc/vcl/button.hxx | 3 | ||||
-rw-r--r-- | vcl/source/control/button.cxx | 58 | ||||
-rw-r--r-- | vcl/source/window/dlgctrl.cxx | 150 |
3 files changed, 162 insertions, 49 deletions
diff --git a/vcl/inc/vcl/button.hxx b/vcl/inc/vcl/button.hxx index 3294f5a92a76..3d6c239a443d 100644 --- a/vcl/inc/vcl/button.hxx +++ b/vcl/inc/vcl/button.hxx @@ -28,7 +28,6 @@ #include <vcl/bitmap.hxx> #include <vcl/salnativewidgets.hxx> -#include <set> #include <vector> class UserDrawEvent; @@ -282,7 +281,7 @@ public: class VCL_DLLPUBLIC RadioButton : public Button { private: - boost::shared_ptr< std::set<RadioButton*> > m_xGroup; + boost::shared_ptr< std::vector<RadioButton*> > m_xGroup; Rectangle maStateRect; Rectangle maMouseRect; Image maImage; diff --git a/vcl/source/control/button.cxx b/vcl/source/control/button.cxx index b71ca99ebcb1..2410ba3c02fd 100644 --- a/vcl/source/control/button.cxx +++ b/vcl/source/control/button.cxx @@ -2354,23 +2354,39 @@ void RadioButton::ImplDrawRadioButton( bool bLayout ) void RadioButton::group(RadioButton &rOther) { + if (&rOther == this) + return; + if (!m_xGroup) { - m_xGroup.reset(new std::set<RadioButton*>); - m_xGroup->insert(this); + m_xGroup.reset(new std::vector<RadioButton*>); + m_xGroup->push_back(this); } - if (rOther.m_xGroup) - m_xGroup->insert(rOther.m_xGroup->begin(), rOther.m_xGroup->end()); + std::vector<RadioButton*>::iterator aFind = std::find(m_xGroup->begin(), m_xGroup->end(), &rOther); + if (aFind == m_xGroup->end()) + { + m_xGroup->push_back(&rOther); - m_xGroup->insert(&rOther); + if (rOther.m_xGroup) + { + std::vector< RadioButton* > aOthers(rOther.GetRadioButtonGroup(false)); + //make all members of the group share the same button group + for (std::vector<RadioButton*>::iterator aI = aOthers.begin(), aEnd = aOthers.end(); aI != aEnd; ++aI) + { + aFind = std::find(m_xGroup->begin(), m_xGroup->end(), *aI); + if (aFind == m_xGroup->end()) + m_xGroup->push_back(*aI); + } + } - //make all members of the group share the same button group - for (std::set<RadioButton*>::iterator aI = m_xGroup->begin(), aEnd = m_xGroup->end(); - aI != aEnd; ++aI) - { - RadioButton* pButton = *aI; - pButton->m_xGroup = m_xGroup; + //make all members of the group share the same button group + for (std::vector<RadioButton*>::iterator aI = m_xGroup->begin(), aEnd = m_xGroup->end(); + aI != aEnd; ++aI) + { + RadioButton* pButton = *aI; + pButton->m_xGroup = m_xGroup; + } } //if this one is checked, uncheck all the others @@ -2382,14 +2398,15 @@ void RadioButton::group(RadioButton &rOther) std::vector< RadioButton* > RadioButton::GetRadioButtonGroup(bool bIncludeThis) const { - std::vector< RadioButton* > aGroup; - if (m_xGroup) { - for (std::set<RadioButton*>::iterator aI = m_xGroup->begin(), aEnd = m_xGroup->end(); aI != aEnd; ++aI) + if (bIncludeThis) + return *m_xGroup; + std::vector< RadioButton* > aGroup; + for (std::vector<RadioButton*>::iterator aI = m_xGroup->begin(), aEnd = m_xGroup->end(); aI != aEnd; ++aI) { RadioButton *pRadioButton = *aI; - if (!bIncludeThis && pRadioButton == this) + if (pRadioButton == this) continue; aGroup.push_back(pRadioButton); } @@ -2409,6 +2426,7 @@ std::vector< RadioButton* > RadioButton::GetRadioButtonGroup(bool bIncludeThis) else break; } + std::vector< RadioButton* > aGroup; // insert radiobuttons up to next group do { @@ -2519,8 +2537,9 @@ void RadioButton::take_properties(Window &rOther) RadioButton &rOtherRadio = static_cast<RadioButton&>(rOther); if (rOtherRadio.m_xGroup.get()) { - rOtherRadio.m_xGroup->erase(&rOtherRadio); - rOtherRadio.m_xGroup->insert(this); + rOtherRadio.m_xGroup->erase(std::remove(rOtherRadio.m_xGroup->begin(), rOtherRadio.m_xGroup->end(), &rOtherRadio), + rOtherRadio.m_xGroup->end()); + rOtherRadio.m_xGroup->push_back(this); } std::swap(m_xGroup, rOtherRadio.m_xGroup); mbChecked = rOtherRadio.mbChecked; @@ -2546,7 +2565,10 @@ void RadioButton::ImplLoadRes( const ResId& rResId ) RadioButton::~RadioButton() { if (m_xGroup) - m_xGroup->erase(this); + { + m_xGroup->erase(std::remove(m_xGroup->begin(), m_xGroup->end(), this), + m_xGroup->end()); + } } // ----------------------------------------------------------------------- diff --git a/vcl/source/window/dlgctrl.cxx b/vcl/source/window/dlgctrl.cxx index 26f730016a15..0ff589bc3407 100644 --- a/vcl/source/window/dlgctrl.cxx +++ b/vcl/source/window/dlgctrl.cxx @@ -526,6 +526,89 @@ void Window::ImplControlFocus( sal_uInt16 nFlags ) // ----------------------------------------------------------------------- +namespace +{ + bool isSuitableDestination(Window *pWindow) + { + return (pWindow && isVisibleInLayout(pWindow) && isEnabledInLayout(pWindow) && pWindow->IsInputEnabled()); + } + + bool backInGroup(std::vector<RadioButton*>::reverse_iterator aRevStart, std::vector<RadioButton*> &rGroup) + { + std::vector<RadioButton*>::reverse_iterator aI(aRevStart); + while (aI != rGroup.rend()) + { + Window *pWindow = *aI; + + if (isSuitableDestination(pWindow)) + { + pWindow->ImplControlFocus( GETFOCUS_CURSOR | GETFOCUS_BACKWARD ); + return true; + } + } + + aI = rGroup.rbegin(); + while (aI != aRevStart) + { + Window *pWindow = *aI; + + if (isSuitableDestination(pWindow)) + { + pWindow->ImplControlFocus( GETFOCUS_CURSOR | GETFOCUS_BACKWARD ); + return true; + } + } + + return false; + } + + bool forwardInGroup(std::vector<RadioButton*>::iterator aStart, std::vector<RadioButton*> &rGroup) + { + std::vector<RadioButton*>::iterator aI(aStart); + while (++aI != rGroup.end()) + { + Window *pWindow = *aI; + + if (isSuitableDestination(pWindow)) + { + pWindow->ImplControlFocus( GETFOCUS_CURSOR | GETFOCUS_FORWARD ); + return true; + } + } + + aI = rGroup.begin(); + while (aI != aStart) + { + Window *pWindow = *aI; + + if (isSuitableDestination(pWindow)) + { + pWindow->ImplControlFocus( GETFOCUS_CURSOR | GETFOCUS_FORWARD ); + return true; + } + } + + return false; + } + + bool nextInGroup(RadioButton *pSourceWindow, bool bBackward) + { + std::vector<RadioButton*> aGroup(pSourceWindow->GetRadioButtonGroup(true)); + + if (aGroup.size() == 1) //only one button in group + return false; + + std::vector<RadioButton*>::iterator aStart(std::find(aGroup.begin(), aGroup.end(), pSourceWindow)); + + assert(aStart != aGroup.end()); + + if (bBackward) + return backInGroup(std::vector<RadioButton*>::reverse_iterator(aStart), aGroup); + else + return forwardInGroup(aStart, aGroup); + } +} + sal_Bool Window::ImplDlgCtrl( const KeyEvent& rKEvt, sal_Bool bKeyInput ) { KeyCode aKeyCode = rKEvt.GetKeyCode(); @@ -796,50 +879,59 @@ sal_Bool Window::ImplDlgCtrl( const KeyEvent& rKEvt, sal_Bool bKeyInput ) } else if ( (nKeyCode == KEY_LEFT) || (nKeyCode == KEY_UP) ) { - Window* pWindow = pSWindow; - WinBits nStyle = pSWindow->GetStyle(); - if ( !(nStyle & WB_GROUP) ) + if (pSWindow->GetType() == WINDOW_RADIOBUTTON) + return nextInGroup(static_cast<RadioButton*>(pSWindow), true); + else { - pWindow = prevLogicalChildOfParent(this, pWindow); - while ( pWindow ) + WinBits nStyle = pSWindow->GetStyle(); + if ( !(nStyle & WB_GROUP) ) { - pWindow = pWindow->ImplGetWindow(); + Window* pWindow = prevLogicalChildOfParent(this, pSWindow); + while ( pWindow ) + { + pWindow = pWindow->ImplGetWindow(); - nStyle = pWindow->GetStyle(); + nStyle = pWindow->GetStyle(); - if ( isVisibleInLayout(pWindow) && isEnabledInLayout(pWindow) && pWindow->IsInputEnabled() ) - { - if ( pWindow != pSWindow ) - pWindow->ImplControlFocus( GETFOCUS_CURSOR | GETFOCUS_BACKWARD ); - return sal_True; - } + if ( isVisibleInLayout(pWindow) && isEnabledInLayout(pWindow) && pWindow->IsInputEnabled() ) + { + if ( pWindow != pSWindow ) + pWindow->ImplControlFocus( GETFOCUS_CURSOR | GETFOCUS_BACKWARD ); + return sal_True; + } - if ( nStyle & WB_GROUP ) - break; + if ( nStyle & WB_GROUP ) + break; - pWindow = prevLogicalChildOfParent(this, pWindow); + pWindow = prevLogicalChildOfParent(this, pWindow); + } } } } else if ( (nKeyCode == KEY_RIGHT) || (nKeyCode == KEY_DOWN) ) { - Window* pWindow = nextLogicalChildOfParent(this, pSWindow); - while ( pWindow ) + if (pSWindow->GetType() == WINDOW_RADIOBUTTON) + return nextInGroup(static_cast<RadioButton*>(pSWindow), false); + else { - pWindow = pWindow->ImplGetWindow(); + Window* pWindow = nextLogicalChildOfParent(this, pSWindow); + while ( pWindow ) + { + pWindow = pWindow->ImplGetWindow(); - WinBits nStyle = pWindow->GetStyle(); + WinBits nStyle = pWindow->GetStyle(); - if ( nStyle & WB_GROUP ) - break; + if ( nStyle & WB_GROUP ) + break; - if ( isVisibleInLayout(pWindow) && isEnabledInLayout(pWindow) && pWindow->IsInputEnabled() ) - { - pWindow->ImplControlFocus( GETFOCUS_CURSOR | GETFOCUS_BACKWARD ); - return sal_True; - } + if (isSuitableDestination(pWindow)) + { + pWindow->ImplControlFocus( GETFOCUS_CURSOR | GETFOCUS_BACKWARD ); + return sal_True; + } - pWindow = nextLogicalChildOfParent(this, pWindow); + pWindow = nextLogicalChildOfParent(this, pWindow); + } } } else @@ -860,7 +952,7 @@ sal_Bool Window::ImplDlgCtrl( const KeyEvent& rKEvt, sal_Bool bKeyInput ) } } - if ( pButtonWindow && isVisibleInLayout(pButtonWindow) && isEnabledInLayout(pButtonWindow) && pButtonWindow->IsInputEnabled() ) + if (isSuitableDestination(pButtonWindow)) { if ( bKeyInput ) { |