]> git.saurik.com Git - wxWidgets.git/blame - include/wx/containr.h
Ignore WM_CLOSE generated by wxMSW edit control when Escape is pressed.
[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
53a2db12 34class WXDLLIMPEXP_CORE wxControlContainerBase
80332672
VZ
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 {
9a83f860 52 wxASSERT_MSG( !m_winParent, wxT("shouldn't be called twice") );
80332672
VZ
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
21bf81db
VZ
73 // this is used to determine whether we can accept focus when Tab or
74 // another navigation key is pressed -- we alsways can, for the same reason
75 // as mentioned above for AcceptsFocusRecursively()
76 bool AcceptsFocusFromKeyboard() const { return true; }
77
00ff24c8
RR
78 // Call this when the number of children of the window changes.
79 // If we have any children, this panel (used just as container for
80 // them) shouldn't get focus for itself.
edc09871 81 void UpdateCanFocus() { SetCanFocus(!HasAnyFocusableChildren()); }
80332672
VZ
82
83protected:
c7bfb76a
JS
84 // set the focus to the child which had it the last time
85 virtual bool SetFocusToChild();
86
edc09871
VZ
87 // return true if we have any children accepting focus
88 bool HasAnyFocusableChildren() const;
80332672 89
80332672
VZ
90 // the parent window we manage the children for
91 wxWindow *m_winParent;
92
1c1ad005
JS
93 // the child which had the focus last time this panel was activated
94 wxWindow *m_winLastFocused;
95
bf0e8244 96private:
80332672
VZ
97 // value returned by AcceptsFocus(), should be changed using SetCanFocus()
98 // only
99 bool m_acceptsFocus;
c7bfb76a
JS
100
101 // a guard against infinite recursion
102 bool m_inSetFocus;
80332672
VZ
103};
104
105// common part of WX_DECLARE_CONTROL_CONTAINER in the native and generic cases,
106// it should be used in the wxWindow-derived class declaration
107#define WX_DECLARE_CONTROL_CONTAINER_BASE() \
108public: \
109 virtual bool AcceptsFocus() const; \
edc09871 110 virtual bool AcceptsFocusRecursively() const; \
21bf81db 111 virtual bool AcceptsFocusFromKeyboard() const; \
80332672
VZ
112 virtual void AddChild(wxWindowBase *child); \
113 virtual void RemoveChild(wxWindowBase *child); \
c7bfb76a 114 virtual void SetFocus(); \
80332672
VZ
115 void SetFocusIgnoringChildren(); \
116 void AcceptFocus(bool acceptFocus) \
117 { \
118 m_container.SetCanFocus(acceptFocus); \
119 } \
120 \
121protected: \
122 wxControlContainer m_container
123
124// this macro must be used in the derived class ctor
125#define WX_INIT_CONTROL_CONTAINER() \
126 m_container.SetContainerWindow(this)
127
128// common part of WX_DELEGATE_TO_CONTROL_CONTAINER in the native and generic
129// cases, must be used in the wxWindow-derived class implementation
130#define WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
131 void classname::AddChild(wxWindowBase *child) \
132 { \
133 basename::AddChild(child); \
134 \
135 m_container.UpdateCanFocus(); \
136 } \
137 \
edc09871
VZ
138 bool classname::AcceptsFocusRecursively() const \
139 { \
140 return m_container.AcceptsFocusRecursively(); \
141 } \
142 \
c7bfb76a
JS
143 void classname::SetFocus() \
144 { \
145 if ( !m_container.DoSetFocus() ) \
146 basename::SetFocus(); \
147 } \
148 \
80332672
VZ
149 bool classname::AcceptsFocus() const \
150 { \
151 return m_container.AcceptsFocus(); \
21bf81db
VZ
152 } \
153 \
154 bool classname::AcceptsFocusFromKeyboard() const \
155 { \
156 return m_container.AcceptsFocusFromKeyboard(); \
80332672
VZ
157 }
158
de160b06
VZ
159#ifdef wxHAS_NATIVE_TAB_TRAVERSAL
160
80332672
VZ
161// ----------------------------------------------------------------------------
162// wxControlContainer for native TAB navigation
163// ----------------------------------------------------------------------------
164
165// this must be a real class as we forward-declare it elsewhere
53a2db12 166class WXDLLIMPEXP_CORE wxControlContainer : public wxControlContainerBase
80332672 167{
c7bfb76a
JS
168protected:
169 // set the focus to the child which had it the last time
170 virtual bool SetFocusToChild();
80332672 171};
de160b06 172
de160b06 173#define WX_EVENT_TABLE_CONTROL_CONTAINER(classname)
80332672
VZ
174
175#define WX_DECLARE_CONTROL_CONTAINER WX_DECLARE_CONTROL_CONTAINER_BASE
176
177#define WX_DELEGATE_TO_CONTROL_CONTAINER(classname, basename) \
178 WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
179 \
180 void classname::RemoveChild(wxWindowBase *child) \
181 { \
182 basename::RemoveChild(child); \
183 \
184 m_container.UpdateCanFocus(); \
185 } \
186 \
187 void classname::SetFocusIgnoringChildren() \
188 { \
00ff24c8 189 basename::SetFocus(); \
80332672 190 }
de160b06
VZ
191
192#else // !wxHAS_NATIVE_TAB_TRAVERSAL
193
b5dbe15d
VS
194class WXDLLIMPEXP_FWD_CORE wxFocusEvent;
195class WXDLLIMPEXP_FWD_CORE wxNavigationKeyEvent;
456bc6d9 196
456bc6d9 197// ----------------------------------------------------------------------------
80332672 198// wxControlContainer for TAB navigation implemented in wx itself
456bc6d9
VZ
199// ----------------------------------------------------------------------------
200
53a2db12 201class WXDLLIMPEXP_CORE wxControlContainer : public wxControlContainerBase
456bc6d9
VZ
202{
203public:
80332672
VZ
204 // default ctor, SetContainerWindow() must be called later
205 wxControlContainer();
456bc6d9 206
456bc6d9
VZ
207 // the methods to be called from the window event handlers
208 void HandleOnNavigationKey(wxNavigationKeyEvent& event);
209 void HandleOnFocus(wxFocusEvent& event);
210 void HandleOnWindowDestroy(wxWindowBase *child);
211
9948d31f
VZ
212 // called from OnChildFocus() handler, i.e. when one of our (grand)
213 // children gets the focus
214 void SetLastFocus(wxWindow *win);
215
456bc6d9 216protected:
b33f7651 217
c0c133e1 218 wxDECLARE_NO_COPY_CLASS(wxControlContainer);
456bc6d9
VZ
219};
220
456bc6d9
VZ
221// ----------------------------------------------------------------------------
222// macros which may be used by the classes wishing to implement TAB navigation
223// among their children
224// ----------------------------------------------------------------------------
225
226// declare the methods to be forwarded
d1cd787b
VZ
227#define WX_DECLARE_CONTROL_CONTAINER() \
228 WX_DECLARE_CONTROL_CONTAINER_BASE(); \
229 \
230public: \
231 void OnNavigationKey(wxNavigationKeyEvent& event); \
232 void OnFocus(wxFocusEvent& event); \
c7bfb76a 233 virtual void OnChildFocus(wxChildFocusEvent& event)
456bc6d9
VZ
234
235// implement the event table entries for wxControlContainer
236#define WX_EVENT_TABLE_CONTROL_CONTAINER(classname) \
237 EVT_SET_FOCUS(classname::OnFocus) \
238 EVT_CHILD_FOCUS(classname::OnChildFocus) \
239 EVT_NAVIGATION_KEY(classname::OnNavigationKey)
240
241// implement the methods forwarding to the wxControlContainer
80332672
VZ
242#define WX_DELEGATE_TO_CONTROL_CONTAINER(classname, basename) \
243 WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
244 \
245 void classname::RemoveChild(wxWindowBase *child) \
246 { \
247 m_container.HandleOnWindowDestroy(child); \
248 \
249 basename::RemoveChild(child); \
250 \
251 m_container.UpdateCanFocus(); \
252 } \
253 \
254 void classname::OnNavigationKey( wxNavigationKeyEvent& event ) \
255 { \
256 m_container.HandleOnNavigationKey(event); \
257 } \
258 \
80332672
VZ
259 void classname::SetFocusIgnoringChildren() \
260 { \
261 basename::SetFocus(); \
262 } \
263 \
264 void classname::OnChildFocus(wxChildFocusEvent& event) \
265 { \
266 m_container.SetLastFocus(event.GetWindow()); \
57c5c10f 267 event.Skip(); \
80332672
VZ
268 } \
269 \
270 void classname::OnFocus(wxFocusEvent& event) \
271 { \
272 m_container.HandleOnFocus(event); \
1c1ad005 273 }
456bc6d9 274
de160b06 275#endif // wxHAS_NATIVE_TAB_TRAVERSAL/!wxHAS_NATIVE_TAB_TRAVERSAL
456bc6d9 276
c7bfb76a
JS
277// this function is for wxWidgets internal use only
278extern bool wxSetFocusToChild(wxWindow *win, wxWindow **child);
279
456bc6d9 280#endif // _WX_CONTAINR_H_