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 class WXDLLIMPEXP_FWD_CORE wxWindow
;
18 class WXDLLIMPEXP_FWD_CORE wxWindowBase
;
21 This header declares wxControlContainer class however it's not a real
22 container of controls but rather just a helper used to implement TAB
23 navigation among the window children. You should rarely need to use it
24 directly, derive from the documented public wxNavigationEnabled<> class to
25 implement TAB navigation in a custom composite window.
28 // ----------------------------------------------------------------------------
29 // wxControlContainerBase: common part used in both native and generic cases
30 // ----------------------------------------------------------------------------
32 class WXDLLIMPEXP_CORE wxControlContainerBase
35 // default ctor, SetContainerWindow() must be called later
36 wxControlContainerBase()
40 // do accept focus initially, we'll stop doing it if/when any children
42 m_acceptsFocus
= true;
44 m_winLastFocused
= NULL
;
46 virtual ~wxControlContainerBase() {}
48 void SetContainerWindow(wxWindow
*winParent
)
50 wxASSERT_MSG( !m_winParent
, wxT("shouldn't be called twice") );
52 m_winParent
= winParent
;
55 // should be called from SetFocus(), returns false if we did nothing with
56 // the focus and the default processing should take place
59 // should be called when we decide that we should [stop] accepting focus
60 void SetCanFocus(bool acceptsFocus
);
62 // returns whether we should accept focus ourselves or not
63 bool AcceptsFocus() const { return m_acceptsFocus
; }
65 // returns whether we or one of our children accepts focus: we always do
66 // because if we don't have any focusable children it probably means that
67 // we're not being used as a container at all (think of wxGrid or generic
68 // wxListCtrl) and so should get focus for ourselves
69 bool AcceptsFocusRecursively() const { return true; }
71 // this is used to determine whether we can accept focus when Tab or
72 // another navigation key is pressed -- we alsways can, for the same reason
73 // as mentioned above for AcceptsFocusRecursively()
74 bool AcceptsFocusFromKeyboard() const { return true; }
76 // Call this when the number of children of the window changes.
77 // If we have any children, this panel (used just as container for
78 // them) shouldn't get focus for itself.
79 void UpdateCanFocus() { SetCanFocus(!HasAnyFocusableChildren()); }
82 // set the focus to the child which had it the last time
83 virtual bool SetFocusToChild();
85 // return true if we have any children accepting focus
86 bool HasAnyFocusableChildren() const;
88 // the parent window we manage the children for
89 wxWindow
*m_winParent
;
91 // the child which had the focus last time this panel was activated
92 wxWindow
*m_winLastFocused
;
95 // value returned by AcceptsFocus(), should be changed using SetCanFocus()
99 // a guard against infinite recursion
103 #ifdef wxHAS_NATIVE_TAB_TRAVERSAL
105 // ----------------------------------------------------------------------------
106 // wxControlContainer for native TAB navigation
107 // ----------------------------------------------------------------------------
109 // this must be a real class as we forward-declare it elsewhere
110 class WXDLLIMPEXP_CORE wxControlContainer
: public wxControlContainerBase
113 // set the focus to the child which had it the last time
114 virtual bool SetFocusToChild();
117 #else // !wxHAS_NATIVE_TAB_TRAVERSAL
119 class WXDLLIMPEXP_FWD_CORE wxFocusEvent
;
120 class WXDLLIMPEXP_FWD_CORE wxNavigationKeyEvent
;
122 // ----------------------------------------------------------------------------
123 // wxControlContainer for TAB navigation implemented in wx itself
124 // ----------------------------------------------------------------------------
126 class WXDLLIMPEXP_CORE wxControlContainer
: public wxControlContainerBase
129 // default ctor, SetContainerWindow() must be called later
130 wxControlContainer();
132 // the methods to be called from the window event handlers
133 void HandleOnNavigationKey(wxNavigationKeyEvent
& event
);
134 void HandleOnFocus(wxFocusEvent
& event
);
135 void HandleOnWindowDestroy(wxWindowBase
*child
);
137 // called from OnChildFocus() handler, i.e. when one of our (grand)
138 // children gets the focus
139 void SetLastFocus(wxWindow
*win
);
143 wxDECLARE_NO_COPY_CLASS(wxControlContainer
);
146 #endif // wxHAS_NATIVE_TAB_TRAVERSAL/!wxHAS_NATIVE_TAB_TRAVERSAL
148 // this function is for wxWidgets internal use only
149 extern bool wxSetFocusToChild(wxWindow
*win
, wxWindow
**child
);
151 // ----------------------------------------------------------------------------
152 // wxNavigationEnabled: Derive from this class to support keyboard navigation
153 // among window children in a wxWindow-derived class. The details of this class
154 // don't matter, you just need to derive from it to make navigation work.
155 // ----------------------------------------------------------------------------
157 // The template parameter W must be a wxWindow-derived class.
159 class wxNavigationEnabled
: public W
162 typedef W BaseWindowClass
;
164 wxNavigationEnabled()
166 m_container
.SetContainerWindow(this);
168 #ifndef wxHAS_NATIVE_TAB_TRAVERSAL
169 Connect(wxEVT_NAVIGATION_KEY
,
170 wxNavigationKeyEventHandler(wxNavigationEnabled::OnNavigationKey
));
172 Connect(wxEVT_SET_FOCUS
,
173 wxFocusEventHandler(wxNavigationEnabled::OnFocus
));
175 Connect(wxEVT_CHILD_FOCUS
,
176 wxChildFocusEventHandler(wxNavigationEnabled::OnChildFocus
));
177 #endif // !wxHAS_NATIVE_TAB_TRAVERSAL
180 virtual bool AcceptsFocus() const
182 return m_container
.AcceptsFocus();
185 virtual bool AcceptsFocusRecursively() const
187 return m_container
.AcceptsFocusRecursively();
190 virtual bool AcceptsFocusFromKeyboard() const
192 return m_container
.AcceptsFocusFromKeyboard();
195 virtual void AddChild(wxWindowBase
*child
)
197 BaseWindowClass::AddChild(child
);
199 m_container
.UpdateCanFocus();
202 virtual void RemoveChild(wxWindowBase
*child
)
204 #ifndef wxHAS_NATIVE_TAB_TRAVERSAL
205 m_container
.HandleOnWindowDestroy(child
);
206 #endif // !wxHAS_NATIVE_TAB_TRAVERSAL
208 BaseWindowClass::RemoveChild(child
);
210 m_container
.UpdateCanFocus();
213 virtual void SetFocus()
215 if ( !m_container
.DoSetFocus() )
216 BaseWindowClass::SetFocus();
219 void SetFocusIgnoringChildren()
221 BaseWindowClass::SetFocus();
224 void AcceptFocus(bool acceptFocus
)
226 m_container
.SetCanFocus(acceptFocus
);
230 #ifndef wxHAS_NATIVE_TAB_TRAVERSAL
231 void OnNavigationKey(wxNavigationKeyEvent
& event
)
233 m_container
.HandleOnNavigationKey(event
);
236 void OnFocus(wxFocusEvent
& event
)
238 m_container
.HandleOnFocus(event
);
241 void OnChildFocus(wxChildFocusEvent
& event
)
243 m_container
.SetLastFocus(event
.GetWindow());
246 #endif // !wxHAS_NATIVE_TAB_TRAVERSAL
248 wxControlContainer m_container
;
251 wxDECLARE_NO_COPY_TEMPLATE_CLASS(wxNavigationEnabled
, W
);
254 // ----------------------------------------------------------------------------
255 // Compatibility macros from now on, do NOT use them and preferably do not even
257 // ----------------------------------------------------------------------------
259 #ifdef WXWIN_COMPATIBILITY_2_8
261 // common part of WX_DECLARE_CONTROL_CONTAINER in the native and generic cases,
262 // it should be used in the wxWindow-derived class declaration
263 #define WX_DECLARE_CONTROL_CONTAINER_BASE() \
265 virtual bool AcceptsFocus() const; \
266 virtual bool AcceptsFocusRecursively() const; \
267 virtual bool AcceptsFocusFromKeyboard() const; \
268 virtual void AddChild(wxWindowBase *child); \
269 virtual void RemoveChild(wxWindowBase *child); \
270 virtual void SetFocus(); \
271 void SetFocusIgnoringChildren(); \
272 void AcceptFocus(bool acceptFocus) \
274 m_container.SetCanFocus(acceptFocus); \
278 wxControlContainer m_container
280 // this macro must be used in the derived class ctor
281 #define WX_INIT_CONTROL_CONTAINER() \
282 m_container.SetContainerWindow(this)
284 // common part of WX_DELEGATE_TO_CONTROL_CONTAINER in the native and generic
285 // cases, must be used in the wxWindow-derived class implementation
286 #define WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
287 void classname::AddChild(wxWindowBase *child) \
289 basename::AddChild(child); \
291 m_container.UpdateCanFocus(); \
294 bool classname::AcceptsFocusRecursively() const \
296 return m_container.AcceptsFocusRecursively(); \
299 void classname::SetFocus() \
301 if ( !m_container.DoSetFocus() ) \
302 basename::SetFocus(); \
305 bool classname::AcceptsFocus() const \
307 return m_container.AcceptsFocus(); \
310 bool classname::AcceptsFocusFromKeyboard() const \
312 return m_container.AcceptsFocusFromKeyboard(); \
316 #ifdef wxHAS_NATIVE_TAB_TRAVERSAL
318 #define WX_EVENT_TABLE_CONTROL_CONTAINER(classname)
320 #define WX_DECLARE_CONTROL_CONTAINER WX_DECLARE_CONTROL_CONTAINER_BASE
322 #define WX_DELEGATE_TO_CONTROL_CONTAINER(classname, basename) \
323 WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
325 void classname::RemoveChild(wxWindowBase *child) \
327 basename::RemoveChild(child); \
329 m_container.UpdateCanFocus(); \
332 void classname::SetFocusIgnoringChildren() \
334 basename::SetFocus(); \
337 #else // !wxHAS_NATIVE_TAB_TRAVERSAL
339 // declare the methods to be forwarded
340 #define WX_DECLARE_CONTROL_CONTAINER() \
341 WX_DECLARE_CONTROL_CONTAINER_BASE(); \
344 void OnNavigationKey(wxNavigationKeyEvent& event); \
345 void OnFocus(wxFocusEvent& event); \
346 virtual void OnChildFocus(wxChildFocusEvent& event)
348 // implement the event table entries for wxControlContainer
349 #define WX_EVENT_TABLE_CONTROL_CONTAINER(classname) \
350 EVT_SET_FOCUS(classname::OnFocus) \
351 EVT_CHILD_FOCUS(classname::OnChildFocus) \
352 EVT_NAVIGATION_KEY(classname::OnNavigationKey)
354 // implement the methods forwarding to the wxControlContainer
355 #define WX_DELEGATE_TO_CONTROL_CONTAINER(classname, basename) \
356 WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
358 void classname::RemoveChild(wxWindowBase *child) \
360 m_container.HandleOnWindowDestroy(child); \
362 basename::RemoveChild(child); \
364 m_container.UpdateCanFocus(); \
367 void classname::OnNavigationKey( wxNavigationKeyEvent& event ) \
369 m_container.HandleOnNavigationKey(event); \
372 void classname::SetFocusIgnoringChildren() \
374 basename::SetFocus(); \
377 void classname::OnChildFocus(wxChildFocusEvent& event) \
379 m_container.SetLastFocus(event.GetWindow()); \
383 void classname::OnFocus(wxFocusEvent& event) \
385 m_container.HandleOnFocus(event); \
388 #endif // wxHAS_NATIVE_TAB_TRAVERSAL/!wxHAS_NATIVE_TAB_TRAVERSAL
390 #endif // WXWIN_COMPATIBILITY_2_8
392 #endif // _WX_CONTAINR_H_