]> git.saurik.com Git - wxWidgets.git/commitdiff
A number of focus handling improvements:
authorJulian Smart <julian@anthemion.co.uk>
Sat, 18 Aug 2007 10:54:31 +0000 (10:54 +0000)
committerJulian Smart <julian@anthemion.co.uk>
Sat, 18 Aug 2007 10:54:31 +0000 (10:54 +0000)
Left clicking on a window only focuses the window if not processed.
wxControlContainer::SetFocus moved to wxControlContainerBase so that a container now focuses the first child even on wxGTK.
wxAuiBook is now a container, need for correct navigation on wxGTK.

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

include/wx/aui/auibook.h
include/wx/containr.h
src/aui/auibook.cpp
src/common/containr.cpp
src/gtk/window.cpp

index b62ec91d30aa4e538109447ba35c2e73d4533e57..a3de9e25cad905b7c0e893b3dfa8e487d2a34ba8 100644 (file)
@@ -1,4 +1,4 @@
-///////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
 // Name:        wx/aui/auibook.h
 // Purpose:     wxaui: wx advanced user interface - notebook
 // Author:      Benjamin I. Williams
@@ -576,7 +576,7 @@ public:
     virtual bool HasMultiplePages() const { return true; }
 
     // we don't want focus for ourselves
-    virtual bool AcceptsFocus() const { return false; }
+    // virtual bool AcceptsFocus() const { return false; }
 
 protected:
 
@@ -641,6 +641,9 @@ protected:
     DECLARE_CLASS(wxAuiNotebook)
     DECLARE_EVENT_TABLE()
 #endif
+
+    WX_DECLARE_CONTROL_CONTAINER();
+
 };
 
 
index 6ac64a461663c27910f1de3fb08d082d5e7f5b10..2d4cd3d0993b15ea50c390d3e9a87bbb871ad186 100644 (file)
@@ -42,7 +42,10 @@ public:
         // do accept focus initially, we'll stop doing it if/when any children
         // are added
         m_acceptsFocus = true;
+        m_inSetFocus = false;
+        m_winLastFocused = NULL;
     }
+    virtual ~wxControlContainerBase() {}
 
     void SetContainerWindow(wxWindow *winParent)
     {
@@ -51,6 +54,10 @@ public:
         m_winParent = winParent;
     }
 
+    // should be called from SetFocus(), returns false if we did nothing with
+    // the focus and the default processing should take place
+    bool DoSetFocus();
+
     // should be called when we decide that we should [stop] accepting focus
     void SetCanFocus(bool acceptsFocus);
 
@@ -70,6 +77,9 @@ public:
     void UpdateCanFocus() { SetCanFocus(!HasAnyFocusableChildren()); }
 
 protected:
+    // set the focus to the child which had it the last time
+    virtual bool SetFocusToChild();
+
     // return true if we have any children accepting focus
     bool HasAnyFocusableChildren() const;
 
@@ -80,6 +90,13 @@ private:
     // value returned by AcceptsFocus(), should be changed using SetCanFocus()
     // only
     bool m_acceptsFocus;
+
+    // a guard against infinite recursion
+    bool m_inSetFocus;
+
+    // the child which had the focus last time this panel was activated
+    wxWindow *m_winLastFocused;
+
 };
 
 // common part of WX_DECLARE_CONTROL_CONTAINER in the native and generic cases,
@@ -90,6 +107,7 @@ public:                                                                       \
     virtual bool AcceptsFocusRecursively() const;                             \
     virtual void AddChild(wxWindowBase *child);                               \
     virtual void RemoveChild(wxWindowBase *child);                            \
+    virtual void SetFocus();                                                  \
     void SetFocusIgnoringChildren();                                          \
     void AcceptFocus(bool acceptFocus)                                        \
     {                                                                         \
@@ -118,6 +136,12 @@ protected:                                                                    \
         return m_container.AcceptsFocusRecursively();                         \
     }                                                                         \
                                                                               \
+    void classname::SetFocus()                                                \
+    {                                                                         \
+        if ( !m_container.DoSetFocus() )                                      \
+            basename::SetFocus();                                             \
+    }                                                                         \
+                                                                              \
     bool classname::AcceptsFocus() const                                      \
     {                                                                         \
         return m_container.AcceptsFocus();                                    \
@@ -133,6 +157,9 @@ protected:                                                                    \
 // this must be a real class as we forward-declare it elsewhere
 class WXDLLEXPORT wxControlContainer : public wxControlContainerBase
 {
+protected:
+    // set the focus to the child which had it the last time
+    virtual bool SetFocusToChild();
 };
 
 #define WX_EVENT_TABLE_CONTROL_CONTAINER(classname)
@@ -174,30 +201,15 @@ public:
     void HandleOnFocus(wxFocusEvent& event);
     void HandleOnWindowDestroy(wxWindowBase *child);
 
-    // should be called from SetFocus(), returns false if we did nothing with
-    // the focus and the default processing should take place
-    bool DoSetFocus();
-
     // called from OnChildFocus() handler, i.e. when one of our (grand)
     // children gets the focus
     void SetLastFocus(wxWindow *win);
 
 protected:
-    // set the focus to the child which had it the last time
-    bool SetFocusToChild();
-
-    // the child which had the focus last time this panel was activated
-    wxWindow *m_winLastFocused;
-
-    // a guard against infinite recursion
-    bool m_inSetFocus;
 
     DECLARE_NO_COPY_CLASS(wxControlContainer)
 };
 
