From 5644933fa64abf5a122e3f15d0a66d415a63c35b Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Mon, 26 Mar 2007 22:10:04 +0000
Subject: [PATCH] added wxWindow::NavigateIn(); provide wxGTK implementation of
 DoNavigateIn() working with native tab traversal

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@45084 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/changes.txt           |  6 ++++++
 docs/latex/wx/tsamples.tex |  6 ++++--
 docs/latex/wx/window.tex   | 19 +++++++++++++++++--
 include/wx/gtk/window.h    |  2 ++
 include/wx/window.h        | 20 ++++++++++++++++++--
 src/common/wincmn.cpp      | 17 +++++++++--------
 src/gtk/window.cpp         | 24 ++++++++++++++++++++++++
 7 files changed, 80 insertions(+), 14 deletions(-)

diff --git a/docs/changes.txt b/docs/changes.txt
index 39627c09e5..e3f0d309f9 100644
--- a/docs/changes.txt
+++ b/docs/changes.txt
@@ -15,6 +15,10 @@ Changes in behaviour not resulting in compilation errors, please read this!
   necessarily the window itself) is disabled, new function IsThisEnabled()
   with the same behaviour as old IsEnabled() was added.
 
+- Generating wxNavigationKeyEvent events doesn't work any more under wxGTK (and
+  other platforms in the future), use wxWindow::Navigate() or NavigateIn()
+  instead.
+
 Changes in behaviour which may result in compilation errors
 -----------------------------------------------------------
 
@@ -85,11 +89,13 @@ All (GUI):
 - Added wxJoystick::GetButtonState/Position() (Frank C Szczerba)
 - Added wxGridUpdateLocker helper class (Evgeniy Tarassov)
 - Support wxGRID_AUTOSIZE in wxGrid::SetRow/ColLabelSize() (Evgeniy Tarassov)
+- Added wxWindow::NavigateIn() in addition to existing Navigate()
 - Add support for <data> tags to wxrc
 
 wxGTK:
 
 - Native implementation for wxHyperlinkCtrl (Francesco Montorsi)
+- Native keyboard navigation implementation
 - Implemented support for underlined fonts in wxStaticText.
 - wxTopLevelWindow::SetSizeHints size increments now work.
 - wxTopLevelWindow::GetSize() returns the size including the WM decorations.
diff --git a/docs/latex/wx/tsamples.tex b/docs/latex/wx/tsamples.tex
index a1977b55cf..d85d0c16fd 100644
--- a/docs/latex/wx/tsamples.tex
+++ b/docs/latex/wx/tsamples.tex
@@ -488,8 +488,10 @@ This sample allows to test keyboard navigation (mostly done using the
 \texttt{\textsc{TAB}} key, hence the sample name) between different controls.
 It shows the use of 
 \helpref{wxWindow::MoveBeforeInTabOrder()}{wxwindowmovebeforeintaborder} and 
-\helpref{MoveAfterInTabOrder()}{wxwindowmoveafterintaborder} methods and of the
-wxNavigationKeyEvent.
+\helpref{MoveAfterInTabOrder()}{wxwindowmoveafterintaborder} methods to change
+the default order of the windows in the navigation chain and of 
+\helpref{wxWindow::Navigate()}{wxwindownavigate} for moving focus along this
+chain.
 
 
 \subsection{Text sample}\label{sampletext}
diff --git a/docs/latex/wx/window.tex b/docs/latex/wx/window.tex
index 874de4a13a..63f676e594 100644
--- a/docs/latex/wx/window.tex
+++ b/docs/latex/wx/window.tex
@@ -1771,13 +1771,19 @@ it.
 
 \func{bool}{Navigate}{\param{int}{ flags = wxNavigationKeyEvent::IsForward}}
 
-Does keyboard navigation from this window to another, by sending
-a wxNavigationKeyEvent.
+Performs a keyboard navigation action starting from this window. This method is
+equivalent to calling \helpref{NavigateIn()}{wxwindownavigatein} method on the
+parent window.
 
 \wxheading{Parameters}
 
 \docparam{flags}{A combination of wxNavigationKeyEvent::IsForward and wxNavigationKeyEvent::WinChange.}
 
+\wxheading{Return value}
+
+Returns \true if the focus was moved to another window or \false if nothing
+changed.
+
 \wxheading{Remarks}
 
 You may wish to call this from a text control custom keypress handler to do the default
@@ -1786,6 +1792,15 @@ a multiline text control with the wxTE\_PROCESS\_TAB style is to insert a tab
 and not navigate to the next control.
 
 
+\membersection{wxWindow::NavigateIn}\label{wxwindownavigatein}
+
+\func{bool}{NavigateIn}{\param{int}{ flags = wxNavigationKeyEvent::IsForward}}
+
+Performs a keyboard navigation action inside this window.
+
+See \helpref{Navigate}{wxwindownavigate} for more information.
+
+
 \membersection{wxWindow::NextControlId}\label{wxwindownextcontrolid}
 
 \func{static int}{NextControlId}{\param{int }{winid}}
