]> git.saurik.com Git - wxWidgets.git/blame - include/wx/containr.h
simpler implementation that also works over remote connections by Kevin O.
[wxWidgets.git] / include / wx / containr.h
CommitLineData
456bc6d9
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: wx/containr.h
4d98817c 3// Purpose: wxControlContainer and wxNavigationEnabled declarations
456bc6d9
VZ
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 06.08.01
7// RCS-ID: $Id$
4d98817c 8// Copyright: (c) 2001, 2011 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
65571936 9// Licence: wxWindows licence
456bc6d9
VZ
10///////////////////////////////////////////////////////////////////////////////
11
12#ifndef _WX_CONTAINR_H_
13#define _WX_CONTAINR_H_
14
617fb24f
VZ
15#include "wx/defs.h"
16
9f1bf940
VZ
17#ifndef wxHAS_NATIVE_TAB_TRAVERSAL
18 // We need wxEVT_XXX declarations in this case.
19 #include "wx/event.h"
20#endif
21
b5dbe15d
VS
22class WXDLLIMPEXP_FWD_CORE wxWindow;
23class WXDLLIMPEXP_FWD_CORE wxWindowBase;
bf0e8244 24
80332672 25/*
4d98817c
VZ
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.
80332672
VZ
31 */
32
33// ----------------------------------------------------------------------------
34// wxControlContainerBase: common part used in both native and generic cases
35// ----------------------------------------------------------------------------
36
53a2db12 37class WXDLLIMPEXP_CORE wxControlContainerBase
80332672
VZ
38{
39public:
40 // default ctor, SetContainerWindow() must be called later
41 wxControlContainerBase()
42 {
43 m_winParent = NULL;
44
45 // do accept focus initially, we'll stop doing it if/when any children
46 // are added
47 m_acceptsFocus = true;
c7bfb76a
JS
48 m_inSetFocus = false;
49 m_winLastFocused = NULL;
80332672 50 }
c7bfb76a 51 virtual ~wxControlContainerBase() {}
80332672
VZ
52
53 void SetContainerWindow(wxWindow *winParent)
54 {
9a83f860 55 wxASSERT_MSG( !m_winParent, wxT("shouldn't be called twice") );
80332672
VZ
56
57 m_winParent = winParent;
58 }
59
c7bfb76a
JS
60 // should be called from SetFocus(), returns false if we did nothing with
61 // the focus and the default processing should take place
62 bool DoSetFocus();
63
80332672
VZ
64 // should be called when we decide that we should [stop] accepting focus
65 void SetCanFocus(bool acceptsFocus);
66
67 // returns whether we should accept focus ourselves or not
68 bool AcceptsFocus() const { return m_acceptsFocus; }
69
edc09871
VZ
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; }
75
21bf81db
VZ
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; }
80
00ff24c8
RR
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.
edc09871 84 void UpdateCanFocus() { SetCanFocus(!HasAnyFocusableChildren()); }
80332672
VZ
85
86protected:
c7bfb76a
JS
87 // set the focus to the child which had it the last time
88 virtual bool SetFocusToChild();
89
edc09871
VZ
90 // return true if we have any children accepting focus
91 bool HasAnyFocusableChildren() const;
80332672 92
80332672
VZ
93 // the parent window we manage the children for
94 wxWindow *m_winParent;
95
1c1ad005
JS
96 // the child which had the focus last time this panel was activated
97 wxWindow *m_winLastFocused;
98
bf0e8244 99private:
80332672
VZ
100 // value returned by AcceptsFocus(), should be changed using SetCanFocus()
101 // only
102 bool m_acceptsFocus;
c7bfb76a
JS
103
104 // a guard against infinite recursion
105 bool m_inSetFocus;
80332672
VZ
106};
107
4d98817c
VZ
108#ifdef wxHAS_NATIVE_TAB_TRAVERSAL
109
110// ----------------------------------------------------------------------------
111// wxControlContainer for native TAB navigation
112// ----------------------------------------------------------------------------
113
114// this must be a real class as we forward-declare it elsewhere
115class WXDLLIMPEXP_CORE wxControlContainer : public wxControlContainerBase
116{
117protected:
118 // set the focus to the child which had it the last time
119 virtual bool SetFocusToChild();
120};
121
122#else // !wxHAS_NATIVE_TAB_TRAVERSAL
123
4d98817c
VZ
124// ----------------------------------------------------------------------------
125// wxControlContainer for TAB navigation implemented in wx itself
126// ----------------------------------------------------------------------------
127
128class WXDLLIMPEXP_CORE wxControlContainer : public wxControlContainerBase
129{
130public:
131 // default ctor, SetContainerWindow() must be called later
132 wxControlContainer();
133
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);
138
139 // called from OnChildFocus() handler, i.e. when one of our (grand)
140 // children gets the focus
141 void SetLastFocus(wxWindow *win);
142
143protected:
144
145 wxDECLARE_NO_COPY_CLASS(wxControlContainer);
146};
147
148#endif // wxHAS_NATIVE_TAB_TRAVERSAL/!wxHAS_NATIVE_TAB_TRAVERSAL
149
150// this function is for wxWidgets internal use only
31af22fa 151extern WXDLLIMPEXP_CORE bool wxSetFocusToChild(wxWindow *win, wxWindow **child);
4d98817c
VZ
152
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// ----------------------------------------------------------------------------
158
159// The template parameter W must be a wxWindow-derived class.
160template <class W>
161class wxNavigationEnabled : public W
162{
163public:
164 typedef W BaseWindowClass;
165
166 wxNavigationEnabled()
167 {
168 m_container.SetContainerWindow(this);
169
170#ifndef wxHAS_NATIVE_TAB_TRAVERSAL
1f6831ea 171 BaseWindowClass::Connect(wxEVT_NAVIGATION_KEY,
4d98817c
VZ
172 wxNavigationKeyEventHandler(wxNavigationEnabled::OnNavigationKey));
173
1f6831ea 174 BaseWindowClass::Connect(wxEVT_SET_FOCUS,
4d98817c
VZ
175 wxFocusEventHandler(wxNavigationEnabled::OnFocus));
176
1f6831ea 177 BaseWindowClass::Connect(wxEVT_CHILD_FOCUS,
4d98817c
VZ
178 wxChildFocusEventHandler(wxNavigationEnabled::OnChildFocus));
179#endif // !wxHAS_NATIVE_TAB_TRAVERSAL
180 }
181
87381108 182 WXDLLIMPEXP_INLINE_CORE virtual bool AcceptsFocus() const
4d98817c
VZ
183 {
184 return m_container.AcceptsFocus();
185 }
186
87381108 187 WXDLLIMPEXP_INLINE_CORE virtual bool AcceptsFocusRecursively() const
4d98817c
VZ
188 {
189 return m_container.AcceptsFocusRecursively();
190 }
191
87381108 192 WXDLLIMPEXP_INLINE_CORE virtual bool AcceptsFocusFromKeyboard() const
4d98817c
VZ
193 {
194 return m_container.AcceptsFocusFromKeyboard();
195 }
196
87381108 197 WXDLLIMPEXP_INLINE_CORE virtual void AddChild(wxWindowBase *child)
4d98817c
VZ
198 {
199 BaseWindowClass::AddChild(child);
200
201 m_container.UpdateCanFocus();
202 }
203
87381108 204 WXDLLIMPEXP_INLINE_CORE virtual void RemoveChild(wxWindowBase *child)
4d98817c
VZ
205 {
206#ifndef wxHAS_NATIVE_TAB_TRAVERSAL
207 m_container.HandleOnWindowDestroy(child);
208#endif // !wxHAS_NATIVE_TAB_TRAVERSAL
209
210 BaseWindowClass::RemoveChild(child);
211
212 m_container.UpdateCanFocus();
213 }
214
87381108 215 WXDLLIMPEXP_INLINE_CORE virtual void SetFocus()
4d98817c
VZ
216 {
217 if ( !m_container.DoSetFocus() )
218 BaseWindowClass::SetFocus();
219 }
220
221 void SetFocusIgnoringChildren()
222 {
223 BaseWindowClass::SetFocus();
224 }
225
226 void AcceptFocus(bool acceptFocus)
227 {
228 m_container.SetCanFocus(acceptFocus);
229 }
230
231protected:
232#ifndef wxHAS_NATIVE_TAB_TRAVERSAL
233 void OnNavigationKey(wxNavigationKeyEvent& event)
234 {
235 m_container.HandleOnNavigationKey(event);
236 }
237
238 void OnFocus(wxFocusEvent& event)
239 {
240 m_container.HandleOnFocus(event);
241 }
242
243 void OnChildFocus(wxChildFocusEvent& event)
244 {
245 m_container.SetLastFocus(event.GetWindow());
246 event.Skip();
247 }
248#endif // !wxHAS_NATIVE_TAB_TRAVERSAL
249
250 wxControlContainer m_container;
251
252
253 wxDECLARE_NO_COPY_TEMPLATE_CLASS(wxNavigationEnabled, W);
254};
255
256// ----------------------------------------------------------------------------
257// Compatibility macros from now on, do NOT use them and preferably do not even
258// look at them.
259// ----------------------------------------------------------------------------
260
7bc57fd9 261#if WXWIN_COMPATIBILITY_2_8
4d98817c 262
80332672
VZ
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() \
266public: \
267 virtual bool AcceptsFocus() const; \
edc09871 268 virtual bool AcceptsFocusRecursively() const; \
21bf81db 269 virtual bool AcceptsFocusFromKeyboard() const; \
80332672
VZ
270 virtual void AddChild(wxWindowBase *child); \
271 virtual void RemoveChild(wxWindowBase *child); \
c7bfb76a 272 virtual void SetFocus(); \
80332672
VZ
273 void SetFocusIgnoringChildren(); \
274 void AcceptFocus(bool acceptFocus) \
275 { \
276 m_container.SetCanFocus(acceptFocus); \
277 } \
278 \
279protected: \
280 wxControlContainer m_container
281
282// this macro must be used in the derived class ctor
283#define WX_INIT_CONTROL_CONTAINER() \
284 m_container.SetContainerWindow(this)
285
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) \
290 { \
291 basename::AddChild(child); \
292 \
293 m_container.UpdateCanFocus(); \
294 } \
295 \
edc09871
VZ
296 bool classname::AcceptsFocusRecursively() const \
297 { \
298 return m_container.AcceptsFocusRecursively(); \
299 } \
300 \
c7bfb76a
JS
301 void classname::SetFocus() \
302 { \
303 if ( !m_container.DoSetFocus() ) \
304 basename::SetFocus(); \
305 } \
306 \
80332672
VZ
307 bool classname::AcceptsFocus() const \
308 { \
309 return m_container.AcceptsFocus(); \
21bf81db
VZ
310 } \
311 \
312 bool classname::AcceptsFocusFromKeyboard() const \
313 { \
314 return m_container.AcceptsFocusFromKeyboard(); \
80332672
VZ
315 }
316
de160b06 317
4d98817c 318#ifdef wxHAS_NATIVE_TAB_TRAVERSAL
de160b06 319
de160b06 320#define WX_EVENT_TABLE_CONTROL_CONTAINER(classname)
80332672
VZ
321
322#define WX_DECLARE_CONTROL_CONTAINER WX_DECLARE_CONTROL_CONTAINER_BASE
323
324#define WX_DELEGATE_TO_CONTROL_CONTAINER(classname, basename) \
325 WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
326 \
327 void classname::RemoveChild(wxWindowBase *child) \
328 { \
329 basename::RemoveChild(child); \
330 \
331 m_container.UpdateCanFocus(); \
332 } \
333 \
334 void classname::SetFocusIgnoringChildren() \
335 { \
00ff24c8 336 basename::SetFocus(); \
80332672 337 }
de160b06
VZ
338
339#else // !wxHAS_NATIVE_TAB_TRAVERSAL
340
456bc6d9 341// declare the methods to be forwarded
d1cd787b
VZ
342#define WX_DECLARE_CONTROL_CONTAINER() \
343 WX_DECLARE_CONTROL_CONTAINER_BASE(); \
344 \
345public: \
346 void OnNavigationKey(wxNavigationKeyEvent& event); \
347 void OnFocus(wxFocusEvent& event); \
c7bfb76a 348 virtual void OnChildFocus(wxChildFocusEvent& event)
456bc6d9
VZ
349
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)
355
356// implement the methods forwarding to the wxControlContainer
80332672
VZ
357#define WX_DELEGATE_TO_CONTROL_CONTAINER(classname, basename) \
358 WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
359 \
360 void classname::RemoveChild(wxWindowBase *child) \
361 { \
362 m_container.HandleOnWindowDestroy(child); \
363 \
364 basename::RemoveChild(child); \
365 \
366 m_container.UpdateCanFocus(); \
367 } \
368 \
369 void classname::OnNavigationKey( wxNavigationKeyEvent& event ) \
370 { \
371 m_container.HandleOnNavigationKey(event); \
372 } \
373 \
80332672
VZ
374 void classname::SetFocusIgnoringChildren() \
375 { \
376 basename::SetFocus(); \
377 } \
378 \
379 void classname::OnChildFocus(wxChildFocusEvent& event) \
380 { \
381 m_container.SetLastFocus(event.GetWindow()); \
57c5c10f 382 event.Skip(); \
80332672
VZ
383 } \
384 \
385 void classname::OnFocus(wxFocusEvent& event) \
386 { \
387 m_container.HandleOnFocus(event); \
1c1ad005 388 }
456bc6d9 389
de160b06 390#endif // wxHAS_NATIVE_TAB_TRAVERSAL/!wxHAS_NATIVE_TAB_TRAVERSAL
456bc6d9 391
4d98817c 392#endif // WXWIN_COMPATIBILITY_2_8
c7bfb76a 393
456bc6d9 394#endif // _WX_CONTAINR_H_