]>
Commit | Line | Data |
---|---|---|
e1d3601a PC |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: wx/xtitypes.h | |
3 | // Purpose: enum, set, basic types support | |
4 | // Author: Stefan Csomor | |
5 | // Modified by: Francesco Montorsi | |
6 | // Created: 27/07/03 | |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) 1997 Julian Smart | |
9 | // (c) 2003 Stefan Csomor | |
10 | // Licence: wxWindows licence | |
11 | ///////////////////////////////////////////////////////////////////////////// | |
12 | ||
13 | #ifndef _XTITYPES_H_ | |
14 | #define _XTITYPES_H_ | |
15 | ||
16 | #include "wx/defs.h" | |
17 | ||
18 | #if wxUSE_EXTENDED_RTTI | |
19 | ||
20 | #include "wx/string.h" | |
21 | #include "wx/hashmap.h" | |
22 | #include "wx/arrstr.h" | |
23 | #include "wx/flags.h" | |
24 | #include "wx/intl.h" | |
25 | #include "wx/log.h" | |
26 | #include <typeinfo> | |
27 | ||
28 | class WXDLLIMPEXP_BASE wxClassInfo; | |
29 | ||
30 | // ---------------------------------------------------------------------------- | |
31 | // Enum Support | |
32 | // | |
33 | // In the header files XTI requires no change from pure c++ code, however in the | |
34 | // implementation, an enum needs to be enumerated eg: | |
35 | // | |
36 | // wxBEGIN_ENUM( wxFlavor ) | |
37 | // wxENUM_MEMBER( Vanilla ) | |
38 | // wxENUM_MEMBER( Chocolate ) | |
39 | // wxENUM_MEMBER( Strawberry ) | |
40 | // wxEND_ENUM( wxFlavor ) | |
41 | // ---------------------------------------------------------------------------- | |
42 | ||
43 | struct WXDLLIMPEXP_BASE wxEnumMemberData | |
44 | { | |
45 | const wxChar* m_name; | |
46 | int m_value; | |
47 | }; | |
48 | ||
49 | class WXDLLIMPEXP_BASE wxEnumData | |
50 | { | |
51 | public: | |
52 | wxEnumData( wxEnumMemberData* data ); | |
53 | ||
54 | // returns true if the member has been found and sets the int value | |
55 | // pointed to accordingly (if ptr != null ) | |
56 | // if not found returns false, value left unchanged | |
57 | bool HasEnumMemberValue( const wxChar *name, int *value = NULL ) const; | |
58 | ||
59 | // returns the value of the member, if not found in debug mode an | |
60 | // assert is issued, in release 0 is returned | |
61 | int GetEnumMemberValue(const wxChar *name ) const; | |
62 | ||
63 | // returns the name of the enum member having the passed in value | |
64 | // returns an emtpy string if not found | |
65 | const wxChar *GetEnumMemberName(int value) const; | |
66 | ||
67 | // returns the number of members in this enum | |
68 | int GetEnumCount() const { return m_count; } | |
69 | ||
70 | // returns the value of the nth member | |
71 | int GetEnumMemberValueByIndex( int n ) const; | |
72 | ||
73 | // returns the value of the nth member | |
74 | const wxChar *GetEnumMemberNameByIndex( int n ) const; | |
75 | ||
76 | private: | |
77 | wxEnumMemberData *m_members; | |
78 | int m_count; | |
79 | }; | |
80 | ||
81 | #define wxBEGIN_ENUM( e ) \ | |
82 | wxEnumMemberData s_enumDataMembers##e[] = { | |
83 | ||
84 | #define wxENUM_MEMBER( v ) { wxT(#v), v }, | |
85 | ||
6c887dde SC |
86 | /* |
87 | WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<e>) \ | |
88 | WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<e*>) \ | |
89 | */ | |
90 | ||
e1d3601a PC |
91 | #define wxEND_ENUM( e ) \ |
92 | { NULL, 0 } }; \ | |
93 | wxEnumData s_enumData##e( s_enumDataMembers##e ); \ | |
94 | wxEnumData *wxGetEnumData(e) { return &s_enumData##e; } \ | |
95 | template<> void wxStringReadValue(const wxString& s, e &data ) \ | |
96 | { data = (e) s_enumData##e.GetEnumMemberValue(s); } \ | |
97 | template<> void wxStringWriteValue(wxString &s, const e &data ) \ | |
98 | { s = s_enumData##e.GetEnumMemberName((int)data); } \ | |
6c887dde SC |
99 | void FromLong##e( long data, wxAny& result ) \ |
100 | { result = wxAny((e)data); } \ | |
101 | void ToLong##e( const wxAny& data, long &result ) \ | |
102 | { result = (long) (data).As(static_cast<e*>(NULL)); } \ | |
e1d3601a PC |
103 | \ |
104 | wxTO_STRING_IMP( e ) \ | |
105 | wxFROM_STRING_IMP( e ) \ | |
106 | wxEnumTypeInfo s_typeInfo##e(wxT_ENUM, &s_enumData##e, \ | |
107 | &wxTO_STRING( e ), &wxFROM_STRING( e ), &ToLong##e, \ | |
108 | &FromLong##e, typeid(e).name() ); | |
109 | ||
110 | ||
111 | // ---------------------------------------------------------------------------- | |
112 | // Set Support | |
113 | // | |
114 | // in the header : | |
115 | // | |
116 | // enum wxFlavor | |
117 | // { | |
118 | // Vanilla, | |
119 | // Chocolate, | |
120 | // Strawberry, | |
121 | // }; | |
122 | // | |
123 | // typedef wxBitset<wxFlavor> wxCoupe; | |
124 | // | |
125 | // in the implementation file : | |
126 | // | |
127 | // wxBEGIN_ENUM( wxFlavor ) | |
128 | // wxENUM_MEMBER( Vanilla ) | |
129 | // wxENUM_MEMBER( Chocolate ) | |
130 | // wxENUM_MEMBER( Strawberry ) | |
131 | // wxEND_ENUM( wxFlavor ) | |
132 | // | |
133 | // wxIMPLEMENT_SET_STREAMING( wxCoupe, wxFlavor ) | |
134 | // | |
135 | // implementation note: no partial specialization for streaming, but a delegation | |
136 | // to a different class | |
137 | // | |
138 | // ---------------------------------------------------------------------------- | |
139 | ||
140 | // in order to remove dependancy on string tokenizer | |
141 | void WXDLLIMPEXP_BASE wxSetStringToArray( const wxString &s, wxArrayString &array ); | |
142 | ||
143 | template<typename e> | |
144 | void wxSetFromString(const wxString &s, wxBitset<e> &data ) | |
145 | { | |
146 | wxEnumData* edata = wxGetEnumData((e) 0); | |
147 | data.reset(); | |
148 | ||
149 | wxArrayString array; | |
150 | wxSetStringToArray( s, array ); | |
151 | wxString flag; | |
152 | for ( int i = 0; i < array.Count(); ++i ) | |
153 | { | |
154 | flag = array[i]; | |
155 | int ivalue; | |
156 | if ( edata->HasEnumMemberValue( flag, &ivalue ) ) | |
157 | { | |
158 | data.set( (e) ivalue ); | |
159 | } | |
160 | } | |
161 | } | |
162 | ||
163 | template<typename e> | |
164 | void wxSetToString( wxString &s, const wxBitset<e> &data ) | |
165 | { | |
166 | wxEnumData* edata = wxGetEnumData((e) 0); | |
167 | int count = edata->GetEnumCount(); | |
168 | int i; | |
169 | s.Clear(); | |
170 | for ( i = 0; i < count; i++ ) | |
171 | { | |
172 | e value = (e) edata->GetEnumMemberValueByIndex(i); | |
173 | if ( data.test( value ) ) | |
174 | { | |
175 | // this could also be done by the templated calls | |
176 | if ( !s.empty() ) | |
177 | s += wxT("|"); | |
178 | s += edata->GetEnumMemberNameByIndex(i); | |
179 | } | |
180 | } | |
181 | } | |
182 | ||
183 | #define wxIMPLEMENT_SET_STREAMING(SetName,e) \ | |
184 | template<> void wxStringReadValue(const wxString &s, wxBitset<e> &data ) \ | |
185 | { wxSetFromString( s, data ); } \ | |
186 | template<> void wxStringWriteValue( wxString &s, const wxBitset<e> &data ) \ | |
187 | { wxSetToString( s, data ); } \ | |
6c887dde SC |
188 | void FromLong##SetName( long data, wxAny& result ) \ |
189 | { result = wxAny(SetName((unsigned long)data)); } \ | |
190 | void ToLong##SetName( const wxAny& data, long &result ) \ | |
191 | { result = (long) (data).As(static_cast<SetName*>(NULL)).to_ulong(); } \ | |
e1d3601a PC |
192 | wxTO_STRING_IMP( SetName ) \ |
193 | wxFROM_STRING_IMP( SetName ) \ | |
194 | wxEnumTypeInfo s_typeInfo##SetName(wxT_SET, &s_enumData##e, \ | |
195 | &wxTO_STRING( SetName ), &wxFROM_STRING( SetName ), \ | |
196 | &ToLong##SetName, &FromLong##SetName, typeid(SetName).name() ); | |
197 | ||
198 | template<typename e> | |
199 | void wxFlagsFromString(const wxString &s, e &data ) | |
200 | { | |
201 | wxEnumData* edata = wxGetEnumData((e*) 0); | |
202 | data.m_data = 0; | |
203 | ||
204 | wxArrayString array; | |
205 | wxSetStringToArray( s, array ); | |
206 | wxString flag; | |
207 | for ( size_t i = 0; i < array.Count(); ++i ) | |
208 | { | |
209 | flag = array[i]; | |
210 | int ivalue; | |
211 | if ( edata->HasEnumMemberValue( flag, &ivalue ) ) | |
212 | { | |
213 | data.m_data |= ivalue; | |
214 | } | |
215 | } | |
216 | } | |
217 | ||
218 | template<typename e> | |
219 | void wxFlagsToString( wxString &s, const e& data ) | |
220 | { | |
221 | wxEnumData* edata = wxGetEnumData((e*) 0); | |
222 | int count = edata->GetEnumCount(); | |
223 | int i; | |
224 | s.Clear(); | |
225 | long dataValue = data.m_data; | |
226 | for ( i = 0; i < count; i++ ) | |
227 | { | |
228 | int value = edata->GetEnumMemberValueByIndex(i); | |
229 | // make this to allow for multi-bit constants to work | |
230 | if ( value && ( dataValue & value ) == value ) | |
231 | { | |
232 | // clear the flags we just set | |
233 | dataValue &= ~value; | |
234 | // this could also be done by the templated calls | |
235 | if ( !s.empty() ) | |
236 | s +=wxT("|"); | |
237 | s += edata->GetEnumMemberNameByIndex(i); | |
238 | } | |
239 | } | |
240 | } | |
241 | ||
242 | #define wxBEGIN_FLAGS( e ) \ | |
243 | wxEnumMemberData s_enumDataMembers##e[] = { | |
244 | ||
245 | #define wxFLAGS_MEMBER( v ) { wxT(#v), v }, | |
246 | ||
6c887dde SC |
247 | /* |
248 | WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<e>) \ | |
249 | WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<e*>) \ | |
250 | */ | |
251 | ||
e1d3601a PC |
252 | #define wxEND_FLAGS( e ) \ |
253 | { NULL, 0 } }; \ | |
254 | wxEnumData s_enumData##e( s_enumDataMembers##e ); \ | |
255 | wxEnumData *wxGetEnumData(e*) { return &s_enumData##e; } \ | |
256 | template<> void wxStringReadValue(const wxString &s, e &data ) \ | |
257 | { wxFlagsFromString<e>( s, data ); } \ | |
258 | template<> void wxStringWriteValue( wxString &s, const e& data ) \ | |
259 | { wxFlagsToString<e>( s, data ); } \ | |
6c887dde SC |
260 | void FromLong##e( long data, wxAny& result ) \ |
261 | { result = wxAny(e(data)); } \ | |
262 | void ToLong##e( const wxAny& data, long &result ) \ | |
263 | { result = (long) (data).As(static_cast<e*>(NULL)).m_data; } \ | |
e1d3601a PC |
264 | wxTO_STRING_IMP( e ) \ |
265 | wxFROM_STRING_IMP( e ) \ | |
266 | wxEnumTypeInfo s_typeInfo##e(wxT_SET, &s_enumData##e, \ | |
267 | &wxTO_STRING( e ), &wxFROM_STRING( e ), &ToLong##e, \ | |
268 | &FromLong##e, typeid(e).name() ); | |
269 | ||
270 | // ---------------------------------------------------------------------------- | |
271 | // Type Information | |
272 | // ---------------------------------------------------------------------------- | |
273 | ||
274 | // All data exposed by the RTTI is characterized using the following classes. | |
275 | // The first characterization is done by wxTypeKind. All enums up to and including | |
276 | // wxT_CUSTOM represent so called simple types. These cannot be divided any further. | |
277 | // They can be converted to and from wxStrings, that's all. | |
278 | // Other wxTypeKinds can instead be splitted recursively into smaller parts until | |
279 | // the simple types are reached. | |
280 | ||
281 | enum wxTypeKind | |
282 | { | |
283 | wxT_VOID = 0, // unknown type | |
284 | wxT_BOOL, | |
285 | wxT_CHAR, | |
286 | wxT_UCHAR, | |
287 | wxT_INT, | |
288 | wxT_UINT, | |
289 | wxT_LONG, | |
290 | wxT_ULONG, | |
6c887dde SC |
291 | wxT_LONGLONG, |
292 | wxT_ULONGLONG, | |
e1d3601a PC |
293 | wxT_FLOAT, |
294 | wxT_DOUBLE, | |
295 | wxT_STRING, // must be wxString | |
296 | wxT_SET, // must be wxBitset<> template | |
297 | wxT_ENUM, | |
298 | wxT_CUSTOM, // user defined type (e.g. wxPoint) | |
299 | ||
300 | wxT_LAST_SIMPLE_TYPE_KIND = wxT_CUSTOM, | |
301 | ||
302 | wxT_OBJECT_PTR, // object reference | |
303 | wxT_OBJECT, // embedded object | |
304 | wxT_COLLECTION, // collection | |
305 | ||
306 | wxT_DELEGATE, // for connecting against an event source | |
307 | ||
308 | wxT_LAST_TYPE_KIND = wxT_DELEGATE // sentinel for bad data, asserts, debugging | |
309 | }; | |
310 | ||
6c887dde | 311 | class WXDLLIMPEXP_BASE wxAny; |
e1d3601a PC |
312 | class WXDLLIMPEXP_BASE wxTypeInfo; |
313 | ||
314 | WX_DECLARE_STRING_HASH_MAP_WITH_DECL( wxTypeInfo*, wxTypeInfoMap, class WXDLLIMPEXP_BASE ); | |
315 | ||
316 | class WXDLLIMPEXP_BASE wxTypeInfo | |
317 | { | |
318 | public: | |
6c887dde SC |
319 | typedef void (*wxVariant2StringFnc)( const wxAny& data, wxString &result ); |
320 | typedef void (*wxString2VariantFnc)( const wxString& data, wxAny &result ); | |
e1d3601a PC |
321 | |
322 | wxTypeInfo(wxTypeKind kind, | |
323 | wxVariant2StringFnc to = NULL, wxString2VariantFnc from = NULL, | |
324 | const wxString &name = wxEmptyString): | |
325 | m_toString(to), m_fromString(from), m_kind(kind), m_name(name) | |
326 | { | |
327 | Register(); | |
328 | } | |
329 | #if wxUSE_UNICODE | |
330 | wxTypeInfo(wxTypeKind kind, | |
331 | wxVariant2StringFnc to, wxString2VariantFnc from, | |
332 | const char *name): | |
333 | m_toString(to), m_fromString(from), m_kind(kind), | |
334 | m_name(wxString::FromAscii(name)) | |
335 | { | |
336 | Register(); | |
337 | } | |
338 | #endif | |
339 | ||
340 | virtual ~wxTypeInfo() | |
341 | { | |
342 | Unregister(); | |
343 | } | |
344 | ||
345 | // return the kind of this type (wxT_... constants) | |
346 | wxTypeKind GetKind() const { return m_kind; } | |
347 | ||
348 | // returns the unique name of this type | |
349 | const wxString& GetTypeName() const { return m_name; } | |
350 | ||
351 | // is this type a delegate type | |
352 | bool IsDelegateType() const { return m_kind == wxT_DELEGATE; } | |
353 | ||
354 | // is this type a custom type | |
355 | bool IsCustomType() const { return m_kind == wxT_CUSTOM; } | |
356 | ||
357 | // is this type an object type | |
358 | bool IsObjectType() const { return m_kind == wxT_OBJECT || m_kind == wxT_OBJECT_PTR; } | |
359 | ||
360 | // can the content of this type be converted to and from strings ? | |
361 | bool HasStringConverters() const { return m_toString != NULL && m_fromString != NULL; } | |
362 | ||
6c887dde SC |
363 | // convert a wxAny holding data of this type into a string |
364 | void ConvertToString( const wxAny& data, wxString &result ) const | |
e1d3601a PC |
365 | { |
366 | if ( m_toString ) | |
367 | (*m_toString)( data, result ); | |
368 | else | |
369 | wxLogError( wxGetTranslation(_T("String conversions not supported")) ); | |
370 | } | |
371 | ||
6c887dde SC |
372 | // convert a string into a wxAny holding the corresponding data in this type |
373 | void ConvertFromString( const wxString& data, wxAny &result ) const | |
e1d3601a PC |
374 | { |
375 | if( m_fromString ) | |
376 | (*m_fromString)( data, result ); | |
377 | else | |
378 | wxLogError( wxGetTranslation(_T("String conversions not supported")) ); | |
379 | } | |
380 | ||
381 | // statics: | |
382 | ||
6c887dde SC |
383 | static wxTypeInfo *FindType( const wxString& typeName ); |
384 | #if 0 // TODO | |
e1d3601a PC |
385 | #if wxUSE_UNICODE |
386 | static wxTypeInfo *FindType(const char *typeName) | |
387 | { return FindType( wxString::FromAscii(typeName) ); } | |
388 | #endif | |
389 | static wxTypeInfo *FindType(const wxChar *typeName); | |
390 | static wxTypeInfo *FindType(const wxString& typeName) | |
391 | { | |
392 | #if wxUSE_UNICODE | |
393 | return FindType( typeName.wchar_str() ); | |
394 | #else | |
395 | return FindType( typeName.char_str() ); | |
396 | #endif | |
397 | } | |
6c887dde | 398 | #endif |
e1d3601a PC |
399 | private: |
400 | void Register(); | |
401 | void Unregister(); | |
402 | ||
403 | wxVariant2StringFnc m_toString; | |
404 | wxString2VariantFnc m_fromString; | |
405 | ||
406 | wxTypeKind m_kind; | |
407 | wxString m_name; | |
408 | ||
409 | // the static list of all types we know about | |
410 | static wxTypeInfoMap* ms_typeTable; | |
411 | }; | |
412 | ||
413 | class WXDLLIMPEXP_BASE wxBuiltInTypeInfo : public wxTypeInfo | |
414 | { | |
415 | public: | |
416 | wxBuiltInTypeInfo( wxTypeKind kind, wxVariant2StringFnc to = NULL, | |
417 | wxString2VariantFnc from = NULL, | |
418 | const wxString &name = wxEmptyString ) : | |
419 | wxTypeInfo( kind, to, from, name ) | |
420 | { wxASSERT_MSG( GetKind() < wxT_SET, wxT("Illegal Kind for Base Type") ); } | |
421 | ||
422 | #if wxUSE_UNICODE | |
423 | wxBuiltInTypeInfo( wxTypeKind kind, wxVariant2StringFnc to, | |
424 | wxString2VariantFnc from , const char *name ) : | |
425 | wxTypeInfo( kind, to, from, name ) | |
426 | { wxASSERT_MSG( GetKind() < wxT_SET, wxT("Illegal Kind for Base Type") ); } | |
427 | #endif | |
428 | }; | |
429 | ||
430 | class WXDLLIMPEXP_BASE wxCustomTypeInfo : public wxTypeInfo | |
431 | { | |
432 | public: | |
433 | wxCustomTypeInfo( const wxString &name, wxVariant2StringFnc to, | |
434 | wxString2VariantFnc from ) : | |
435 | wxTypeInfo( wxT_CUSTOM, to, from, name ) | |
436 | {} | |
437 | ||
438 | #if wxUSE_UNICODE | |
439 | wxCustomTypeInfo( const char *name , wxVariant2StringFnc to, | |
440 | wxString2VariantFnc from ) : | |
441 | wxTypeInfo( wxT_CUSTOM, to, from, name ) | |
442 | {} | |
443 | #endif | |
444 | }; | |
445 | ||
446 | class WXDLLIMPEXP_BASE wxEnumTypeInfo : public wxTypeInfo | |
447 | { | |
448 | public: | |
6c887dde SC |
449 | typedef void (*converterToLong_t)( const wxAny& data, long &result ); |
450 | typedef void (*converterFromLong_t)( long data, wxAny &result ); | |
e1d3601a PC |
451 | |
452 | wxEnumTypeInfo( wxTypeKind kind, wxEnumData* enumInfo, wxVariant2StringFnc to, | |
453 | wxString2VariantFnc from, converterToLong_t toLong, | |
454 | converterFromLong_t fromLong, const wxString &name ) : | |
455 | wxTypeInfo( kind, to, from, name ), m_toLong( toLong ), m_fromLong( fromLong ) | |
456 | { | |
457 | wxASSERT_MSG( kind == wxT_ENUM || kind == wxT_SET, | |
458 | wxT("Illegal Kind for Enum Type")); | |
459 | m_enumInfo = enumInfo; | |
460 | } | |
461 | ||
462 | #if wxUSE_UNICODE | |
463 | wxEnumTypeInfo( wxTypeKind kind, wxEnumData* enumInfo, wxVariant2StringFnc to, | |
464 | wxString2VariantFnc from, converterToLong_t toLong, | |
465 | converterFromLong_t fromLong, const char * name ) : | |
466 | wxTypeInfo( kind, to, from, name ), m_toLong( toLong ), m_fromLong( fromLong ) | |
467 | { | |
468 | wxASSERT_MSG( kind == wxT_ENUM || kind == wxT_SET, | |
469 | wxT("Illegal Kind for Enum Type")); | |
470 | m_enumInfo = enumInfo; | |
471 | } | |
472 | #endif | |
473 | const wxEnumData* GetEnumData() const { return m_enumInfo; } | |
474 | ||
6c887dde SC |
475 | // convert a wxAny holding data of this type into a long |
476 | void ConvertToLong( const wxAny& data, long &result ) const | |
e1d3601a PC |
477 | { |
478 | if( m_toLong ) | |
479 | (*m_toLong)( data, result ); | |
480 | else | |
481 | wxLogError( wxGetTranslation(_T("Long Conversions not supported")) ); | |
482 | } | |
483 | ||
6c887dde SC |
484 | // convert a long into a wxAny holding the corresponding data in this type |
485 | void ConvertFromLong( long data, wxAny &result ) const | |
e1d3601a PC |
486 | { |
487 | if( m_fromLong ) | |
488 | (*m_fromLong)( data, result ); | |
489 | else | |
490 | wxLogError( wxGetTranslation(_T("Long Conversions not supported")) ); | |
491 | } | |
492 | ||
493 | private: | |
494 | converterToLong_t m_toLong; | |
495 | converterFromLong_t m_fromLong; | |
496 | ||
497 | wxEnumData *m_enumInfo; // Kind == wxT_ENUM or Kind == wxT_SET | |
498 | }; | |
499 | ||
500 | class WXDLLIMPEXP_BASE wxClassTypeInfo : public wxTypeInfo | |
501 | { | |
502 | public: | |
503 | wxClassTypeInfo( wxTypeKind kind, wxClassInfo* classInfo, | |
504 | wxVariant2StringFnc to = NULL, wxString2VariantFnc from = NULL, | |
505 | const wxString &name = wxEmptyString); | |
506 | ||
507 | #if wxUSE_UNICODE | |
508 | wxClassTypeInfo( wxTypeKind kind, wxClassInfo* classInfo, wxVariant2StringFnc to, | |
509 | wxString2VariantFnc from , const char *name ); | |
510 | #endif | |
511 | ||
512 | const wxClassInfo *GetClassInfo() const { return m_classInfo; } | |
513 | ||
514 | private: | |
515 | wxClassInfo *m_classInfo; // Kind == wxT_OBJECT - could be NULL | |
516 | }; | |
517 | ||
518 | class WXDLLIMPEXP_BASE wxCollectionTypeInfo : public wxTypeInfo | |
519 | { | |
520 | public: | |
521 | wxCollectionTypeInfo( const wxString &elementName, wxVariant2StringFnc to, | |
522 | wxString2VariantFnc from , const wxString &name) : | |
523 | wxTypeInfo( wxT_COLLECTION, to, from, name ) | |
524 | { m_elementTypeName = elementName; m_elementType = NULL; } | |
525 | ||
526 | #if wxUSE_UNICODE | |
527 | wxCollectionTypeInfo( const char *elementName, wxVariant2StringFnc to, | |
528 | wxString2VariantFnc from , const char *name ) : | |
529 | wxTypeInfo( wxT_COLLECTION, to, from, name ) | |
530 | { m_elementTypeName = wxString::FromAscii( elementName ); m_elementType = NULL; } | |
531 | #endif | |
532 | ||
533 | const wxTypeInfo* GetElementType() const | |
534 | { | |
535 | if ( m_elementType == NULL ) | |
536 | m_elementType = wxTypeInfo::FindType( m_elementTypeName ); | |
537 | return m_elementType; | |
538 | } | |
539 | ||
540 | private: | |
541 | mutable wxTypeInfo * m_elementType; | |
542 | wxString m_elementTypeName; | |
543 | }; | |
544 | ||
545 | class WXDLLIMPEXP_BASE wxEventSourceTypeInfo : public wxTypeInfo | |
546 | { | |
547 | public: | |
548 | wxEventSourceTypeInfo( int eventType, wxClassInfo* eventClass, | |
549 | wxVariant2StringFnc to = NULL, | |
550 | wxString2VariantFnc from = NULL ); | |
551 | wxEventSourceTypeInfo( int eventType, int lastEventType, wxClassInfo* eventClass, | |
552 | wxVariant2StringFnc to = NULL, wxString2VariantFnc from = NULL ); | |
553 | ||
554 | int GetEventType() const { return m_eventType; } | |
555 | int GetLastEventType() const { return m_lastEventType; } | |
556 | const wxClassInfo* GetEventClass() const { return m_eventClass; } | |
557 | ||
558 | private: | |
559 | const wxClassInfo *m_eventClass; // (extended will merge into classinfo) | |
560 | int m_eventType; | |
561 | int m_lastEventType; | |
562 | }; | |
563 | ||
6c887dde | 564 | template<typename T> const wxTypeInfo* wxGetTypeInfo( T * ) |
e1d3601a PC |
565 | { return wxTypeInfo::FindType(typeid(T).name()); } |
566 | ||
567 | // this macro is for usage with custom, non-object derived classes and structs, | |
568 | // wxPoint is such a custom type | |
569 | ||
570 | #if wxUSE_FUNC_TEMPLATE_POINTER | |
571 | #define wxCUSTOM_TYPE_INFO( e, toString, fromString ) \ | |
572 | wxCustomTypeInfo s_typeInfo##e(typeid(e).name(), &toString, &fromString); | |
573 | #else | |
574 | #define wxCUSTOM_TYPE_INFO( e, toString, fromString ) \ | |
6c887dde | 575 | void ToString##e( const wxAny& data, wxString &result ) \ |
e1d3601a | 576 | { toString(data, result); } \ |
6c887dde | 577 | void FromString##e( const wxString& data, wxAny &result ) \ |
e1d3601a PC |
578 | { fromString(data, result); } \ |
579 | wxCustomTypeInfo s_typeInfo##e(typeid(e).name(), \ | |
580 | &ToString##e, &FromString##e); | |
581 | #endif | |
582 | ||
583 | #define wxCOLLECTION_TYPE_INFO( element, collection ) \ | |
584 | wxCollectionTypeInfo s_typeInfo##collection( typeid(element).name(), \ | |
585 | NULL, NULL, typeid(collection).name() ); | |
586 | ||
587 | // sometimes a compiler invents specializations that are nowhere called, | |
588 | // use this macro to satisfy the refs, currently we don't have to play | |
589 | // tricks, but if we will have to according to the compiler, we will use | |
590 | // that macro for that | |
591 | ||
592 | #define wxILLEGAL_TYPE_SPECIALIZATION( a ) | |
593 | ||
594 | #endif // wxUSE_EXTENDED_RTTI | |
595 | #endif // _XTITYPES_H_ |