define wxHAS_NATIVE_TAB_TRAVERSAL in wx/features.h; include wx/defs.h from wx/contain...
[wxWidgets.git] / include / wx / containr.h
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: wx/containr.h
3 // Purpose: wxControlContainer class declration: a "mix-in" class which
4 // implements the TAB navigation between the controls
5 // Author: Vadim Zeitlin
6 // Modified by:
7 // Created: 06.08.01
8 // RCS-ID: $Id$
9 // Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
10 // Licence: wxWindows licence
11 ///////////////////////////////////////////////////////////////////////////////
12
13 #ifndef _WX_CONTAINR_H_
14 #define _WX_CONTAINR_H_
15
16 #include "wx/defs.h"
17
18 #ifdef wxHAS_NATIVE_TAB_TRAVERSAL
19
20 #define WX_DECLARE_CONTROL_CONTAINER() \
21 virtual bool AcceptsFocus() const { return false; } \
22 void SetFocusIgnoringChildren() { SetFocus(); }
23
24 #define WX_INIT_CONTROL_CONTAINER()
25 #define WX_EVENT_TABLE_CONTROL_CONTAINER(classname)
26 #define WX_DELEGATE_TO_CONTROL_CONTAINER(classname, basename)
27
28 #else // !wxHAS_NATIVE_TAB_TRAVERSAL
29
30 class WXDLLEXPORT wxFocusEvent;
31 class WXDLLEXPORT wxNavigationKeyEvent;
32 class WXDLLEXPORT wxWindow;
33 class WXDLLEXPORT wxWindowBase;
34
35 /*
36 Implementation note: wxControlContainer is not a real mix-in but rather
37 a class meant to be aggregated with (and not inherited from). Although
38 logically it should be a mix-in, doing it like this has no advantage from
39 the point of view of the existing code but does have some problems (we'd
40 need to play tricks with event handlers which may be difficult to do
41 safely). The price we pay for this simplicity is the ugly macros below.
42 */
43
44 // ----------------------------------------------------------------------------
45 // wxControlContainer
46 // ----------------------------------------------------------------------------
47
48 class WXDLLEXPORT wxControlContainer
49 {
50 public:
51 // ctors and such
52 wxControlContainer(wxWindow *winParent = NULL);
53 void SetContainerWindow(wxWindow *winParent) { m_winParent = winParent; }
54
55 // the methods to be called from the window event handlers
56 void HandleOnNavigationKey(wxNavigationKeyEvent& event);
57 void HandleOnFocus(wxFocusEvent& event);
58 void HandleOnWindowDestroy(wxWindowBase *child);
59
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
64 // can our child get the focus?
65 bool AcceptsFocus() const;
66
67 // called from OnChildFocus() handler, i.e. when one of our (grand)
68 // children gets the focus
69 void SetLastFocus(wxWindow *win);
70
71 protected:
72 // set the focus to the child which had it the last time
73 bool SetFocusToChild();
74
75 // the parent window we manage the children for
76 wxWindow *m_winParent;
77
78 // the child which had the focus last time this panel was activated
79 wxWindow *m_winLastFocused;
80
81 // a guard against infinite recursion
82 bool m_inSetFocus;
83
84 DECLARE_NO_COPY_CLASS(wxControlContainer)
85 };
86
87 // this function is for wxWidgets internal use only
88 extern bool wxSetFocusToChild(wxWindow *win, wxWindow **child);
89
90 // ----------------------------------------------------------------------------
91 // macros which may be used by the classes wishing to implement TAB navigation
92 // among their children
93 // ----------------------------------------------------------------------------
94
95 // declare the methods to be forwarded
96 #define WX_DECLARE_CONTROL_CONTAINER() \
97 public: \
98 void OnNavigationKey(wxNavigationKeyEvent& event); \
99 void OnFocus(wxFocusEvent& event); \
100 virtual void OnChildFocus(wxChildFocusEvent& event); \
101 virtual void SetFocus(); \
102 virtual void SetFocusIgnoringChildren(); \
103 virtual void RemoveChild(wxWindowBase *child); \
104 virtual bool AcceptsFocus() const; \
105 \
106 protected: \
107 wxControlContainer m_container
108
109 // this macro must be used in the derived class ctor
110 #define WX_INIT_CONTROL_CONTAINER() \
111 m_container.SetContainerWindow(this)
112
113 // implement the event table entries for wxControlContainer
114 #define WX_EVENT_TABLE_CONTROL_CONTAINER(classname) \
115 EVT_SET_FOCUS(classname::OnFocus) \
116 EVT_CHILD_FOCUS(classname::OnChildFocus) \
117 EVT_NAVIGATION_KEY(classname::OnNavigationKey)
118
119 // implement the methods forwarding to the wxControlContainer
120 #define WX_DELEGATE_TO_CONTROL_CONTAINER(classname, basename) \
121 void classname::OnNavigationKey( wxNavigationKeyEvent& event ) \
122 { \
123 m_container.HandleOnNavigationKey(event); \
124 } \
125 \
126 void classname::RemoveChild(wxWindowBase *child) \
127 { \
128 m_container.HandleOnWindowDestroy(child); \
129 \
130 basename::RemoveChild(child); \
131 } \
132 \
133 void classname::SetFocus() \
134 { \
135 if ( !m_container.DoSetFocus() ) \
136 basename::SetFocus(); \
137 } \
138 \
139 void classname::SetFocusIgnoringChildren() \
140 { \
141 basename::SetFocus(); \
142 } \
143 \
144 void classname::OnChildFocus(wxChildFocusEvent& event) \
145 { \
146 m_container.SetLastFocus(event.GetWindow()); \
147 } \
148 \
149 void classname::OnFocus(wxFocusEvent& event) \
150 { \
151 m_container.HandleOnFocus(event); \
152 } \
153 bool classname::AcceptsFocus() const \
154 { \
155 return m_container.AcceptsFocus(); \
156 }
157
158 #endif // wxHAS_NATIVE_TAB_TRAVERSAL/!wxHAS_NATIVE_TAB_TRAVERSAL
159
160 #endif // _WX_CONTAINR_H_