1 /* propertyproxy_base.h
2 *
3 * Copyright 2002 The gtkmm Development Team
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include <glibmm/propertyproxy_base.h>
20
21 #include <glibmm/signalproxy_connectionnode.h>
22 #include <glibmm/object.h>
23 #include <glibmm/private/object_p.h>
24 #include <utility> // For std::move()
25
26 namespace Glib
27 {
28
29 // PropertyProxyConnectionNode implementation:
30
PropertyProxyConnectionNode(const sigc::slot_base & slot,GObject * gobject)31 PropertyProxyConnectionNode::PropertyProxyConnectionNode(
32 const sigc::slot_base& slot, GObject* gobject)
33 : SignalProxyConnectionNode(slot, gobject)
34 {
35 }
36
PropertyProxyConnectionNode(sigc::slot_base && slot,GObject * gobject)37 PropertyProxyConnectionNode::PropertyProxyConnectionNode(sigc::slot_base&& slot, GObject* gobject)
38 : SignalProxyConnectionNode(std::move(slot), gobject)
39 {
40 }
41
42 sigc::connection
connect_changed(const Glib::ustring & property_name)43 PropertyProxyConnectionNode::connect_changed(const Glib::ustring& property_name)
44 {
45 // connect it to glib
46 // 'this' will be passed as the data argument to the callback.
47 const Glib::ustring notify_signal_name = "notify::" + property_name;
48 connection_id_ = g_signal_connect_data(object_, notify_signal_name.c_str(),
49 (GCallback)(&PropertyProxyConnectionNode::callback), this,
50 &PropertyProxyConnectionNode::destroy_notify_handler, G_CONNECT_AFTER);
51
52 return sigc::connection(slot_);
53 }
54
callback(GObject *,GParamSpec * pspec,gpointer data)55 void PropertyProxyConnectionNode::callback(GObject*, GParamSpec* pspec, gpointer data) // static
56 {
57 if (pspec && data)
58 {
59 if (sigc::slot_base* const slot = SignalProxyBase::data_to_slot(data))
60 (*static_cast<sigc::slot<void>*>(slot))();
61 }
62 }
63
64 // SignalProxyProperty implementation:
65
SignalProxyProperty(Glib::ObjectBase * obj,const gchar * property_name)66 SignalProxyProperty::SignalProxyProperty(Glib::ObjectBase* obj, const gchar* property_name)
67 : SignalProxyBase(obj), property_name_(property_name)
68 {
69 }
70
~SignalProxyProperty()71 SignalProxyProperty::~SignalProxyProperty() noexcept
72 {
73 }
74
75 sigc::connection
connect(const SlotType & slot)76 SignalProxyProperty::connect(const SlotType& slot)
77 {
78 // Create a proxy to hold our connection info
79 // This will be deleted by destroy_notify_handler.
80 auto pConnectionNode = new PropertyProxyConnectionNode(slot, obj_->gobj());
81
82 // connect it to glib
83 // pConnectionNode will be passed as the data argument to the callback.
84 return pConnectionNode->connect_changed(property_name_);
85 }
86
87 sigc::connection
connect(SlotType && slot)88 SignalProxyProperty::connect(SlotType&& slot)
89 {
90 // Create a proxy to hold our connection info
91 // This will be deleted by destroy_notify_handler.
92 auto pConnectionNode = new PropertyProxyConnectionNode(std::move(slot), obj_->gobj());
93
94 // connect it to glib
95 // pConnectionNode will be passed as the data argument to the callback.
96 return pConnectionNode->connect_changed(property_name_);
97 }
98
99 // PropertyProxy_Base implementation:
100
PropertyProxy_Base(ObjectBase * obj,const char * property_name)101 PropertyProxy_Base::PropertyProxy_Base(ObjectBase* obj, const char* property_name)
102 : obj_(obj), property_name_(property_name)
103 {
104 }
105
PropertyProxy_Base(const PropertyProxy_Base & other)106 PropertyProxy_Base::PropertyProxy_Base(const PropertyProxy_Base& other)
107 : obj_(other.obj_), property_name_(other.property_name_)
108 {
109 }
110
111 SignalProxyProperty
signal_changed()112 PropertyProxy_Base::signal_changed()
113 {
114 return SignalProxyProperty(obj_, property_name_);
115 }
116
117 void
set_property_(const Glib::ValueBase & value)118 PropertyProxy_Base::set_property_(const Glib::ValueBase& value)
119 {
120 g_object_set_property(obj_->gobj(), property_name_, value.gobj());
121 }
122
123 void
get_property_(Glib::ValueBase & value) const124 PropertyProxy_Base::get_property_(Glib::ValueBase& value) const
125 {
126 g_object_get_property(obj_->gobj(), property_name_, value.gobj());
127 }
128
129 void
reset_property_()130 PropertyProxy_Base::reset_property_()
131 {
132 // Get information about the parameter:
133 const GParamSpec* const pParamSpec =
134 g_object_class_find_property(G_OBJECT_GET_CLASS(obj_->gobj()), property_name_);
135
136 g_return_if_fail(pParamSpec != nullptr);
137
138 Glib::ValueBase value;
139 value.init(G_PARAM_SPEC_VALUE_TYPE(pParamSpec));
140
141 // An explicit reset is not needed, because ValueBase:init()
142 // has already initialized it to the default value for this type.
143 // value.reset();
144
145 g_object_set_property(obj_->gobj(), property_name_, value.gobj());
146 }
147
148 } // namespace Glib
149