1 #ifndef _GLIBMM_PROPERTYPROXY_H
2 #define _GLIBMM_PROPERTYPROXY_H
3 
4 /* propertyproxy.h
5  *
6  * Copyright 2002 The gtkmm Development Team
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include <glibmmconfig.h>
23 #include <glibmm/propertyproxy_base.h>
24 
25 namespace Glib
26 {
27 
28 /** A PropertyProxy can be used to get and set the value of an object's property.
29  * There are usually also get and set methods on the class itself, which you might find more
30  * convenient.
31  * With the PropertyProxy, you may use either get_value() and set_value(), or operator=() and
32  * operator PropertyType(), like so:
33  * @code
34  * int height = cellrenderer.property_height();
35  * cellrenderer.property_editable() = true;
36  * @endcode
37  *
38  * You may also receive notification when a property's value changes, by connecting to
39  * signal_changed().
40  */
41 template <class T>
42 class PropertyProxy : public PropertyProxy_Base
43 {
44 public:
45   using PropertyType = T;
46 
PropertyProxy(ObjectBase * obj,const char * name)47   PropertyProxy(ObjectBase* obj, const char* name) : PropertyProxy_Base(obj, name) {}
48 
49   /** Set the value of this property.
50    * @param data The new value for the property.
51    */
52   void set_value(const PropertyType& data);
53 
54   /** Get the value of this property.
55    * @result The current value of the property.
56    */
57   PropertyType get_value() const;
58 
59   /** Set the value of this property back to its default value
60    */
reset_value()61   void reset_value() { reset_property_(); }
62 
63   PropertyProxy<T>& operator=(const PropertyType& data)
64   {
65     this->set_value(data);
66     return *this;
67   }
68 
PropertyType()69   operator PropertyType() const { return this->get_value(); }
70 };
71 
72 /** See PropertyProxy().
73  * This property can be written, but not read, so there is no get_value() method.
74  */
75 template <class T>
76 class PropertyProxy_WriteOnly : public PropertyProxy_Base
77 {
78 public:
79   using PropertyType = T;
80 
PropertyProxy_WriteOnly(ObjectBase * obj,const char * name)81   PropertyProxy_WriteOnly(ObjectBase* obj, const char* name) : PropertyProxy_Base(obj, name) {}
82 
83   /** Set the value of this property.
84    * @param data The new value for the property.
85    */
86   void set_value(const PropertyType& data);
87 
88   /** Set the value of this property back to its default value
89    */
reset_value()90   void reset_value() { reset_property_(); }
91 
92   PropertyProxy_WriteOnly<T>& operator=(const PropertyType& data)
93   {
94     this->set_value(data);
95     return *this;
96   }
97 };
98 
99 /** See PropertyProxy().
100  * This property can be read, but not written, so there is no set_value() method.
101  */
102 template <class T>
103 class PropertyProxy_ReadOnly : public PropertyProxy_Base
104 {
105 public:
106   using PropertyType = T;
107 
108   // obj is const, because this should be returned by const accessors.
PropertyProxy_ReadOnly(const ObjectBase * obj,const char * name)109   PropertyProxy_ReadOnly(const ObjectBase* obj, const char* name)
110   : PropertyProxy_Base(const_cast<ObjectBase*>(obj), name)
111   {
112   }
113 
114   /** Get the value of this property.
115    * @result The current value of the property.
116    */
117   PropertyType get_value() const;
118 
PropertyType()119   operator PropertyType() const { return this->get_value(); }
120 };
121 
122 /**** Template Implementation **********************************************/
123 
124 #ifndef DOXYGEN_SHOULD_SKIP_THIS
125 
126 template <class T>
127 void
set_value(const T & data)128 PropertyProxy<T>::set_value(const T& data)
129 {
130   Glib::Value<T> value;
131   value.init(Glib::Value<T>::value_type());
132 
133   value.set(data);
134   set_property_(value);
135 }
136 
137 template <class T>
138 T
get_value()139 PropertyProxy<T>::get_value() const
140 {
141   Glib::Value<T> value;
142   value.init(Glib::Value<T>::value_type());
143 
144   get_property_(value);
145   return value.get();
146 }
147 
148 // We previously just static_cast<> PropertyProxy_WriteOnly<> to PropertyProxy<> to call its
149 // set_value(),
150 // to avoid code duplication.
151 // But the AIX compiler does not like that hack.
152 template <class T>
153 void
set_value(const T & data)154 PropertyProxy_WriteOnly<T>::set_value(const T& data)
155 {
156   Glib::Value<T> value;
157   value.init(Glib::Value<T>::value_type());
158 
159   value.set(data);
160   set_property_(value);
161 }
162 
163 // We previously just static_cast<> PropertyProxy_WriteOnly<> to PropertyProxy<> to call its
164 // set_value(),
165 // to avoid code duplication.
166 // But the AIX compiler does not like that hack.
167 template <class T>
168 T
get_value()169 PropertyProxy_ReadOnly<T>::get_value() const
170 {
171   Glib::Value<T> value;
172   value.init(Glib::Value<T>::value_type());
173 
174   get_property_(value);
175   return value.get();
176 }
177 
178 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
179 
180 } // namespace Glib
181 
182 #endif /* _GLIBMM_PROPERTYPROXY_H */
183