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