=?utf-8?q?=5Bgtk+=5D_Added_new_function_gtk=5Fbuilder=5Fexpose=5Fobject?= =?utf-8?q?=28=29_based_on_the_original_work_by_Marco_Diego_Aur=C3=A9lio_M?= =?utf-8?q?e?=



commit a3e4fa3809e9281f9dc7e10f37e89e86e0fd219a
Author: Juan Pablo Ugarte <juanpablougarte gmail com>
Date:   Mon Dec 10 14:53:53 2012 -0300

    Added new function gtk_builder_expose_object() based on the original work by
    Marco Diego AurÃlio Mesquita on bug #447972

 docs/reference/gtk/gtk3-sections.txt |    1 +
 gtk/gtkbuilder.c                     |   88 ++++++++++++++++++++++++---------
 gtk/gtkbuilder.h                     |    3 +
 gtk/tests/builder.c                  |   51 +++++++++++++++++++
 4 files changed, 119 insertions(+), 24 deletions(-)
---
diff --git a/docs/reference/gtk/gtk3-sections.txt b/docs/reference/gtk/gtk3-sections.txt
index 0cdc991..3d23fd5 100644
--- a/docs/reference/gtk/gtk3-sections.txt
+++ b/docs/reference/gtk/gtk3-sections.txt
@@ -536,6 +536,7 @@ gtk_builder_add_objects_from_string
 gtk_builder_add_objects_from_resource
 gtk_builder_get_object
 gtk_builder_get_objects
+gtk_builder_expose_object
 gtk_builder_connect_signals
 gtk_builder_connect_signals_full
 gtk_builder_set_translation_domain
diff --git a/gtk/gtkbuilder.c b/gtk/gtkbuilder.c
index bf75922..9923bc2 100644
--- a/gtk/gtkbuilder.c
+++ b/gtk/gtkbuilder.c
@@ -123,12 +123,14 @@
  * (can be specified by their name, nick or integer value), flags (can be
  * specified by their name, nick, integer value, optionally combined with "|",
  * e.g. "GTK_VISIBLE|GTK_REALIZED")  and colors (in a format understood by
- * gdk_color_parse()). Objects can be referred to by their name. Pixbufs can be
- * specified as a filename of an image file to load. In general, GtkBuilder
- * allows forward references to objects &mdash; an object doesn't have to be
- * constructed before it can be referred to. The exception to this rule is that
- * an object has to be constructed before it can be used as the value of a
- * construct-only property.
+ * gdk_color_parse()). Pixbufs can be specified as a filename of an image file to load. 
+ * Objects can be referred to by their name and by default refer to objects declared
+ * in the local xml fragment and objects exposed via gtk_builder_expose_object().
+ * 
+ * In general, GtkBuilder allows forward references to objects &mdash declared
+ * in the local xml; an object doesn't have to be constructed before it can be referred to. 
+ * The exception to this rule is that an object has to be constructed before 
+ * it can be used as the value of a construct-only property.
  *
  * Signal handlers are set up with the &lt;signal&gt; element. The "name"
  * attribute specifies the name of the signal, and the "handler" attribute
@@ -574,6 +576,24 @@ gtk_builder_get_internal_child (GtkBuilder  *builder,
   return obj;
 }
 
+static inline void
+object_set_name (GObject *object, const gchar *name)
+{
+  if (GTK_IS_BUILDABLE (object))
+    gtk_buildable_set_name (GTK_BUILDABLE (object), name);
+  else
+    g_object_set_data_full (object, "gtk-builder-name", g_strdup (name), g_free);
+}
+
+void
+_gtk_builder_add_object (GtkBuilder  *builder,
+                         const gchar *id,
+                         GObject     *object)
+{
+  object_set_name (object, id);
+  g_hash_table_insert (builder->priv->objects, g_strdup (id), g_object_ref (object));
+}
+
 GObject *
 _gtk_builder_construct (GtkBuilder *builder,
                         ObjectInfo *info,
@@ -703,30 +723,17 @@ _gtk_builder_construct (GtkBuilder *builder,
       g_value_unset (&param->value);
     }
   g_array_free (parameters, TRUE);
-  
-  if (GTK_IS_BUILDABLE (obj))
-    gtk_buildable_set_name (buildable, info->id);
-  else
-    g_object_set_data_full (obj,
-                            "gtk-builder-name",
-                            g_strdup (info->id),
-                            g_free);
 
-  /* we already own a reference to obj.  put it in the hash table. */
-  g_hash_table_insert (builder->priv->objects, g_strdup (info->id), obj);
+  /* put it in the hash table. */
+  _gtk_builder_add_object (builder, info->id, obj);
+  
+  /* we already own a reference to obj. */ 
+  g_object_unref (obj);
   
   return obj;
 }
 
 void
