From a24de76b33ff8c30343d322ba9031527f0ba060f Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Thu, 1 Jul 2004 11:44:37 +0000
Subject: [PATCH] added and documented wxWindow::MoveBefore/AfterInTabOrder()

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@28132 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/changes.txt         |  5 +++--
 docs/latex/wx/window.tex | 28 ++++++++++++++++++++++++++++
 include/wx/window.h      | 17 ++++++++++++++++-
 src/common/wincmn.cpp    | 26 +++++++++++++++++++++++++-
 4 files changed, 72 insertions(+), 4 deletions(-)

diff --git a/docs/changes.txt b/docs/changes.txt
index a0d54f66a4..583bb24b1e 100644
--- a/docs/changes.txt
+++ b/docs/changes.txt
@@ -120,11 +120,12 @@ All:
 
 All (GUI):
 
+- added wxWindow::MoveBefore/AfterInTabOrder() to change tab navigation order
 - added wxTaskBarIcon::CreatePopupMenu which is now recommended way
   of showing popup menu; calling wxTaskBarIcon::PopupMenu directly
   is discouraged
-- Added ..._CMD_...(id) variants for wxGrid event table entry macros
-- Added wxWindow::Navigate for programmatic navigation to the next control.
+- added ..._CMD_...(id) variants for wxGrid event table entry macros
+- added wxWindow::Navigate for programmatic navigation to the next control.
 - wxTextCtrl::OnChar now inserts a tab character if wxTE_PROCESS_TAB is set
 - added wxKeyEvent::GetUnicodeKey()
 - added wxKeyEvent::CmdDown() and wxMouseEvent::CmdDown()
diff --git a/docs/latex/wx/window.tex b/docs/latex/wx/window.tex
index 9cf6cadb0c..b3b6ba5ab0 100644
--- a/docs/latex/wx/window.tex
+++ b/docs/latex/wx/window.tex
@@ -1461,6 +1461,34 @@ implements the following methods:\par
 \end{twocollist}}
 }
 
+
+\membersection{wxWindow::MoveAfterInTabOrder}\label{wxwindowmoveafterintaborder}
+
+\func{void}{MoveAfterInTabOrder}{\param{wxWindow *}{win}}
+
+Moves this window in the tab navigation order after the specified \arg{win}.
+This means that when the user presses \texttt{TAB} key on that other window,
+the focus switches to this window.
+
+Default tab order is the same as creation order, this function and 
+\helpref{MoveBeforeInTabOrder()}{wxwindowmovebeforeintaborder} allow to change
+it after creating all the windows.
+
+\wxheading{Parameters}
+
+\docparam{win}{A sibling of this window which should precede it in tab order,
+must not be NULL}
+
+
+\membersection{wxWindow::MoveBeforeInTabOrder}\label{wxwindowmovebeforeintaborder}
+
+\func{void}{MoveBeforeInTabOrder}{\param{wxWindow *}{win}}
+
+Same as \helpref{MoveAfterInTabOrder}{wxwindowmoveafterintaborder} except that
+it inserts this window just before \arg{win} instead of putting it right after
+it.
+
+
 \membersection{wxWindow::Navigate}\label{wxwindownavigate}
 
 \func{bool}{Navigate}{\param{int}{ flags = wxNavigationKeyEvent::IsForward}}
diff --git a/include/wx/window.h b/include/wx/window.h
index dec9b3fe58..166885d752 100644
--- a/include/wx/window.h
+++ b/include/wx/window.h
@@ -513,9 +513,17 @@ public:
         // set this child as temporary default
     virtual void SetTmpDefaultItem(wxWindow * WXUNUSED(win)) { }
 
-        // Navigates in the specified direction by sending a wxNavigationKeyEvent
+        // navigates in the specified direction by sending a wxNavigationKeyEvent
     virtual bool Navigate(int flags = wxNavigationKeyEvent::IsForward);
 
+        // move this window just before/after the specified one in tab order
+        // (the other window must be our sibling!)
+    void MoveBeforeInTabOrder(wxWindow *win)
+        { DoMoveInTabOrder(win, MoveBefore); }
+    void MoveAfterInTabOrder(wxWindow *win)
+        { DoMoveInTabOrder(win, MoveAfter); }
+
+
     // parent/children relations
     // -------------------------
 
@@ -1031,6 +1039,13 @@ protected:
     virtual bool TryValidator(wxEvent& event);
     virtual bool TryParent(wxEvent& event);
 
+    // common part of MoveBefore/AfterInTabOrder()
+    enum MoveKind
+    {
+        MoveBefore,     // insert before the given window
+        MoveAfter       // insert after the given window
+    };
+    virtual void DoMoveInTabOrder(wxWindow *win, MoveKind move);
 
 #if wxUSE_CONSTRAINTS
     // satisfy the constraints for the windows but don't set the window sizes
diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp
index 5c24fd2e89..45d4fbf8a0 100644
--- a/src/common/wincmn.cpp
+++ b/src/common/wincmn.cpp
@@ -2408,7 +2408,7 @@ bool wxWindowBase::TryParent(wxEvent& event)
 }
 
 // ----------------------------------------------------------------------------
-// navigation
+// keyboard navigation
 // ----------------------------------------------------------------------------
 
 // Navigates in the specified direction.
@@ -2424,6 +2424,30 @@ bool wxWindowBase::Navigate(int flags)
     return false;
 }
 
+void wxWindowBase::DoMoveInTabOrder(wxWindow *win, MoveKind move)
+{
+    // check that we're not a top level window
+    wxCHECK_RET( GetParent(),
+                    _T("MoveBefore/AfterInTabOrder() don't work for TLWs!") );
+
+    // find the target window in the siblings list
+    wxWindowList& siblings = GetParent()->GetChildren();
+    wxWindowList::compatibility_iterator i = siblings.Find(win);
+    wxCHECK_RET( i, _T("MoveBefore/AfterInTabOrder(): win is not a sibling") );
+
+    // unfortunately, when wxUSE_STL == 1 DetachNode() is not implemented so we
+    // can't just move the node around
+    siblings.DeleteObject(this);
+    if ( move == MoveBefore || ((i = i->GetNext()) != NULL) )
+    {
+        siblings.Insert(i, this);
+    }
+    else // MoveAfter and win was the last sibling
+    {
+        siblings.Append(this);
+    }
+}
+
 // ----------------------------------------------------------------------------
 // global functions
 // ----------------------------------------------------------------------------
-- 
2.50.0

