[glib] binding: Add SYNC_CREATE to the flags



commit f587cb57f249a8f4b869231ca20f5f19602a20ec
Author: Emmanuele Bassi <ebassi linux intel com>
Date:   Mon Jun 21 12:26:42 2010 +0100

    binding: Add SYNC_CREATE to the flags
    
    When creating a binding between two object properties we might want to
    automatically synchronize the two values at the moment of the binding
    creation, instead of waiting for the next change.
    
    The G_BINDING_SYNC_CREATE flag does exactly what it says on the tin.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=622281

 gobject/gbinding.c      |    9 +++++++++
 gobject/gbinding.h      |    6 +++++-
 gobject/tests/binding.c |   36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 50 insertions(+), 1 deletions(-)
---
diff --git a/gobject/gbinding.c b/gobject/gbinding.c
index 628ede9..8bb91a8 100644
--- a/gobject/gbinding.c
+++ b/gobject/gbinding.c
@@ -124,6 +124,7 @@ g_binding_flags_get_type (void)
       static const GFlagsValue values[] = {
         { G_BINDING_DEFAULT, "G_BINDING_DEFAULT", "default" },
         { G_BINDING_BIDIRECTIONAL, "G_BINDING_BIDIRECTIONAL", "bidirectional" },
+        { G_BINDING_SYNC_CREATE, "G_BINDING_SYNC_CREATE", "sync-create" },
         { 0, NULL, NULL }
       };
       GType g_define_type_id =
@@ -893,6 +894,14 @@ g_object_bind_property_full (gpointer               source,
   binding->transform_data = user_data;
   binding->notify = notify;
 
+  /* synchronize the target with the source by faking an emission of
+   * the ::notify signal for the source property; this will also take
+   * care of the bidirectional binding case because the eventual change
+   * will emit a notification on the target
+   */
+  if (flags & G_BINDING_SYNC_CREATE)
+    on_source_notify (binding->source, binding->source_pspec, binding);
+
   return binding;
 }
 
diff --git a/gobject/gbinding.h b/gobject/gbinding.h
index 90dac60..6a5cc0f 100644
--- a/gobject/gbinding.h
+++ b/gobject/gbinding.h
@@ -76,6 +76,9 @@ typedef gboolean (* GBindingTransformFunc) (GBinding     *binding,
  * @G_BINDING_BIDIRECTIONAL: Bidirectional binding; if either the
  *   property of the source or the property of the target changes,
  *   the other is updated
+ * @G_BINDING_SYNC_CREATE: Synchronize the values of the source and
+ *   target properties when creating the binding; the direction of
+ *   the synchronization is always from the source to the target
  *
  * Flags to be passed to g_object_bind_property() or
  * g_object_bind_property_full().
@@ -87,7 +90,8 @@ typedef gboolean (* GBindingTransformFunc) (GBinding     *binding,
 typedef enum { /*< prefix=G_BINDING >*/
   G_BINDING_DEFAULT       = 0,
 
-  G_BINDING_BIDIRECTIONAL = 1 << 0
+  G_BINDING_BIDIRECTIONAL = 1 << 0,
+  G_BINDING_SYNC_CREATE   = 1 << 1
 } GBindingFlags;
 
 GType                 g_binding_flags_get_type      (void) G_GNUC_CONST;
diff --git a/gobject/tests/binding.c b/gobject/tests/binding.c
index eef4590..c4d4ffe 100644
--- a/gobject/tests/binding.c
+++ b/gobject/tests/binding.c
@@ -346,6 +346,41 @@ binding_chain (void)
   g_object_unref (c);
 }
 
+static void
+binding_sync_create (void)
+{
+  BindingSource *source = g_object_new (binding_source_get_type (),
+                                        "foo", 42,
+                                        NULL);
+  BindingTarget *target = g_object_new (binding_target_get_type (),
+                                        "bar", 47,
+                                        NULL);
+  GBinding *binding;
+
+  binding = g_object_bind_property (source, "foo",
+                                    target, "bar",
+                                    G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
+
+  g_assert_cmpint (source->foo, ==, 42);
+  g_assert_cmpint (target->bar, ==, 42);
+
+  g_object_set (source, "foo", 47, NULL);
+  g_assert_cmpint (source->foo, ==, target->bar);
+
+  g_object_unref (binding);
+
+  g_object_set (target, "bar", 49, NULL);
+
+  binding = g_object_bind_property (source, "foo",
+                                    target, "bar",
+                                    G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+  g_assert_cmpint (source->foo, ==, 47);
+  g_assert_cmpint (target->bar, ==, 47);
+
+  g_object_unref (source);
+  g_object_unref (target);
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -356,6 +391,7 @@ main (int argc, char *argv[])
   g_test_add_func ("/binding/bidirectional", binding_bidirectional);
   g_test_add_func ("/binding/transform", binding_transform);
   g_test_add_func ("/binding/chain", binding_chain);
+  g_test_add_func ("/binding/sync-create", binding_sync_create);
 
   return g_test_run ();
 }



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