1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxControlContainer class declration: a "mix-in" class which
4 // implements the TAB navigation between the controls
5 // Author: Vadim Zeitlin
9 // Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
10 // Licence: wxWindows licence
11 ///////////////////////////////////////////////////////////////////////////////
13 #ifndef _WX_CONTAINR_H_
14 #define _WX_CONTAINR_H_
18 class WXDLLEXPORT wxWindow
;
19 class WXDLLEXPORT wxWindowBase
;
22 Implementation note: wxControlContainer is not a real mix-in but rather
23 a class meant to be aggregated with (and not inherited from). Although
24 logically it should be a mix-in, doing it like this has no advantage from
25 the point of view of the existing code but does have some problems (we'd
26 need to play tricks with event handlers which may be difficult to do
27 safely). The price we pay for this simplicity is the ugly macros below.
30 // ----------------------------------------------------------------------------
31 // wxControlContainerBase: common part used in both native and generic cases
32 // ----------------------------------------------------------------------------
34 class WXDLLEXPORT wxControlContainerBase
37 // default ctor, SetContainerWindow() must be called later
38 wxControlContainerBase()
42 // do accept focus initially, we'll stop doing it if/when any children
44 m_acceptsFocus
= true;
47 void SetContainerWindow(wxWindow
*winParent
)
49 wxASSERT_MSG( !m_winParent
, _T("shouldn't be called twice") );
51 m_winParent
= winParent
;
54 // should be called when we decide that we should [stop] accepting focus
55 void SetCanFocus(bool acceptsFocus
);
57 // returns whether we should accept focus ourselves or not
58 bool AcceptsFocus() const { return m_acceptsFocus
; }
60 // call this when the number of children of the window changes
61 void UpdateCanFocus() { SetCanFocus(ShouldAcceptFocus()); }
64 // return true if we should be focusable
65 bool ShouldAcceptFocus() const;
67 // the parent window we manage the children for
68 wxWindow
*m_winParent
;
71 // value returned by AcceptsFocus(), should be changed using SetCanFocus()
76 // common part of WX_DECLARE_CONTROL_CONTAINER in the native and generic cases,
77 // it should be used in the wxWindow-derived class declaration
78 #define WX_DECLARE_CONTROL_CONTAINER_BASE() \
80 virtual bool AcceptsFocus() const; \
81 virtual void AddChild(wxWindowBase *child); \
82 virtual void RemoveChild(wxWindowBase *child); \
83 void SetFocusIgnoringChildren(); \
84 void AcceptFocus(bool acceptFocus) \
86 m_container.SetCanFocus(acceptFocus); \
90 wxControlContainer m_container
92 // this macro must be used in the derived class ctor
93 #define WX_INIT_CONTROL_CONTAINER() \
94 m_container.SetContainerWindow(this)
96 // common part of WX_DELEGATE_TO_CONTROL_CONTAINER in the native and generic
97 // cases, must be used in the wxWindow-derived class implementation
98 #define WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
99 void classname::AddChild(wxWindowBase *child) \
101 basename::AddChild(child); \
103 m_container.UpdateCanFocus(); \
106 bool classname::AcceptsFocus() const \
108 return m_container.AcceptsFocus(); \
112 #ifdef wxHAS_NATIVE_TAB_TRAVERSAL
114 // ----------------------------------------------------------------------------
115 // wxControlContainer for native TAB navigation
116 // ----------------------------------------------------------------------------
118 // this must be a real class as we forward-declare it elsewhere
119 class WXDLLEXPORT wxControlContainer
: public wxControlContainerBase
123 #define WX_EVENT_TABLE_CONTROL_CONTAINER(classname)
125 #define WX_DECLARE_CONTROL_CONTAINER WX_DECLARE_CONTROL_CONTAINER_BASE
127 #define WX_DELEGATE_TO_CONTROL_CONTAINER(classname, basename) \
128 WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
130 void classname::RemoveChild(wxWindowBase *child) \
132 basename::RemoveChild(child); \
134 m_container.UpdateCanFocus(); \
137 void classname::SetFocusIgnoringChildren() \
142 #else // !wxHAS_NATIVE_TAB_TRAVERSAL
144 class WXDLLEXPORT wxFocusEvent
;
145 class WXDLLEXPORT wxNavigationKeyEvent
;
147 // ----------------------------------------------------------------------------
148 // wxControlContainer for TAB navigation implemented in wx itself
149 // ----------------------------------------------------------------------------
151 class WXDLLEXPORT wxControlContainer
: public wxControlContainerBase
154 // default ctor, SetContainerWindow() must be called later
155 wxControlContainer();
157 // the methods to be called from the window event handlers
158 void HandleOnNavigationKey(wxNavigationKeyEvent
& event
);
159 void HandleOnFocus(wxFocusEvent
& event
);
160 void HandleOnWindowDestroy(wxWindowBase
*child
);
162 // should be called from SetFocus(), returns false if we did nothing with
163 // the focus and the default processing should take place
166 // can our child get the focus?
167 bool AcceptsFocus() const;
169 // called from OnChildFocus() handler, i.e. when one of our (grand)
170 // children gets the focus
171 void SetLastFocus(wxWindow
*win
);
174 // set the focus to the child which had it the last time
175 bool SetFocusToChild();
177 // the child which had the focus last time this panel was activated
178 wxWindow
*m_winLastFocused
;
180 // a guard against infinite recursion
183 DECLARE_NO_COPY_CLASS(wxControlContainer
)
186 // this function is for wxWidgets internal use only
187 extern bool wxSetFocusToChild(wxWindow
*win
, wxWindow
**child
);
189 // ----------------------------------------------------------------------------
190 // macros which may be used by the classes wishing to implement TAB navigation
191 // among their children
192 // ----------------------------------------------------------------------------
194 // declare the methods to be forwarded
195 #define WX_DECLARE_CONTROL_CONTAINER() \
197 void OnNavigationKey(wxNavigationKeyEvent& event); \
198 void OnFocus(wxFocusEvent& event); \
199 void SetFocusIgnoringChildren(); \
200 virtual void OnChildFocus(wxChildFocusEvent& event); \
201 virtual void SetFocus(); \
202 virtual void RemoveChild(wxWindowBase *child); \
203 virtual bool AcceptsFocus() const; \
206 wxControlContainer m_container
208 // implement the event table entries for wxControlContainer
209 #define WX_EVENT_TABLE_CONTROL_CONTAINER(classname) \
210 EVT_SET_FOCUS(classname::OnFocus) \
211 EVT_CHILD_FOCUS(classname::OnChildFocus) \
212 EVT_NAVIGATION_KEY(classname::OnNavigationKey)
214 // implement the methods forwarding to the wxControlContainer
215 #define WX_DELEGATE_TO_CONTROL_CONTAINER(classname, basename) \
216 WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
218 void classname::RemoveChild(wxWindowBase *child) \
220 m_container.HandleOnWindowDestroy(child); \
222 basename::RemoveChild(child); \
224 m_container.UpdateCanFocus(); \
227 void classname::OnNavigationKey( wxNavigationKeyEvent& event ) \
229 m_container.HandleOnNavigationKey(event); \
232 void classname::SetFocus() \
234 if ( !m_container.DoSetFocus() ) \
235 basename::SetFocus(); \
238 void classname::SetFocusIgnoringChildren() \
240 basename::SetFocus(); \
243 void classname::OnChildFocus(wxChildFocusEvent& event) \
245 m_container.SetLastFocus(event.GetWindow()); \
248 void classname::OnFocus(wxFocusEvent& event) \
250 m_container.HandleOnFocus(event); \
253 #endif // wxHAS_NATIVE_TAB_TRAVERSAL/!wxHAS_NATIVE_TAB_TRAVERSAL
255 #endif // _WX_CONTAINR_H_