]> git.saurik.com Git - wxWidgets.git/commitdiff
Fix tab navigation bug with radio boxes without enabled items.
authorVadim Zeitlin <vadim@wxwidgets.org>
Tue, 23 Jul 2013 12:44:33 +0000 (12:44 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Tue, 23 Jul 2013 12:44:33 +0000 (12:44 +0000)
There was a bug similar to the one in the preceding commit with radio boxes
under wxMSW too: if all radio box buttons were disabled (or hidden, although
this should be much more rare in practice, unlike the disabled case which was
deemed to be rare in r74583 commit message but turned out to actually happen),
the radio box still pretended to accept focus but didn't really do it.

Fix this by allowing to override wxWindow::CanBeFocused() and do it in
wxRadioBox to check whether we have any enabled visible items.

Also add a check for CanBeFocused() to wxControlContainer code.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74586 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/containr.h
include/wx/msw/radiobox.h
include/wx/window.h
src/msw/radiobox.cpp

index 3f91f3e6a37c6c6f524aab780f920365852c1dcd..b465e33c30b5c8aec34f8e19a539211a4f79741d 100644 (file)
@@ -76,11 +76,12 @@ public:
     bool DoSetFocus();
 
     // returns whether we should accept focus ourselves or not
     bool DoSetFocus();
 
     // returns whether we should accept focus ourselves or not
-    bool AcceptsFocus() const { return m_acceptsFocusSelf; }
+    bool AcceptsFocus() const
+        { return m_acceptsFocusSelf && m_winParent->CanBeFocused(); }
 
     // Returns whether we or one of our children accepts focus.
     bool AcceptsFocusRecursively() const
 
     // Returns whether we or one of our children accepts focus.
     bool AcceptsFocusRecursively() const
-        { return m_acceptsFocusSelf ||
+        { return AcceptsFocus() ||
             (m_acceptsFocusChildren && HasAnyChildrenAcceptingFocus()); }
 
     // We accept focus from keyboard if we accept it at all.
             (m_acceptsFocusChildren && HasAnyChildrenAcceptingFocus()); }
 
     // We accept focus from keyboard if we accept it at all.
index a0f546df9dd998173d668ebabcecdcc636c276f5..def96487c80f6982eebc54e82a48f80d0c90fc38 100644 (file)
@@ -97,6 +97,7 @@ public:
     // override some base class methods
     virtual bool Show(bool show = true);
     virtual bool Enable(bool enable = true);
     // override some base class methods
     virtual bool Show(bool show = true);
     virtual bool Enable(bool enable = true);
+    virtual bool CanBeFocused() const;
     virtual void SetFocus();
     virtual bool SetFont(const wxFont& font);
     virtual bool ContainsHWND(WXHWND hWnd) const;
     virtual void SetFocus();
     virtual bool SetFont(const wxFont& font);
     virtual bool ContainsHWND(WXHWND hWnd) const;
index 52c7a4c466bacd097afd74c1044deffc79efad59..a8f757037b0d7917d4b3155df0def00734daea5e 100644 (file)
@@ -724,8 +724,13 @@ public:
     virtual bool AcceptsFocusFromKeyboard() const { return AcceptsFocus(); }
 
 
     virtual bool AcceptsFocusFromKeyboard() const { return AcceptsFocus(); }
 
 
-        // this is mostly a helper for the various functions using it below
-    bool CanBeFocused() const { return IsShown() && IsEnabled(); }
+        // Can this window be focused right now, in its current state? This
+        // shouldn't be called at all if AcceptsFocus() returns false.
+        //
+        // It is a convenient helper for the various functions using it below
+        // but also a hook allowing to override the default logic for some rare
+        // cases (currently just wxRadioBox in wxMSW) when it's inappropriate.
+    virtual bool CanBeFocused() const { return IsShown() && IsEnabled(); }
 
         // can this window itself have focus?
     bool IsFocusable() const { return AcceptsFocus() && CanBeFocused(); }
 
         // can this window itself have focus?
     bool IsFocusable() const { return AcceptsFocus() && CanBeFocused(); }
index 7f811c921651530846ec9c039aefa0d188dbe83b..51fbac285ac3699e6c5f2a42eda3d03802af6323 100644 (file)
@@ -444,6 +444,25 @@ void wxRadioBox::SetFocus()
     }
 }
 
     }
 }
 
+bool wxRadioBox::CanBeFocused() const
+{
+    // If the control itself is hidden or disabled, no need to check anything
+    // else.
+    if ( !wxStaticBox::CanBeFocused() )
+        return false;
+
+    // Otherwise, check if we have any buttons that can be focused.
+    for ( size_t item = 0; item < m_radioButtons->GetCount(); item++ )
+    {
+        if ( IsItemEnabled(item) && IsItemShown(item) )
+            return true;
+    }
+
+    // We didn't find any items that can accept focus, so neither can we as a
+    // whole accept it.
+    return false;
+}
+
 // Enable a specific button
 bool wxRadioBox::Enable(unsigned int item, bool enable)
 {
 // Enable a specific button
 bool wxRadioBox::Enable(unsigned int item, bool enable)
 {