+ // the event is propagated downwards if the event emitter was our parent
+ bool goingDown = event.GetEventObject() == GetParent();
+
+ const wxWindowList& children = GetChildren();
+
+ // there is not much to do if we don't have children and we're not
+ // interested in "notebook page change" events here
+ if ( !children.GetCount() || event.IsWindowChange() )
+ {
+ // let the parent process it unless it already comes from our parent
+ // of we don't have any
+ wxWindow *parent = GetParent();
+ if ( goingDown ||
+ !parent || !parent->GetEventHandler()->ProcessEvent(event) )
+ {
+ event.Skip();
+ }
+
+ return;
+ }
+
+ // where are we going?
+ bool forward = event.GetDirection();
+
+ // the node of the children list from which we should start looking for the
+ // next acceptable child
+ wxWindowList::Node *node, *start_node;
+
+ // we should start from the first/last control and not from the one which
+ // had focus the last time if we're propagating the event downwards because
+ // for our parent we look like a single control
+ if ( goingDown )
+ {
+ // just to be sure it's not used (normally this is not necessary, but
+ // doesn't hurt neither)
+ m_winLastFocused = (wxWindow *)NULL;
+
+ // start from first or last depending on where we're going
+ node = forward ? children.GetFirst() : children.GetLast();
+
+ // we want to cycle over all nodes
+ start_node = (wxWindowList::Node *)NULL;
+ }
+ else
+ {
+ // try to find the child which has the focus currently
+
+ // the event emitter might have done this for us
+ wxWindow *winFocus = event.GetCurrentFocus();
+
+ // but if not, we might know where the focus was ourselves
+ if (!winFocus)
+ winFocus = m_winLastFocused;
+
+ // if still no luck, do it the hard way
+ if (!winFocus)
+ winFocus = wxWindow::FindFocus();
+
+ if ( winFocus )
+ {
+ // ok, we found the focus - now is it our child?
+ start_node = children.Find( winFocus );
+ }
+ else
+ {
+ start_node = (wxWindowList::Node *)NULL;
+ }
+
+ if ( !start_node && m_winLastFocused )
+ {
+ // window which has focus isn't our child, fall back to the one
+ // which had the focus the last time
+ start_node = children.Find( m_winLastFocused );
+ }
+
+ // if we still didn't find anything, we should start with the first one
+ if ( !start_node )
+ {
+ start_node = children.GetFirst();
+ }
+
+ // and the first child which we can try setting focus to is the next or
+ // the previous one
+ node = forward ? start_node->GetNext() : start_node->GetPrevious();