1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxControlContainer class declration: a "mix-in" class which
4 // implements the TAB navigation between the controls
5 // Author: Vadim Zeitlin
9 // Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
10 // Licence: wxWindows licence
11 ///////////////////////////////////////////////////////////////////////////////
13 #ifndef _WX_CONTAINR_H_
14 #define _WX_CONTAINR_H_
19 Implementation note: wxControlContainer is not a real mix-in but rather
20 a class meant to be aggregated with (and not inherited from). Although
21 logically it should be a mix-in, doing it like this has no advantage from
22 the point of view of the existing code but does have some problems (we'd
23 need to play tricks with event handlers which may be difficult to do
24 safely). The price we pay for this simplicity is the ugly macros below.
27 // ----------------------------------------------------------------------------
28 // wxControlContainerBase: common part used in both native and generic cases
29 // ----------------------------------------------------------------------------
31 class WXDLLEXPORT wxControlContainerBase
34 // default ctor, SetContainerWindow() must be called later
35 wxControlContainerBase()
39 // do accept focus initially, we'll stop doing it if/when any children
41 m_acceptsFocus
= true;
44 void SetContainerWindow(wxWindow
*winParent
)
46 wxASSERT_MSG( !m_winParent
, _T("shouldn't be called twice") );
48 m_winParent
= winParent
;
51 // should be called when we decide that we should [stop] accepting focus
52 void SetCanFocus(bool acceptsFocus
);
54 // returns whether we should accept focus ourselves or not
55 bool AcceptsFocus() const { return m_acceptsFocus
; }
57 // call this when the number of children of the window changes
58 void UpdateCanFocus() { SetCanFocus(ShouldAcceptFocus()); }
61 // return true if we should be focusable
62 bool ShouldAcceptFocus() const;
65 // the parent window we manage the children for
66 wxWindow
*m_winParent
;
68 // value returned by AcceptsFocus(), should be changed using SetCanFocus()
73 // common part of WX_DECLARE_CONTROL_CONTAINER in the native and generic cases,
74 // it should be used in the wxWindow-derived class declaration
75 #define WX_DECLARE_CONTROL_CONTAINER_BASE() \
77 virtual bool AcceptsFocus() const; \
78 virtual void AddChild(wxWindowBase *child); \
79 virtual void RemoveChild(wxWindowBase *child); \
80 void SetFocusIgnoringChildren(); \
81 void AcceptFocus(bool acceptFocus) \
83 m_container.SetCanFocus(acceptFocus); \
87 wxControlContainer m_container
89 // this macro must be used in the derived class ctor
90 #define WX_INIT_CONTROL_CONTAINER() \
91 m_container.SetContainerWindow(this)
93 // common part of WX_DELEGATE_TO_CONTROL_CONTAINER in the native and generic
94 // cases, must be used in the wxWindow-derived class implementation
95 #define WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
96 void classname::AddChild(wxWindowBase *child) \
98 basename::AddChild(child); \
100 m_container.UpdateCanFocus(); \
103 bool classname::AcceptsFocus() const \
105 return m_container.AcceptsFocus(); \
109 #ifdef wxHAS_NATIVE_TAB_TRAVERSAL
111 // ----------------------------------------------------------------------------
112 // wxControlContainer for native TAB navigation
113 // ----------------------------------------------------------------------------
115 // this must be a real class as we forward-declare it elsewhere
116 class WXDLLEXPORT wxControlContainer
: public wxControlContainerBase
120 #define WX_EVENT_TABLE_CONTROL_CONTAINER(classname)
122 #define WX_DECLARE_CONTROL_CONTAINER WX_DECLARE_CONTROL_CONTAINER_BASE
124 #define WX_DELEGATE_TO_CONTROL_CONTAINER(classname, basename) \
125 WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
127 void classname::RemoveChild(wxWindowBase *child) \
129 basename::RemoveChild(child); \
131 m_container.UpdateCanFocus(); \
134 void classname::SetFocusIgnoringChildren() \
139 #else // !wxHAS_NATIVE_TAB_TRAVERSAL
141 class WXDLLEXPORT wxFocusEvent
;
142 class WXDLLEXPORT wxNavigationKeyEvent
;
143 class WXDLLEXPORT wxWindow
;
144 class WXDLLEXPORT wxWindowBase
;
146 // ----------------------------------------------------------------------------
147 // wxControlContainer for TAB navigation implemented in wx itself
148 // ----------------------------------------------------------------------------
150 class WXDLLEXPORT wxControlContainer
: public wxControlContainerBase
153 // default ctor, SetContainerWindow() must be called later
154 wxControlContainer();
156 // the methods to be called from the window event handlers
157 void HandleOnNavigationKey(wxNavigationKeyEvent
& event
);
158 void HandleOnFocus(wxFocusEvent
& event
);
159 void HandleOnWindowDestroy(wxWindowBase
*child
);
161 // should be called from SetFocus(), returns false if we did nothing with
162 // the focus and the default processing should take place
165 // can our child get the focus?
166 bool AcceptsFocus() const;
168 // called from OnChildFocus() handler, i.e. when one of our (grand)
169 // children gets the focus
170 void SetLastFocus(wxWindow
*win
);
173 // set the focus to the child which had it the last time
174 bool SetFocusToChild();
176 // the child which had the focus last time this panel was activated
177 wxWindow
*m_winLastFocused
;
179 // a guard against infinite recursion
182 DECLARE_NO_COPY_CLASS(wxControlContainer
)
185 // this function is for wxWidgets internal use only
186 extern bool wxSetFocusToChild(wxWindow
*win
, wxWindow
**child
);
188 // ----------------------------------------------------------------------------
189 // macros which may be used by the classes wishing to implement TAB navigation
190 // among their children
191 // ----------------------------------------------------------------------------
193 // declare the methods to be forwarded
194 #define WX_DECLARE_CONTROL_CONTAINER() \
196 void OnNavigationKey(wxNavigationKeyEvent& event); \
197 void OnFocus(wxFocusEvent& event); \
198 void SetFocusIgnoringChildren(); \
199 virtual void OnChildFocus(wxChildFocusEvent& event); \
200 virtual void SetFocus(); \
201 virtual void RemoveChild(wxWindowBase *child); \
202 virtual bool AcceptsFocus() const; \
205 wxControlContainer m_container
207 // implement the event table entries for wxControlContainer
208 #define WX_EVENT_TABLE_CONTROL_CONTAINER(classname) \
209 EVT_SET_FOCUS(classname::OnFocus) \
210 EVT_CHILD_FOCUS(classname::OnChildFocus) \
211 EVT_NAVIGATION_KEY(classname::OnNavigationKey)
213 // implement the methods forwarding to the wxControlContainer
214 #define WX_DELEGATE_TO_CONTROL_CONTAINER(classname, basename) \
215 WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
217 void classname::RemoveChild(wxWindowBase *child) \
219 m_container.HandleOnWindowDestroy(child); \
221 basename::RemoveChild(child); \
223 m_container.UpdateCanFocus(); \
226 void classname::OnNavigationKey( wxNavigationKeyEvent& event ) \
228 m_container.HandleOnNavigationKey(event); \
231 void classname::SetFocus() \
233 if ( !m_container.DoSetFocus() ) \
234 basename::SetFocus(); \
237 void classname::SetFocusIgnoringChildren() \
239 basename::SetFocus(); \
242 void classname::OnChildFocus(wxChildFocusEvent& event) \
244 m_container.SetLastFocus(event.GetWindow()); \
247 void classname::OnFocus(wxFocusEvent& event) \
249 m_container.HandleOnFocus(event); \
252 #endif // wxHAS_NATIVE_TAB_TRAVERSAL/!wxHAS_NATIVE_TAB_TRAVERSAL
254 #endif // _WX_CONTAINR_H_