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