fix keyboard navigation in radio boxes containing hidden or disabled items
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@54930 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -49,7 +49,8 @@ public:
|
|||||||
unsigned int GetColumnCount() const { return m_numCols; }
|
unsigned int GetColumnCount() const { return m_numCols; }
|
||||||
unsigned int GetRowCount() const { return m_numRows; }
|
unsigned int GetRowCount() const { return m_numRows; }
|
||||||
|
|
||||||
// return the item above/below/to the left/right of the given one
|
// return the next active (i.e. shown and not disabled) item above/below/to
|
||||||
|
// the left/right of the given one
|
||||||
int GetNextItem(int item, wxDirection dir, long style) const;
|
int GetNextItem(int item, wxDirection dir, long style) const;
|
||||||
|
|
||||||
#if wxUSE_TOOLTIPS
|
#if wxUSE_TOOLTIPS
|
||||||
|
@@ -64,96 +64,106 @@ void wxRadioBoxBase::SetMajorDim(unsigned int majorDim, long style)
|
|||||||
|
|
||||||
int wxRadioBoxBase::GetNextItem(int item, wxDirection dir, long style) const
|
int wxRadioBoxBase::GetNextItem(int item, wxDirection dir, long style) const
|
||||||
{
|
{
|
||||||
|
const int itemStart = item;
|
||||||
|
|
||||||
int count = GetCount(),
|
int count = GetCount(),
|
||||||
numCols = GetColumnCount(),
|
numCols = GetColumnCount(),
|
||||||
numRows = GetRowCount();
|
numRows = GetRowCount();
|
||||||
|
|
||||||
bool horz = (style & wxRA_SPECIFY_COLS) != 0;
|
bool horz = (style & wxRA_SPECIFY_COLS) != 0;
|
||||||
|
|
||||||
switch ( dir )
|
do
|
||||||
{
|
{
|
||||||
case wxUP:
|
switch ( dir )
|
||||||
if ( horz )
|
{
|
||||||
{
|
case wxUP:
|
||||||
item -= numCols;
|
if ( horz )
|
||||||
}
|
{
|
||||||
else // vertical layout
|
item -= numCols;
|
||||||
{
|
}
|
||||||
if ( !item-- )
|
else // vertical layout
|
||||||
item = count - 1;
|
{
|
||||||
}
|
if ( !item-- )
|
||||||
break;
|
item = count - 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case wxLEFT:
|
case wxLEFT:
|
||||||
if ( horz )
|
if ( horz )
|
||||||
{
|
{
|
||||||
if ( !item-- )
|
if ( !item-- )
|
||||||
item = count - 1;
|
item = count - 1;
|
||||||
}
|
}
|
||||||
else // vertical layout
|
else // vertical layout
|
||||||
{
|
{
|
||||||
item -= numRows;
|
item -= numRows;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case wxDOWN:
|
case wxDOWN:
|
||||||
if ( horz )
|
if ( horz )
|
||||||
{
|
{
|
||||||
item += numCols;
|
item += numCols;
|
||||||
}
|
}
|
||||||
else // vertical layout
|
else // vertical layout
|
||||||
{
|
{
|
||||||
if ( ++item == count )
|
if ( ++item == count )
|
||||||
item = 0;
|
item = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case wxRIGHT:
|
case wxRIGHT:
|
||||||
if ( horz )
|
if ( horz )
|
||||||
{
|
{
|
||||||
if ( ++item == count )
|
if ( ++item == count )
|
||||||
item = 0;
|
item = 0;
|
||||||
}
|
}
|
||||||
else // vertical layout
|
else // vertical layout
|
||||||
{
|
{
|
||||||
item += numRows;
|
item += numRows;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
wxFAIL_MSG( _T("unexpected wxDirection value") );
|
wxFAIL_MSG( _T("unexpected wxDirection value") );
|
||||||
return wxNOT_FOUND;
|
return wxNOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure that the item is in range [0..count)
|
||||||
|
if ( item < 0 )
|
||||||
|
{
|
||||||
|
// first map the item to the one in the same column but in the last
|
||||||
|
// row
|
||||||
|
item += count;
|
||||||
|
|
||||||
|
// now there are 2 cases: either it is the first item of the last
|
||||||
|
// row in which case we need to wrap again and get to the last item
|
||||||
|
// or we can just go to the previous item
|
||||||
|
if ( item % (horz ? numCols : numRows) )
|
||||||
|
item--;
|
||||||
|
else
|
||||||
|
item = count - 1;
|
||||||
|
}
|
||||||
|
else if ( item >= count )
|
||||||
|
{
|
||||||
|
// same logic as above
|
||||||
|
item -= count;
|
||||||
|
|
||||||
|
// ... except that we need to check if this is not the last item,
|
||||||
|
// not the first one
|
||||||
|
if ( (item + 1) % (horz ? numCols : numRows) )
|
||||||
|
item++;
|
||||||
|
else
|
||||||
|
item = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxASSERT_MSG( item < count && item >= 0,
|
||||||
|
_T("logic error in wxRadioBox::GetNextItem()") );
|
||||||
}
|
}
|
||||||
|
// we shouldn't select the non-active items, continue looking for a
|
||||||
// ensure that the item is in range [0..count)
|
// visible and shown one unless we came back to the item we started from in
|
||||||
if ( item < 0 )
|
// which case bail out to avoid infinite loop
|
||||||
{
|
while ( !(IsItemShown(item) && IsItemEnabled(item)) && item != itemStart );
|
||||||
// first map the item to the one in the same column but in the last row
|
|
||||||
item += count;
|
|
||||||
|
|
||||||
// now there are 2 cases: either it is the first item of the last row
|
|
||||||
// in which case we need to wrap again and get to the last item or we
|
|
||||||
// can just go to the previous item
|
|
||||||
if ( item % (horz ? numCols : numRows) )
|
|
||||||
item--;
|
|
||||||
else
|
|
||||||
item = count - 1;
|
|
||||||
}
|
|
||||||
else if ( item >= count )
|
|
||||||
{
|
|
||||||
// same logic as above
|
|
||||||
item -= count;
|
|
||||||
|
|
||||||
// ... except that we need to check if this is not the last item, not
|
|
||||||
// the first one
|
|
||||||
if ( (item + 1) % (horz ? numCols : numRows) )
|
|
||||||
item++;
|
|
||||||
else
|
|
||||||
item = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxASSERT_MSG( item < count && item >= 0,
|
|
||||||
_T("logic error in wxRadioBox::GetNextItem()") );
|
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user