KiCad PCB EDA Suite
property.h
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2020 CERN
5  * Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
6  * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
7  * @author Maciej Suminski <maciej.suminski@cern.ch>
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 3
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #ifndef PROPERTY_H
24 #define PROPERTY_H
25 
26 #include <wx/any.h>
27 #include <wx/string.h>
28 #include <wx/bitmap.h>
29 #include <wx/font.h> // required for propgrid
30 #include <wx/validate.h> // required for propgrid
31 #include <wx/propgrid/property.h>
32 
33 #include <functional>
34 #include <map>
35 #include <memory>
36 #include <typeindex>
37 #include <type_traits>
38 
39 class wxPGProperty;
40 class INSPECTABLE;
41 class PROPERTY_BASE;
42 
43 template<typename T>
44 class ENUM_MAP;
45 
48 {
53 };
54 
56 #define TYPE_HASH( x ) typeid( x ).hash_code()
57 #define TYPE_NAME( x ) typeid( x ).name()
58 //#define TYPE_HASH( x ) typeid( std::decay<x>::type ).hash_code()
59 
60 template<typename Owner, typename T>
62 {
63 public:
64  virtual ~GETTER_BASE() {}
65 
66  virtual T operator()( Owner* aOwner ) const = 0;
67 };
68 
69 template<typename Owner, typename T, typename FuncType>
70 class GETTER : public GETTER_BASE<Owner, T>
71 {
72 public:
73  GETTER( FuncType aFunc )
74  : m_func( aFunc )
75  {
76  }
77 
78  T operator()( Owner* aOwner ) const override
79  {
80  return ( aOwner->*m_func )();
81  }
82 
83 private:
84  FuncType m_func;
85 };
86 
87 template<typename Owner, typename T>
89 {
90 public:
91  virtual ~SETTER_BASE() {}
92 
93  virtual void operator()( Owner* aOwner, T aValue ) = 0;
94 };
95 
96 template<typename Owner, typename T, typename FuncType>
97 class SETTER : public SETTER_BASE<Owner, T>
98 {
99 public:
100  SETTER( FuncType aFunc )
101  : m_func( aFunc )
102  {
103  }
104 
105  void operator()( Owner* aOwner, T aValue ) override
106  {
107  wxCHECK( m_func, /*void*/ );
108  ( aOwner->*m_func )( aValue );
109  }
110 
111 private:
112  FuncType m_func;
113 };
114 
115 
116 template<typename Owner, typename T, typename Base = Owner>
117 class METHOD
118 {
119 public:
120  constexpr static GETTER_BASE<Owner, T>* Wrap( T (Base::*aFunc)() )
121  {
122  return new GETTER<Owner, T, T (Base::*)()>( aFunc );
123  }
124 
125  constexpr static GETTER_BASE<Owner, T>* Wrap( const T (Base::*aFunc)() )
126  {
127  return new GETTER<Owner, T, T (Base::*)()>( aFunc );
128  }
129 
130  constexpr static GETTER_BASE<Owner, T>* Wrap( const T& (Base::*aFunc)() )
131  {
132  return new GETTER<Owner, T, const T& (Base::*)()>( aFunc );
133  }
134 
135  constexpr static GETTER_BASE<Owner, T>* Wrap( T (Base::*aFunc)() const )
136  {
137  return new GETTER<Owner, T, T (Base::*)() const>( aFunc );
138  }
139 
140  constexpr static GETTER_BASE<Owner, T>* Wrap( const T (Base::*aFunc)() const )
141  {
143  }
144 
145  constexpr static GETTER_BASE<Owner, T>* Wrap( const T& (Base::*aFunc)() const )
146  {
148  }
149 
150  constexpr static SETTER_BASE<Owner, T>* Wrap( void (Base::*aFunc)( T ) )
151  {
152  return aFunc ? new SETTER<Owner, T, void (Base::*)( T )>( aFunc ) : nullptr;
153  }
154 
155  constexpr static SETTER_BASE<Owner, T>* Wrap( void (Base::*aFunc)( T& ) )
156  {
157  return aFunc ? new SETTER<Owner, T, void (Base::*)( T& )>( aFunc ) : nullptr;
158  }
159 
160  constexpr static SETTER_BASE<Owner, T>* Wrap( void (Base::*aFunc)( const T& ) )
161  {
162  return aFunc ? new SETTER<Owner, T, void (Base::*)( const T& )>( aFunc ) : nullptr;
163  }
164 
165  METHOD() = delete;
166 };
167 
168 
170 {
171 private:
173 
174 public:
175  PROPERTY_BASE( const wxString& aName, PROPERTY_DISPLAY aDisplay = DEFAULT ) :
176  m_name( aName ),
177  m_display( aDisplay ),
178  m_availFunc( [](INSPECTABLE*)->bool { return true; } )
179  {
180  }
181 
182  virtual ~PROPERTY_BASE()
183  {
184  }
185 
186  const wxString& Name() const
187  {
188  return m_name;
189  }
190 
195  virtual const wxPGChoices& Choices() const
196  {
197  static wxPGChoices empty;
198  return empty;
199  }
200 
204  virtual void SetChoices( const wxPGChoices& aChoices )
205  {
206  wxFAIL; // only possible for PROPERTY_ENUM
207  }
208 
213  virtual bool HasChoices() const
214  {
215  return false;
216  }
217 
221  bool Available( INSPECTABLE* aObject ) const
222  {
223  return m_availFunc( aObject );
224  }
225 
229  void SetAvailableFunc( std::function<bool(INSPECTABLE*)> aFunc )
230  {
231  m_availFunc = aFunc;
232  }
233 
237  virtual size_t OwnerHash() const = 0;
238 
242  virtual size_t BaseHash() const = 0;
243 
247  virtual size_t TypeHash() const = 0;
248 
249  virtual bool IsReadOnly() const = 0;
250 
252  {
253  return m_display;
254  }
255 
256 protected:
257  template<typename T>
258  void set( void* aObject, T aValue )
259  {
260  wxAny a = aValue;
261  setter( aObject, a );
262  }
263 
264  template<typename T>
265  T get( void* aObject )
266  {
267  wxAny a = getter( aObject );
268 
269  if ( !( std::is_enum<T>::value && a.CheckType<int>() ) && !a.CheckType<T>() )
270  throw std::invalid_argument( "Invalid requested type" );
271 
272  return wxANY_AS(a, T);
273  }
274 
275  virtual void setter( void* aObject, wxAny& aValue ) = 0;
276  virtual wxAny getter( void* aObject ) const = 0;
277 
278 private:
279  const wxString m_name;
281 
282  std::function<bool(INSPECTABLE*)> m_availFunc;
283 
284  friend class INSPECTABLE;
285 };
286 
287 
288 template<typename Owner, typename T, typename Base = Owner>
289 class PROPERTY : public PROPERTY_BASE
290 {
291 public:
292  typedef typename std::decay<T>::type BASE_TYPE;
293  typedef void (Base::*SETTER)( T );
294 
295  template<typename SetType, typename GetType>
296  PROPERTY( const wxString& aName,
297  void ( Base::*aSetter )( SetType ), GetType( Base::*aGetter )(),
298  PROPERTY_DISPLAY aDisplay = DEFAULT )
299  : PROPERTY( aName, METHOD<Owner, T, Base>::Wrap( aSetter ),
300  METHOD<Owner, T, Base>::Wrap( aGetter ), aDisplay )
301  {
302  }
303 
304  template<typename SetType, typename GetType>
305  PROPERTY( const wxString& aName,
306  void ( Base::*aSetter )( SetType ), GetType( Base::*aGetter )() const,
307  PROPERTY_DISPLAY aDisplay = DEFAULT )
308  : PROPERTY( aName, METHOD<Owner, T, Base>::Wrap( aSetter ),
309  METHOD<Owner, T, Base>::Wrap( aGetter ), aDisplay )
310  {
311  }
312 
313  size_t OwnerHash() const override
314  {
315  return m_ownerHash;
316  }
317 
318  size_t BaseHash() const override
319  {
320  return m_baseHash;
321  }
322 
323  size_t TypeHash() const override
324  {
325  return m_typeHash;
326  }
327 
328  bool IsReadOnly() const override
329  {
330  return !m_setter;
331  }
332 
333 protected:
334  PROPERTY( const wxString& aName, SETTER_BASE<Owner, T>* s, GETTER_BASE<Owner, T>* g,
335  PROPERTY_DISPLAY aDisplay )
336  : PROPERTY_BASE( aName, aDisplay ), m_setter( s ), m_getter( g ),
337  m_ownerHash( TYPE_HASH( Owner ) ), m_baseHash( TYPE_HASH( Base ) ),
339  {
340  }
341 
342  virtual ~PROPERTY() {}
343 
344  virtual void setter( void* obj, wxAny& v ) override
345  {
346  wxCHECK( !IsReadOnly(), /*void*/ );
347 
348  if( !v.CheckType<T>() )
349  throw std::invalid_argument( "Invalid type requested" );
350 
351  Owner* o = reinterpret_cast<Owner*>( obj );
352  BASE_TYPE value = wxANY_AS(v, BASE_TYPE);
353  (*m_setter)( o, value );
354  }
355 
356  virtual wxAny getter( void* obj ) const override
357  {
358  Owner* o = reinterpret_cast<Owner*>( obj );
359  wxAny res = (*m_getter)( o );
360  return res;
361  }
362 
364  std::unique_ptr<SETTER_BASE<Owner, T>> m_setter;
365 
367  std::unique_ptr<GETTER_BASE<Owner, T>> m_getter;
368 
370  const size_t m_ownerHash;
371 
373  const size_t m_baseHash;
374 
376  const size_t m_typeHash;
377 };
378 
379 
380 template<typename Owner, typename T, typename Base = Owner>
381 class PROPERTY_ENUM : public PROPERTY<Owner, T, Base>
382 {
383 public:
384  template<typename SetType, typename GetType>
385  PROPERTY_ENUM( const wxString& aName,
386  void ( Base::*aSetter )( SetType ), GetType( Base::*aGetter )(),
388  : PROPERTY<Owner, T, Base>( aName, METHOD<Owner, T, Base>::Wrap( aSetter ),
389  METHOD<Owner, T, Base>::Wrap( aGetter ), aDisplay )
390  {
391  if ( std::is_enum<T>::value )
392  {
393  m_choices = ENUM_MAP<T>::Instance().Choices();
394  wxASSERT_MSG( m_choices.GetCount() > 0, "No enum choices defined" );
395  }
396  }
397 
398  template<typename SetType, typename GetType>
399  PROPERTY_ENUM( const wxString& aName,
400  void ( Base::*aSetter )( SetType ), GetType( Base::*aGetter )() const,
402  : PROPERTY<Owner, T, Base>( aName, METHOD<Owner, T, Base>::Wrap( aSetter ),
403  METHOD<Owner, T, Base>::Wrap( aGetter ), aDisplay )
404  {
405  if ( std::is_enum<T>::value )
406  {
407  m_choices = ENUM_MAP<T>::Instance().Choices();
408  wxASSERT_MSG( m_choices.GetCount() > 0, "No enum choices defined" );
409  }
410  }
411 
412  virtual void setter( void* obj, wxAny& v ) override
413  {
414  wxCHECK( !( PROPERTY<Owner, T, Base>::IsReadOnly() ), /*void*/ );
415  Owner* o = reinterpret_cast<Owner*>( obj );
416 
417  if( v.CheckType<T>() )
418  {
419  T value = wxANY_AS(v, T);
420  (*PROPERTY<Owner, T, Base>::m_setter)( o, value );
421  }
422  else if (v.CheckType<int>() )
423  {
424  int value = wxANY_AS(v, int);
425  (*PROPERTY<Owner, T, Base>::m_setter)( o, static_cast<T>( value ) );
426  }
427  else
428  {
429  throw std::invalid_argument( "Invalid type requested" );
430  }
431  }
432 
433  virtual wxAny getter( void* obj ) const override
434  {
435  Owner* o = reinterpret_cast<Owner*>( obj );
436  wxAny res = static_cast<T>( (*PROPERTY<Owner, T, Base>::m_getter)( o ) );
437  return res;
438  }
439 
440  const wxPGChoices& Choices() const override
441  {
442  return m_choices;
443  }
444 
445  void SetChoices( const wxPGChoices& aChoices ) override
446  {
447  m_choices = aChoices;
448  }
449 
450  bool HasChoices() const override
451  {
452  return m_choices.GetCount() > 0;
453  }
454 
455 protected:
456  wxPGChoices m_choices;
457 };
458 
459 
461 {
462 public:
463  virtual ~TYPE_CAST_BASE() {}
464  virtual void* operator()( void* aPointer ) const = 0;
465  virtual const void* operator()( const void* aPointer ) const = 0;
466  virtual size_t BaseHash() const = 0;
467  virtual size_t DerivedHash() const = 0;
468 };
469 
470 
471 template<typename Base, typename Derived>
472 class TYPE_CAST : public TYPE_CAST_BASE
473 {
474 public:
476  {
477  }
478 
479  void* operator()( void* aPointer ) const override
480  {
481  Base* base = reinterpret_cast<Base*>( aPointer );
482  return static_cast<Derived*>( base );
483  }
484 
485  const void* operator()( const void* aPointer ) const override
486  {
487  const Base* base = reinterpret_cast<const Base*>( aPointer );
488  return static_cast<const Derived*>( base );
489  }
490 
491  size_t BaseHash() const override
492  {
493  return TYPE_HASH( Base );
494  }
495 
496  size_t DerivedHash() const override
497  {
498  return TYPE_HASH( Derived );
499  }
500 };
501 
502 
503 template<typename T>
504 class ENUM_MAP
505 {
506 public:
508  {
509  static ENUM_MAP<T> inst;
510  return inst;
511  }
512 
513  ENUM_MAP& Map( T aValue, const wxString& aName )
514  {
515  m_choices.Add( aName, static_cast<int>( aValue ) );
516  m_reverseMap[ aName ] = aValue;
517  return *this;
518  }
519 
520  ENUM_MAP& Undefined( T aValue )
521  {
522  m_undefined = aValue;
523  return *this;
524  }
525 
526  const wxString& ToString( T value ) const
527  {
528  static const wxString s_undef = "UNDEFINED";
529 
530  int idx = m_choices.Index( static_cast<int>( value ) );
531 
532  if( idx >= 0 && idx < (int) m_choices.GetCount() )
533  return m_choices.GetLabel( static_cast<int>( idx ) );
534  else
535  return s_undef;
536  }
537 
538  const T ToEnum( const wxString value )
539  {
540  if( m_reverseMap.count( value ) )
541  return m_reverseMap[ value ];
542  else
543  return m_undefined;
544  }
545 
546  wxPGChoices& Choices()
547  {
548  return m_choices;
549  }
550 
551 private:
552  wxPGChoices m_choices;
553  std::unordered_map<wxString, T> m_reverseMap;
554  T m_undefined; // Returned if the string is not recognized
555 
557  {
558  }
559 };
560 
561 
562 // Helper macros to handle enum types
563 #define DECLARE_ENUM_TO_WXANY( type ) \
564  template <> \
565  class wxAnyValueTypeImpl<type> : public wxAnyValueTypeImplBase<type> \
566  { \
567  WX_DECLARE_ANY_VALUE_TYPE( wxAnyValueTypeImpl<type> ) \
568  public: \
569  wxAnyValueTypeImpl() : wxAnyValueTypeImplBase<type>() {} \
570  virtual ~wxAnyValueTypeImpl() {} \
571  virtual bool ConvertValue( const wxAnyValueBuffer& src, wxAnyValueType* dstType, \
572  wxAnyValueBuffer& dst ) const override \
573  { \
574  type value = GetValue( src ); \
575  ENUM_MAP<type>& conv = ENUM_MAP<type>::Instance(); \
576  if( dstType->CheckType<wxString>() ) \
577  { \
578  wxAnyValueTypeImpl<wxString>::SetValue( conv.ToString( value ), dst ); \
579  return true; \
580  } \
581  if( dstType->CheckType<int>() ) \
582  { \
583  wxAnyValueTypeImpl<int>::SetValue( static_cast<int>( value ), dst ); \
584  return true; \
585  } \
586  else \
587  { \
588  return false; \
589  } \
590  } \
591  };
592 
593 #define IMPLEMENT_ENUM_TO_WXANY( type ) WX_IMPLEMENT_ANY_VALUE_TYPE( wxAnyValueTypeImpl<type> )
594 
595 #define ENUM_TO_WXANY( type ) \
596  DECLARE_ENUM_TO_WXANY( type ) \
597  IMPLEMENT_ENUM_TO_WXANY( type )
598 
600 #define NO_SETTER( owner, type ) ( ( void ( owner::* )( type ) ) nullptr )
601 
602 /*
603 #define DECLARE_PROPERTY(owner,type,name,getter,setter) \
604 namespace anonymous {\
605 static PROPERTY<owner,type> prop##_owner##_name_( "##name#", setter, getter );\
606 };
607 */
608 #endif /* PROPERTY_H */
size_t BaseHash() const override
Definition: property.h:491
Display value expressed in degrees.
Definition: property.h:51
virtual void * operator()(void *aPointer) const =0
virtual ~SETTER_BASE()
Definition: property.h:91
static constexpr GETTER_BASE< Owner, T > * Wrap(const T &(Base::*aFunc)() const)
Definition: property.h:145
virtual bool HasChoices() const
Returns true if this PROPERTY has a limited set of possible values.
Definition: property.h:213
#define TYPE_HASH(x)
Macro to generate unique identifier for a type
Definition: property.h:56
virtual size_t BaseHash() const =0
PROPERTY_BASE(const wxString &aName, PROPERTY_DISPLAY aDisplay=DEFAULT)
Used to generate unique IDs. Must come up front so it's initialized before ctor.
Definition: property.h:175
void * operator()(void *aPointer) const override
Definition: property.h:479
METHOD()=delete
static constexpr GETTER_BASE< Owner, T > * Wrap(const T &(Base::*aFunc)())
Definition: property.h:130
virtual void setter(void *obj, wxAny &v) override
Definition: property.h:344
ENUM_MAP & Undefined(T aValue)
Definition: property.h:520
PROPERTY(const wxString &aName, void(Base::*aSetter)(SetType), GetType(Base::*aGetter)(), PROPERTY_DISPLAY aDisplay=DEFAULT)
Definition: property.h:296
const size_t m_typeHash
Property value type-id
Definition: property.h:376
std::unique_ptr< GETTER_BASE< Owner, T > > m_getter
Get method
Definition: property.h:367
virtual T operator()(Owner *aOwner) const =0
const wxPGChoices & Choices() const override
Returns a limited set of possible values (e.g.
Definition: property.h:440
virtual void operator()(Owner *aOwner, T aValue)=0
virtual size_t TypeHash() const =0
Returns type-id of the property type.
std::unique_ptr< SETTER_BASE< Owner, T > > m_setter
Set method
Definition: property.h:364
static ENUM_MAP< T > & Instance()
Definition: property.h:507
PROPERTY_DISPLAY GetDisplay() const
Definition: property.h:251
static constexpr GETTER_BASE< Owner, T > * Wrap(const T(Base::*aFunc)())
Definition: property.h:125
virtual size_t DerivedHash() const =0
static constexpr GETTER_BASE< Owner, T > * Wrap(const T(Base::*aFunc)() const)
Definition: property.h:140
wxPGChoices & Choices()
Definition: property.h:546
std::decay< T >::type BASE_TYPE
Definition: property.h:292
virtual wxAny getter(void *obj) const override
Definition: property.h:356
virtual wxAny getter(void *aObject) const =0
PROPERTY_ENUM(const wxString &aName, void(Base::*aSetter)(SetType), GetType(Base::*aGetter)() const, PROPERTY_DISPLAY aDisplay=PROPERTY_DISPLAY::DEFAULT)
Definition: property.h:399
const PROPERTY_DISPLAY m_display
Definition: property.h:280
virtual void setter(void *obj, wxAny &v) override
Definition: property.h:412
SETTER(FuncType aFunc)
Definition: property.h:100
static constexpr GETTER_BASE< Owner, T > * Wrap(T(Base::*aFunc)() const)
Definition: property.h:135
void operator()(Owner *aOwner, T aValue) override
Definition: property.h:105
bool IsReadOnly() const override
Definition: property.h:328
FuncType m_func
Definition: property.h:84
Display value expressed in distance units (mm/inch)
Definition: property.h:50
const void * operator()(const void *aPointer) const override
Definition: property.h:485
PROPERTY_ENUM(const wxString &aName, void(Base::*aSetter)(SetType), GetType(Base::*aGetter)(), PROPERTY_DISPLAY aDisplay=PROPERTY_DISPLAY::DEFAULT)
Definition: property.h:385
const T ToEnum(const wxString value)
Definition: property.h:538
virtual ~TYPE_CAST_BASE()
Definition: property.h:463
void SetAvailableFunc(std::function< bool(INSPECTABLE *)> aFunc)
Sets a callback function to determine whether an object provides this property.
Definition: property.h:229
PROPERTY(const wxString &aName, SETTER_BASE< Owner, T > *s, GETTER_BASE< Owner, T > *g, PROPERTY_DISPLAY aDisplay)
Definition: property.h:334
Convert decidegrees to degrees for display.
Definition: property.h:52
virtual wxAny getter(void *obj) const override
Definition: property.h:433
const wxString m_name
Definition: property.h:279
const wxString & Name() const
Definition: property.h:186
bool HasChoices() const override
Returns true if this PROPERTY has a limited set of possible values.
Definition: property.h:450
static constexpr SETTER_BASE< Owner, T > * Wrap(void(Base::*aFunc)(T &))
Definition: property.h:155
virtual ~GETTER_BASE()
Definition: property.h:64
static constexpr SETTER_BASE< Owner, T > * Wrap(void(Base::*aFunc)(T))
Definition: property.h:150
PROPERTY_DISPLAY
Common property types
Definition: property.h:47
Class that other classes need to inherit from, in order to be inspectable.
Definition: inspectable.h:33
virtual ~PROPERTY()
Definition: property.h:342
T operator()(Owner *aOwner) const override
Definition: property.h:78
virtual const wxPGChoices & Choices() const
Returns a limited set of possible values (e.g.
Definition: property.h:195
virtual void setter(void *aObject, wxAny &aValue)=0
T m_undefined
Definition: property.h:554
size_t DerivedHash() const override
Definition: property.h:496
std::function< bool(INSPECTABLE *)> m_availFunc
Definition: property.h:282
virtual bool IsReadOnly() const =0
void SetChoices(const wxPGChoices &aChoices) override
Sets the possible values for for the property.
Definition: property.h:445
static constexpr GETTER_BASE< Owner, T > * Wrap(T(Base::*aFunc)())
Definition: property.h:120
virtual void SetChoices(const wxPGChoices &aChoices)
Sets the possible values for for the property.
Definition: property.h:204
bool Available(INSPECTABLE *aObject) const
Returns true if aObject offers this PROPERTY.
Definition: property.h:221
TYPE_CAST()
Definition: property.h:475
static bool empty(const wxTextEntryBase *aCtrl)
std::unordered_map< wxString, T > m_reverseMap
Definition: property.h:553
static constexpr SETTER_BASE< Owner, T > * Wrap(void(Base::*aFunc)(const T &))
Definition: property.h:160
size_t BaseHash() const override
Returns type-id of the Base class.
Definition: property.h:318
wxPGChoices m_choices
Definition: property.h:552
const size_t m_ownerHash
Owner class type-id
Definition: property.h:370
virtual size_t BaseHash() const =0
Returns type-id of the Base class.
size_t OwnerHash() const override
Returns type-id of the Owner class.
Definition: property.h:313
T get(void *aObject)
Definition: property.h:265
void set(void *aObject, T aValue)
Definition: property.h:258
Default property for a given type.
Definition: property.h:49
ENUM_MAP & Map(T aValue, const wxString &aName)
Definition: property.h:513
FuncType m_func
Definition: property.h:112
virtual size_t OwnerHash() const =0
Returns type-id of the Owner class.
size_t TypeHash() const override
Returns type-id of the property type.
Definition: property.h:323
const size_t m_baseHash
Base class type-id
Definition: property.h:373
virtual ~PROPERTY_BASE()
Definition: property.h:182
wxPGChoices m_choices
Definition: property.h:456
const wxString & ToString(T value) const
Definition: property.h:526
PROPERTY(const wxString &aName, void(Base::*aSetter)(SetType), GetType(Base::*aGetter)() const, PROPERTY_DISPLAY aDisplay=DEFAULT)
Definition: property.h:305
GETTER(FuncType aFunc)
Definition: property.h:73