]> git.saurik.com Git - wxWidgets.git/blame - include/wx/containr.h
Richtext interface fixes and additions for Phoenix
[wxWidgets.git] / include / wx / containr.h
CommitLineData
456bc6d9
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: wx/containr.h
4d98817c 3// Purpose: wxControlContainer and wxNavigationEnabled declarations
456bc6d9
VZ
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 06.08.01
7// RCS-ID: $Id$
4d98817c 8// Copyright: (c) 2001, 2011 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
65571936 9// Licence: wxWindows licence
456bc6d9
VZ
10///////////////////////////////////////////////////////////////////////////////
11
12#ifndef _WX_CONTAINR_H_
13#define _WX_CONTAINR_H_
14
617fb24f
VZ
15#include "wx/defs.h"
16
9f1bf940
VZ
17#ifndef wxHAS_NATIVE_TAB_TRAVERSAL
18 // We need wxEVT_XXX declarations in this case.
19 #include "wx/event.h"
20#endif
21
b5dbe15d
VS
22class WXDLLIMPEXP_FWD_CORE wxWindow;
23class WXDLLIMPEXP_FWD_CORE wxWindowBase;
bf0e8244 24
80332672 25/*
4d98817c
VZ
26 This header declares wxControlContainer class however it's not a real
27 container of controls but rather just a helper used to implement TAB
28 navigation among the window children. You should rarely need to use it
29 directly, derive from the documented public wxNavigationEnabled<> class to
30 implement TAB navigation in a custom composite window.
80332672
VZ
31 */
32
33// ----------------------------------------------------------------------------
34// wxControlContainerBase: common part used in both native and generic cases
35// ----------------------------------------------------------------------------
36
53a2db12 37class WXDLLIMPEXP_CORE wxControlContainerBase
80332672
VZ
38{
39public:
40 // default ctor, SetContainerWindow() must be called later
41 wxControlContainerBase()
42 {
43 m_winParent = NULL;
44
e68b7b36
VZ
45 // By default, we accept focus ourselves.
46 m_acceptsFocusSelf = true;
47
48 // But we don't have any children accepting it yet.
49 m_acceptsFocusChildren = false;
50
c7bfb76a
JS
51 m_inSetFocus = false;
52 m_winLastFocused = NULL;
80332672 53 }
c7bfb76a 54 virtual ~wxControlContainerBase() {}
80332672
VZ
55
56 void SetContainerWindow(wxWindow *winParent)
57 {
9a83f860 58 wxASSERT_MSG( !m_winParent, wxT("shouldn't be called twice") );
80332672
VZ
59
60 m_winParent = winParent;
61 }
62
e68b7b36
VZ
63 // This can be called by the window to indicate that it never wants to have
64 // the focus for itself.
65 void DisableSelfFocus() { m_acceptsFocusSelf = false; }
66
c7bfb76a
JS
67 // should be called from SetFocus(), returns false if we did nothing with
68 // the focus and the default processing should take place
69 bool DoSetFocus();
70
80332672 71 // returns whether we should accept focus ourselves or not
e68b7b36 72 bool AcceptsFocus() const { return m_acceptsFocusSelf; }
80332672 73
e68b7b36
VZ
74 // Returns whether we or one of our children accepts focus.
75 bool AcceptsFocusRecursively() const
861bdae4 76 { return m_acceptsFocusSelf || m_acceptsFocusChildren; }
edc09871 77
e68b7b36
VZ
78 // We accept focus from keyboard if we accept it at all.
79 bool AcceptsFocusFromKeyboard() const { return AcceptsFocusRecursively(); }
21bf81db 80
00ff24c8 81 // Call this when the number of children of the window changes.
e68b7b36
VZ
82 //
83 // Returns true if we have any focusable children, false otherwise.
84 bool UpdateCanFocusChildren();
80332672
VZ
85
86protected:
c7bfb76a
JS
87 // set the focus to the child which had it the last time
88 virtual bool SetFocusToChild();
89
edc09871
VZ
90 // return true if we have any children accepting focus
91 bool HasAnyFocusableChildren() const;
80332672 92
80332672
VZ
93 // the parent window we manage the children for
94 wxWindow *m_winParent;
95
1c1ad005
JS
96 // the child which had the focus last time this panel was activated
97 wxWindow *m_winLastFocused;
98
bf0e8244 99private:
e68b7b36
VZ
100 // Indicates whether the associated window can ever have focus itself.
101 //
102 // Usually this is the case, e.g. a wxPanel can be used either as a
103 // container for its children or just as a normal window which can be
104 // focused. But sometimes, e.g. for wxStaticBox, we can never have focus
105 // ourselves and can only get it if we have any focusable children.
106 bool m_acceptsFocusSelf;
107
108 // Cached value remembering whether we have any children accepting focus.
109 bool m_acceptsFocusChildren;
c7bfb76a
JS
110
111 // a guard against infinite recursion
112 bool m_inSetFocus;
80332672
VZ
113};
114
4d98817c
VZ
115#ifdef wxHAS_NATIVE_TAB_TRAVERSAL
116
117// ----------------------------------------------------------------------------
118// wxControlContainer for native TAB navigation
119// ----------------------------------------------------------------------------
120
121// this must be a real class as we forward-declare it elsewhere
122class WXDLLIMPEXP_CORE wxControlContainer : public wxControlContainerBase
123{
124protected:
125 // set the focus to the child which had it the last time
126 virtual bool SetFocusToChild();
127};
128
129#else // !wxHAS_NATIVE_TAB_TRAVERSAL
130
4d98817c
VZ
131// ----------------------------------------------------------------------------
132// wxControlContainer for TAB navigation implemented in wx itself
133// ----------------------------------------------------------------------------
134
135class WXDLLIMPEXP_CORE wxControlContainer : public wxControlContainerBase
136{
137public:
138 // default ctor, SetContainerWindow() must be called later
139 wxControlContainer();
140
141 // the methods to be called from the window event handlers
142 void HandleOnNavigationKey(wxNavigationKeyEvent& event);
143 void HandleOnFocus(wxFocusEvent& event);
144 void HandleOnWindowDestroy(wxWindowBase *child);
145
146 // called from OnChildFocus() handler, i.e. when one of our (grand)
147 // children gets the focus
148 void SetLastFocus(wxWindow *win);
149
150protected:
151
152 wxDECLARE_NO_COPY_CLASS(wxControlContainer);
153};
154
155#endif // wxHAS_NATIVE_TAB_TRAVERSAL/!wxHAS_NATIVE_TAB_TRAVERSAL
156
157// this function is for wxWidgets internal use only
31af22fa 158extern WXDLLIMPEXP_CORE bool wxSetFocusToChild(wxWindow *win, wxWindow **child);
4d98817c
VZ
159
160// ----------------------------------------------------------------------------
161// wxNavigationEnabled: Derive from this class to support keyboard navigation
162// among window children in a wxWindow-derived class. The details of this class
163// don't matter, you just need to derive from it to make navigation work.
164// ----------------------------------------------------------------------------
165
166// The template parameter W must be a wxWindow-derived class.
167template <class W>
168class wxNavigationEnabled : public W
169{
170public:
171 typedef W BaseWindowClass;
172
173 wxNavigationEnabled()
174 {
175 m_container.SetContainerWindow(this);
176
177#ifndef wxHAS_NATIVE_TAB_TRAVERSAL
1f6831ea 178 BaseWindowClass::Connect(wxEVT_NAVIGATION_KEY,
4d98817c
VZ
179 wxNavigationKeyEventHandler(wxNavigationEnabled::OnNavigationKey));
180
1f6831ea 181 BaseWindowClass::Connect(wxEVT_SET_FOCUS,
4d98817c
VZ
182 wxFocusEventHandler(wxNavigationEnabled::OnFocus));
183
1f6831ea 184 BaseWindowClass::Connect(wxEVT_CHILD_FOCUS,
4d98817c
VZ
185 wxChildFocusEventHandler(wxNavigationEnabled::OnChildFocus));
186#endif // !wxHAS_NATIVE_TAB_TRAVERSAL
187 }
188
87381108 189 WXDLLIMPEXP_INLINE_CORE virtual bool AcceptsFocus() const
4d98817c
VZ
190 {
191 return m_container.AcceptsFocus();
192 }
193
87381108 194 WXDLLIMPEXP_INLINE_CORE virtual bool AcceptsFocusRecursively() const
4d98817c
VZ
195 {
196 return m_container.AcceptsFocusRecursively();
197 }
198
87381108 199 WXDLLIMPEXP_INLINE_CORE virtual bool AcceptsFocusFromKeyboard() const
4d98817c
VZ
200 {
201 return m_container.AcceptsFocusFromKeyboard();
202 }
203
87381108 204 WXDLLIMPEXP_INLINE_CORE virtual void AddChild(wxWindowBase *child)
4d98817c
VZ
205 {
206 BaseWindowClass::AddChild(child);
207
861bdae4
VZ
208 if ( m_container.UpdateCanFocusChildren() )
209 {
210 // Under MSW we must have wxTAB_TRAVERSAL style for TAB navigation
211 // to work.
212 if ( !BaseWindowClass::HasFlag(wxTAB_TRAVERSAL) )
213 BaseWindowClass::ToggleWindowStyle(wxTAB_TRAVERSAL);
214 }
4d98817c
VZ
215 }
216
87381108 217 WXDLLIMPEXP_INLINE_CORE virtual void RemoveChild(wxWindowBase *child)
4d98817c
VZ
218 {
219#ifndef wxHAS_NATIVE_TAB_TRAVERSAL
220 m_container.HandleOnWindowDestroy(child);
221#endif // !wxHAS_NATIVE_TAB_TRAVERSAL
222
223 BaseWindowClass::RemoveChild(child);
224
861bdae4
VZ
225 // We could reset wxTAB_TRAVERSAL here but it doesn't seem to do any
226 // harm to keep it.
e68b7b36 227 m_container.UpdateCanFocusChildren();
4d98817c
VZ
228 }
229
87381108 230 WXDLLIMPEXP_INLINE_CORE virtual void SetFocus()
4d98817c
VZ
231 {
232 if ( !m_container.DoSetFocus() )
233 BaseWindowClass::SetFocus();
234 }
235
236 void SetFocusIgnoringChildren()
237 {
238 BaseWindowClass::SetFocus();
239 }
240
4d98817c
VZ
241protected:
242#ifndef wxHAS_NATIVE_TAB_TRAVERSAL
243 void OnNavigationKey(wxNavigationKeyEvent& event)
244 {
245 m_container.HandleOnNavigationKey(event);
246 }
247
248 void OnFocus(wxFocusEvent& event)
249 {
250 m_container.HandleOnFocus(event);
251 }
252
253 void OnChildFocus(wxChildFocusEvent& event)
254 {
255 m_container.SetLastFocus(event.GetWindow());
256 event.Skip();
257 }
258#endif // !wxHAS_NATIVE_TAB_TRAVERSAL
259
260 wxControlContainer m_container;
261
262
263 wxDECLARE_NO_COPY_TEMPLATE_CLASS(wxNavigationEnabled, W);
264};
265
266// ----------------------------------------------------------------------------
267// Compatibility macros from now on, do NOT use them and preferably do not even
268// look at them.
269// ----------------------------------------------------------------------------
270
7bc57fd9 271#if WXWIN_COMPATIBILITY_2_8
4d98817c 272
80332672
VZ
273// common part of WX_DECLARE_CONTROL_CONTAINER in the native and generic cases,
274// it should be used in the wxWindow-derived class declaration
275#define WX_DECLARE_CONTROL_CONTAINER_BASE() \
276public: \
277 virtual bool AcceptsFocus() const; \
edc09871 278 virtual bool AcceptsFocusRecursively() const; \
21bf81db 279 virtual bool AcceptsFocusFromKeyboard() const; \
80332672
VZ
280 virtual void AddChild(wxWindowBase *child); \
281 virtual void RemoveChild(wxWindowBase *child); \
c7bfb76a 282 virtual void SetFocus(); \
80332672 283 void SetFocusIgnoringChildren(); \
80332672
VZ
284 \
285protected: \
286 wxControlContainer m_container
287
288// this macro must be used in the derived class ctor
289#define WX_INIT_CONTROL_CONTAINER() \
290 m_container.SetContainerWindow(this)
291
292// common part of WX_DELEGATE_TO_CONTROL_CONTAINER in the native and generic
293// cases, must be used in the wxWindow-derived class implementation
294#define WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
295 void classname::AddChild(wxWindowBase *child) \
296 { \
297 basename::AddChild(child); \
298 \
e68b7b36 299 m_container.UpdateCanFocusChildren(); \
80332672
VZ
300 } \
301 \
edc09871
VZ
302 bool classname::AcceptsFocusRecursively() const \
303 { \
304 return m_container.AcceptsFocusRecursively(); \
305 } \
306 \
c7bfb76a
JS
307 void classname::SetFocus() \
308 { \
309 if ( !m_container.DoSetFocus() ) \
310 basename::SetFocus(); \
311 } \
312 \
80332672
VZ
313 bool classname::AcceptsFocus() const \
314 { \
315 return m_container.AcceptsFocus(); \
21bf81db
VZ
316 } \
317 \
318 bool classname::AcceptsFocusFromKeyboard() const \
319 { \
320 return m_container.AcceptsFocusFromKeyboard(); \
80332672
VZ
321 }
322
de160b06 323
4d98817c 324#ifdef wxHAS_NATIVE_TAB_TRAVERSAL
de160b06 325
de160b06 326#define WX_EVENT_TABLE_CONTROL_CONTAINER(classname)
80332672
VZ
327
328#define WX_DECLARE_CONTROL_CONTAINER WX_DECLARE_CONTROL_CONTAINER_BASE
329
330#define WX_DELEGATE_TO_CONTROL_CONTAINER(classname, basename) \
331 WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
332 \
333 void classname::RemoveChild(wxWindowBase *child) \
334 { \
335 basename::RemoveChild(child); \
336 \
e68b7b36 337 m_container.UpdateCanFocusChildren(); \
80332672
VZ
338 } \
339 \
340 void classname::SetFocusIgnoringChildren() \
341 { \
00ff24c8 342 basename::SetFocus(); \
80332672 343 }
de160b06
VZ
344
345#else // !wxHAS_NATIVE_TAB_TRAVERSAL
346
456bc6d9 347// declare the methods to be forwarded
d1cd787b
VZ
348#define WX_DECLARE_CONTROL_CONTAINER() \
349 WX_DECLARE_CONTROL_CONTAINER_BASE(); \
350 \
351public: \
352 void OnNavigationKey(wxNavigationKeyEvent& event); \
353 void OnFocus(wxFocusEvent& event); \
c7bfb76a 354 virtual void OnChildFocus(wxChildFocusEvent& event)
456bc6d9
VZ
355
356// implement the event table entries for wxControlContainer
357#define WX_EVENT_TABLE_CONTROL_CONTAINER(classname) \
358 EVT_SET_FOCUS(classname::OnFocus) \
359 EVT_CHILD_FOCUS(classname::OnChildFocus) \
360 EVT_NAVIGATION_KEY(classname::OnNavigationKey)
361
362// implement the methods forwarding to the wxControlContainer
80332672
VZ
363#define WX_DELEGATE_TO_CONTROL_CONTAINER(classname, basename) \
364 WX_DELEGATE_TO_CONTROL_CONTAINER_BASE(classname, basename) \
365 \
366 void classname::RemoveChild(wxWindowBase *child) \
367 { \
368 m_container.HandleOnWindowDestroy(child); \
369 \
370 basename::RemoveChild(child); \
371 \
e68b7b36 372 m_container.UpdateCanFocusChildren(); \
80332672
VZ
373 } \
374 \
375 void classname::OnNavigationKey( wxNavigationKeyEvent& event ) \
376 { \
377 m_container.HandleOnNavigationKey(event); \
378 } \
379 \
80332672
VZ
380 void classname::SetFocusIgnoringChildren() \
381 { \
382 basename::SetFocus(); \
383 } \
384 \
385 void classname::OnChildFocus(wxChildFocusEvent& event) \
386 { \
387 m_container.SetLastFocus(event.GetWindow()); \
57c5c10f 388 event.Skip(); \
80332672
VZ
389 } \
390 \
391 void classname::OnFocus(wxFocusEvent& event) \
392 { \
393 m_container.HandleOnFocus(event); \
1c1ad005 394 }
456bc6d9 395
de160b06 396#endif // wxHAS_NATIVE_TAB_TRAVERSAL/!wxHAS_NATIVE_TAB_TRAVERSAL
456bc6d9 397
4d98817c 398#endif // WXWIN_COMPATIBILITY_2_8
c7bfb76a 399
456bc6d9 400#endif // _WX_CONTAINR_H_