X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/3d3afaecfb60725ac2dc86e10a46f8a5d7899810..855f31ebe72bef834a32df2c274b41fb282ad265:/src/common/containr.cpp diff --git a/src/common/containr.cpp b/src/common/containr.cpp index b4b63b63af..3333232ec5 100644 --- a/src/common/containr.cpp +++ b/src/common/containr.cpp @@ -28,17 +28,10 @@ #include "wx/log.h" #include "wx/event.h" #include "wx/window.h" -#endif //WX_PRECOMP - -#include "wx/containr.h" - -#ifdef __WXMAC__ #include "wx/scrolbar.h" -#endif - -#ifdef __WXMSW__ #include "wx/radiobut.h" -#endif + #include "wx/containr.h" +#endif //WX_PRECOMP // trace mask for focus messages #define TRACE_FOCUS _T("focus") @@ -50,10 +43,7 @@ wxControlContainer::wxControlContainer(wxWindow *winParent) { m_winParent = winParent; - - m_winLastFocused = - m_winTmpDefault = - m_winDefault = NULL; + m_winLastFocused = NULL; m_inSetFocus = false; } @@ -78,18 +68,17 @@ bool wxControlContainer::AcceptsFocus() const while ( node ) { wxWindow *child = node->GetData(); + node = node->GetNext(); +#ifdef __WXMAC__ + if ( m_winParent->MacIsWindowScrollbar( child ) ) + continue; + hasRealChildren = true ; +#endif if ( child->AcceptsFocus() ) { return true; } - -#ifdef __WXMAC__ - wxScrollBar *sb = wxDynamicCast( child , wxScrollBar ) ; - if ( sb == NULL || !m_winParent->MacIsWindowScrollbar( sb ) ) - hasRealChildren = true ; -#endif - node = node->GetNext(); } #ifdef __WXMAC__ @@ -286,6 +275,49 @@ void wxControlContainer::HandleOnNavigationKey( wxNavigationKeyEvent& event ) const wxWindowList& children = m_winParent->GetChildren(); + // if we have exactly one notebook-like child window (actually it could be + // any window that returns true from its HasMultiplePages()), then + // [Shift-]Ctrl-Tab and Ctrl-PageUp/Down keys should iterate over its pages + // even if the focus is outside of the control because this is how the + // standard MSW properties dialogs behave and we do it under other platforms + // as well because it seems like a good idea -- but we can always put this + // block inside "#ifdef __WXMSW__" if it's not suitable there + if ( event.IsWindowChange() && !goingDown ) + { + // check if we have a unique notebook-like child + wxWindow *bookctrl = NULL; + for ( wxWindowList::const_iterator i = children.begin(), + end = children.end(); + i != end; + ++i ) + { + wxWindow * const window = *i; + if ( window->HasMultiplePages() ) + { + if ( bookctrl ) + { + // this is the second book-like control already so don't do + // anything as we don't know which one should have its page + // changed + bookctrl = NULL; + break; + } + + bookctrl = window; + } + } + + if ( bookctrl ) + { + // make sure that we don't bubble up the event again from the book + // control resulting in infinite recursion + wxNavigationKeyEvent eventCopy(event); + eventCopy.SetEventObject(m_winParent); + if ( bookctrl->GetEventHandler()->ProcessEvent(eventCopy) ) + return; + } + } + // 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() ) @@ -302,7 +334,7 @@ void wxControlContainer::HandleOnNavigationKey( wxNavigationKeyEvent& event ) } // where are we going? - bool forward = event.GetDirection(); + const bool forward = event.GetDirection(); // the node of the children list from which we should start looking for the // next acceptable child @@ -319,11 +351,8 @@ void wxControlContainer::HandleOnNavigationKey( wxNavigationKeyEvent& event ) // 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::compatibility_iterator(); } - else + else // going up { // try to find the child which has the focus currently @@ -349,10 +378,6 @@ void wxControlContainer::HandleOnNavigationKey( wxNavigationKeyEvent& event ) // ok, we found the focus - now is it our child? start_node = children.Find( winFocus ); } - else - { - start_node = wxWindowList::compatibility_iterator(); - } if ( !start_node && m_winLastFocused ) { @@ -373,14 +398,24 @@ void wxControlContainer::HandleOnNavigationKey( wxNavigationKeyEvent& event ) } // we want to cycle over all elements passing by NULL - while ( node != start_node ) + for ( ;; ) { + // don't go into infinite loop + if ( start_node && node && node == start_node ) + break; + // Have we come to the last or first item on the panel? if ( !node ) { + if ( !start_node ) + { + // exit now as otherwise we'd loop forever + break; + } + if ( !goingDown ) { - // Check if our (may be grand) parent is another panel: if this + // Check if our (maybe grand) parent is another panel: if this // is the case, they will know what to do with this navigation // key and so give them the chance to process it instead of // looping inside this panel (normally, the focus will go to @@ -508,12 +543,6 @@ void wxControlContainer::HandleOnWindowDestroy(wxWindowBase *child) { if ( child == m_winLastFocused ) m_winLastFocused = NULL; - - if ( child == m_winDefault ) - m_winDefault = NULL; - - if ( child == m_winTmpDefault ) - m_winTmpDefault = NULL; } // ---------------------------------------------------------------------------- @@ -614,7 +643,13 @@ bool wxSetFocusToChild(wxWindow *win, wxWindow **childLastFocused) while ( node ) { wxWindow *child = node->GetData(); + node = node->GetNext(); +#ifdef __WXMAC__ + if ( child->GetParent()->MacIsWindowScrollbar( child ) ) + continue; +#endif + if ( child->AcceptsFocusFromKeyboard() && !child->IsTopLevel() ) { #ifdef __WXMSW__ @@ -637,10 +672,7 @@ bool wxSetFocusToChild(wxWindow *win, wxWindow **childLastFocused) child->SetFocusFromKbd(); return true; } - - node = node->GetNext(); } return false; } -