1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxControlContainer and wxNavigationEnabled declarations
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2001, 2011 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 #ifndef _WX_CONTAINR_H_
13 #define _WX_CONTAINR_H_
17 #ifndef wxHAS_NATIVE_TAB_TRAVERSAL
18 // We need wxEVT_XXX declarations in this case.
22 class WXDLLIMPEXP_FWD_CORE wxWindow
;
23 class WXDLLIMPEXP_FWD_CORE wxWindowBase
;
26 This header declares wxControlContainer class however it's not a real
27 container of controls but rather just a helper used to implement TAB
28 navigation among the window children. You should rarely need to use it
29 directly, derive from the documented public wxNavigationEnabled<> class to
30 implement TAB navigation in a custom composite window.
33 // ----------------------------------------------------------------------------
34 // wxControlContainerBase: common part used in both native and generic cases
35 // ----------------------------------------------------------------------------
37 class WXDLLIMPEXP_CORE wxControlContainerBase
40 // default ctor, SetContainerWindow() must be called later
41 wxControlContainerBase()
45 // do accept focus initially, we'll stop doing it if/when any children
47 m_acceptsFocus
= true;
49 m_winLastFocused
= NULL
;
51 virtual ~wxControlContainerBase() {}
53 void SetContainerWindow(wxWindow
*winParent
)
55 wxASSERT_MSG( !m_winParent
, wxT("shouldn't be called twice") );
57 m_winParent
= winParent
;
60 // should be called from SetFocus(), returns false if we did nothing with
61 // the focus and the default processing should take place
64 // should be called when we decide that we should [stop] accepting focus
65 void SetCanFocus(bool acceptsFocus
);
67 // returns whether we should accept focus ourselves or not
68 bool AcceptsFocus() const { return m_acceptsFocus
; }
70 // returns whether we or one of our children accepts focus: we always do
71 // because if we don't have any focusable children it probably means that
72 // we're not being used as a container at all (think of wxGrid or generic
73 // wxListCtrl) and so should get focus for ourselves
74 bool AcceptsFocusRecursively() const { return true; }
76 // this is used to determine whether we can accept focus when Tab or
77 // another navigation key is pressed -- we alsways can, for the same reason
78 // as mentioned above for AcceptsFocusRecursively()
79 bool AcceptsFocusFromKeyboard() const { return true; }
81 // Call this when the number of children of the window changes.
82 // If we have any children, this panel (used just as container for
83 // them) shouldn't get focus for itself.
84 void UpdateCanFocus() { SetCanFocus(!HasAnyFocusableChildren()); }
87 // set the focus to the child which had it the last time
88 virtual bool SetFocusToChild();
90 // return true if we have any children accepting focus
91 bool HasAnyFocusableChildren() const;
93 // the parent window we manage the children for
94 wxWindow
*m_winParent
;
96 // the child which had the focus last time this panel was activated
97 wxWindow
*m_winLastFocused
;
100 // value returned by AcceptsFocus(), should be changed using SetCanFocus()
104 // a guard against infinite recursion
108 #ifdef wxHAS_NATIVE_TAB_TRAVERSAL
110 // ----------------------------------------------------------------------------
111 // wxControlContainer for native TAB navigation
112 // ----------------------------------------------------------------------------
114 // this must be a real class as we forward-declare it elsewhere
115 class WXDLLIMPEXP_CORE wxControlContainer
: public wxControlContainerBase
118 // set the focus to the child which had it the last time
119 virtual bool SetFocusToChild();
122 #else // !wxHAS_NATIVE_TAB_TRAVERSAL
124 // ----------------------------------------------------------------------------
125 // wxControlContainer for TAB navigation implemented in wx itself
126 // ----------------------------------------------------------------------------
128 class WXDLLIMPEXP_CORE wxControlContainer
: public wxControlContainerBase
131 // default ctor, SetContainerWindow() must be called later
132 wxControlContainer();
134 // the methods to be called from the window event handlers
135 void HandleOnNavigationKey(wxNavigationKeyEvent
& event
);
136 void HandleOnFocus(wxFocusEvent
& event
);
137 void HandleOnWindowDestroy(wxWindowBase
*child
);
139 // called from OnChildFocus() handler, i.e. when one of our (grand)
140 // children gets the focus
141 void SetLastFocus(wxWindow
*win
);
145 wxDECLARE_NO_COPY_CLASS(wxControlContainer
);
148 #endif // wxHAS_NATIVE_TAB_TRAVERSAL/!wxHAS_NATIVE_TAB_TRAVERSAL
150 // this function is for wxWidgets internal use only
151 extern WXDLLIMPEXP_CORE
bool wxSetFocusToChild(wxWindow
*win
, wxWindow
**child
);
153 // ----------------------------------------------------------------------------
154 // wxNavigationEnabled: Derive from this class to support keyboard navigation
155 // among window children in a wxWindow-derived class. The details of this class
156 // don't matter, you just need to derive from it to make navigation work.
157 // ----------------------------------------------------------------------------
159 // The template parameter W must be a wxWindow-derived class.
161 class wxNavigationEnabled
: public W
164 typedef W BaseWindowClass
;
166 wxNavigationEnabled()
168 m_container
.SetContainerWindow(this);
170 #ifndef wxHAS_NATIVE_TAB_TRAVERSAL
171 BaseWindowClass::Connect(wxEVT_NAVIGATION_KEY
,
172 wxNavigationKeyEventHandler(wxNavigationEnabled::OnNavigationKey
));
174 BaseWindowClass::Connect(wxEVT_SET_FOCUS
,
175 wxFocusEventHandler(wxNavigationEnabled::OnFocus
));
177 BaseWindowClass::Connect(wxEVT_CHILD_FOCUS
,
178 wxChildFocusEventHandler(wxNavigationEnabled::OnChildFocus
));
179 #endif // !wxHAS_NATIVE_TAB_TRAVERSAL
182 WXDLLIMPEXP_INLINE_CORE
virtual bool AcceptsFocus() const
184 return m_container
.AcceptsFocus();
187 WXDLLIMPEXP_INLINE_CORE
virtual bool AcceptsFocusRecursively() const
189 return m_container
.AcceptsFocusRecursively();
192 WXDLLIMPEXP_INLINE_CORE
virtual bool AcceptsFocusFromKeyboard() const
194 return m_container
.AcceptsFocusFromKeyboard();
197 WXDLLIMPEXP_INLINE_CORE
virtual void AddChild(wxWindowBase
*child
)
199 BaseWindowClass::AddChild(child
);
201 m_container
.UpdateCanFocus();
204 WXDLLIMPEXP_INLINE_CORE
virtual void RemoveChild(wxWindowBase
*child
)
206 #ifndef wxHAS_NATIVE_TAB_TRAVERSAL
207 m_container
.HandleOnWindowDestroy(child
);
208 #endif // !wxHAS_NATIVE_TAB_TRAVERSAL
210 BaseWindowClass::RemoveChild(child
);
212 m_container
.UpdateCanFocus();
215 WXDLLIMPEXP_INLINE_CORE
virtual void SetFocus()
217 if ( !m_container
.DoSetFocus() )
218 BaseWindowClass::SetFocus();
221 void SetFocusIgnoringChildren()
223 BaseWindowClass::SetFocus();
226 void AcceptFocus(bool acceptFocus
)
228 m_container
.SetCanFocus(acceptFocus
);
232 #ifndef wxHAS_NATIVE_TAB_TRAVERSAL
233 void OnNavigationKey(wxNavigationKeyEvent
& event
)
235 m_container
.HandleOnNavigationKey(event
);
238 void OnFocus(wxFocusEvent
& event
)
240 m_container
.HandleOnFocus(event
);
243 void OnChildFocus(wxChildFocusEvent
& event
)
245 m_container
.SetLastFocus(event
.GetWindow());
248 #endif // !wxHAS_NATIVE_TAB_TRAVERSAL
250 wxControlContainer m_container
;
253 wxDECLARE_NO_COPY_TEMPLATE_CLASS(wxNavigationEnabled
, W
);
256 // ----------------------------------------------------------------------------
257 // Compatibility macros from now on, do NOT use them and preferably do not even
259 // ----------------------------------------------------------------------------
261 #if WXWIN_COMPATIBILITY_2_8
263 // common part of WX_DECLARE_CONTROL_CONTAINER in the native and generic cases,
264 // it should be used in the wxWindow-derived class declaration
265 #define WX_DECLARE_CONTROL_CONTAINER_BASE() \
267 virtual bool AcceptsFocus() const; \
268 virtual bool AcceptsFocusRecursively() const; \
269 virtual bool AcceptsFocusFromKeyboard() const; \
270 virtual void AddChild(wxWindowBase *child); \
271 virtual void RemoveChild(wxWindowBase *child); \
272 virtual void SetFocus(); \
273 void SetFocusIgnoringChildren(); \
274 void AcceptFocus(bool acceptFocus) \
276 m_container.SetCanFocus(acceptFocus); \
280 wxControlContainer m_container
282 // this macro must be used in the derived class ctor
283 #define WX_INIT_CONTROL_CONTAINER() \
284 m_container.SetContainerWindow(this)
286 // common part of WX_DELEGATE_TO_CONTROL_CONTAINER in the native and generic
287 // cases, must be used in the wxWindow-derived class implementation
288 #define WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
289 void classname::AddChild(wxWindowBase *child) \
291 basename::AddChild(child); \
293 m_container.UpdateCanFocus(); \
296 bool classname::AcceptsFocusRecursively() const \
298 return m_container.AcceptsFocusRecursively(); \
301 void classname::SetFocus() \
303 if ( !m_container.DoSetFocus() ) \
304 basename::SetFocus(); \
307 bool classname::AcceptsFocus() const \
309 return m_container.AcceptsFocus(); \
312 bool classname::AcceptsFocusFromKeyboard() const \
314 return m_container.AcceptsFocusFromKeyboard(); \
318 #ifdef wxHAS_NATIVE_TAB_TRAVERSAL
320 #define WX_EVENT_TABLE_CONTROL_CONTAINER(classname)
322 #define WX_DECLARE_CONTROL_CONTAINER WX_DECLARE_CONTROL_CONTAINER_BASE
324 #define WX_DELEGATE_TO_CONTROL_CONTAINER(classname, basename) \
325 WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
327 void classname::RemoveChild(wxWindowBase *child) \
329 basename::RemoveChild(child); \
331 m_container.UpdateCanFocus(); \
334 void classname::SetFocusIgnoringChildren() \
336 basename::SetFocus(); \
339 #else // !wxHAS_NATIVE_TAB_TRAVERSAL
341 // declare the methods to be forwarded
342 #define WX_DECLARE_CONTROL_CONTAINER() \
343 WX_DECLARE_CONTROL_CONTAINER_BASE(); \
346 void OnNavigationKey(wxNavigationKeyEvent& event); \
347 void OnFocus(wxFocusEvent& event); \
348 virtual void OnChildFocus(wxChildFocusEvent& event)
350 // implement the event table entries for wxControlContainer
351 #define WX_EVENT_TABLE_CONTROL_CONTAINER(classname) \
352 EVT_SET_FOCUS(classname::OnFocus) \
353 EVT_CHILD_FOCUS(classname::OnChildFocus) \
354 EVT_NAVIGATION_KEY(classname::OnNavigationKey)
356 // implement the methods forwarding to the wxControlContainer
357 #define WX_DELEGATE_TO_CONTROL_CONTAINER(classname, basename) \
358 WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
360 void classname::RemoveChild(wxWindowBase *child) \
362 m_container.HandleOnWindowDestroy(child); \
364 basename::RemoveChild(child); \
366 m_container.UpdateCanFocus(); \
369 void classname::OnNavigationKey( wxNavigationKeyEvent& event ) \
371 m_container.HandleOnNavigationKey(event); \
374 void classname::SetFocusIgnoringChildren() \
376 basename::SetFocus(); \
379 void classname::OnChildFocus(wxChildFocusEvent& event) \
381 m_container.SetLastFocus(event.GetWindow()); \
385 void classname::OnFocus(wxFocusEvent& event) \
387 m_container.HandleOnFocus(event); \
390 #endif // wxHAS_NATIVE_TAB_TRAVERSAL/!wxHAS_NATIVE_TAB_TRAVERSAL
392 #endif // WXWIN_COMPATIBILITY_2_8
394 #endif // _WX_CONTAINR_H_