]> git.saurik.com Git - wxWidgets.git/blame - include/wx/containr.h
Added event handler macro
[wxWidgets.git] / include / wx / containr.h
CommitLineData
456bc6d9
VZ
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>
65571936 10// Licence: wxWindows licence
456bc6d9
VZ
11///////////////////////////////////////////////////////////////////////////////
12
13#ifndef _WX_CONTAINR_H_
14#define _WX_CONTAINR_H_
15
617fb24f
VZ
16#include "wx/defs.h"
17
b5dbe15d
VS
18class WXDLLIMPEXP_FWD_CORE wxWindow;
19class WXDLLIMPEXP_FWD_CORE wxWindowBase;
bf0e8244 20
80332672
VZ
21/*
22 Implementation note: wxControlContainer is not a real mix-in but rather
23 a class meant to be aggregated with (and not inherited from). Although
24 logically it should be a mix-in, doing it like this has no advantage from
25 the point of view of the existing code but does have some problems (we'd
26 need to play tricks with event handlers which may be difficult to do
27 safely). The price we pay for this simplicity is the ugly macros below.
28 */
29
30// ----------------------------------------------------------------------------
31// wxControlContainerBase: common part used in both native and generic cases
32// ----------------------------------------------------------------------------
33
34class WXDLLEXPORT wxControlContainerBase
35{
36public:
37 // default ctor, SetContainerWindow() must be called later
38 wxControlContainerBase()
39 {
40 m_winParent = NULL;
41
42 // do accept focus initially, we'll stop doing it if/when any children
43 // are added
44 m_acceptsFocus = true;
c7bfb76a
JS
45 m_inSetFocus = false;
46 m_winLastFocused = NULL;
80332672 47 }
c7bfb76a 48 virtual ~wxControlContainerBase() {}
80332672
VZ
49
50 void SetContainerWindow(wxWindow *winParent)
51 {
52 wxASSERT_MSG( !m_winParent, _T("shouldn't be called twice") );
53
54 m_winParent = winParent;
55 }
56
c7bfb76a
JS
57 // should be called from SetFocus(), returns false if we did nothing with
58 // the focus and the default processing should take place
59 bool DoSetFocus();
60
80332672
VZ
61 // should be called when we decide that we should [stop] accepting focus
62 void SetCanFocus(bool acceptsFocus);
63
64 // returns whether we should accept focus ourselves or not
65 bool AcceptsFocus() const { return m_acceptsFocus; }
66
edc09871
VZ
67 // returns whether we or one of our children accepts focus: we always do
68 // because if we don't have any focusable children it probably means that
69 // we're not being used as a container at all (think of wxGrid or generic
70 // wxListCtrl) and so should get focus for ourselves
71 bool AcceptsFocusRecursively() const { return true; }
72
00ff24c8
RR
73 // Call this when the number of children of the window changes.
74 // If we have any children, this panel (used just as container for
75 // them) shouldn't get focus for itself.
edc09871 76 void UpdateCanFocus() { SetCanFocus(!HasAnyFocusableChildren()); }
80332672
VZ
77
78protected:
c7bfb76a
JS
79 // set the focus to the child which had it the last time
80 virtual bool SetFocusToChild();
81
edc09871
VZ
82 // return true if we have any children accepting focus
83 bool HasAnyFocusableChildren() const;
80332672 84
80332672
VZ
85 // the parent window we manage the children for
86 wxWindow *m_winParent;
87
1c1ad005
JS
88 // the child which had the focus last time this panel was activated
89 wxWindow *m_winLastFocused;
90
bf0e8244 91private:
80332672
VZ
92 // value returned by AcceptsFocus(), should be changed using SetCanFocus()
93 // only
94 bool m_acceptsFocus;
c7bfb76a
JS
95
96 // a guard against infinite recursion
97 bool m_inSetFocus;
80332672
VZ
98};
99
100// common part of WX_DECLARE_CONTROL_CONTAINER in the native and generic cases,
101// it should be used in the wxWindow-derived class declaration
102#define WX_DECLARE_CONTROL_CONTAINER_BASE() \
103public: \
104 virtual bool AcceptsFocus() const; \
edc09871 105 virtual bool AcceptsFocusRecursively() const; \
80332672
VZ
106 virtual void AddChild(wxWindowBase *child); \
107 virtual void RemoveChild(wxWindowBase *child); \
c7bfb76a 108 virtual void SetFocus(); \
80332672
VZ
109 void SetFocusIgnoringChildren(); \
110 void AcceptFocus(bool acceptFocus) \
111 { \
112 m_container.SetCanFocus(acceptFocus); \
113 } \
114 \
115protected: \
116 wxControlContainer m_container
117
118// this macro must be used in the derived class ctor
119#define WX_INIT_CONTROL_CONTAINER() \
120 m_container.SetContainerWindow(this)
121
122// common part of WX_DELEGATE_TO_CONTROL_CONTAINER in the native and generic
123// cases, must be used in the wxWindow-derived class implementation
124#define WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
125 void classname::AddChild(wxWindowBase *child) \
126 { \
127 basename::AddChild(child); \
128 \
129 m_container.UpdateCanFocus(); \
130 } \
131 \
edc09871
VZ
132 bool classname::AcceptsFocusRecursively() const \
133 { \
134 return m_container.AcceptsFocusRecursively(); \
135 } \
136 \
c7bfb76a
JS
137 void classname::SetFocus() \
138 { \
139 if ( !m_container.DoSetFocus() ) \
140 basename::SetFocus(); \
141 } \
142 \
80332672
VZ
143 bool classname::AcceptsFocus() const \
144 { \
145 return m_container.AcceptsFocus(); \
146 }
147
148
de160b06
VZ
149#ifdef wxHAS_NATIVE_TAB_TRAVERSAL
150
80332672
VZ
151// ----------------------------------------------------------------------------
152// wxControlContainer for native TAB navigation
153// ----------------------------------------------------------------------------
154
155// this must be a real class as we forward-declare it elsewhere
156class WXDLLEXPORT wxControlContainer : public wxControlContainerBase
157{
c7bfb76a
JS
158protected:
159 // set the focus to the child which had it the last time
160 virtual bool SetFocusToChild();
80332672 161};
de160b06 162
de160b06 163#define WX_EVENT_TABLE_CONTROL_CONTAINER(classname)
80332672
VZ
164
165#define WX_DECLARE_CONTROL_CONTAINER WX_DECLARE_CONTROL_CONTAINER_BASE
166
167#define WX_DELEGATE_TO_CONTROL_CONTAINER(classname, basename) \
168 WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
169 \
170 void classname::RemoveChild(wxWindowBase *child) \
171 { \
172 basename::RemoveChild(child); \
173 \
174 m_container.UpdateCanFocus(); \
175 } \
176 \
177 void classname::SetFocusIgnoringChildren() \
178 { \
00ff24c8 179 basename::SetFocus(); \
80332672 180 }
de160b06
VZ
181
182#else // !wxHAS_NATIVE_TAB_TRAVERSAL
183
b5dbe15d
VS
184class WXDLLIMPEXP_FWD_CORE wxFocusEvent;
185class WXDLLIMPEXP_FWD_CORE wxNavigationKeyEvent;
456bc6d9 186
456bc6d9 187// ----------------------------------------------------------------------------
80332672 188// wxControlContainer for TAB navigation implemented in wx itself
456bc6d9
VZ
189// ----------------------------------------------------------------------------
190
80332672 191class WXDLLEXPORT wxControlContainer : public wxControlContainerBase
456bc6d9
VZ
192{
193public:
80332672
VZ
194 // default ctor, SetContainerWindow() must be called later
195 wxControlContainer();
456bc6d9 196
456bc6d9
VZ
197 // the methods to be called from the window event handlers
198 void HandleOnNavigationKey(wxNavigationKeyEvent& event);
199 void HandleOnFocus(wxFocusEvent& event);
200 void HandleOnWindowDestroy(wxWindowBase *child);
201
9948d31f
VZ
202 // called from OnChildFocus() handler, i.e. when one of our (grand)
203 // children gets the focus
204 void SetLastFocus(wxWindow *win);
205
456bc6d9 206protected:
b33f7651 207
036da5e3 208 DECLARE_NO_COPY_CLASS(wxControlContainer)
456bc6d9
VZ
209};
210
456bc6d9
VZ
211// ----------------------------------------------------------------------------
212// macros which may be used by the classes wishing to implement TAB navigation
213// among their children
214// ----------------------------------------------------------------------------
215
216// declare the methods to be forwarded
d1cd787b
VZ
217#define WX_DECLARE_CONTROL_CONTAINER() \
218 WX_DECLARE_CONTROL_CONTAINER_BASE(); \
219 \
220public: \
221 void OnNavigationKey(wxNavigationKeyEvent& event); \
222 void OnFocus(wxFocusEvent& event); \
c7bfb76a 223 virtual void OnChildFocus(wxChildFocusEvent& event)
456bc6d9
VZ
224
225// implement the event table entries for wxControlContainer
226#define WX_EVENT_TABLE_CONTROL_CONTAINER(classname) \
227 EVT_SET_FOCUS(classname::OnFocus) \
228 EVT_CHILD_FOCUS(classname::OnChildFocus) \
229 EVT_NAVIGATION_KEY(classname::OnNavigationKey)
230
231// implement the methods forwarding to the wxControlContainer
80332672
VZ
232#define WX_DELEGATE_TO_CONTROL_CONTAINER(classname, basename) \
233 WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
234 \
235 void classname::RemoveChild(wxWindowBase *child) \
236 { \
237 m_container.HandleOnWindowDestroy(child); \
238 \
239 basename::RemoveChild(child); \
240 \
241 m_container.UpdateCanFocus(); \
242 } \
243 \
244 void classname::OnNavigationKey( wxNavigationKeyEvent& event ) \
245 { \
246 m_container.HandleOnNavigationKey(event); \
247 } \
248 \
80332672
VZ
249 void classname::SetFocusIgnoringChildren() \
250 { \
251 basename::SetFocus(); \
252 } \
253 \
254 void classname::OnChildFocus(wxChildFocusEvent& event) \
255 { \
256 m_container.SetLastFocus(event.GetWindow()); \
57c5c10f 257 event.Skip(); \
80332672
VZ
258 } \
259 \
260 void classname::OnFocus(wxFocusEvent& event) \
261 { \
262 m_container.HandleOnFocus(event); \
1c1ad005 263 }
456bc6d9 264
de160b06 265#endif // wxHAS_NATIVE_TAB_TRAVERSAL/!wxHAS_NATIVE_TAB_TRAVERSAL
456bc6d9 266
c7bfb76a
JS
267// this function is for wxWidgets internal use only
268extern bool wxSetFocusToChild(wxWindow *win, wxWindow **child);
269
456bc6d9 270#endif // _WX_CONTAINR_H_