Rapicorn - Experimental UI Toolkit - Source Code
13.07.0
|
00001 // Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html 00002 #ifndef __RAPICORN_AIDA_PROPS_HH__ 00003 #define __RAPICORN_AIDA_PROPS_HH__ 00004 00005 #include <rcore/aida.hh> 00006 #include <rcore/strings.hh> 00007 00008 namespace Rapicorn { namespace Aida { 00009 00010 // == PropertyHostInterface == 00011 typedef ImplicitBase PropertyHostInterface; 00012 00013 // == Property == 00014 class Property { 00015 protected: 00016 virtual ~Property(); 00017 public: 00018 const char *ident; 00019 char *label; 00020 char *blurb; 00021 char *hints; 00022 Property (const char *cident, const char *clabel, const char *cblurb, const char *chints); 00023 virtual void set_value (PropertyHostInterface &obj, const String &svalue) = 0; 00024 virtual String get_value (PropertyHostInterface &obj) = 0; 00025 virtual bool get_range (PropertyHostInterface &obj, double &minimum, double &maximum, double &stepping) = 0; 00026 bool readable () const; 00027 bool writable () const; 00028 }; 00029 00030 // == PropertyList == 00031 struct PropertyList 00032 { 00033 typedef Aida::Property Property; // make Property available as class member 00034 private: 00035 size_t n_properties_; 00036 Property **properties_; 00037 void append_properties (size_t n_props, Property **props, const PropertyList &c0, const PropertyList &c1, 00038 const PropertyList &c2, const PropertyList &c3, const PropertyList &c4, const PropertyList &c5, 00039 const PropertyList &c6, const PropertyList &c7, const PropertyList &c8, const PropertyList &c9); 00040 public: 00041 Property** list_properties (size_t *n_properties) const; 00042 /*dtor*/ ~PropertyList (); 00043 explicit PropertyList () : n_properties_ (0), properties_ (NULL) {} 00044 template<typename Array> 00045 explicit PropertyList (Array &a, const PropertyList &c0 = PropertyList(), const PropertyList &c1 = PropertyList(), 00046 const PropertyList &c2 = PropertyList(), const PropertyList &c3 = PropertyList(), 00047 const PropertyList &c4 = PropertyList(), const PropertyList &c5 = PropertyList(), 00048 const PropertyList &c6 = PropertyList(), const PropertyList &c7 = PropertyList(), 00049 const PropertyList &c8 = PropertyList(), const PropertyList &c9 = PropertyList()) : 00050 n_properties_ (0), properties_ (NULL) 00051 { 00052 const size_t n_props = sizeof (a) / sizeof (a[0]); 00053 Property *props[n_props]; 00054 for (size_t i = 0; i < sizeof (a) / sizeof (a[0]); i++) 00055 props[i] = a[i]; 00056 append_properties (n_props, props, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9); 00057 } 00058 }; 00059 00060 // == Property Creation == 00061 #define RAPICORN_AIDA_PROPERTY(Type, accessor, label, blurb, ...) \ 00062 Rapicorn::Aida::create_property (&Type::accessor, &Type::accessor, #accessor, label, blurb, __VA_ARGS__) 00063 00064 #define RAPICORN_AIDA_PROPERTY_CHAIN(first,...) (*({ \ 00065 static Property *__dummy_[] = {}; \ 00066 static const PropertyList property_list (__dummy_, first, __VA_ARGS__); \ 00067 &property_list; })) 00068 00069 /* --- bool --- */ 00070 template<class Class> 00071 struct PropertyBool : Property { 00072 void (Class::*setter) (bool); 00073 bool (Class::*getter) () const; 00074 PropertyBool (void (Class::*csetter) (bool), bool (Class::*cgetter) () const, 00075 const char *cident, const char *clabel, const char *cblurb, 00076 const char *chints); 00077 virtual void set_value (PropertyHostInterface &obj, const String &svalue); 00078 virtual String get_value (PropertyHostInterface &obj); 00079 virtual bool get_range (PropertyHostInterface &obj, double &minimum, double &maximum, double &stepping) { return false; } 00080 }; 00081 template<class Class> inline Property* 00082 create_property (void (Class::*setter) (bool), bool (Class::*getter) () const, 00083 const char *ident, const char *label, const char *blurb, const char *hints) 00084 { return new PropertyBool<Class> (setter, getter, ident, label, blurb, hints); } 00085 00086 /* --- range --- */ 00087 template<class Class, typename Type> 00088 struct PropertyRange : Property { 00089 Type minimum_value; 00090 Type maximum_value; 00091 Type stepping; 00092 void (Class::*setter) (Type); 00093 Type (Class::*getter) () const; 00094 PropertyRange (void (Class::*csetter) (Type), Type (Class::*cgetter) () const, 00095 const char *cident, const char *clabel, const char *cblurb, 00096 Type cminimum_value, Type cmaximum_value, 00097 Type cstepping, const char *chints); 00098 virtual void set_value (PropertyHostInterface &obj, const String &svalue); 00099 virtual String get_value (PropertyHostInterface &obj); 00100 virtual bool get_range (PropertyHostInterface &obj, double &minimum, double &maximum, double &stepping); 00101 }; 00102 /* int */ 00103 template<class Class> inline Property* 00104 create_property (void (Class::*setter) (int), int (Class::*getter) () const, 00105 const char *ident, const char *label, const char *blurb, 00106 int min_value, int max_value, int stepping, const char *hints) 00107 { return new PropertyRange<Class,int> (setter, getter, ident, label, blurb, min_value, max_value, stepping, hints); } 00108 template<class Class> inline Property* 00109 create_property (void (Class::*setter) (int), int (Class::*getter) () const, 00110 const char *ident, const char *label, const char *blurb, const char *hints) 00111 { return new PropertyRange<Class,int> (setter, getter, ident, label, blurb, INT_MIN, INT_MAX, 1, hints); } 00112 /* int16 */ 00113 template<class Class> inline Property* 00114 create_property (void (Class::*setter) (int16), int16 (Class::*getter) () const, 00115 const char *ident, const char *label, const char *blurb, 00116 int16 min_value, int16 max_value, int16 stepping, const char *hints) 00117 { return new PropertyRange<Class,int16> (setter, getter, ident, label, blurb, min_value, max_value, stepping, hints); } 00118 /* uint */ 00119 template<class Class> inline Property* 00120 create_property (void (Class::*setter) (uint), uint (Class::*getter) () const, 00121 const char *ident, const char *label, const char *blurb, 00122 uint min_value, uint max_value, uint stepping, const char *hints) 00123 { return new PropertyRange<Class,uint> (setter, getter, ident, label, blurb, min_value, max_value, stepping, hints); } 00124 /* uint16 */ 00125 template<class Class> inline Property* 00126 create_property (void (Class::*setter) (uint16), uint16 (Class::*getter) () const, 00127 const char *ident, const char *label, const char *blurb, 00128 uint16 min_value, uint16 max_value, uint16 stepping, const char *hints) 00129 { return new PropertyRange<Class,uint16> (setter, getter, ident, label, blurb, min_value, max_value, stepping, hints); } 00130 /* float */ 00131 template<class Class> inline Property* 00132 create_property (void (Class::*setter) (float), float (Class::*getter) () const, 00133 const char *ident, const char *label, const char *blurb, 00134 float min_value, float max_value, float stepping, const char *hints) 00135 { return new PropertyRange<Class,float> (setter, getter, ident, label, blurb, min_value, max_value, stepping, hints); } 00136 /* double */ 00137 template<class Class> inline Property* 00138 create_property (void (Class::*setter) (double), double (Class::*getter) () const, 00139 const char *ident, const char *label, const char *blurb, 00140 double min_value, double max_value, double stepping, const char *hints) 00141 { return new PropertyRange<Class,double> (setter, getter, ident, label, blurb, min_value, max_value, stepping, hints); } 00142 template<class Class> inline Property* 00143 create_property (void (Class::*setter) (double), double (Class::*getter) () const, 00144 const char *ident, const char *label, const char *blurb, const char *hints) 00145 { return new PropertyRange<Class,double> (setter, getter, ident, label, blurb, DBL_MIN, DBL_MAX, 1, hints); } 00146 00147 /* --- string --- */ 00148 template<class Class> 00149 struct PropertyString : Property { 00150 void (Class::*setter) (const String&); 00151 String (Class::*getter) () const; 00152 PropertyString (void (Class::*csetter) (const String&), String (Class::*cgetter) () const, 00153 const char *cident, const char *clabel, const char *cblurb, 00154 const char *chints); 00155 virtual void set_value (PropertyHostInterface &obj, const String &svalue); 00156 virtual String get_value (PropertyHostInterface &obj); 00157 virtual bool get_range (PropertyHostInterface &obj, double &minimum, double &maximum, double &stepping) { return false; } 00158 }; 00159 template<class Class> inline Property* 00160 create_property (void (Class::*setter) (const String&), String (Class::*getter) () const, 00161 const char *ident, const char *label, const char *blurb, const char *hints) 00162 { return new PropertyString<Class> (setter, getter, ident, label, blurb, hints); } 00163 00164 // == Enum Properties == 00165 template<class Class, typename Type> 00166 struct PropertyEnum : Property { 00167 const TypeCode enum_type; 00168 void (Class::*setter) (Type); 00169 Type (Class::*getter) () const; 00170 PropertyEnum (void (Class::*csetter) (Type), Type (Class::*cgetter) () const, 00171 const char *cident, const char *clabel, const char *cblurb, 00172 const TypeCode &etype, const char *chints); 00173 virtual void set_value (PropertyHostInterface &obj, const String &svalue); 00174 virtual String get_value (PropertyHostInterface &obj); 00175 virtual bool get_range (PropertyHostInterface &obj, double &minimum, double &maximum, double &stepping) { return false; } 00176 }; 00177 template<class Class, typename Type> inline Property* 00178 create_property (void (Class::*setter) (Type), Type (Class::*getter) () const, 00179 const char *ident, const char *label, const char *blurb, const char *hints) 00180 { 00181 static const TypeCode etype = TypeCode::from_enum<Type>(); 00182 return new PropertyEnum<Class,Type> (setter, getter, ident, label, blurb, etype, hints); 00183 } 00184 00185 /* --- implementations --- */ 00186 /* bool property implementation */ 00187 template<class Class> 00188 PropertyBool<Class>::PropertyBool (void (Class::*csetter) (bool), bool (Class::*cgetter) () const, 00189 const char *cident, const char *clabel, const char *cblurb, 00190 const char *chints) : 00191 Property (cident, clabel, cblurb, chints), 00192 setter (csetter), 00193 getter (cgetter) 00194 {} 00195 00196 template<class Class> void 00197 PropertyBool<Class>::set_value (PropertyHostInterface &obj, const String &svalue) 00198 { 00199 bool b = string_to_bool (svalue); 00200 Class *instance = dynamic_cast<Class*> (&obj); 00201 (instance->*setter) (b); 00202 } 00203 00204 template<class Class> String 00205 PropertyBool<Class>::get_value (PropertyHostInterface &obj) 00206 { 00207 Class *instance = dynamic_cast<Class*> (&obj); 00208 bool b = (instance->*getter) (); 00209 return string_from_bool (b); 00210 } 00211 00212 /* range property implementation */ 00213 template<class Class, typename Type> 00214 PropertyRange<Class,Type>::PropertyRange (void (Class::*csetter) (Type), Type (Class::*cgetter) () const, 00215 const char *cident, const char *clabel, const char *cblurb, 00216 Type cminimum_value, Type cmaximum_value, 00217 Type cstepping, const char *chints) : 00218 Property (cident, clabel, cblurb, chints), 00219 minimum_value (cminimum_value), 00220 maximum_value (cmaximum_value), 00221 stepping (cstepping), 00222 setter (csetter), 00223 getter (cgetter) 00224 { 00225 AIDA_ASSERT (minimum_value <= maximum_value); 00226 AIDA_ASSERT (minimum_value + stepping <= maximum_value); 00227 } 00228 00229 template<class Class, typename Type> void 00230 PropertyRange<Class,Type>::set_value (PropertyHostInterface &obj, const String &svalue) 00231 { 00232 Type v = string_to_type<Type> (svalue); 00233 Class *instance = dynamic_cast<Class*> (&obj); 00234 (instance->*setter) (v); 00235 } 00236 00237 template<class Class, typename Type> String 00238 PropertyRange<Class,Type>::get_value (PropertyHostInterface &obj) 00239 { 00240 Class *instance = dynamic_cast<Class*> (&obj); 00241 Type v = (instance->*getter) (); 00242 return string_from_type<Type> (v); 00243 } 00244 00245 template<class Class, typename Type> bool 00246 PropertyRange<Class,Type>::get_range (PropertyHostInterface &obj, double &minimum, double &maximum, double &vstepping) 00247 { 00248 minimum = minimum_value, maximum = maximum_value, vstepping = stepping; 00249 return true; 00250 } 00251 00252 /* string property implementation */ 00253 template<class Class> 00254 PropertyString<Class>::PropertyString (void (Class::*csetter) (const String&), String (Class::*cgetter) () const, 00255 const char *cident, const char *clabel, const char *cblurb, 00256 const char *chints) : 00257 Property (cident, clabel, cblurb, chints), 00258 setter (csetter), 00259 getter (cgetter) 00260 {} 00261 00262 template<class Class> void 00263 PropertyString<Class>::set_value (PropertyHostInterface &obj, const String &svalue) 00264 { 00265 Class *instance = dynamic_cast<Class*> (&obj); 00266 (instance->*setter) (svalue); 00267 } 00268 00269 template<class Class> String 00270 PropertyString<Class>::get_value (PropertyHostInterface &obj) 00271 { 00272 Class *instance = dynamic_cast<Class*> (&obj); 00273 return (instance->*getter) (); 00274 } 00275 00276 /* enum property implementation */ 00277 template<class Class, typename Type> 00278 PropertyEnum<Class,Type>::PropertyEnum (void (Class::*csetter) (Type), Type (Class::*cgetter) () const, 00279 const char *cident, const char *clabel, const char *cblurb, 00280 const TypeCode &etype, const char *chints) : 00281 Property (cident, clabel, cblurb, chints), 00282 enum_type (etype), 00283 setter (csetter), 00284 getter (cgetter) 00285 {} 00286 00287 template<class Class, typename Type> void 00288 PropertyEnum<Class,Type>::set_value (PropertyHostInterface &obj, const String &svalue) 00289 { 00290 String error_string; 00291 uint64 value = enum_type.enum_parse (svalue.c_str(), &error_string); 00292 // if (0 && error_string.size() && !value && string_has_int (svalue)) 00293 // value = enum_type.constrain (string_to_int (svalue)); 00294 if (!error_string.empty()) 00295 print_warning (String() + __PRETTY_FUNCTION__ + ": invalid enum value name '" + enum_type.name() + "': " + error_string); 00296 Type v = Type (value); 00297 Class *instance = dynamic_cast<Class*> (&obj); 00298 (instance->*setter) (v); 00299 } 00300 00301 template<class Class, typename Type> String 00302 PropertyEnum<Class,Type>::get_value (PropertyHostInterface &obj) 00303 { 00304 Class *instance = dynamic_cast<Class*> (&obj); 00305 Type v = (instance->*getter) (); 00306 return enum_type.enum_string (v); 00307 } 00308 00309 } } // Rapicorn::Aida 00310 00311 #endif // __RAPICORN_AIDA_PROPS_HH__