]> git.saurik.com Git - wxWidgets.git/commitdiff
fix keyboard navigation in radio boxes containing hidden or disabled items
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 2 Aug 2008 19:45:23 +0000 (19:45 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 2 Aug 2008 19:45:23 +0000 (19:45 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@54930 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/radiobox.h
src/common/radiocmn.cpp

index f8d1a6ef48ed430f4ef5c9e0abd3181f1dc9ccc3..d5d0582026b81ec3079c42521a5243ed6bb6581d 100644 (file)
@@ -49,7 +49,8 @@ public:
     unsigned int GetColumnCount() const { return m_numCols; }
     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;
 
 #if wxUSE_TOOLTIPS
index 82d9d5bef7300413694fee0355f72150f75a6c31..8d954df010a949f7bca70ee8732588b0ea15d4af 100644 (file)
@@ -64,96 +64,106 @@ void wxRadioBoxBase::SetMajorDim(unsigned int majorDim, long style)
 
 int wxRadioBoxBase::GetNextItem(int item, wxDirection dir, long style) const
 {
+    const int itemStart = item;
+
     int count = GetCount(),
         numCols = GetColumnCount(),
         numRows = GetRowCount();
 
     bool horz = (style & wxRA_SPECIFY_COLS) != 0;
 
-    switch ( dir )
+    do
     {
-        case wxUP:
-            if ( horz )
-            {
-                item -= numCols;
-            }
-            else // vertical layout
-            {
-                if ( !item-- )
-                    item = count - 1;
-            }
-            break;
-
-        case wxLEFT:
-            if ( horz )
-            {
-                if ( !item-- )
-                    item = count - 1;
-            }
-            else // vertical layout
-            {
-                item -= numRows;
-            }
-            break;
-
-        case wxDOWN:
-            if ( horz )
-            {
-                item += numCols;
-            }
-            else // vertical layout
-            {
-                if ( ++item == count )
-                    item = 0;
-            }
-            break;
-
-        case wxRIGHT:
-            if ( horz )
-            {
-                if ( ++item == count )
-                    item = 0;
-            }
-            else // vertical layout
-            {
-                item += numRows;
-            }
-            break;
-
-        default:
-            wxFAIL_MSG( _T("unexpected wxDirection value") );
-            return wxNOT_FOUND;
-    }
+        switch ( dir )
+        {
+            case wxUP:
+                if ( horz )
+                {
+                    item -= numCols;
+                }
+                else // vertical layout
+                {
+                    if ( !item-- )
+                        item = count - 1;
+                }
+                break;
+
+            case wxLEFT:
+                if ( horz )
+                {
+                    if ( !item-- )
+                        item = count - 1;
+                }
+                else // vertical layout
+                {
+                    item -= numRows;
+                }
+                break;
+
+            case wxDOWN:
+                if ( horz )
+                {
+                    item += numCols;
+                }
+                else // vertical layout
+                {
+                    if ( ++item == count )
+                        item = 0;
+                }
+                break;
+
+            case wxRIGHT:
+                if ( horz )
+                {
+                    if ( ++item == count )
+                        item = 0;
+                }
+                else // vertical layout
+                {
+                    item += numRows;
+                }
+                break;
+
+            default:
+                wxFAIL_MSG( _T("unexpected wxDirection value") );
+                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;
-    }
+        // 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()") );
+        wxASSERT_MSG( item < count && item >= 0,
+                      _T("logic error in wxRadioBox::GetNextItem()") );
+    }
+    // we shouldn't select the non-active items, continue looking for a
+    // visible and shown one unless we came back to the item we started from in
+    // which case bail out to avoid infinite loop
+    while ( !(IsItemShown(item) && IsItemEnabled(item)) && item != itemStart );
 
     return item;
 }