summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2012-11-22 17:14:23 +0000
committerCaolán McNamara <caolanm@redhat.com>2012-11-22 20:11:52 +0000
commitdf0cef5bc7b15c40caa9b3224d5f033063856afb (patch)
tree12779d3c500566a3f6acedfd7aba55271963301b /vcl
parent1b329fd5ccc0ff270d776dfd03571da3f4d6f34d (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.hxx3
-rw-r--r--vcl/source/control/button.cxx58
-rw-r--r--vcl/source/window/dlgctrl.cxx150
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 )
{