X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/906c935a80b10d53cecf57f71ab5f3f4f1d529ec..0492f62e0bee1c391a4557f5af84b838430902a0:/include/wx/containr.h?ds=inline diff --git a/include/wx/containr.h b/include/wx/containr.h index 7cb13e8fc1..24e404a7f8 100644 --- a/include/wx/containr.h +++ b/include/wx/containr.h @@ -14,6 +14,11 @@ #include "wx/defs.h" +#ifndef wxHAS_NATIVE_TAB_TRAVERSAL + // We need wxEVT_XXX declarations in this case. + #include "wx/event.h" +#endif + class WXDLLIMPEXP_FWD_CORE wxWindow; class WXDLLIMPEXP_FWD_CORE wxWindowBase; @@ -37,9 +42,12 @@ public: { m_winParent = NULL; - // do accept focus initially, we'll stop doing it if/when any children - // are added - m_acceptsFocus = true; + // By default, we accept focus ourselves. + m_acceptsFocusSelf = true; + + // But we don't have any children accepting it yet. + m_acceptsFocusChildren = false; + m_inSetFocus = false; m_winLastFocused = NULL; } @@ -52,31 +60,28 @@ public: m_winParent = winParent; } + // This can be called by the window to indicate that it never wants to have + // the focus for itself. + void DisableSelfFocus() { m_acceptsFocusSelf = false; } + // 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); - // returns whether we should accept focus ourselves or not - bool AcceptsFocus() const { return m_acceptsFocus; } + bool AcceptsFocus() const { return m_acceptsFocusSelf; } - // returns whether we or one of our children accepts focus: we always do - // because if we don't have any focusable children it probably means that - // we're not being used as a container at all (think of wxGrid or generic - // wxListCtrl) and so should get focus for ourselves - bool AcceptsFocusRecursively() const { return true; } + // Returns whether we or one of our children accepts focus. + bool AcceptsFocusRecursively() const + { return m_acceptsFocusSelf || m_acceptsFocusChildren; } - // this is used to determine whether we can accept focus when Tab or - // another navigation key is pressed -- we alsways can, for the same reason - // as mentioned above for AcceptsFocusRecursively() - bool AcceptsFocusFromKeyboard() const { return true; } + // We accept focus from keyboard if we accept it at all. + bool AcceptsFocusFromKeyboard() const { return AcceptsFocusRecursively(); } // Call this when the number of children of the window changes. - // If we have any children, this panel (used just as container for - // them) shouldn't get focus for itself. - void UpdateCanFocus() { SetCanFocus(!HasAnyFocusableChildren()); } + // + // Returns true if we have any focusable children, false otherwise. + bool UpdateCanFocusChildren(); protected: // set the focus to the child which had it the last time @@ -92,9 +97,16 @@ protected: wxWindow *m_winLastFocused; private: - // value returned by AcceptsFocus(), should be changed using SetCanFocus() - // only - bool m_acceptsFocus; + // Indicates whether the associated window can ever have focus itself. + // + // Usually this is the case, e.g. a wxPanel can be used either as a + // container for its children or just as a normal window which can be + // focused. But sometimes, e.g. for wxStaticBox, we can never have focus + // ourselves and can only get it if we have any focusable children. + bool m_acceptsFocusSelf; + + // Cached value remembering whether we have any children accepting focus. + bool m_acceptsFocusChildren; // a guard against infinite recursion bool m_inSetFocus; @@ -116,9 +128,6 @@ protected: #else // !wxHAS_NATIVE_TAB_TRAVERSAL -class WXDLLIMPEXP_FWD_CORE wxFocusEvent; -class WXDLLIMPEXP_FWD_CORE wxNavigationKeyEvent; - // ---------------------------------------------------------------------------- // wxControlContainer for TAB navigation implemented in wx itself // ---------------------------------------------------------------------------- @@ -146,7 +155,7 @@ protected: #endif // wxHAS_NATIVE_TAB_TRAVERSAL/!wxHAS_NATIVE_TAB_TRAVERSAL // this function is for wxWidgets internal use only -extern bool wxSetFocusToChild(wxWindow *win, wxWindow **child); +extern WXDLLIMPEXP_CORE bool wxSetFocusToChild(wxWindow *win, wxWindow **child); // ---------------------------------------------------------------------------- // wxNavigationEnabled: Derive from this class to support keyboard navigation @@ -166,40 +175,46 @@ public: m_container.SetContainerWindow(this); #ifndef wxHAS_NATIVE_TAB_TRAVERSAL - Connect(wxEVT_NAVIGATION_KEY, + BaseWindowClass::Connect(wxEVT_NAVIGATION_KEY, wxNavigationKeyEventHandler(wxNavigationEnabled::OnNavigationKey)); - Connect(wxEVT_SET_FOCUS, + BaseWindowClass::Connect(wxEVT_SET_FOCUS, wxFocusEventHandler(wxNavigationEnabled::OnFocus)); - Connect(wxEVT_CHILD_FOCUS, + BaseWindowClass::Connect(wxEVT_CHILD_FOCUS, wxChildFocusEventHandler(wxNavigationEnabled::OnChildFocus)); #endif // !wxHAS_NATIVE_TAB_TRAVERSAL } - virtual bool AcceptsFocus() const + WXDLLIMPEXP_INLINE_CORE virtual bool AcceptsFocus() const { return m_container.AcceptsFocus(); } - virtual bool AcceptsFocusRecursively() const + WXDLLIMPEXP_INLINE_CORE virtual bool AcceptsFocusRecursively() const { return m_container.AcceptsFocusRecursively(); } - virtual bool AcceptsFocusFromKeyboard() const + WXDLLIMPEXP_INLINE_CORE virtual bool AcceptsFocusFromKeyboard() const { return m_container.AcceptsFocusFromKeyboard(); } - virtual void AddChild(wxWindowBase *child) + WXDLLIMPEXP_INLINE_CORE virtual void AddChild(wxWindowBase *child) { BaseWindowClass::AddChild(child); - m_container.UpdateCanFocus(); + if ( m_container.UpdateCanFocusChildren() ) + { + // Under MSW we must have wxTAB_TRAVERSAL style for TAB navigation + // to work. + if ( !BaseWindowClass::HasFlag(wxTAB_TRAVERSAL) ) + BaseWindowClass::ToggleWindowStyle(wxTAB_TRAVERSAL); + } } - virtual void RemoveChild(wxWindowBase *child) + WXDLLIMPEXP_INLINE_CORE virtual void RemoveChild(wxWindowBase *child) { #ifndef wxHAS_NATIVE_TAB_TRAVERSAL m_container.HandleOnWindowDestroy(child); @@ -207,10 +222,12 @@ public: BaseWindowClass::RemoveChild(child); - m_container.UpdateCanFocus(); + // We could reset wxTAB_TRAVERSAL here but it doesn't seem to do any + // harm to keep it. + m_container.UpdateCanFocusChildren(); } - virtual void SetFocus() + WXDLLIMPEXP_INLINE_CORE virtual void SetFocus() { if ( !m_container.DoSetFocus() ) BaseWindowClass::SetFocus(); @@ -221,11 +238,6 @@ public: BaseWindowClass::SetFocus(); } - void AcceptFocus(bool acceptFocus) - { - m_container.SetCanFocus(acceptFocus); - } - protected: #ifndef wxHAS_NATIVE_TAB_TRAVERSAL void OnNavigationKey(wxNavigationKeyEvent& event) @@ -256,7 +268,7 @@ protected: // look at them. // ---------------------------------------------------------------------------- -#ifdef WXWIN_COMPATIBILITY_2_8 +#if WXWIN_COMPATIBILITY_2_8 // common part of WX_DECLARE_CONTROL_CONTAINER in the native and generic cases, // it should be used in the wxWindow-derived class declaration @@ -269,10 +281,6 @@ public: \ virtual void RemoveChild(wxWindowBase *child); \ virtual void SetFocus(); \ void SetFocusIgnoringChildren(); \ - void AcceptFocus(bool acceptFocus) \ - { \ - m_container.SetCanFocus(acceptFocus); \ - } \ \ protected: \ wxControlContainer m_container @@ -288,7 +296,7 @@ protected: \ { \ basename::AddChild(child); \ \ - m_container.UpdateCanFocus(); \ + m_container.UpdateCanFocusChildren(); \ } \ \ bool classname::AcceptsFocusRecursively() const \ @@ -326,7 +334,7 @@ protected: \ { \ basename::RemoveChild(child); \ \ - m_container.UpdateCanFocus(); \ + m_container.UpdateCanFocusChildren(); \ } \ \ void classname::SetFocusIgnoringChildren() \ @@ -361,7 +369,7 @@ public: \ \ basename::RemoveChild(child); \ \ - m_container.UpdateCanFocus(); \ + m_container.UpdateCanFocusChildren(); \ } \ \ void classname::OnNavigationKey( wxNavigationKeyEvent& event ) \