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