From 00ff24c81c0343c7372b9c45cbd1f9fbb8648555 Mon Sep 17 00:00:00 2001
From: Robert Roebling <robert@roebling.de>
Date: Mon, 17 Sep 2007 10:17:12 +0000
Subject: [PATCH] Always make wxWindow::SetFocus() focus the window, overriding
 SetCanFocus, some more focus related docs

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@48747 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/latex/wx/panel.tex  | 31 +++++++++++++-----
 docs/latex/wx/window.tex | 68 ++++++++++++++++++++++++++--------------
 include/wx/containr.h    |  9 +++---
 include/wx/gtk/window.h  |  3 +-
 src/gtk/window.cpp       | 31 ++++++------------
 5 files changed, 84 insertions(+), 58 deletions(-)

diff --git a/docs/latex/wx/panel.tex b/docs/latex/wx/panel.tex
index 6ccfa0a7f6..5883f63799 100644
--- a/docs/latex/wx/panel.tex
+++ b/docs/latex/wx/panel.tex
@@ -1,13 +1,19 @@
 \section{\class{wxPanel}}\label{wxpanel}
 
-A panel is a window on which controls are placed. It is usually placed within a frame.
-It contains minimal extra functionality over and above its parent class wxWindow; its main
-purpose is to be similar in appearance and functionality to a dialog, but with the flexibility of
-having any window as a parent.
+A panel is a window on which controls are placed. It is usually placed within
+a frame. Its main feature over its parent class wxWindow is code for handling
+child windows and TAB traversal. Since wxWidgets 2.9, there is support both
+for TAB traversal implemented by wxWidgets itself as well as native TAB
+traversal (such as for GTK 2.0).
 
-{\it Note:} if not all characters are being intercepted by your OnKeyDown or OnChar handler,
-it may be because you are using the wxTAB\_TRAVERSAL style, which grabs some keypresses for use
-by child controls.
+{\it Note:} Tab traversal is implemented through an otherwise undocumented
+intermediate wxControlContainer class from which any class can derive
+in addition to the normal wxWindow base class. Please see <wx/containr.h>
+and <wx/panel.h> to find out how this is achieved.
+
+{\it Note:} if not all characters are being intercepted by your OnKeyDown or
+OnChar handler, it may be because you are using the wxTAB\_TRAVERSAL style, 
+which grabs some keypresses for use by child controls.
 
 \wxheading{Derived from}
 
@@ -88,6 +94,17 @@ Destructor. Deletes any child windows before deleting the physical window.
 Used for two-step panel construction. See \helpref{wxPanel::wxPanel}{wxpanelctor}\rtfsp
 for details.
 
+
+\membersection{wxPanel::AcceptsFocus}\label{wxpanelacceptsfocus}
+
+\constfunc{bool}{AcceptsFocus}{\void}
+
+This method is overridden from \helpref{wxWindow::AcceptsFocus}{wxwindowacceptsfocus}
+and returns true only if there is no child window in the panel which
+can accept the focus. This is reevaluated each time a child
+window is added or removed from the panel.
+
+
 \membersection{wxPanel::InitDialog}\label{wxpanelinitdialog}
 
 \func{void}{InitDialog}{\void}
diff --git a/docs/latex/wx/window.tex b/docs/latex/wx/window.tex
index 7fad11545a..1ce3f15b5f 100644
--- a/docs/latex/wx/window.tex
+++ b/docs/latex/wx/window.tex
@@ -2780,26 +2780,23 @@ background, such as a tiled bitmap. Currently the style has no effect on other p
 \helpref{wxWindow::GetBackgroundStyle}{wxwindowgetbackgroundstyle}
 
 
-\membersection{wxWindow::SetInitialSize}\label{wxwindowsetinitialsize}
-
-\func{void}{SetInitialSize}{\param{const wxSize\& }{size = wxDefaultSize}}
 
-A {\it smart} SetSize that will fill in default size components with the
-window's {\it best} size values.  Also sets the window's minsize to
-the value passed in for use with sizers.  This means that if a full or
-partial size is passed to this function then the sizers will use that
-size instead of the results of GetBestSize to determine the minimum
-needs of the window for layout.
+\membersection{wxWindow::SetCanFocus}\label{wxwindowsetcanfocus}
 
