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