-_gtk_builder_add_object (GtkBuilder  *builder,
-                         const gchar *id,
-                         GObject     *object)
-{
-  g_hash_table_insert (builder->priv->objects, g_strdup (id), g_object_ref (object));
-}
-
-void
 _gtk_builder_add (GtkBuilder *builder,
                   ChildInfo  *child_info)
 {
@@ -1340,6 +1347,39 @@ gtk_builder_get_translation_domain (GtkBuilder *builder)
   return builder->priv->domain;
 }
 
+/**
+ * gtk_builder_expose_object:
+ * @builder: a #GtkBuilder
+ * @name: the name of the object exposed to the builder
+ * @object: the object to expose
+ *
+ * Add @object to the @builder object pool so it can be referenced just like any
+ * other object built by builder.
+ *
+ * To make this function even more useful a new special entry point element
+ * &lt;external-object&gt; is defined. It is similar to &lt;object&gt; but has 
+ * to reference an external object exposed with this function.
+ * This way you can change properties and even add children to an
+ * external object using builder, not just reference it.
+ * 
+ * Since: 3.8
+ **/
+void
+gtk_builder_expose_object (GtkBuilder    *builder,
+                           const gchar   *name,
+                           GObject       *object)
+{
+  g_return_if_fail (GTK_IS_BUILDER (builder));
+  g_return_if_fail (name && name[0]);
+  g_return_if_fail (gtk_builder_get_object (builder, name) == NULL);
+
+  object_set_name (object, name);
+  g_hash_table_insert (builder->priv->objects,
+                       g_strdup (name),
+                       g_object_ref (object));
+}
+
+
 typedef struct {
   GModule *module;
   gpointer data;
diff --git a/gtk/gtkbuilder.h b/gtk/gtkbuilder.h
index 60b358a..a10359b 100644
--- a/gtk/gtkbuilder.h
+++ b/gtk/gtkbuilder.h
@@ -141,6 +141,9 @@ guint        gtk_builder_add_objects_from_string (GtkBuilder    *builder,
 GObject*     gtk_builder_get_object              (GtkBuilder    *builder,
                                                   const gchar   *name);
 GSList*      gtk_builder_get_objects             (GtkBuilder    *builder);
+void         gtk_builder_expose_object           (GtkBuilder    *builder,
+                                                  const gchar   *name,
+                                                  GObject       *object);
 void         gtk_builder_connect_signals         (GtkBuilder    *builder,
 						  gpointer       user_data);
 void         gtk_builder_connect_signals_full    (GtkBuilder    *builder,
diff --git a/gtk/tests/builder.c b/gtk/tests/builder.c
index d5a3d1f..5e086a5 100644
--- a/gtk/tests/builder.c
+++ b/gtk/tests/builder.c
@@ -2715,6 +2715,56 @@ test_level_bar (void)
   g_object_unref (builder);
 }
 
+static GObject *external_object = NULL, *external_object_swapped = NULL;
+
+void
+on_button_clicked (GtkButton *button, GObject *data)
+{
+  external_object = data;
+}
+
+void
+on_button_clicked_swapped (GObject *data, GtkButton *button)
+{
+  external_object_swapped = data;
+}
+
+static void
+test_expose_object (void)
+{
+  GtkBuilder *builder;
+  GError *error = NULL;
+  GtkWidget *image;
+  GObject *obj;
+  const gchar buffer[] =
+    "<interface>"
+    "  <object class=\"GtkButton\" id=\"button\">"
+    "    <property name=\"image\">external_image</property>"
+    "    <signal name=\"clicked\" handler=\"on_button_clicked\" object=\"builder\" swapped=\"no\"/>"
+    "    <signal name=\"clicked\" handler=\"on_button_clicked_swapped\" object=\"builder\"/>"
+    "  </object>"
+    "</interface>";
+
+  image = gtk_image_new ();
+  builder = gtk_builder_new ();
+  gtk_builder_expose_object (builder, "external_image", G_OBJECT (image));
+  gtk_builder_expose_object (builder, "builder", G_OBJECT (builder));
+  gtk_builder_add_from_string (builder, buffer, -1, &error);
+  g_assert (error == NULL);
+
+  obj = gtk_builder_get_object (builder, "button");
+  g_assert (GTK_IS_BUTTON (obj));
+
+  g_assert (gtk_button_get_image (GTK_BUTTON (obj)) == image);
+
+  /* Connect signals and fake clicked event */
+  gtk_builder_connect_signals (builder, NULL);
+  gtk_button_clicked (GTK_BUTTON (obj));
+
+  g_assert (external_object == G_OBJECT (builder));
+  g_assert (external_object_swapped == G_OBJECT (builder));
+}
+
 int
 main (int argc, char **argv)
 {
@@ -2763,6 +2813,7 @@ main (int argc, char **argv)
   g_test_add_func ("/Builder/MessageDialog", test_message_dialog);
   g_test_add_func ("/Builder/GMenu", test_gmenu);
   g_test_add_func ("/Builder/LevelBar", test_level_bar);
+  g_test_add_func ("/Builder/Expose Object", test_expose_object);
 
   return g_test_run();
 }



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