]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/containr.cpp
As small as possible reorganization within wxDateTime to please PCH in DLL build...
[wxWidgets.git] / src / common / containr.cpp
index 368cee065daaa97b9e30e7b3d0d67dc2c2b8baac..a08c3b16aeef1c7b38019190c3727c9d4e3e5ed4 100644 (file)
     #include "wx/scrolbar.h"
 #endif
 
+#ifdef __WXMSW__
+    #include "wx/radiobut.h"
+#endif
+
 // ============================================================================
 // implementation
 // ============================================================================
@@ -51,6 +55,7 @@ wxControlContainer::wxControlContainer(wxWindow *winParent)
     m_winLastFocused =
     m_winTmpDefault =
     m_winDefault = NULL;
+    m_inSetFocus = false;
 }
 
 bool wxControlContainer::AcceptsFocus() const
@@ -63,21 +68,21 @@ bool wxControlContainer::AcceptsFocus() const
         // at least one child will accept focus
         wxWindowList::compatibility_iterator node = m_winParent->GetChildren().GetFirst();
         if ( !node )
-            return TRUE;
+            return true;
 
 #ifdef __WXMAC__
         // wxMac has eventually the two scrollbars as children, they don't count
         // as real children in the algorithm mentioned above
         bool hasRealChildren = false ;
 #endif
-        
+
         while ( node )
         {
             wxWindow *child = node->GetData();
 
             if ( child->AcceptsFocus() )
             {
-                return TRUE;
+                return true;
             }
 
 #ifdef __WXMAC__
@@ -87,14 +92,14 @@ bool wxControlContainer::AcceptsFocus() const
 #endif
             node = node->GetNext();
         }
-        
+
 #ifdef __WXMAC__
         if ( !hasRealChildren )
-            return TRUE ;
+            return true ;
 #endif
     }
 
-    return FALSE;
+    return false;
 }
 
 void wxControlContainer::SetLastFocus(wxWindow *win)
@@ -286,13 +291,50 @@ void wxControlContainer::HandleOnNavigationKey( wxNavigationKeyEvent& event )
 
         wxWindow *child = node->GetData();
 
-        if ( child->AcceptsFocusFromKeyboard() )
+#if defined(__WXMSW__)
+        bool is_not_msw_rb = !m_winLastFocused ||
+                                !wxIsKindOf(m_winLastFocused,wxRadioButton);
+#else
+        static const bool is_not_msw_rb = true;
+#endif
+
+        if ( child->AcceptsFocusFromKeyboard() && is_not_msw_rb )
         {
             // if we're setting the focus to a child panel we should prevent it
             // from giving it to the child which had the focus the last time
             // and instead give it to the first/last child depending from which
             // direction we're coming
             event.SetEventObject(m_winParent);
+
+#if defined(__WXMSW__)
+            // we need to hop to the next activated
+            // radio button, not just the next radio
+            // button under MSW
+            if (wxIsKindOf(child,wxRadioButton))
+            {
+                wxRadioButton *rb = (wxRadioButton*) child;
+                if (!rb->GetValue())
+                {
+                    for (;;)
+                    {
+                        wxWindowList::compatibility_iterator node = children.Find( child );
+                        if (forward)
+                            node = node->GetNext();
+                        else
+                            node = node->GetPrevious();
+                        if (!node)
+                            return; // this would probably an error
+                        child = node->GetData();
+                        if (!wxIsKindOf(child,wxRadioButton))
+                            continue;
+                        rb = (wxRadioButton*) child;
+                        if (rb->GetValue())
+                            break;
+                    }
+                }
+            }
+#endif // __WXMSW__
+
             // disable propagation for this call as otherwise the event might
             // bounce back to us.
             wxPropagationDisabler disableProp(event);
@@ -307,7 +349,7 @@ void wxControlContainer::HandleOnNavigationKey( wxNavigationKeyEvent& event )
             }
             //else: the child manages its focus itself
 
-            event.Skip( FALSE );
+            event.Skip( false );
 
             return;
         }
@@ -341,6 +383,9 @@ bool wxControlContainer::DoSetFocus()
     wxLogTrace(_T("focus"), _T("SetFocus on wxPanel 0x%08lx."),
                (unsigned long)m_winParent->GetHandle());
 
+    if (m_inSetFocus)
+        return true;
+
     // when the panel gets the focus we move the focus to either the last
     // window that had the focus or the first one that can get it unless the
     // focus had been already set to some other child
@@ -351,7 +396,7 @@ bool wxControlContainer::DoSetFocus()
         if ( win == m_winParent )
         {
             // our child already has focus, don't take it away from it
-            return TRUE;
+            return true;
         }
 
         if ( win->IsTopLevel() )
@@ -364,7 +409,14 @@ bool wxControlContainer::DoSetFocus()
         win = win->GetParent();
     }
 
-    return SetFocusToChild();
+    // protect against infinite recursion:
+    m_inSetFocus = true;
+
+    bool ret = SetFocusToChild();
+
+    m_inSetFocus = false;
+
+    return ret;
 }
 
 void wxControlContainer::HandleOnFocus(wxFocusEvent& event)
@@ -390,8 +442,8 @@ bool wxControlContainer::SetFocusToChild()
 
 bool wxSetFocusToChild(wxWindow *win, wxWindow **childLastFocused)
 {
-    wxCHECK_MSG( win, FALSE, _T("wxSetFocusToChild(): invalid window") );
-    wxCHECK_MSG( childLastFocused, FALSE,
+    wxCHECK_MSG( win, false, _T("wxSetFocusToChild(): invalid window") );
+    wxCHECK_MSG( childLastFocused, false,
                  _T("wxSetFocusToChild(): NULL child poonter") );
 
     if ( *childLastFocused )
@@ -406,7 +458,7 @@ bool wxSetFocusToChild(wxWindow *win, wxWindow **childLastFocused)
             // not SetFocusFromKbd(): we're restoring focus back to the old
             // window and not setting it as the result of a kbd action
             (*childLastFocused)->SetFocus();
-            return TRUE;
+            return true;
         }
         else
         {
@@ -429,12 +481,12 @@ bool wxSetFocusToChild(wxWindow *win, wxWindow **childLastFocused)
 
             *childLastFocused = child;
             child->SetFocusFromKbd();
-            return TRUE;
+            return true;
         }
 
         node = node->GetNext();
     }
 
-    return FALSE;
+    return false;
 }