[glibmm] Add Glib::Binding



commit 983dd287da4b00baedbd04ce0f777c043d93f5b0
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date:   Thu Nov 20 16:54:58 2014 +0100

    Add Glib::Binding
    
    * .gitignore: Ignore binding.[h|cc].
    * glib/glibmm/objectbase.h: Add a comment.
    * glib/src/filelist.am: Add glib_signals.defs and binding.hg.
    * glib/src/glib.defs:  Add glib_signals.defs.
    * glib/glibmm.h: Add binding.h.
    * tools/extra_defs_gen/generate_defs_glib.cc: Add get_defs(G_TYPE_BINDING).
    * tools/m4/convert_glib.m4: Add conversion for BindingFlags.
    * tools/generate_wrap_init.pl.in: Define GLIBMM_INCLUDED_FROM_WRAP_INIT_CC.
    * glib/src/binding.[hg|ccg]: New files with enum BindingFlags and class Binding.
    * glib/src/glib_signals.defs: New file with info about GBinding's properties.
    Bug #738663.

 .gitignore                                 |    2 +
 glib/glibmm.h                              |    8 +-
 glib/glibmm/objectbase.h                   |    5 +-
 glib/src/binding.ccg                       |  148 ++++++++++
 glib/src/binding.hg                        |  423 ++++++++++++++++++++++++++++
 glib/src/filelist.am                       |    2 +
 glib/src/glib.defs                         |    1 +
 glib/src/glib_signals.defs                 |   78 +++++
 tools/extra_defs_gen/generate_defs_glib.cc |    5 +-
 tools/generate_wrap_init.pl.in             |    3 +-
 tools/m4/convert_glib.m4                   |    1 +
 11 files changed, 668 insertions(+), 8 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 265d489..dc64b96 100644
--- a/.gitignore
+++ b/.gitignore
@@ -97,6 +97,8 @@ giommconfig.h
 /glib/glibmm-*.pc
 /glib/glibmm/balancedtree.cc
 /glib/glibmm/balancedtree.h
+/glib/glibmm/binding.cc
+/glib/glibmm/binding.h
 /glib/glibmm/bytearray.cc
 /glib/glibmm/bytearray.h
 /glib/glibmm/bytes.cc
diff --git a/glib/glibmm.h b/glib/glibmm.h
index 296db7b..fb409f8 100644
--- a/glib/glibmm.h
+++ b/glib/glibmm.h
@@ -82,8 +82,8 @@
 #include <glibmmconfig.h>
 //#include <glibmm/i18n.h> //This must be included by the application, after system headers such as 
<iostream>.
 
-//Include this first because we need it to be the first thing to include <glib.h>, 
-//so we can do an undef trick to still use deprecated API in the header: 
+//Include this first because we need it to be the first thing to include <glib.h>,
+//so we can do an undef trick to still use deprecated API in the header:
 #include <glibmm/thread.h>
 
 #include <glibmm/threads.h>
@@ -91,6 +91,10 @@
 #include <glibmm/arrayhandle.h>
 #include <glibmm/balancedtree.h>
 #include <glibmm/base64.h>
+#ifndef GLIBMM_INCLUDED_FROM_WRAP_INIT_CC
+// wrap_init.cc includes this file after it has cleared G_GNUC_CONST.
+#include <glibmm/binding.h>
+#endif
 #include <glibmm/bytearray.h>
 #include <glibmm/bytes.h>
 #include <glibmm/checksum.h>
diff --git a/glib/glibmm/objectbase.h b/glib/glibmm/objectbase.h
index 9c4c4e8..a3afd83 100644
--- a/glib/glibmm/objectbase.h
+++ b/glib/glibmm/objectbase.h
@@ -1,4 +1,3 @@
-// -*- c++ -*-
 #ifndef _GLIBMM_OBJECTBASE_H
 #define _GLIBMM_OBJECTBASE_H
 
@@ -144,7 +143,9 @@ public:
    */
   void thaw_notify();
 
-  //TODO: Why are these virtual?
+  // Why are these virtual?
+  // Don't know why they were originally made virtual, but it came in handy when
+  // I wrapped GBinding in Glib::Binding. /Kjell
   /** Increment the reference count for this object.
    * You should never need to do this manually - use the object via a RefPtr instead.
    */
