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