-Most controls will use this to set their initial size, and their min
-size to the passed in value (if any.)
+\func{virtual void}{SetCanFocus}{\param{bool}{ canFocus}}
 
+This method is only implemented by ports which have support for
+native TAB traversal (such as GTK+ 2.0). It is called by wxWidgets'
+container control code to give the native system a hint when
+doing TAB traversal. A call to this does not disable or change
+the effect of programmatically calling 
+\helpref{wxWindow::SetFocus}{wxwindowsetfocus}.
 
 \wxheading{See also}
 
-\helpref{wxWindow::SetSize}{wxwindowsetsize},\rtfsp
-\helpref{wxWindow::GetBestSize}{wxwindowgetbestsize},\rtfsp
-\helpref{wxWindow::GetEffectiveMinSize}{wxwindowgeteffectiveminsize}
+\helpref{wxFocusEvent}{wxfocusevent}
+\helpref{wxPanel::SetFocus}{wxpanelsetfocus}
+\helpref{wxPanel::SetFocusIgnoringChildren}{wxpanelsetfocusignoringchildren}
 
 
 \membersection{wxWindow::SetCaret}\label{wxwindowsetcaret}
@@ -2903,13 +2900,6 @@ If the window already has a drop target, it is deleted.
 
 
 
-\membersection{wxWindow::SetInitialBestSize}\label{wxwindowsetinitialbestsize}
-
-\func{virtual void}{SetInitialBestSize}{\param{const wxSize\& }{size}}
-
-Sets the initial window size if none is given (i.e. at least one of the
-components of the size passed to ctor/Create() is wxDefaultCoord).
-
 \membersection{wxWindow::SetEventHandler}\label{wxwindowseteventhandler}
 
 \func{void}{SetEventHandler}{\param{wxEvtHandler* }{handler}}
@@ -2928,9 +2918,9 @@ an application may wish to substitute another, for example to allow
 central implementation of event-handling for a variety of different
 window classes.
 
-It is usually better to use \helpref{wxWindow::PushEventHandler}{wxwindowpusheventhandler} since
-this sets up a chain of event handlers, where an event not handled by one event handler is
-handed to the next one in the chain.
+It is usually better to use \helpref{wxWindow::PushEventHandler}{wxwindowpusheventhandler}
+since this sets up a chain of event handlers, where an event not handled by
+one event handler is handed to the next one in the chain.
 
 \wxheading{See also}
 
@@ -3098,6 +3088,36 @@ on creation and should not be modified subsequently.
 
 
 
+\membersection{wxWindow::SetInitialBestSize}\label{wxwindowsetinitialbestsize}
+
+\func{virtual void}{SetInitialBestSize}{\param{const wxSize\& }{size}}
+
+Sets the initial window size if none is given (i.e. at least one of the
+components of the size passed to ctor/Create() is wxDefaultCoord).
+
+
+\membersection{wxWindow::SetInitialSize}\label{wxwindowsetinitialsize}
+
+\func{void}{SetInitialSize}{\param{const wxSize\& }{size = wxDefaultSize}}
+
+A {\it smart} SetSize that will fill in default size components with the
+window's {\it best} size values.  Also sets the window's minsize to
+the value passed in for use with sizers.  This means that if a full or
+partial size is passed to this function then the sizers will use that
+size instead of the results of GetBestSize to determine the minimum
+needs of the window for layout.
+
+Most controls will use this to set their initial size, and their min
+size to the passed in value (if any.)
+
+
+\wxheading{See also}
+
+\helpref{wxWindow::SetSize}{wxwindowsetsize},\rtfsp
+\helpref{wxWindow::GetBestSize}{wxwindowgetbestsize},\rtfsp
+\helpref{wxWindow::GetEffectiveMinSize}{wxwindowgeteffectiveminsize}
+
+
 \membersection{wxWindow::SetLabel}\label{wxwindowsetlabel}
 
 \func{virtual void}{SetLabel}{\param{const wxString\& }{label}}