diff --git a/glib/src/binding.ccg b/glib/src/binding.ccg
new file mode 100644
index 0000000..c9e839b
--- /dev/null
+++ b/glib/src/binding.ccg
@@ -0,0 +1,148 @@
+/* Copyright (C) 2014 The glibmm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glibmm/binding.h>
+#include <glib.h>
+
+namespace
+{
+struct BindingTransformSlots
+{
+  BindingTransformSlots(
+    const Glib::Binding::BindingTransformSlot& transform_to,
+    const Glib::Binding::BindingTransformSlot& transform_from)
+  :
+  from_source_to_target(transform_to), from_target_to_source(transform_from)
+  {}
+
+  Glib::Binding::BindingTransformSlot from_source_to_target;
+  Glib::Binding::BindingTransformSlot from_target_to_source;
+};
+
+gboolean Binding_transform_callback_common(GBinding* binding,
+  const GValue* from_value, GValue* to_value,
+  Glib::Binding::BindingTransformSlot& the_slot)
+{
+  bool result = false;
+  try
+  {
+    Glib::RefPtr<Glib::Binding> cpp_binding = Glib::wrap(binding, true);
+    result = the_slot(cpp_binding, from_value, to_value);
+  }
+  catch (...)
+  {
+    Glib::exception_handlers_invoke();
+  }
+  return result;
+}
+
+gboolean Binding_transform_to_callback(GBinding* binding,
+  const GValue* from_value, GValue* to_value, gpointer user_data)
+{
+  Glib::Binding::BindingTransformSlot& the_slot =
+    static_cast<BindingTransformSlots*>(user_data)->from_source_to_target;
+
+  return Binding_transform_callback_common(binding, from_value, to_value, the_slot);
+}
+
+gboolean Binding_transform_from_callback(GBinding* binding,
+  const GValue* from_value, GValue* to_value, gpointer user_data)
+{
+  Glib::Binding::BindingTransformSlot& the_slot =
+    static_cast<BindingTransformSlots*>(user_data)->from_target_to_source;
+
+  return Binding_transform_callback_common(binding, from_value, to_value, the_slot);
+}
+
+void Binding_transform_callback_destroy(gpointer user_data)
+{
+  delete static_cast<BindingTransformSlots*>(user_data);
+}
+
+} // anonymous namespace
+
+namespace Glib
+{
+//static
+Glib::RefPtr<Binding> Binding::bind_property_value(
+  const PropertyProxy_Base& source_property,
+  const PropertyProxy_Base& target_property,
+  BindingFlags flags,
+  const BindingTransformSlot& transform_to,
+  const BindingTransformSlot& transform_from)
+{
+  GBinding* binding = 0;
+  if (transform_to.empty() && transform_from.empty())
+  {
+    // No user-supplied transformations.
+    binding = g_object_bind_property(
+      source_property.get_object()->gobj(), source_property.get_name(),
+      target_property.get_object()->gobj(), target_property.get_name(),
+      (GBindingFlags)flags);
+  }
+  else
+  {
+    // Create copies of the slots. A pointer to this will be passed
+    // through the callback's data parameter. It will be deleted
+    // when Binding_transform_callback_destroy() is called.
+    BindingTransformSlots* slots_copy = new BindingTransformSlots(transform_to, transform_from);
+
+    binding = g_object_bind_property_full(
+      source_property.get_object()->gobj(), source_property.get_name(),
+      target_property.get_object()->gobj(), target_property.get_name(),
+      (GBindingFlags)flags,
+      transform_to.empty() ? 0 : &Binding_transform_to_callback,
+      transform_from.empty() ? 0 : &Binding_transform_from_callback,
+      slots_copy, &Binding_transform_callback_destroy);
+  }
+
+  if (!binding)
+    return Glib::RefPtr<Binding>();
+
+  // Take an extra ref. GBinding uses one ref itself, and drops it if
+  // either the source object or the target object is finalized.
+  // The GBinding object must not be destroyed while there are RefPtrs around.
+  g_object_ref(binding);
+  return Glib::RefPtr<Binding>(new Binding(binding));
+}
+
+void Binding::unbind()
+{
+  // Call g_binding_unbind() only once. It always calls g_object_unref().
+  if (g_binding_get_source(gobj()))
+    g_binding_unbind(gobj());
+}
+
+// Override unreference() from ObjectBase.
+//
+// Why is this necessary? Because GBinding is an unusual kind of GObject.
+// It calls g_object_unref() itself, if either the source object or the
+// target object is finalized, almost like g_binding_unbind().
+// But the GBinding object shall be destroyed when and only when the last
+// reference from a Glib::RefPtr is dropped.
+void Binding::unreference() const
+{
+  GBinding* const binding = const_cast<GBinding*>(gobj());
+
+  // If the last Glib::RefPtr is being deleted, and the binding has not been unbound,
+  // then drop the extra reference that was added by bind_property_value().
+  if (gobject_->ref_count == 2 && g_binding_get_source(binding))
+    g_object_unref(binding);
+
+  Object::unreference();
+}
+
+} // namespace Glib
diff --git a/glib/src/binding.hg b/glib/src/binding.hg
new file mode 100644
index 0000000..f776037
--- /dev/null
+++ b/glib/src/binding.hg
@@ -0,0 +1,423 @@
+/* Copyright (C) 2014 The glibmm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glibmm/object.h>
+#include <glibmm/refptr.h>
+#include <glibmm/ustring.h>
+#include <glibmm/value.h>
+
+_DEFS(glibmm,glib)
+_PINCLUDE(glibmm/private/object_p.h)
+
+namespace Glib
+{
+_WRAP_ENUM(BindingFlags, GBindingFlags)
+
+/** Bind two object properties.
+ *
+ * Glib::Binding is the representation of a binding between a property on a
+ * Glib::ObjectBase instance (or source) and another property on another Glib::ObjectBase
+ * instance (or target). Whenever the source property changes, the same
+ * value is applied to the target property; for instance, the following binding:
+ *
+ * @code
+ * Glib::Binding::bind_property(object1->property_a(), object2->property_b());
+ * @endcode
+ *
+ * will cause property_b() of @a object2 to be updated
+ * every time the value of property_a() of @a object1 changes.
+ *
+ * It is possible to create a bidirectional binding between two properties
+ * of two Glib::ObjectBase instances, so that if either property changes, the
+ * other is updated as well, for instance:
+ *
+ * @code
+ * Glib::Binding::bind_property(object1->property_a(), object2->property_b(),
+ *   Glib::BINDING_BIDIRECTIONAL);
+ * @endcode
+ *
+ * will keep the two properties in sync.
+ *
+ * It is also possible to set a custom transformation function (in both
+ * directions, in case of a bidirectional binding) to apply a custom
+ * transformation from the source value to the target value before
+ * applying it; for instance, the following binding:
+ *
+ * @code
+ * bool celsius_to_fahrenheit(const Glib::RefPtr<Glib::Binding>& binding,
+ *                            const double& celsius, double& fahrenheit);
+ * bool fahrenheit_to_celsius(const Glib::RefPtr<Glib::Binding>& binding,
+ *                            const double& fahrenheit, double& celsius);
+ * Glib::Binding::bind_property(adjustment1->property_value(),
+ *   adjustment2->property_value(), Glib::BINDING_BIDIRECTIONAL,
+ *   sigc::ptr_fun(celsius_to_fahrenheit), sigc::ptr_fun(fahrenheit_to_celsius));
+ * @endcode
+ *
+ * will keep property_value() of the two adjustments in sync; the
+ * celsius_to_fahrenheit() function will be called whenever
+ * property_value() of @a adjustment1 changes and will transform the current value
+ * of the property before applying it to property_value() of @a adjustment2.
+ *
+ * Vice versa, the fahrenheit_to_celsius() function will be called whenever
+ * property_value() of @a adjustment2 changes, and will transform the
+ * current value of the property before applying it to property_value()
+ * of @a adjustment1.
+ *
+ * Note that Glib::Binding does not resolve cycles by itself; a cycle like
+ *
+ * @code
+ *   object1->property_A() -> object2->property_B()
+ *   object2->property_B() -> object3->property_C()
+ *   object3->property_C() -> object1->property_A()
+ * @endcode
+ *
+ * might lead to an infinite loop. The loop, in this particular case,
+ * can be avoided if the objects emit the GObject::notify signal only
+ * if the value has effectively been changed. A binding is implemented
+ * using the GObject::notify signal, so it is susceptible to all the
+ * various ways of blocking a signal emission, like Glib::SignalProxyNormal::emission_stop()
+ * or g_signal_handler_block().
+ *
+ * A binding will be severed, and the resources it allocates freed, whenever
+ * either one of the Glib::ObjectBase instances it refers to is deleted,
+ * when unbind() is called, or when the Glib::Binding instance loses
+ * its last reference.
+ *
+ * @newin{2,44}
+ */
+class Binding : public Glib::Object
+{
+  _CLASS_GOBJECT(Binding, GBinding, G_BINDING, Glib::Object, GObject)
+
+public:
+  /** For instance,<br>
+   *   bool on_transform_to(const Glib::RefPtr<Binding>& binding, const GValue* from_value, GValue* 
to_value);
+   *
+   * @return <tt>true</tt> if the transformation was successful, and <tt>false</tt> otherwise.
+   */
+  typedef sigc::slot<bool, const Glib::RefPtr<Binding>&, const GValue*, GValue*> BindingTransformSlot;
+
+  /** Creates a binding between @a source_property and @a target_property,
+   * allowing you to set the transformation functions to be used by the binding.
+   *
+   * If @a flags contains Glib::BINDING_BIDIRECTIONAL then the binding will be mutual:
+   * if @a target_property changes then the @a source_property
+   * will be updated as well. The @a transform_from function is only used in case
+   * of bidirectional bindings, otherwise it will be ignored.
+   *
+   * The binding will automatically be removed when either the source or the
+   * target instance is deleted. To remove the binding without affecting the
+   * source and the target you can call unbind() on the returned Binding instance.
+   *
+   * A Glib::ObjectBase instance can have multiple bindings.
+   *
+   * If you supply transformation functions, it is usually easier to use one of the
+   * bind_property() overloads, to avoid the use of GValue in the transformation functions.
+   *
+   * @param source_property The source property to bind.
+   * @param target_property The target property to bind.
+   * @param flags Flags to pass to Binding.
+   * @param transform_to The transformation function from the source to the target,
+   *        or an empty slot to use the default.
+   * @param transform_from The transformation function from the target to the source,
+   *        or an empty slot to use the default.
+   * @return The Binding instance representing the binding between the two
+   *         Glib::ObjectBase instances, or <tt>0</tt> in case of error.
+   *
+   * @newin{2,44}
+   */
+  static Glib::RefPtr<Binding> bind_property_value(
+    const PropertyProxy_Base& source_property,
+    const PropertyProxy_Base& target_property,
+    BindingFlags flags = BINDING_DEFAULT,
+    const BindingTransformSlot& transform_to = BindingTransformSlot(),
+    const BindingTransformSlot& transform_from = BindingTransformSlot());
+
+  _IGNORE(g_object_bind_property, g_object_bind_property_full, g_object_bind_property_with_closures)
+
+  /** Creates a binding between @a source_property and @a target_property.
+   *
+   * @param source_property The source property to bind.
+   * @param target_property The target property to bind.
+   * @param flags Flags to pass to Binding.
+   * @return The Binding instance representing the binding between the two
+   *         Glib::ObjectBase instances, or <tt>0</tt> in case of error.
+   *
+   * @see bind_property_value()
+   *
+   * @newin{2,44}
+   */
+  static Glib::RefPtr<Binding> bind_property(
+    const PropertyProxy_Base& source_property,
+    const PropertyProxy_Base& target_property,
+    BindingFlags flags = BINDING_DEFAULT)
+  {
+    return bind_property_value(source_property, target_property, flags);
+  }
+
+  /** Creates a binding between @a source_property and @a target_property,
+   * allowing you to set a transformation function to be used by the binding.
+   *
+   * @param source_property The source property to bind.
+   * @param target_property The target property to bind.
+   * @param flags Flags to pass to Binding.
+   * @param transform_to The transformation function from the source to the target,
+   *        or an empty slot to use the default.
+   * @return The Binding instance representing the binding between the two
+   *         Glib::ObjectBase instances, or <tt>0</tt> in case of error.
+   *
+   * @tparam T_source Type of the source property. Must be a type that can be
+   *         stored in a Glib::Value<T_source> object.
+   * @tparam T_target Type of the target property. Must be a type that can be
+   *         stored in a Glib::Value<T_target> object.
+   * @tparam T_functor_to Type of functor that translates from the source to the target.
+   *         Must be convertible to<br>
+   *         sigc::slot<bool, const Glib::RefPtr<Binding>&, const T_source&, T_target&>.
+   *
+   * @see bind_property_value()
+   *
+   * @newin{2,44}
+   */
+  template <typename T_source, typename T_target, typename T_functor_to>
+  static Glib::RefPtr<Binding> bind_property(
+    const PropertyProxy<T_source>& source_property,
+    const PropertyProxy<T_target>& target_property,
+    BindingFlags flags,
+    const T_functor_to& transform_to)
+  {
+    sigc::slot<bool, const Glib::RefPtr<Binding>&, const T_source&, T_target&> slot_transform_to = 
transform_to;
+
+    return bind_property_value(source_property, target_property, flags,
+      slot_transform_to.empty() ? BindingTransformSlot() : TransformProp<T_source, 
T_target>(slot_transform_to));
+  }
+
+  /** Creates a binding between @a source_property and @a target_property,
+   * allowing you to set a transformation function to be used by the binding.
+   *
+   * @param source_property The source property to bind.
+   * @param target_property The target property to bind.
+   * @param flags Flags to pass to Binding.
+   * @param transform_to The transformation function from the source to the target,
+   *        or an empty slot to use the default.
+   * @return The Binding instance representing the binding between the two
+   *         Glib::ObjectBase instances, or <tt>0</tt> in case of error.
+   *
+   * @tparam T_source Type of the source property. Must be a type that can be
+   *         stored in a Glib::Value<T_source> object.
+   * @tparam T_target Type of the target property. Must be a type that can be
+   *         stored in a Glib::Value<T_target> object.
+   * @tparam T_functor_to Type of functor that translates from the source to the target.
+   *         Must be convertible to<br>
+   *         sigc::slot<bool, const Glib::RefPtr<Binding>&, const T_source&, T_target&>.
+   *
+   * @see bind_property_value()
+   *
+   * @newin{2,44}
+   */
+  template <typename T_source, typename T_target, typename T_functor_to>
+  static Glib::RefPtr<Binding> bind_property(
+    const PropertyProxy<T_source>& source_property,
+    const PropertyProxy_WriteOnly<T_target>& target_property,
+    BindingFlags flags,
+    const T_functor_to& transform_to)
+  {
+    sigc::slot<bool, const Glib::RefPtr<Binding>&, const T_source&, T_target&> slot_transform_to = 
transform_to;
+
+    return bind_property_value(source_property, target_property, flags,
+      slot_transform_to.empty() ? BindingTransformSlot() : TransformProp<T_source, 
T_target>(slot_transform_to));
+  }
+
+  /** Creates a binding between @a source_property and @a target_property,
+   * allowing you to set a transformation function to be used by the binding.
+   *
+   * @param source_property The source property to bind.
+   * @param target_property The target property to bind.
+   * @param flags Flags to pass to Binding.
+   * @param transform_to The transformation function from the source to the target,
+   *        or an empty slot to use the default.
+   * @return The Binding instance representing the binding between the two
+   *         Glib::ObjectBase instances, or <tt>0</tt> in case of error.
+   *
+   * @tparam T_source Type of the source property. Must be a type that can be
+   *         stored in a Glib::Value<T_source> object.
+   * @tparam T_target Type of the target property. Must be a type that can be
+   *         stored in a Glib::Value<T_target> object.
+   * @tparam T_functor_to Type of functor that translates from the source to the target.
+   *         Must be convertible to<br>
+   *         sigc::slot<bool, const Glib::RefPtr<Binding>&, const T_source&, T_target&>.
+   *
+   * @see bind_property_value()
+   *
+   * @newin{2,44}
+   */
+  template <typename T_source, typename T_target, typename T_functor_to>
+  static Glib::RefPtr<Binding> bind_property(
+    const PropertyProxy_ReadOnly<T_source>& source_property,
+    const PropertyProxy<T_target>& target_property,
+    BindingFlags flags,
+    const T_functor_to& transform_to)
+  {
+    sigc::slot<bool, const Glib::RefPtr<Binding>&, const T_source&, T_target&> slot_transform_to = 
transform_to;
+
+    return bind_property_value(source_property, target_property, flags,
+      slot_transform_to.empty() ? BindingTransformSlot() : TransformProp<T_source, 
T_target>(slot_transform_to));
+  }
+
+  /** Creates a binding between @a source_property and @a target_property,
+   * allowing you to set a transformation function to be used by the binding.
+   *
+   * @param source_property The source property to bind.
+   * @param target_property The target property to bind.
+   * @param flags Flags to pass to Binding.
+   * @param transform_to The transformation function from the source to the target,
+   *        or an empty slot to use the default.
+   * @return The Binding instance representing the binding between the two
+   *         Glib::ObjectBase instances, or <tt>0</tt> in case of error.
+   *
+   * @tparam T_source Type of the source property. Must be a type that can be
+   *         stored in a Glib::Value<T_source> object.
+   * @tparam T_target Type of the target property. Must be a type that can be
+   *         stored in a Glib::Value<T_target> object.
+   * @tparam T_functor_to Type of functor that translates from the source to the target.
+   *         Must be convertible to<br>
+   *         sigc::slot<bool, const Glib::RefPtr<Binding>&, const T_source&, T_target&>.
+   *
+   * @see bind_property_value()
+   *
+   * @newin{2,44}
+   */
+  template <typename T_source, typename T_target, typename T_functor_to>
+  static Glib::RefPtr<Binding> bind_property(
+    const PropertyProxy_ReadOnly<T_source>& source_property,
+    const PropertyProxy_WriteOnly<T_target>& target_property,
+    BindingFlags flags,
+    const T_functor_to& transform_to)
+  {
+    sigc::slot<bool, const Glib::RefPtr<Binding>&, const T_source&, T_target&> slot_transform_to = 
transform_to;
+
+    return bind_property_value(source_property, target_property, flags,
+      slot_transform_to.empty() ? BindingTransformSlot() : TransformProp<T_source, 
T_target>(slot_transform_to));
+  }
+
+  /** Creates a binding between @a source_property and @a target_property,
+   * allowing you to set the transformation functions to be used by the binding.
+   *
+   * @param source_property The source property to bind.
+   * @param target_property The target property to bind.
+   * @param flags Flags to pass to Binding.
+   * @param transform_to The transformation function from the source to the target,
+   *        or an empty slot to use the default.
+   * @param transform_from The transformation function from the target to the source,
+   *        or an empty slot to use the default.
+   * @return The Binding instance representing the binding between the two
+   *         Glib::ObjectBase instances, or <tt>0</tt> in case of error.
+   *
+   * @tparam T_source Type of the source property. Must be a type that can be
+   *         stored in a Glib::Value<T_source> object.
+   * @tparam T_target Type of the target property. Must be a type that can be
+   *         stored in a Glib::Value<T_target> object.
+   * @tparam T_functor_to Type of functor that translates from the source to the target.
+   *         Must be convertible to<br>
+   *         sigc::slot<bool, const Glib::RefPtr<Binding>&, const T_source&, T_target&>.
+   * @tparam T_functor_from Type of functor that translates from the target to the source.
+   *         Must be convertible to<br>
+   *         sigc::slot<bool, const Glib::RefPtr<Binding>&, const T_target&, T_source&>.
+   *
+   * @see bind_property_value()
+   *
+   * @newin{2,44}
+   */
+  template <typename T_source, typename T_target, typename T_functor_to, typename T_functor_from>
+  static Glib::RefPtr<Binding> bind_property(
+    const PropertyProxy<T_source>& source_property,
+    const PropertyProxy<T_target>& target_property,
+    BindingFlags flags,
+    const T_functor_to& transform_to,
+    const T_functor_from& transform_from)
+  {
+    sigc::slot<bool, const Glib::RefPtr<Binding>&, const T_source&, T_target&> slot_transform_to = 
transform_to;
+    sigc::slot<bool, const Glib::RefPtr<Binding>&, const T_target&, T_source&> slot_transform_from = 
transform_from;
+
+    return bind_property_value(source_property, target_property, flags,
+      slot_transform_to.empty() ? BindingTransformSlot() : TransformProp<T_source, 
T_target>(slot_transform_to),
+      slot_transform_from.empty() ? BindingTransformSlot() : TransformProp<T_target, 
T_source>(slot_transform_from));
+  }
+
+  _WRAP_METHOD(Glib::RefPtr<Glib::ObjectBase> get_source(), g_binding_get_source, refreturn)
+  _WRAP_METHOD(Glib::RefPtr<const Glib::ObjectBase> get_source() const, g_binding_get_source, refreturn, 
constversion)
+  _WRAP_METHOD(Glib::ustring get_source_property() const, g_binding_get_source_property)
+  _WRAP_METHOD(Glib::RefPtr<Glib::ObjectBase> get_target(), g_binding_get_target, refreturn)
+  _WRAP_METHOD(Glib::RefPtr<const Glib::ObjectBase> get_target() const, g_binding_get_target, refreturn, 
constversion)
+  _WRAP_METHOD(Glib::ustring get_target_property() const, g_binding_get_target_property)
+  _WRAP_METHOD(BindingFlags get_flags() const, g_binding_get_flags)
+
+  /** Explicitly releases the binding between the source and the target
+   * property expressed by this Binding instance.
+   *
+   * The binding is also released if either the source object or the target
+   * object is deleted, or this Binding instance loses its last reference,
+   * i.e. there is no more Glib::RefPtr that holds a pointer to it.
+   *
+   * @newin{2,44}
+   */
+  void unbind();
+  _IGNORE(g_binding_unbind)
+
+  _WRAP_PROPERTY("flags", Glib::BindingFlags)
+  _WRAP_PROPERTY("source", Glib::RefPtr<Glib::ObjectBase>)
+  _WRAP_PROPERTY("source-property", Glib::ustring)
+  _WRAP_PROPERTY("target", Glib::RefPtr<Glib::ObjectBase>)
+  _WRAP_PROPERTY("target-property", Glib::ustring)
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+  /** Decrement the reference count for this object.
+   * You should never need to do this manually - use the object via a RefPtr instead.
+   */
+  virtual void unreference() const;
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+private:
+  // The functor TransformProp can be implicitly converted to a BindingTransformSlot
+  // and used in a call to bind_property_value().
+  template <typename T_from, typename T_to>
+  class TransformProp : public sigc::functor_base
+  {
+  public:
+    typedef bool result_type;
+    typedef sigc::slot<bool, const Glib::RefPtr<Binding>&, const T_from&, T_to&> TypedBindingTransformSlot;
+
+    TransformProp(const TypedBindingTransformSlot& slot) : typed_transform(slot) {}
+
+    bool operator()(const Glib::RefPtr<Binding>& binding, const GValue* from_value, GValue* to_value)
+    {
+      Glib::Value<T_from> from_glib_value;
+      from_glib_value.init(from_value);
+      Glib::Value<T_to> to_glib_value;
+      to_glib_value.init(to_value);
+      T_to to = to_glib_value.get();
+
+      const bool result = typed_transform(binding, from_glib_value.get(), to);
+      to_glib_value.set(to);
+      g_value_copy(to_glib_value.gobj(), to_value);
+      return result;
+    }
+
+  private:
+    TypedBindingTransformSlot typed_transform;
+  };
+};
+
+} // namespace Glib
diff --git a/glib/src/filelist.am b/glib/src/filelist.am
index d240146..c66e01b 100644
--- a/glib/src/filelist.am
+++ b/glib/src/filelist.am
@@ -6,6 +6,7 @@ glibmm_files_defs =             \
        glib_deprecated_enums.defs      \
        glib_functions.defs     \
        glib_extra_objects.defs \
