X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d1cd787b75f5ba9df06b1d51818496e0a6b214dd..da8b1d4b3b535aba94d04494f5b6e2b3e47901ee:/include/wx/containr.h?ds=sidebyside diff --git a/include/wx/containr.h b/include/wx/containr.h index 375caff127..594af01367 100644 --- a/include/wx/containr.h +++ b/include/wx/containr.h @@ -15,8 +15,8 @@ #include "wx/defs.h" -class WXDLLEXPORT wxWindow; -class WXDLLEXPORT wxWindowBase; +class WXDLLIMPEXP_FWD_CORE wxWindow; +class WXDLLIMPEXP_FWD_CORE wxWindowBase; /* Implementation note: wxControlContainer is not a real mix-in but rather @@ -31,7 +31,7 @@ class WXDLLEXPORT wxWindowBase; // wxControlContainerBase: common part used in both native and generic cases // ---------------------------------------------------------------------------- -class WXDLLEXPORT wxControlContainerBase +class WXDLLIMPEXP_CORE wxControlContainerBase { public: // default ctor, SetContainerWindow() must be called later @@ -42,35 +42,64 @@ public: // do accept focus initially, we'll stop doing it if/when any children // are added m_acceptsFocus = true; + m_inSetFocus = false; + m_winLastFocused = NULL; } + virtual ~wxControlContainerBase() {} void SetContainerWindow(wxWindow *winParent) { - wxASSERT_MSG( !m_winParent, _T("shouldn't be called twice") ); + wxASSERT_MSG( !m_winParent, wxT("shouldn't be called twice") ); m_winParent = winParent; } + // 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; } - // call this when the number of children of the window changes - void UpdateCanFocus() { SetCanFocus(ShouldAcceptFocus()); } + // 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; } + + // 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; } + + // 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()); } protected: - // return true if we should be focusable - bool ShouldAcceptFocus() const; + // set the focus to the child which had it the last time + virtual bool SetFocusToChild(); + + // return true if we have any children accepting focus + bool HasAnyFocusableChildren() const; // the parent window we manage the children for wxWindow *m_winParent; + // the child which had the focus last time this panel was activated + wxWindow *m_winLastFocused; + private: // value returned by AcceptsFocus(), should be changed using SetCanFocus() // only bool m_acceptsFocus; + + // a guard against infinite recursion + bool m_inSetFocus; }; // common part of WX_DECLARE_CONTROL_CONTAINER in the native and generic cases, @@ -78,8 +107,11 @@ private: #define WX_DECLARE_CONTROL_CONTAINER_BASE() \ public: \ virtual bool AcceptsFocus() const; \ + virtual bool AcceptsFocusRecursively() const; \ + virtual bool AcceptsFocusFromKeyboard() const; \ virtual void AddChild(wxWindowBase *child); \ virtual void RemoveChild(wxWindowBase *child); \ + virtual void SetFocus(); \ void SetFocusIgnoringChildren(); \ void AcceptFocus(bool acceptFocus) \ { \ @@ -103,12 +135,27 @@ protected: \ m_container.UpdateCanFocus(); \ } \ \ + bool classname::AcceptsFocusRecursively() const \ + { \ + return m_container.AcceptsFocusRecursively(); \ + } \ + \ + void classname::SetFocus() \ + { \ + if ( !m_container.DoSetFocus() ) \ + basename::SetFocus(); \ + } \ + \ bool classname::AcceptsFocus() const \ { \ return m_container.AcceptsFocus(); \ + } \ + \ + bool classname::AcceptsFocusFromKeyboard() const \ + { \ + return m_container.AcceptsFocusFromKeyboard(); \ } - #ifdef wxHAS_NATIVE_TAB_TRAVERSAL // ---------------------------------------------------------------------------- @@ -116,8 +163,11 @@ protected: \ // ---------------------------------------------------------------------------- // this must be a real class as we forward-declare it elsewhere -class WXDLLEXPORT wxControlContainer : public wxControlContainerBase +class WXDLLIMPEXP_CORE wxControlContainer : public wxControlContainerBase { +protected: + // set the focus to the child which had it the last time + virtual bool SetFocusToChild(); }; #define WX_EVENT_TABLE_CONTROL_CONTAINER(classname) @@ -136,19 +186,19 @@ class WXDLLEXPORT wxControlContainer : public wxControlContainerBase \ void classname::SetFocusIgnoringChildren() \ { \ - SetFocus(); \ + basename::SetFocus(); \ } #else // !wxHAS_NATIVE_TAB_TRAVERSAL -class WXDLLEXPORT wxFocusEvent; -class WXDLLEXPORT wxNavigationKeyEvent; +class WXDLLIMPEXP_FWD_CORE wxFocusEvent; +class WXDLLIMPEXP_FWD_CORE wxNavigationKeyEvent; // ---------------------------------------------------------------------------- // wxControlContainer for TAB navigation implemented in wx itself // ---------------------------------------------------------------------------- -class WXDLLEXPORT wxControlContainer : public wxControlContainerBase +class WXDLLIMPEXP_CORE wxControlContainer : public wxControlContainerBase { public: // default ctor, SetContainerWindow() must be called later @@ -159,30 +209,15 @@ public: void HandleOnFocus(wxFocusEvent& event); void HandleOnWindowDestroy(wxWindowBase *child); - // should be called from SetFocus(), returns false if we did nothing with - // the focus and the default processing should take place - bool DoSetFocus(); - // called from OnChildFocus() handler, i.e. when one of our (grand) // children gets the focus void SetLastFocus(wxWindow *win); protected: - // set the focus to the child which had it the last time - bool SetFocusToChild(); - - // the child which had the focus last time this panel was activated - wxWindow *m_winLastFocused; - - // a guard against infinite recursion - bool m_inSetFocus; - DECLARE_NO_COPY_CLASS(wxControlContainer) + wxDECLARE_NO_COPY_CLASS(wxControlContainer); }; -// this function is for wxWidgets internal use only -extern bool wxSetFocusToChild(wxWindow *win, wxWindow **child); - // ---------------------------------------------------------------------------- // macros which may be used by the classes wishing to implement TAB navigation // among their children @@ -195,8 +230,7 @@ extern bool wxSetFocusToChild(wxWindow *win, wxWindow **child); public: \ void OnNavigationKey(wxNavigationKeyEvent& event); \ void OnFocus(wxFocusEvent& event); \ - virtual void OnChildFocus(wxChildFocusEvent& event); \ - virtual void SetFocus() + virtual void OnChildFocus(wxChildFocusEvent& event) // implement the event table entries for wxControlContainer #define WX_EVENT_TABLE_CONTROL_CONTAINER(classname) \ @@ -222,12 +256,6 @@ public: \ m_container.HandleOnNavigationKey(event); \ } \ \ - void classname::SetFocus() \ - { \ - if ( !m_container.DoSetFocus() ) \ - basename::SetFocus(); \ - } \ - \ void classname::SetFocusIgnoringChildren() \ { \ basename::SetFocus(); \ @@ -236,13 +264,17 @@ public: \ void classname::OnChildFocus(wxChildFocusEvent& event) \ { \ m_container.SetLastFocus(event.GetWindow()); \ + event.Skip(); \ } \ \ void classname::OnFocus(wxFocusEvent& event) \ { \ m_container.HandleOnFocus(event); \ - } + } #endif // wxHAS_NATIVE_TAB_TRAVERSAL/!wxHAS_NATIVE_TAB_TRAVERSAL +// this function is for wxWidgets internal use only +extern bool wxSetFocusToChild(wxWindow *win, wxWindow **child); + #endif // _WX_CONTAINR_H_