diff --git a/include/wx/containr.h b/include/wx/containr.h
index 0d38361739..87ab324a28 100644
--- a/include/wx/containr.h
+++ b/include/wx/containr.h
@@ -70,10 +70,9 @@ public:
     // wxListCtrl) and so should get focus for ourselves
     bool AcceptsFocusRecursively() const { return true; }
 
-    // call this when the number of children of the window changes
-    //
-    // note that we have any children, this panel (used just as container for
-    // them) shouldn't get focus for itself
+    // Call this when the number of children of the window changes.
+    // If we have any children, this panel (used just as container for
+    // them) shouldn't get focus for itself.
     void UpdateCanFocus() { SetCanFocus(!HasAnyFocusableChildren()); }
 
 protected:
@@ -177,7 +176,7 @@ protected:
                                                                               \
     void classname::SetFocusIgnoringChildren()                                \
     {                                                                         \
-        basename::SetFocusIgnoringChildren();                                 \
+        basename::SetFocus();                                                 \
     }
 
 #else // !wxHAS_NATIVE_TAB_TRAVERSAL
diff --git a/include/wx/gtk/window.h b/include/wx/gtk/window.h
index 2a623ee0c1..f2126cf432 100644
--- a/include/wx/gtk/window.h
+++ b/include/wx/gtk/window.h
@@ -60,7 +60,8 @@ public:
     virtual bool IsRetained() const;
 
     virtual void SetFocus();
-    virtual void SetFocusIgnoringChildren();
+    
+    // hint from wx to native GTK+ tab traversal code
     virtual void SetCanFocus(bool canFocus);
 
     virtual bool Reparent( wxWindowBase *newParent );
diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp
index bb6bd9a565..d8ae28d541 100644
--- a/src/gtk/window.cpp
+++ b/src/gtk/window.cpp
@@ -25,7 +25,6 @@
     #include "wx/settings.h"
     #include "wx/msgdlg.h"
     #include "wx/textctrl.h"
-    #include "wx/radiobut.h"
     #include "wx/toolbar.h"
     #include "wx/combobox.h"
     #include "wx/layout.h"
@@ -3172,7 +3171,7 @@ bool wxWindowGTK::GTKSetDelayedFocusIfNeeded()
     return false;
 }
 
-void wxWindowGTK::SetFocusIgnoringChildren()
+void wxWindowGTK::SetFocus()
 {
     wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
     if ( m_hasFocus )
@@ -3183,24 +3182,11 @@ void wxWindowGTK::SetFocusIgnoringChildren()
 
     if (m_wxwindow)
     {
+        // wxWindow::SetFocus() should really set the focus to
+        // this control, whatever the flags are
         if (!GTK_WIDGET_CAN_FOCUS(m_wxwindow))
             GTK_WIDGET_SET_FLAGS(m_wxwindow, GTK_CAN_FOCUS);
-    }
-    
-    wxWindowGTK::SetFocus();
-}
-
-void wxWindowGTK::SetFocus()
-{
-    wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
-    if ( m_hasFocus )
-    {
-        // don't do anything if we already have focus
-        return;
-    }
-
-    if (m_wxwindow)
-    {
+            
         if (!GTK_WIDGET_HAS_FOCUS (m_wxwindow))
         {
             gtk_widget_grab_focus (m_wxwindow);
@@ -3208,15 +3194,18 @@ void wxWindowGTK::SetFocus()
     }
     else if (m_widget)
     {
+        // wxWindow::SetFocus() should really set the focus to
+        // this control, whatever the flags are
+        if (!GTK_WIDGET_CAN_FOCUS(m_widget))
+            GTK_WIDGET_SET_FLAGS(m_widget, GTK_CAN_FOCUS);
+            
         if (GTK_IS_CONTAINER(m_widget))
         {
-#if wxUSE_RADIOBTN
-            if (IsKindOf(CLASSINFO(wxRadioButton)))
+            if (GTK_IS_RADIO_BUTTON(m_widget))
             {
                 gtk_widget_grab_focus (m_widget);
                 return;
             }
-#endif // wxUSE_RADIOBTN
 
             gtk_widget_child_focus( m_widget, GTK_DIR_TAB_FORWARD );
         }
-- 
2.50.0