diff --git a/include/wx/gtk/window.h b/include/wx/gtk/window.h
index e8d0e60fe3..82b9f99d8c 100644
--- a/include/wx/gtk/window.h
+++ b/include/wx/gtk/window.h
@@ -344,6 +344,8 @@ protected:
     void Init();
 
     virtual void DoMoveInTabOrder(wxWindow *win, MoveKind move);
+    virtual bool DoNavigateIn(int flags);
+
 
     // Copies m_children tab order to GTK focus chain:
     void RealizeTabOrder();
diff --git a/include/wx/window.h b/include/wx/window.h
index c48e7b8579..0a704011a7 100644
--- a/include/wx/window.h
+++ b/include/wx/window.h
@@ -62,6 +62,12 @@
     #define wxHAS_NATIVE_ENABLED_MANAGEMENT
 #endif
 
+// This is defined when the underlying toolkit handles tab traversal natively
+// (currently this only works under GTK+ 2)
+#ifdef __WXGTK20__
+    #define wxHAS_NATIVE_TAB_TRAVERSAL
+#endif
+
 // ----------------------------------------------------------------------------
 // forward declarations
 // ----------------------------------------------------------------------------
@@ -592,8 +598,14 @@ public:
     bool CanAcceptFocusFromKeyboard() const
         { return AcceptsFocusFromKeyboard() && CanAcceptFocus(); }
 
-        // navigates in the specified direction by sending a wxNavigationKeyEvent
-    virtual bool Navigate(int flags = wxNavigationKeyEvent::IsForward);
+        // navigates inside this window
+    bool NavigateIn(int flags = wxNavigationKeyEvent::IsForward)
+        { return DoNavigateIn(flags); }
+
+        // navigates in the specified direction from this window, this is
+        // equivalent to GetParent()->NavigateIn()
+    bool Navigate(int flags = wxNavigationKeyEvent::IsForward)
+        { return m_parent && ((wxWindowBase *)m_parent)->DoNavigateIn(flags); }
 
         // move this window just before/after the specified one in tab order
         // (the other window must be our sibling!)
@@ -1200,6 +1212,10 @@ protected:
     };
     virtual void DoMoveInTabOrder(wxWindow *win, MoveKind move);
 
+    // implementation of Navigate() and NavigateIn()
+    virtual bool DoNavigateIn(int flags);
+
+
 #if wxUSE_CONSTRAINTS
     // satisfy the constraints for the windows but don't set the window sizes
     void SatisfyConstraints();
diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp
index 51b6e771c3..49417dbaf7 100644
--- a/src/common/wincmn.cpp
+++ b/src/common/wincmn.cpp
@@ -2651,17 +2651,18 @@ bool wxWindowBase::TryParent(wxEvent& event)
 // keyboard navigation
 // ----------------------------------------------------------------------------
 
-// Navigates in the specified direction.
-bool wxWindowBase::Navigate(int flags)
+// Navigates in the specified direction inside this window
+bool wxWindowBase::DoNavigateIn(int flags)
 {
+#ifdef wxHAS_NATIVE_TAB_TRAVERSAL
+    // native code doesn't process our wxNavigationKeyEvents anyhow
+    return false;
+#else // !wxHAS_NATIVE_TAB_TRAVERSAL
     wxNavigationKeyEvent eventNav;
     eventNav.SetFlags(flags);
-    eventNav.SetEventObject(this);
-    if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav) )
-    {
-        return true;
-    }
-    return false;
+    eventNav.SetEventObject(FindFocus());
+    return GetEventHandler()->ProcessEvent(eventNav);
+#endif // wxHAS_NATIVE_TAB_TRAVERSAL/!wxHAS_NATIVE_TAB_TRAVERSAL
 }
 
 void wxWindowBase::DoMoveInTabOrder(wxWindow *win, MoveKind move)
diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp
index 291b13c614..7a5501119c 100644
--- a/src/gtk/window.cpp
+++ b/src/gtk/window.cpp
@@ -3358,6 +3358,30 @@ void wxWindowGTK::DoMoveInTabOrder(wxWindow *win, MoveKind move)
         wxapp_install_idle_handler();
 }
 
+bool wxWindowGTK::DoNavigateIn(int flags)
+{
+    if ( flags & wxNavigationKeyEvent::WinChange )
+    {
+        wxFAIL_MSG( _T("not implemented") );
+
+        return false;
+    }
+    else // navigate inside the container
+    {
+        wxWindow *parent = wxGetTopLevelParent(this);
+        wxCHECK_MSG( parent, false, _T("every window must have a TLW parent") );
+
+        GtkDirectionType dir;
+        dir = flags & wxNavigationKeyEvent::IsForward ? GTK_DIR_TAB_FORWARD
+                                                      : GTK_DIR_TAB_BACKWARD;
+
+        gboolean rc;
+        g_signal_emit_by_name(parent->m_widget, "focus", dir, &rc);
+
+        return rc == TRUE;
+    }
+}
+
 bool wxWindowGTK::GTKWidgetNeedsMnemonic() const
 {
     // none needed by default
-- 
2.50.0

