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