Rapicorn - Experimental UI Toolkit - Source Code 10.08.1
properties.hh
Go to the documentation of this file.
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__ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines