Initial revision
[ardour.git] / libs / glibmm2 / glibmm / property.h
1 // -*- c++ -*-
2 #ifndef _GLIBMM_PROPERTY_H
3 #define _GLIBMM_PROPERTY_H
4 /* $Id$ */
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 Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 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  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the Free
20  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22
23 #include <glibmm/propertyproxy.h>
24 #include <glibmm/value.h>
25
26
27 namespace Glib
28 {
29
30 #ifndef DOXYGEN_SHOULD_SKIP_THIS
31
32 #ifdef GLIBMM_CXX_CAN_USE_NAMESPACES_INSIDE_EXTERNC
33 //For the AIX xlC compiler, I can not find a way to do this without putting the functions in the global namespace. murrayc
34 extern "C"
35 {
36 #endif //GLIBMM_CXX_CAN_USE_NAMESPACES_INSIDE_EXTERNC
37
38 void custom_get_property_callback(GObject* object, unsigned int property_id,
39                                   GValue* value, GParamSpec* param_spec);
40
41 void custom_set_property_callback(GObject* object, unsigned int property_id,
42                                   const GValue* value, GParamSpec* param_spec);
43
44 #ifdef GLIBMM_CXX_CAN_USE_NAMESPACES_INSIDE_EXTERNC
45 } //extern "C"
46 #endif //GLIBMM_CXX_CAN_USE_NAMESPACES_INSIDE_EXTERNC
47
48 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
49
50
51 class PropertyBase
52 {
53 public:
54   Glib::ustring get_name() const;
55   void notify();
56
57 protected:
58   Glib::Object*   object_;
59   Glib::ValueBase value_;
60   GParamSpec*     param_spec_;
61
62   PropertyBase(Glib::Object& object, GType value_type);
63   ~PropertyBase();
64
65   bool lookup_property(const Glib::ustring& name);
66   void install_property(GParamSpec* param_spec);
67
68   const char* get_name_internal() const;
69
70 private:
71   // noncopyable
72   PropertyBase(const PropertyBase&);
73   PropertyBase& operator=(const PropertyBase&);
74
75 #ifndef DOXYGEN_SHOULD_SKIP_THIS
76
77   friend void Glib::custom_get_property_callback(GObject* object, unsigned int property_id,
78                                                  GValue* value, GParamSpec* param_spec);
79
80   friend void Glib::custom_set_property_callback(GObject* object, unsigned int property_id,
81                                                  const GValue* value, GParamSpec* param_spec);
82
83 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
84 };
85
86
87 template <class T>
88 class Property : public PropertyBase
89 {
90 public:
91   typedef T PropertyType;
92   typedef Glib::Value<T> ValueType;
93
94   Property(Glib::Object& object, const Glib::ustring& name);
95   Property(Glib::Object& object, const Glib::ustring& name, const PropertyType& default_value);
96
97   inline void set_value(const PropertyType& data);
98   inline PropertyType get_value() const;
99
100   inline Property<T>& operator=(const PropertyType& data);
101   inline operator PropertyType() const;
102
103   inline Glib::PropertyProxy<T> get_proxy();
104 };
105
106
107 #ifndef DOXYGEN_SHOULD_SKIP_THIS
108
109 /**** Glib::Property<T> ****************************************************/
110
111 template <class T>
112 Property<T>::Property(Glib::Object& object, const Glib::ustring& name)
113 :
114   PropertyBase(object, ValueType::value_type())
115 {
116   if(!lookup_property(name))
117     install_property(static_cast<ValueType&>(value_).create_param_spec(name));
118 }
119
120 template <class T>
121 Property<T>::Property(Glib::Object& object, const Glib::ustring& name,
122                       const typename Property<T>::PropertyType& default_value)
123 :
124   PropertyBase(object, ValueType::value_type())
125 {
126   static_cast<ValueType&>(value_).set(default_value);
127
128   if(!lookup_property(name))
129     install_property(static_cast<ValueType&>(value_).create_param_spec(name));
130 }
131
132 template <class T> inline
133 void Property<T>::set_value(const typename Property<T>::PropertyType& data)
134 {
135   static_cast<ValueType&>(value_).set(data);
136   this->notify();
137 }
138
139 template <class T> inline
140 typename Property<T>::PropertyType Property<T>::get_value() const
141 {
142   return static_cast<const ValueType&>(value_).get();
143 }
144
145 template <class T> inline
146 Property<T>& Property<T>::operator=(const typename Property<T>::PropertyType& data)
147 {
148   static_cast<ValueType&>(value_).set(data);
149   this->notify();
150   return *this;
151 }
152
153 template <class T> inline
154 Property<T>::operator T() const
155 {
156   return static_cast<const ValueType&>(value_).get();
157 }
158
159 template <class T> inline
160 Glib::PropertyProxy<T> Property<T>::get_proxy()
161 {
162   return Glib::PropertyProxy<T>(object_, get_name_internal());
163 }
164
165 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
166
167 } // namespace Glib
168
169
170 #endif /* _GLIBMM_PROPERTY_H */
171