]> git.saurik.com Git - wxWidgets.git/blame - include/wx/containr.h
Document wxKill(wxSIGTERM) reliance on having an open window in wxMSW.
[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
e68b7b36
VZ
45 // By default, we accept focus ourselves.
46 m_acceptsFocusSelf = true;
47
48 // But we don't have any children accepting it yet.
49 m_acceptsFocusChildren = false;
50
c7bfb76a
JS
51 m_inSetFocus = false;
52 m_winLastFocused = NULL;
80332672 53 }
c7bfb76a 54 virtual ~wxControlContainerBase() {}
80332672
VZ
55
56 void SetContainerWindow(wxWindow *winParent)
57 {
9a83f860 58 wxASSERT_MSG( !m_winParent, wxT("shouldn't be called twice") );
80332672
VZ
59
60 m_winParent = winParent;
61 }
62
e68b7b36
VZ
63 // This can be called by the window to indicate that it never wants to have
64 // the focus for itself.
043ad13f
VZ
65 void DisableSelfFocus()
66 { m_acceptsFocusSelf = false; UpdateParentCanFocus(); }
67
68 // This can be called to undo the effect of a previous DisableSelfFocus()
69 // (otherwise calling it is not necessary as the window does accept focus
70 // by default).
71 void EnableSelfFocus()
72 { m_acceptsFocusSelf = true; UpdateParentCanFocus(); }
e68b7b36 73
c7bfb76a
JS
74 // should be called from SetFocus(), returns false if we did nothing with
75 // the focus and the default processing should take place
76 bool DoSetFocus();
77
80332672 78 // returns whether we should accept focus ourselves or not
bd6ca54f
VZ
79 bool AcceptsFocus() const
80 { return m_acceptsFocusSelf && m_winParent->CanBeFocused(); }
80332672 81
e68b7b36
VZ
82 // Returns whether we or one of our children accepts focus.
83 bool AcceptsFocusRecursively() const
bd6ca54f 84 { return AcceptsFocus() ||
dee22e31 85 (m_acceptsFocusChildren && HasAnyChildrenAcceptingFocus()); }
edc09871 86
e68b7b36
VZ
87 // We accept focus from keyboard if we accept it at all.
88 bool AcceptsFocusFromKeyboard() const { return AcceptsFocusRecursively(); }
21bf81db 89
00ff24c8 90 // Call this when the number of children of the window changes.
e68b7b36
VZ
91 //
92 // Returns true if we have any focusable children, false otherwise.
93 bool UpdateCanFocusChildren();
80332672
VZ
94
95protected:
c7bfb76a
JS
96 // set the focus to the child which had it the last time
97 virtual bool SetFocusToChild();
98
edc09871
VZ
99 // return true if we have any children accepting focus
100 bool HasAnyFocusableChildren() const;
80332672 101
dee22e31
VZ
102 // return true if we have any children that do accept focus right now
103 bool HasAnyChildrenAcceptingFocus() const;
104
105
80332672
VZ
106 // the parent window we manage the children for
107 wxWindow *m_winParent;
108
1c1ad005
JS
109 // the child which had the focus last time this panel was activated
110 wxWindow *m_winLastFocused;
111
bf0e8244 112private:
2c750dae
VZ
113 // Update the window status to reflect whether it is getting focus or not.
114 void UpdateParentCanFocus();
115
e68b7b36
VZ
116 // Indicates whether the associated window can ever have focus itself.
117 //
118 // Usually this is the case, e.g. a wxPanel can be used either as a
119 // container for its children or just as a normal window which can be
120 // focused. But sometimes, e.g. for wxStaticBox, we can never have focus
121 // ourselves and can only get it if we have any focusable children.
122 bool m_acceptsFocusSelf;
123
124 // Cached value remembering whether we have any children accepting focus.
125 bool m_acceptsFocusChildren;
c7bfb76a
JS
126
127 // a guard against infinite recursion
128 bool m_inSetFocus;
80332672
VZ
129};
130
4d98817c
VZ
131#ifdef wxHAS_NATIVE_TAB_TRAVERSAL
132
133// ----------------------------------------------------------------------------
134// wxControlContainer for native TAB navigation
135// ----------------------------------------------------------------------------
136
137// this must be a real class as we forward-declare it elsewhere
138class WXDLLIMPEXP_CORE wxControlContainer : public wxControlContainerBase
139{
140protected:
141 // set the focus to the child which had it the last time
142 virtual bool SetFocusToChild();
143};
144
145#else // !wxHAS_NATIVE_TAB_TRAVERSAL
146
4d98817c
VZ
147// ----------------------------------------------------------------------------
148// wxControlContainer for TAB navigation implemented in wx itself
149// ----------------------------------------------------------------------------
150
151class WXDLLIMPEXP_CORE wxControlContainer : public wxControlContainerBase
152{
153public:
154 // default ctor, SetContainerWindow() must be called later
155 wxControlContainer();
156
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);
161
162 // called from OnChildFocus() handler, i.e. when one of our (grand)
163 // children gets the focus
164 void SetLastFocus(wxWindow *win);
165
166protected:
167
168 wxDECLARE_NO_COPY_CLASS(wxControlContainer);
169};
170
171#endif // wxHAS_NATIVE_TAB_TRAVERSAL/!wxHAS_NATIVE_TAB_TRAVERSAL
172
173// this function is for wxWidgets internal use only
31af22fa 174extern WXDLLIMPEXP_CORE bool wxSetFocusToChild(wxWindow *win, wxWindow **child);
4d98817c
VZ
175
176// ----------------------------------------------------------------------------
177// wxNavigationEnabled: Derive from this class to support keyboard navigation
178// among window children in a wxWindow-derived class. The details of this class
179// don't matter, you just need to derive from it to make navigation work.
180// ----------------------------------------------------------------------------
181
182// The template parameter W must be a wxWindow-derived class.
183template <class W>
184class wxNavigationEnabled : public W
185{
186public:
187 typedef W BaseWindowClass;
188
189 wxNavigationEnabled()
190 {
191 m_container.SetContainerWindow(this);
192
193#ifndef wxHAS_NATIVE_TAB_TRAVERSAL
1f6831ea 194 BaseWindowClass::Connect(wxEVT_NAVIGATION_KEY,
4d98817c
VZ
195 wxNavigationKeyEventHandler(wxNavigationEnabled::OnNavigationKey));
196
1f6831ea 197 BaseWindowClass::Connect(wxEVT_SET_FOCUS,
4d98817c
VZ
198 wxFocusEventHandler(wxNavigationEnabled::OnFocus));
199
1f6831ea 200 BaseWindowClass::Connect(wxEVT_CHILD_FOCUS,
4d98817c
VZ
201 wxChildFocusEventHandler(wxNavigationEnabled::OnChildFocus));
202#endif // !wxHAS_NATIVE_TAB_TRAVERSAL
203 }
204
87381108 205 WXDLLIMPEXP_INLINE_CORE virtual bool AcceptsFocus() const
4d98817c
VZ
206 {
207 return m_container.AcceptsFocus();
208 }
209
87381108 210 WXDLLIMPEXP_INLINE_CORE virtual bool AcceptsFocusRecursively() const
4d98817c
VZ
211 {
212 return m_container.AcceptsFocusRecursively();
213 }
214
87381108 215 WXDLLIMPEXP_INLINE_CORE virtual bool AcceptsFocusFromKeyboard() const
4d98817c
VZ
216 {
217 return m_container.AcceptsFocusFromKeyboard();
218 }
219
87381108 220 WXDLLIMPEXP_INLINE_CORE virtual void AddChild(wxWindowBase *child)
4d98817c
VZ
221 {
222 BaseWindowClass::AddChild(child);
223
861bdae4
VZ
224 if ( m_container.UpdateCanFocusChildren() )
225 {
226 // Under MSW we must have wxTAB_TRAVERSAL style for TAB navigation
227 // to work.
228 if ( !BaseWindowClass::HasFlag(wxTAB_TRAVERSAL) )
229 BaseWindowClass::ToggleWindowStyle(wxTAB_TRAVERSAL);
230 }
4d98817c
VZ
231 }
232
87381108 233 WXDLLIMPEXP_INLINE_CORE virtual void RemoveChild(wxWindowBase *child)
4d98817c
VZ
234 {
235#ifndef wxHAS_NATIVE_TAB_TRAVERSAL
236 m_container.HandleOnWindowDestroy(child);
237#endif // !wxHAS_NATIVE_TAB_TRAVERSAL
238
239 BaseWindowClass::RemoveChild(child);
240
861bdae4
VZ
241 // We could reset wxTAB_TRAVERSAL here but it doesn't seem to do any
242 // harm to keep it.
e68b7b36 243 m_container.UpdateCanFocusChildren();
4d98817c
VZ
244 }
245
87381108 246 WXDLLIMPEXP_INLINE_CORE virtual void SetFocus()
4d98817c
VZ
247 {
248 if ( !m_container.DoSetFocus() )
249 BaseWindowClass::SetFocus();
250 }
251
252 void SetFocusIgnoringChildren()
253 {
254 BaseWindowClass::SetFocus();
255 }
256
4d98817c
VZ
257protected:
258#ifndef wxHAS_NATIVE_TAB_TRAVERSAL
259 void OnNavigationKey(wxNavigationKeyEvent& event)
260 {
261 m_container.HandleOnNavigationKey(event);
262 }
263
264 void OnFocus(wxFocusEvent& event)
265 {
266 m_container.HandleOnFocus(event);
267 }
268
269 void OnChildFocus(wxChildFocusEvent& event)
270 {
271 m_container.SetLastFocus(event.GetWindow());
272 event.Skip();
273 }
274#endif // !wxHAS_NATIVE_TAB_TRAVERSAL
275
276 wxControlContainer m_container;
277
278
279 wxDECLARE_NO_COPY_TEMPLATE_CLASS(wxNavigationEnabled, W);
280};
281
282// ----------------------------------------------------------------------------
283// Compatibility macros from now on, do NOT use them and preferably do not even
284// look at them.
285// ----------------------------------------------------------------------------
286
7bc57fd9 287#if WXWIN_COMPATIBILITY_2_8
4d98817c 288
80332672
VZ
289// common part of WX_DECLARE_CONTROL_CONTAINER in the native and generic cases,
290// it should be used in the wxWindow-derived class declaration
291#define WX_DECLARE_CONTROL_CONTAINER_BASE() \
292public: \
293 virtual bool AcceptsFocus() const; \
edc09871 294 virtual bool AcceptsFocusRecursively() const; \
21bf81db 295 virtual bool AcceptsFocusFromKeyboard() const; \
80332672
VZ
296 virtual void AddChild(wxWindowBase *child); \
297 virtual void RemoveChild(wxWindowBase *child); \
c7bfb76a 298 virtual void SetFocus(); \
80332672 299 void SetFocusIgnoringChildren(); \
80332672
VZ
300 \
301protected: \
302 wxControlContainer m_container
303
304// this macro must be used in the derived class ctor
305#define WX_INIT_CONTROL_CONTAINER() \
306 m_container.SetContainerWindow(this)
307
308// common part of WX_DELEGATE_TO_CONTROL_CONTAINER in the native and generic
309// cases, must be used in the wxWindow-derived class implementation
310#define WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
311 void classname::AddChild(wxWindowBase *child) \
312 { \
313 basename::AddChild(child); \
314 \
e68b7b36 315 m_container.UpdateCanFocusChildren(); \
80332672
VZ
316 } \
317 \
edc09871
VZ
318 bool classname::AcceptsFocusRecursively() const \
319 { \
320 return m_container.AcceptsFocusRecursively(); \
321 } \
322 \
c7bfb76a
JS
323 void classname::SetFocus() \
324 { \
325 if ( !m_container.DoSetFocus() ) \
326 basename::SetFocus(); \
327 } \
328 \
80332672
VZ
329 bool classname::AcceptsFocus() const \
330 { \
331 return m_container.AcceptsFocus(); \
21bf81db
VZ
332 } \
333 \
334 bool classname::AcceptsFocusFromKeyboard() const \
335 { \
336 return m_container.AcceptsFocusFromKeyboard(); \
80332672
VZ
337 }
338
de160b06 339
4d98817c 340#ifdef wxHAS_NATIVE_TAB_TRAVERSAL
de160b06 341
de160b06 342#define WX_EVENT_TABLE_CONTROL_CONTAINER(classname)
80332672
VZ
343
344#define WX_DECLARE_CONTROL_CONTAINER WX_DECLARE_CONTROL_CONTAINER_BASE
345
346#define WX_DELEGATE_TO_CONTROL_CONTAINER(classname, basename) \
347 WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
348 \
349 void classname::RemoveChild(wxWindowBase *child) \
350 { \
351 basename::RemoveChild(child); \
352 \
e68b7b36 353 m_container.UpdateCanFocusChildren(); \
80332672
VZ
354 } \
355 \
356 void classname::SetFocusIgnoringChildren() \
357 { \
00ff24c8 358 basename::SetFocus(); \
80332672 359 }
de160b06
VZ
360
361#else // !wxHAS_NATIVE_TAB_TRAVERSAL
362
456bc6d9 363// declare the methods to be forwarded
d1cd787b
VZ
364#define WX_DECLARE_CONTROL_CONTAINER() \
365 WX_DECLARE_CONTROL_CONTAINER_BASE(); \
366 \
367public: \
368 void OnNavigationKey(wxNavigationKeyEvent& event); \
369 void OnFocus(wxFocusEvent& event); \
c7bfb76a 370 virtual void OnChildFocus(wxChildFocusEvent& event)
456bc6d9
VZ
371
372// implement the event table entries for wxControlContainer
373#define WX_EVENT_TABLE_CONTROL_CONTAINER(classname) \
374 EVT_SET_FOCUS(classname::OnFocus) \
375 EVT_CHILD_FOCUS(classname::OnChildFocus) \
376 EVT_NAVIGATION_KEY(classname::OnNavigationKey)
377
378// implement the methods forwarding to the wxControlContainer
80332672
VZ
379#define WX_DELEGATE_TO_CONTROL_CONTAINER(classname, basename) \
380 WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
381 \
382 void classname::RemoveChild(wxWindowBase *child) \
383 { \
384 m_container.HandleOnWindowDestroy(child); \
385 \
386 basename::RemoveChild(child); \
387 \
e68b7b36 388 m_container.UpdateCanFocusChildren(); \
80332672
VZ
389 } \
390 \
391 void classname::OnNavigationKey( wxNavigationKeyEvent& event ) \
392 { \
393 m_container.HandleOnNavigationKey(event); \
394 } \
395 \
80332672
VZ
396 void classname::SetFocusIgnoringChildren() \
397 { \
398 basename::SetFocus(); \
399 } \
400 \
401 void classname::OnChildFocus(wxChildFocusEvent& event) \
402 { \
403 m_container.SetLastFocus(event.GetWindow()); \
57c5c10f 404 event.Skip(); \
80332672
VZ
405 } \
406 \
407 void classname::OnFocus(wxFocusEvent& event) \
408 { \
409 m_container.HandleOnFocus(event); \
1c1ad005 410 }
456bc6d9 411
de160b06 412#endif // wxHAS_NATIVE_TAB_TRAVERSAL/!wxHAS_NATIVE_TAB_TRAVERSAL
456bc6d9 413
4d98817c 414#endif // WXWIN_COMPATIBILITY_2_8
c7bfb76a 415
456bc6d9 416#endif // _WX_CONTAINR_H_