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_
16 #ifdef wxHAS_NATIVE_TAB_TRAVERSAL
18 #define WX_DECLARE_CONTROL_CONTAINER() \
19 virtual bool AcceptsFocus() const { return false; } \
20 void SetFocusIgnoringChildren() { SetFocus(); }
22 #define WX_INIT_CONTROL_CONTAINER()
23 #define WX_EVENT_TABLE_CONTROL_CONTAINER(classname)
24 #define WX_DELEGATE_TO_CONTROL_CONTAINER(classname, basename)
26 #else // !wxHAS_NATIVE_TAB_TRAVERSAL
28 class WXDLLEXPORT wxFocusEvent
;
29 class WXDLLEXPORT wxNavigationKeyEvent
;
30 class WXDLLEXPORT wxWindow
;
31 class WXDLLEXPORT wxWindowBase
;
34 Implementation note: wxControlContainer is not a real mix-in but rather
35 a class meant to be aggregated with (and not inherited from). Although
36 logically it should be a mix-in, doing it like this has no advantage from
37 the point of view of the existing code but does have some problems (we'd
38 need to play tricks with event handlers which may be difficult to do
39 safely). The price we pay for this simplicity is the ugly macros below.
42 // ----------------------------------------------------------------------------
44 // ----------------------------------------------------------------------------
46 class WXDLLEXPORT wxControlContainer
50 wxControlContainer(wxWindow
*winParent
= NULL
);
51 void SetContainerWindow(wxWindow
*winParent
) { m_winParent
= winParent
; }
53 // the methods to be called from the window event handlers
54 void HandleOnNavigationKey(wxNavigationKeyEvent
& event
);
55 void HandleOnFocus(wxFocusEvent
& event
);
56 void HandleOnWindowDestroy(wxWindowBase
*child
);
58 // should be called from SetFocus(), returns false if we did nothing with
59 // the focus and the default processing should take place
62 // can our child get the focus?
63 bool AcceptsFocus() const;
65 // called from OnChildFocus() handler, i.e. when one of our (grand)
66 // children gets the focus
67 void SetLastFocus(wxWindow
*win
);
70 // set the focus to the child which had it the last time
71 bool SetFocusToChild();
73 // the parent window we manage the children for
74 wxWindow
*m_winParent
;
76 // the child which had the focus last time this panel was activated
77 wxWindow
*m_winLastFocused
;
79 // a guard against infinite recursion
82 DECLARE_NO_COPY_CLASS(wxControlContainer
)
85 // this function is for wxWidgets internal use only
86 extern bool wxSetFocusToChild(wxWindow
*win
, wxWindow
**child
);
88 // ----------------------------------------------------------------------------
89 // macros which may be used by the classes wishing to implement TAB navigation
90 // among their children
91 // ----------------------------------------------------------------------------
93 // declare the methods to be forwarded
94 #define WX_DECLARE_CONTROL_CONTAINER() \
96 void OnNavigationKey(wxNavigationKeyEvent& event); \
97 void OnFocus(wxFocusEvent& event); \
98 virtual void OnChildFocus(wxChildFocusEvent& event); \
99 virtual void SetFocus(); \
100 virtual void SetFocusIgnoringChildren(); \
101 virtual void RemoveChild(wxWindowBase *child); \
102 virtual bool AcceptsFocus() const; \
105 wxControlContainer m_container
107 // this macro must be used in the derived class ctor
108 #define WX_INIT_CONTROL_CONTAINER() \
109 m_container.SetContainerWindow(this)
111 // implement the event table entries for wxControlContainer
112 #define WX_EVENT_TABLE_CONTROL_CONTAINER(classname) \
113 EVT_SET_FOCUS(classname::OnFocus) \
114 EVT_CHILD_FOCUS(classname::OnChildFocus) \
115 EVT_NAVIGATION_KEY(classname::OnNavigationKey)
117 // implement the methods forwarding to the wxControlContainer
118 #define WX_DELEGATE_TO_CONTROL_CONTAINER(classname, basename) \
119 void classname::OnNavigationKey( wxNavigationKeyEvent& event ) \
121 m_container.HandleOnNavigationKey(event); \
124 void classname::RemoveChild(wxWindowBase *child) \
126 m_container.HandleOnWindowDestroy(child); \
128 basename::RemoveChild(child); \
131 void classname::SetFocus() \
133 if ( !m_container.DoSetFocus() ) \
134 basename::SetFocus(); \
137 void classname::SetFocusIgnoringChildren() \
139 basename::SetFocus(); \
142 void classname::OnChildFocus(wxChildFocusEvent& event) \
144 m_container.SetLastFocus(event.GetWindow()); \
147 void classname::OnFocus(wxFocusEvent& event) \
149 m_container.HandleOnFocus(event); \
151 bool classname::AcceptsFocus() const \
153 return m_container.AcceptsFocus(); \
156 #endif // wxHAS_NATIVE_TAB_TRAVERSAL/!wxHAS_NATIVE_TAB_TRAVERSAL
158 #endif // _WX_CONTAINR_H_