|
Rapicorn - Experimental UI Toolkit - Source Code 10.08.1
|
00001 /* Rapicorn 00002 * Copyright (C) 2005 Tim Janik 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * A copy of the GNU Lesser General Public License should ship along 00015 * with this library; if not, see http://www.gnu.org/copyleft/. 00016 */ 00017 #ifndef __RAPICORN_PROPERTIES_HH__ 00018 #define __RAPICORN_PROPERTIES_HH__ 00019 00020 #include <ui/primitives.hh> 00021 #include <ui/utilities.hh> 00022 00023 namespace Rapicorn { 00024 00025 struct Property : ReferenceCountable { 00026 const char *ident; 00027 char *label; 00028 char *blurb; 00029 char *hints; 00030 Property (const char *cident, const char *clabel, const char *cblurb, const char *chints); 00031 virtual void set_value (Deletable *obj, const String &svalue) = 0; 00032 virtual String get_value (Deletable *obj) = 0; 00033 virtual bool get_range (Deletable *obj, double &minimum, double &maximum, double &stepping) = 0; 00034 bool readable () const; 00035 bool writable () const; 00036 protected: 00037 virtual ~Property(); 00038 }; 00039 00040 class PropertyList { 00041 void append_properties (uint n_props, 00042 Property **props, 00043 const PropertyList &chain0, 00044 const PropertyList &chain1, 00045 const PropertyList &chain2, 00046 const PropertyList &chain3, 00047 const PropertyList &chain4, 00048 const PropertyList &chain5, 00049 const PropertyList &chain6, 00050 const PropertyList &chain7, 00051 const PropertyList &chain8); 00052 public: 00053 uint n_properties; 00054 Property **properties; 00055 PropertyList () : n_properties (0), properties (NULL) {} 00056 template<typename Array> 00057 PropertyList (Array &a, 00058 const PropertyList &chain0 = PropertyList(), 00059 const PropertyList &chain1 = PropertyList(), 00060 const PropertyList &chain2 = PropertyList(), 00061 const PropertyList &chain3 = PropertyList(), 00062 const PropertyList &chain4 = PropertyList(), 00063 const PropertyList &chain5 = PropertyList(), 00064 const PropertyList &chain6 = PropertyList(), 00065 const PropertyList &chain7 = PropertyList(), 00066 const PropertyList &chain8 = PropertyList()) : 00067 n_properties (0), 00068 properties (NULL) 00069 { 00070 append_properties (sizeof (a) / sizeof (a[0]), a, 00071 chain0, chain1, chain2, chain3, 00072 chain4, chain5, chain6, chain7, chain8); 00073 } 00074 ~PropertyList(); 00075 }; 00076 00077 #define RAPICORN_MakeProperty(Type, accessor, label, blurb, ...) \ 00078 create_property (&Type::accessor, &Type::accessor, #accessor, label, blurb, __VA_ARGS__) 00079 00080 template<typename Return, class Class> 00081 inline Return (Class::* 00082 noconst_getter (Return (Class::*const_getter)() const) 00083 ) () 00084 { return reinterpret_cast<Return (Class::*)()> (const_getter); } 00085 00086 /* --- bool --- */ 00087 template<class Class> 00088 struct PropertyBool : Property { 00089 void (Class::*setter) (bool); 00090 bool (Class::*getter) (); 00091 PropertyBool (void (Class::*csetter) (bool), bool (Class::*cgetter) (), 00092 const char *cident, const char *clabel, const char *cblurb, 00093 const char *chints); 00094 virtual void set_value (Deletable *obj, const String &svalue); 00095 virtual String get_value (Deletable *obj); 00096 virtual bool get_range (Deletable *obj, double &minimum, double &maximum, double &stepping) { return false; } 00097 }; 00098 template<class Class> inline Property* 00099 create_property (void (Class::*setter) (bool), bool (Class::*getter) (), 00100 const char *ident, const char *label, const char *blurb, const char *hints) 00101 { return new PropertyBool<Class> (setter, getter, ident, label, blurb, hints); } 00102 template<class Class> inline Property* 00103 create_property (void (Class::*setter) (bool), bool (Class::*getter) () const, 00104 const char *ident, const char *label, const char *blurb, const char *hints) 00105 { return new PropertyBool<Class> (setter, noconst_getter (getter), ident, label, blurb, hints); } 00106 00107 /* --- range --- */ 00108 template<class Class, typename Type> 00109 struct PropertyRange : Property { 00110 Type minimum_value; 00111 Type maximum_value; 00112 Type stepping; 00113 void (Class::*setter) (Type); 00114 Type (Class::*getter) (); 00115 PropertyRange (void (Class::*csetter) (Type), Type (Class::*cgetter) (), 00116 const char *cident, const char *clabel, const char *cblurb, 00117 Type cminimum_value, Type cmaximum_value, 00118 Type cstepping, const char *chints); 00119 virtual void set_value (Deletable *obj, const String &svalue); 00120 virtual String get_value (Deletable *obj); 00121 virtual bool get_range (Deletable *obj, double &minimum, double &maximum, double &stepping); 00122 }; 00123 /* int */ 00124 template<class Class> inline Property* 00125 create_property (void (Class::*setter) (int), int (Class::*getter) (), 00126 const char *ident, const char *label, const char *blurb, 00127 int min_value, int max_value, int stepping, const char *hints) 00128 { return new PropertyRange<Class,int> (setter, getter, ident, label, blurb, min_value, max_value, stepping, hints); } 00129 template<class Class> inline Property* 00130 create_property (void (Class::*setter) (int), int (Class::*getter) () const, 00131 const char *ident, const char *label, const char *blurb, 00132 int min_value, int max_value, int stepping, const char *hints) 00133 { return new PropertyRange<Class,int> (setter, noconst_getter (getter), ident, label, blurb, min_value, max_value, stepping, hints); } 00134 /* int16 */ 00135 template<class Class> inline Property* 00136 create_property (void (Class::*setter) (int16), int16 (Class::*getter) (), 00137 const char *ident, const char *label, const char *blurb, 00138 int16 min_value, int16 max_value, int16 stepping, const char *hints) 00139 { return new PropertyRange<Class,int16> (setter, getter, ident, label, blurb, min_value, max_value, stepping, hints); } 00140 template<class Class> inline Property* 00141 create_property (void (Class::*setter) (int16), int16 (Class::*getter) () const, 00142 const char *ident, const char *label, const char *blurb, 00143 int16 min_value, int16 max_value, int16 stepping, const char *hints) 00144 { return new PropertyRange<Class,int16> (setter, noconst_getter (getter), ident, label, blurb, min_value, max_value, stepping, hints); } 00145 /* uint */ 00146 template<class Class> inline Property* 00147 create_property (void (Class::*setter) (uint), uint (Class::*getter) (), 00148 const char *ident, const char *label, const char *blurb, 00149 uint min_value, uint max_value, uint stepping, const char *hints) 00150 { return new PropertyRange<Class,uint> (setter, getter, ident, label, blurb, min_value, max_value, stepping, hints); } 00151 template<class Class> inline Property* 00152 create_property (void (Class::*setter) (uint), uint (Class::*getter) () const, 00153 const char *ident, const char *label, const char *blurb, 00154 uint min_value, uint max_value, uint stepping, const char *hints) 00155 { return new PropertyRange<Class,uint> (setter, noconst_getter (getter), ident, label, blurb, min_value, max_value, stepping, hints); } 00156 /* uint16 */ 00157 template<class Class> inline Property* 00158 create_property (void (Class::*setter) (uint16), uint16 (Class::*getter) (), 00159 const char *ident, const char *label, const char *blurb, 00160 uint16 min_value, uint16 max_value, uint16 stepping, const char *hints) 00161 { return new PropertyRange<Class,uint16> (setter, getter, ident, label, blurb, min_value, max_value, stepping, hints); } 00162 template<class Class> inline Property* 00163 create_property (void (Class::*setter) (uint16), uint16 (Class::*getter) () const, 00164 const char *ident, const char *label, const char *blurb, 00165 uint16 min_value, uint16 max_value, uint16 stepping, const char *hints) 00166 { return new PropertyRange<Class,uint16> (setter, noconst_getter (getter), ident, label, blurb, min_value, max_value, stepping, hints); } 00167 /* float */ 00168 template<class Class> inline Property* 00169 create_property (void (Class::*setter) (float), float (Class::*getter) (), 00170 const char *ident, const char *label, const char *blurb, 00171 float min_value, float max_value, float stepping, const char *hints) 00172 { return new PropertyRange<Class,float> (setter, getter, ident, label, blurb, min_value, max_value, stepping, hints); } 00173 template<class Class> inline Property* 00174 create_property (void (Class::*setter) (float), float (Class::*getter) () const, 00175 const char *ident, const char *label, const char *blurb, 00176 float min_value, float max_value, float stepping, const char *hints) 00177 { return new PropertyRange<Class,float> (setter, noconst_getter (getter), ident, label, blurb, min_value, max_value, stepping, hints); } 00178 /* double */ 00179 template<class Class> inline Property* 00180 create_property (void (Class::*setter) (double), double (Class::*getter) (), 00181 const char *ident, const char *label, const char *blurb, 00182 double min_value, double max_value, double stepping, const char *hints) 00183 { return new PropertyRange<Class,double> (setter, getter, ident, label, blurb, min_value, max_value, stepping, hints); } 00184 template<class Class> inline Property* 00185 create_property (void (Class::*setter) (double), double (Class::*getter) () const, 00186 const char *ident, const char *label, const char *blurb, 00187 double min_value, double max_value, double stepping, const char *hints) 00188 { return new PropertyRange<Class,double> (setter, noconst_getter (getter), ident, label, blurb, min_value, max_value, stepping, hints); } 00189 00190 /* --- point --- */ 00191 template<class Class> 00192 struct PropertyPoint : Property { 00193 Point minimum_value; 00194 Point maximum_value; 00195 void (Class::*setter) (Point); 00196 Point (Class::*getter) (); 00197 PropertyPoint (void (Class::*csetter) (Point), Point (Class::*cgetter) (), 00198 const char *cident, const char *clabel, const char *cblurb, 00199 Point cminimum_value, Point cmaximum_value, 00200 const char *chints); 00201 virtual void set_value (Deletable *obj, const String &svalue); 00202 virtual String get_value (Deletable *obj); 00203 virtual bool get_range (Deletable *obj, Point &minimum, Point &maximum); 00204 virtual bool get_range (Deletable *obj, double &minimum, double &maximum, double &stepping) { return false; } 00205 }; 00206 template<class Class> inline Property* 00207 create_property (void (Class::*setter) (Point), Point (Class::*getter) (), 00208 const char *ident, const char *label, const char *blurb, 00209 const Point &min_value, const Point &max_value, const char *hints) 00210 { return new PropertyPoint<Class> (setter, getter, ident, label, blurb, min_value, max_value, hints); } 00211 template<class Class> inline Property* 00212 create_property (void (Class::*setter) (Point), Point (Class::*getter) () const, 00213 const char *ident, const char *label, const char *blurb, 00214 const Point &min_value, const Point &max_value, const char *hints) 00215 { return new PropertyPoint<Class> (setter, noconst_getter (getter), ident, label, blurb, min_value, max_value, hints); } 00216 00217 /* --- string --- */ 00218 template<class Class> 00219 struct PropertyString : Property { 00220 void (Class::*setter) (const String&); 00221 String (Class::*getter) (); 00222 PropertyString (void (Class::*csetter) (const String&), String (Class::*cgetter) (), 00223 const char *cident, const char *clabel, const char *cblurb, 00224 const char *chints); 00225 virtual void set_value (Deletable *obj, const String &svalue); 00226 virtual String get_value (Deletable *obj); 00227 virtual bool get_range (Deletable *obj, double &minimum, double &maximum, double &stepping) { return false; } 00228 }; 00229 template<class Class> inline Property* 00230 create_property (void (Class::*setter) (const String&), String (Class::*getter) (), 00231 const char *ident, const char *label, const char *blurb, const char *hints) 00232 { return new PropertyString<Class> (setter, getter, ident, label, blurb, hints); } 00233 template<class Class> inline Property* 00234 create_property (void (Class::*setter) (const String&), String (Class::*getter) () const, 00235 const char *ident, const char *label, const char *blurb, const char *hints) 00236 { return new PropertyString<Class> (setter, noconst_getter (getter), ident, label, blurb, hints); } 00237 00238 /* --- enum --- */ 00239 template<class Class, typename Type> 00240 struct PropertyEnum : Property { 00241 const EnumClass &enum_class; 00242 void (Class::*setter) (Type); 00243 Type (Class::*getter) (); 00244 PropertyEnum (void (Class::*csetter) (Type), Type (Class::*cgetter) (), 00245 const char *cident, const char *clabel, const char *cblurb, 00246 const EnumClass &eclass, const char *chints); 00247 virtual void set_value (Deletable *obj, const String &svalue); 00248 virtual String get_value (Deletable *obj); 00249 virtual bool get_range (Deletable *obj, double &minimum, double &maximum, double &stepping) { return false; } 00250 }; 00251 template<class Class, typename Type> inline Property* 00252 create_property (void (Class::*setter) (Type), Type (Class::*getter) (), 00253 const char *ident, const char *label, const char *blurb, const char *hints) 00254 { 00255 static const EnumType<Type> enum_class; 00256 return new PropertyEnum<Class,Type> (setter, getter, ident, label, blurb, enum_class, hints); 00257 } 00258 template<class Class, typename Type> inline Property* 00259 create_property (void (Class::*setter) (Type), Type (Class::*getter) () const, 00260 const char *ident, const char *label, const char *blurb, const char *hints) 00261 { 00262 static const EnumType<Type> enum_class; 00263 return new PropertyEnum<Class,Type> (setter, noconst_getter (getter), ident, label, blurb, enum_class, hints); 00264 } 00265 00266 /* --- implementations --- */ 00267 /* bool property implementation */ 00268 template<class Class> 00269 PropertyBool<Class>::PropertyBool (void (Class::*csetter) (bool), bool (Class::*cgetter) (), 00270 const char *cident, const char *clabel, const char *cblurb, 00271 const char *chints) : 00272 Property (cident, clabel, cblurb, chints), 00273 setter (csetter), 00274 getter (cgetter) 00275 {} 00276 00277 template<class Class> void 00278 PropertyBool<Class>::set_value (Deletable *obj, const String &svalue) 00279 { 00280 bool b = string_to_bool (svalue); 00281 Class *instance = dynamic_cast<Class*> (obj); 00282 (instance->*setter) (b); 00283 } 00284 00285 template<class Class> String 00286 PropertyBool<Class>::get_value (Deletable *obj) 00287 { 00288 Class *instance = dynamic_cast<Class*> (obj); 00289 bool b = (instance->*getter) (); 00290 return string_from_bool (b); 00291 } 00292 00293 /* range property implementation */ 00294 template<class Class, typename Type> 00295 PropertyRange<Class,Type>::PropertyRange (void (Class::*csetter) (Type), Type (Class::*cgetter) (), 00296 const char *cident, const char *clabel, const char *cblurb, 00297 Type cminimum_value, Type cmaximum_value, 00298 Type cstepping, const char *chints) : 00299 Property (cident, clabel, cblurb, chints), 00300 minimum_value (cminimum_value), 00301 maximum_value (cmaximum_value), 00302 stepping (cstepping), 00303 setter (csetter), 00304 getter (cgetter) 00305 { 00306 RAPICORN_ASSERT (minimum_value <= maximum_value); 00307 RAPICORN_ASSERT (minimum_value + stepping <= maximum_value); 00308 } 00309 00310 template<class Class, typename Type> void 00311 PropertyRange<Class,Type>::set_value (Deletable *obj, const String &svalue) 00312 { 00313 Type v = string_to_type<Type> (svalue); 00314 Class *instance = dynamic_cast<Class*> (obj); 00315 (instance->*setter) (v); 00316 } 00317 00318 template<class Class, typename Type> String 00319 PropertyRange<Class,Type>::get_value (Deletable *obj) 00320 { 00321 Class *instance = dynamic_cast<Class*> (obj); 00322 Type v = (instance->*getter) (); 00323 return string_from_type<Type> (v); 00324 } 00325 00326 template<class Class, typename Type> bool 00327 PropertyRange<Class,Type>::get_range (Deletable *obj, double &minimum, double &maximum, double &vstepping) 00328 { 00329 minimum = minimum_value, maximum = maximum_value, vstepping = stepping; 00330 return true; 00331 } 00332 00333 /* point property implementation */ 00334 template<class Class> 00335 PropertyPoint<Class>::PropertyPoint (void (Class::*csetter) (Point), Point (Class::*cgetter) (), 00336 const char *cident, const char *clabel, const char *cblurb, 00337 Point cminimum_value, Point cmaximum_value, 00338 const char *chints) : 00339 Property (cident, clabel, cblurb, chints), 00340 setter (csetter), 00341 getter (cgetter) 00342 {} 00343 00344 template<class Class> void 00345 PropertyPoint<Class>::set_value (Deletable *obj, const String &svalue) 00346 { 00347 Class *instance = dynamic_cast<Class*> (obj); 00348 Point point; 00349 vector<double> dvec = string_to_vector (svalue); 00350 if (dvec.size() == 2) 00351 point = Point (dvec[0], dvec[1]); 00352 (instance->*setter) (point); 00353 } 00354 00355 template<class Class> String 00356 PropertyPoint<Class>::get_value (Deletable *obj) 00357 { 00358 Class *instance = dynamic_cast<Class*> (obj); 00359 Point point = (instance->*getter) (); 00360 vector<double> dvec; 00361 dvec.push_back (point.x); 00362 dvec.push_back (point.y); 00363 return string_from_vector (dvec); 00364 } 00365 00366 template<class Class> bool 00367 PropertyPoint<Class>::get_range (Deletable *obj, Point &minimum, Point &maximum) 00368 { 00369 minimum = minimum_value, maximum = maximum_value; 00370 return true; 00371 } 00372 00373 /* string property implementation */ 00374 template<class Class> 00375 PropertyString<Class>::PropertyString (void (Class::*csetter) (const String&), String (Class::*cgetter) (), 00376 const char *cident, const char *clabel, const char *cblurb, 00377 const char *chints) : 00378 Property (cident, clabel, cblurb, chints), 00379 setter (csetter), 00380 getter (cgetter) 00381 {} 00382 00383 template<class Class> void 00384 PropertyString<Class>::set_value (Deletable *obj, const String &svalue) 00385 { 00386 Class *instance = dynamic_cast<Class*> (obj); 00387 (instance->*setter) (svalue); 00388 } 00389 00390 template<class Class> String 00391 PropertyString<Class>::get_value (Deletable *obj) 00392 { 00393 Class *instance = dynamic_cast<Class*> (obj); 00394 return (instance->*getter) (); 00395 } 00396 00397 /* enum property implementation */ 00398 template<class Class, typename Type> 00399 PropertyEnum<Class,Type>::PropertyEnum (void (Class::*csetter) (Type), Type (Class::*cgetter) (), 00400 const char *cident, const char *clabel, const char *cblurb, 00401 const EnumClass &eclass, const char *chints) : 00402 Property (cident, clabel, cblurb, chints), 00403 enum_class (eclass), 00404 setter (csetter), 00405 getter (cgetter) 00406 {} 00407 00408 template<class Class, typename Type> void 00409 PropertyEnum<Class,Type>::set_value (Deletable *obj, const String &svalue) 00410 { 00411 String error_string; 00412 uint64 value = enum_class.parse (svalue.c_str(), &error_string); 00413 if (0 && error_string.size() && !value && string_has_int (svalue)) 00414 value = enum_class.constrain (string_to_int (svalue)); 00415 else if (error_string.size()) 00416 critical ("%s: invalid enum value name '%s': %s", RAPICORN_SIMPLE_FUNCTION, enum_class.enum_name(), error_string.c_str()); 00417 Type v = Type (value); 00418 Class *instance = dynamic_cast<Class*> (obj); 00419 (instance->*setter) (v); 00420 } 00421 00422 template<class Class, typename Type> String 00423 PropertyEnum<Class,Type>::get_value (Deletable *obj) 00424 { 00425 Class *instance = dynamic_cast<Class*> (obj); 00426 Type v = (instance->*getter) (); 00427 return enum_class.string (v); 00428 } 00429 00430 } // Rapicorn 00431 00432 #endif /* __RAPICORN_PROPERTIES_HH__ */
1.7.4