+       glib_signals.defs       \
        gmodule_enums.defs      \
        gmodule_functions.defs  \
        gobject.defs            \
@@ -16,6 +17,7 @@ glibmm_files_defs =           \
 
 glibmm_files_any_hg =          \
        balancedtree.hg         \
+       binding.hg              \
        bytes.hg                \
        bytearray.hg            \
        checksum.hg             \
diff --git a/glib/src/glib.defs b/glib/src/glib.defs
index 1823191..e106d6b 100644
--- a/glib/src/glib.defs
+++ b/glib/src/glib.defs
@@ -3,6 +3,7 @@
 (include glib_enums.defs)
 (include glib_deprecated_enums.defs)
 (include glib_extra_objects.defs)
+(include glib_signals.defs)
 (include gobject_enums.defs)
 (include gobject_functions.defs)
 (include gmodule_functions.defs)
diff --git a/glib/src/glib_signals.defs b/glib/src/glib_signals.defs
new file mode 100644
index 0000000..d65d39e
--- /dev/null
+++ b/glib/src/glib_signals.defs
@@ -0,0 +1,78 @@
+;; From GBinding
+
+(define-property source
+  (of-object "GBinding")
+  (prop-type "GParamObject")
+  (docs "The source of the binding")
+  (readable #t)
+  (writable #t)
+  (construct-only #t)
+)
+
+(define-property target
+  (of-object "GBinding")
+  (prop-type "GParamObject")
+  (docs "The target of the binding")
+  (readable #t)
+  (writable #t)
+  (construct-only #t)
+)
+
+(define-property source-property
+  (of-object "GBinding")
+  (prop-type "GParamString")
+  (docs "The property on the source to bind")
+  (readable #t)
+  (writable #t)
+  (construct-only #t)
+)
+
+(define-property target-property
+  (of-object "GBinding")
+  (prop-type "GParamString")
+  (docs "The property on the target to bind")
+  (readable #t)
+  (writable #t)
+  (construct-only #t)
+)
+
+(define-property flags
+  (of-object "GBinding")
+  (prop-type "GParamFlags")
+  (docs "The binding flags")
+  (readable #t)
+  (writable #t)
+  (construct-only #t)
+)
+
+;; GBytes is neither a GObject nor a GInterface. Not checked for signals and properties.
+
+;; GChecksum is neither a GObject nor a GInterface. Not checked for signals and properties.
+
+;; GDate is neither a GObject nor a GInterface. Not checked for signals and properties.
+
+;; GDateTime is neither a GObject nor a GInterface. Not checked for signals and properties.
+
+;; GIOChannel is neither a GObject nor a GInterface. Not checked for signals and properties.
+
+;; GKeyFile is neither a GObject nor a GInterface. Not checked for signals and properties.
+
+;; GMainContext is neither a GObject nor a GInterface. Not checked for signals and properties.
+
+;; GMainLoop is neither a GObject nor a GInterface. Not checked for signals and properties.
+
+;; GMatchInfo is neither a GObject nor a GInterface. Not checked for signals and properties.
+
+;; GRegex is neither a GObject nor a GInterface. Not checked for signals and properties.
+
+;; GSource is neither a GObject nor a GInterface. Not checked for signals and properties.
+
+;; GThread is neither a GObject nor a GInterface. Not checked for signals and properties.
+
+;; GVariant is neither a GObject nor a GInterface. Not checked for signals and properties.
+
+;; GVariantBuilder is neither a GObject nor a GInterface. Not checked for signals and properties.
+
+;; GVariantDict is neither a GObject nor a GInterface. Not checked for signals and properties.
+
+
diff --git a/tools/extra_defs_gen/generate_defs_glib.cc b/tools/extra_defs_gen/generate_defs_glib.cc
index 2ead0a0..1e32edb 100644
--- a/tools/extra_defs_gen/generate_defs_glib.cc
+++ b/tools/extra_defs_gen/generate_defs_glib.cc
@@ -1,5 +1,3 @@
-/* $Id$ */
-
 /* generate_defs_gtk.cc
  *
  * Copyright (C) 2001 The Free Software Foundation
@@ -27,7 +25,8 @@ int main()
   // g_type_init() is deprecated as of 2.36.
   // g_type_init();
 
-  std::cout << get_defs( G_TYPE_BYTES )
+  std::cout << get_defs( G_TYPE_BINDING )
+            << get_defs( G_TYPE_BYTES )
             << get_defs( G_TYPE_CHECKSUM )
             << get_defs( G_TYPE_DATE )
             << get_defs( G_TYPE_DATE_TIME )
diff --git a/tools/generate_wrap_init.pl.in b/tools/generate_wrap_init.pl.in
index 59cd654..1381dfe 100644
--- a/tools/generate_wrap_init.pl.in
+++ b/tools/generate_wrap_init.pl.in
@@ -192,7 +192,7 @@ while ($ARGV[0])
     elsif (/\b_NO_WRAP_INIT_REGISTRATION\b/)
     {
       $exclude_from_wrap_init{$filename_header} = 1;
-    } 
+    }
   }
 
   shift @ARGV;
@@ -205,6 +205,7 @@ while ($ARGV[0])
 print << "EOF";
 // Generated by generate_wrap_init.pl -- DO NOT MODIFY!
 
+#define GLIBMM_INCLUDED_FROM_WRAP_INIT_CC
 #include <glibmm.h>
 
 // Disable the 'const' function attribute of the get_type() functions.
diff --git a/tools/m4/convert_glib.m4 b/tools/m4/convert_glib.m4
index f7e768c..0c70cdf 100644
--- a/tools/m4/convert_glib.m4
+++ b/tools/m4/convert_glib.m4
@@ -60,6 +60,7 @@ dnl
 dnl # These are for fixmegtkconst
 _CONVERSION(`const guchar*',`guchar*',`const_cast<guchar*>($3)',`$3')
 
+_CONV_GLIB_ENUM(BindingFlags)
 _CONV_GLIB_ENUM(IOCondition)
 _CONV_GLIB_ENUM(IOFlags)
 _CONV_GLIB_ENUM(IOStatus)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]