-// this function is for wxWidgets internal use only
-extern bool wxSetFocusToChild(wxWindow *win, wxWindow **child);
-
 // ----------------------------------------------------------------------------
 // macros which may be used by the classes wishing to implement TAB navigation
 // among their children
@@ -210,8 +222,7 @@ extern bool wxSetFocusToChild(wxWindow *win, wxWindow **child);
 public:                                                                       \
     void OnNavigationKey(wxNavigationKeyEvent& event);                        \
     void OnFocus(wxFocusEvent& event);                                        \
-    virtual void OnChildFocus(wxChildFocusEvent& event);                      \
-    virtual void SetFocus()
+    virtual void OnChildFocus(wxChildFocusEvent& event)
 
 // implement the event table entries for wxControlContainer
 #define WX_EVENT_TABLE_CONTROL_CONTAINER(classname) \
@@ -237,12 +248,6 @@ public:                                                                       \
         m_container.HandleOnNavigationKey(event);                             \
     }                                                                         \
                                                                               \
-    void classname::SetFocus()                                                \
-    {                                                                         \
-        if ( !m_container.DoSetFocus() )                                      \
-            basename::SetFocus();                                             \
-    }                                                                         \
-                                                                              \
     void classname::SetFocusIgnoringChildren()                                \
     {                                                                         \
         basename::SetFocus();                                                 \
@@ -260,4 +265,7 @@ public:                                                                       \
 
 #endif // wxHAS_NATIVE_TAB_TRAVERSAL/!wxHAS_NATIVE_TAB_TRAVERSAL
 
+// this function is for wxWidgets internal use only
+extern bool wxSetFocusToChild(wxWindow *win, wxWindow **child);
+
 #endif // _WX_CONTAINR_H_
index 1676de5b211ff1be2335cae893735f621e015808..6288695abe3705896bc8769fa576974e232fd9c2 100644 (file)
@@ -2168,6 +2168,7 @@ wxAuiTabCtrl::wxAuiTabCtrl(wxWindow* parent,
                            const wxSize& size,
                            long style) : wxControl(parent, id, pos, size, style)
 {
+    SetName(wxT("wxAuiTabCtrl"));
     m_click_pt = wxDefaultPosition;
     m_is_dragging = false;
     m_hover_button = NULL;
@@ -2712,8 +2713,12 @@ BEGIN_EVENT_TABLE(wxAuiNotebook, wxControl)
                       wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP,
                       wxAuiNotebook::OnTabRightUp)
     EVT_NAVIGATION_KEY(wxAuiNotebook::OnNavigationKey)
+
+    WX_EVENT_TABLE_CONTROL_CONTAINER(wxAuiNotebook)
 END_EVENT_TABLE()
 
+WX_DELEGATE_TO_CONTROL_CONTAINER(wxAuiNotebook, wxControl)
+
 wxAuiNotebook::wxAuiNotebook()
 {
     m_curpage = -1;
@@ -2754,6 +2759,10 @@ bool wxAuiNotebook::Create(wxWindow* parent,
 // code called by all constructors
 void wxAuiNotebook::InitNotebook(long style)
 {
+    WX_INIT_CONTROL_CONTAINER();
+    // SetCanFocus(false);
+
+    SetName(wxT("wxAuiNotebook"));
     m_curpage = -1;
     m_tab_id_counter = wxAuiBaseTabCtrlId;
     m_dummy_wnd = NULL;
index c62e2ebd427c275967d3c9c3b006fb76d8e9017a..2f702e6f1af7831f0b4f2ae9e4bd4f45963b9cb5 100644 (file)
@@ -77,6 +77,52 @@ bool wxControlContainerBase::HasAnyFocusableChildren() const
     return false;
 }
 
+bool wxControlContainerBase::DoSetFocus()
+{
+    wxLogTrace(TRACE_FOCUS, _T("SetFocus on wxPanel 0x%p."),
+               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
+
+    wxWindow *win = wxWindow::FindFocus();
+    while ( win )
+    {
+        if ( win == m_winParent )
+        {
+            // our child already has focus, don't take it away from it
+            return true;
+        }
+
+        if ( win->IsTopLevel() )
+        {
+            // don't look beyond the first top level parent - useless and
+            // unnecessary
+            break;
+        }
+
+        win = win->GetParent();
+    }
+
+    // protect against infinite recursion:
+    m_inSetFocus = true;
+
+    bool ret = SetFocusToChild();
+
+    m_inSetFocus = false;
+
+    return ret;
+}
+
+bool wxControlContainerBase::SetFocusToChild()
+{
+    return wxSetFocusToChild(m_winParent, &m_winLastFocused);
+}
+
 #ifndef wxHAS_NATIVE_TAB_TRAVERSAL
 
 // ----------------------------------------------------------------------------
@@ -86,7 +132,6 @@ bool wxControlContainerBase::HasAnyFocusableChildren() const
 wxControlContainer::wxControlContainer()
 {
     m_winLastFocused = NULL;
-    m_inSetFocus = false;
 }
 
 void wxControlContainer::SetLastFocus(wxWindow *win)
@@ -552,47 +597,6 @@ void wxControlContainer::HandleOnWindowDestroy(wxWindowBase *child)
 // focus handling
 // ----------------------------------------------------------------------------
 
-bool wxControlContainer::DoSetFocus()
-{
-    wxLogTrace(TRACE_FOCUS, _T("SetFocus on wxPanel 0x%p."),
-               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
-
-    wxWindow *win = wxWindow::FindFocus();
-    while ( win )
-    {
-        if ( win == m_winParent )
-        {
-            // our child already has focus, don't take it away from it
-            return true;
-        }
-
-        if ( win->IsTopLevel() )
-        {
-            // don't look beyond the first top level parent - useless and
-            // unnecessary
-            break;
-        }
-
-        win = win->GetParent();
-    }
-
-    // protect against infinite recursion:
-    m_inSetFocus = true;
-
-    bool ret = SetFocusToChild();
-
-    m_inSetFocus = false;
-
-    return ret;
-}
-
 void wxControlContainer::HandleOnFocus(wxFocusEvent& event)
 {
     wxLogTrace(TRACE_FOCUS, _T("OnFocus on wxPanel 0x%p, name: %s"),
@@ -604,11 +608,18 @@ void wxControlContainer::HandleOnFocus(wxFocusEvent& event)
     event.Skip();
 }
 
+
+#else
+  // wxHAS_NATIVE_TAB_TRAVERSAL
+
 bool wxControlContainer::SetFocusToChild()
 {
-    return wxSetFocusToChild(m_winParent, &m_winLastFocused);
+    return wxSetFocusToChild(m_winParent, NULL);
 }
 
+
+#endif // !wxHAS_NATIVE_TAB_TRAVERSAL
+
 // ----------------------------------------------------------------------------
 // SetFocusToChild(): this function is used by wxPanel but also by wxFrame in
 // wxMSW, this is why it is outside of wxControlContainer class
@@ -617,10 +628,10 @@ bool wxControlContainer::SetFocusToChild()
 bool wxSetFocusToChild(wxWindow *win, wxWindow **childLastFocused)
 {
     wxCHECK_MSG( win, false, _T("wxSetFocusToChild(): invalid window") );
-    wxCHECK_MSG( childLastFocused, false,
-                 _T("wxSetFocusToChild(): NULL child poonter") );
+    //    wxCHECK_MSG( childLastFocused, false,
+    //             _T("wxSetFocusToChild(): NULL child poonter") );
 
-    if ( *childLastFocused )
+    if ( childLastFocused && *childLastFocused )
     {
         // It might happen that the window got reparented
         if ( (*childLastFocused)->GetParent() == win )
@@ -670,7 +681,8 @@ bool wxSetFocusToChild(wxWindow *win, wxWindow **childLastFocused)
                        _T("SetFocusToChild() => first child (0x%p)."),
                        child->GetHandle());
 
-            *childLastFocused = child;
+            if (childLastFocused)
+                *childLastFocused = child;
             child->SetFocusFromKbd();
             return true;
         }
@@ -679,4 +691,3 @@ bool wxSetFocusToChild(wxWindow *win, wxWindow **childLastFocused)
     return false;
 }
 
-#endif // !wxHAS_NATIVE_TAB_TRAVERSAL
index 5c68e602d4da8d74d8d8b20bb379235ea0ee01d1..e8b8ed17199df2c4bd92977964fb616459fdd0ac 100644 (file)
@@ -1440,11 +1440,6 @@ gtk_window_button_press_callback( GtkWidget *widget,
 
     g_lastButtonNumber = gdk_event->button;
 
-    if (win->m_wxwindow && (g_focusWindow != win) && win->IsFocusable())
-    {
-        gtk_widget_grab_focus( win->m_wxwindow );
-    }
-
     // GDK sends surplus button down events
     // before a double click event. We
     // need to filter these out.
@@ -1576,9 +1571,9 @@ gtk_window_button_press_callback( GtkWidget *widget,
         return TRUE;
 
     if ((event_type == wxEVT_LEFT_DOWN) && !win->IsOfStandardClass() && 
-        (g_focusWindow != win) && win->IsFocusable())
+        (g_focusWindow != win) /* && win->IsFocusable() */)
     {
-        gtk_widget_grab_focus( win->m_wxwindow );
+        win->SetFocus();
     }
 
     if (event_type == wxEVT_RIGHT_DOWN)
@@ -1870,7 +1865,9 @@ gtk_window_focus_out_callback( GtkWidget *widget,
         // Disable default focus handling for custom windows
         // since the default GTK+ handler issues a repaint
         if ( has_wxwindow )
+       {
             return TRUE;
+       }
     }
 
     // continue with normal processing