Added new function gtk_builder_expose_object() based on the original work by
Marco Diego Aurélio Mesquita on bug #447972
This commit is contained in:
@ -536,6 +536,7 @@ gtk_builder_add_objects_from_string
|
|||||||
gtk_builder_add_objects_from_resource
|
gtk_builder_add_objects_from_resource
|
||||||
gtk_builder_get_object
|
gtk_builder_get_object
|
||||||
gtk_builder_get_objects
|
gtk_builder_get_objects
|
||||||
|
gtk_builder_expose_object
|
||||||
gtk_builder_connect_signals
|
gtk_builder_connect_signals
|
||||||
gtk_builder_connect_signals_full
|
gtk_builder_connect_signals_full
|
||||||
gtk_builder_set_translation_domain
|
gtk_builder_set_translation_domain
|
||||||
|
|||||||
@ -123,12 +123,14 @@
|
|||||||
* (can be specified by their name, nick or integer value), flags (can be
|
* (can be specified by their name, nick or integer value), flags (can be
|
||||||
* specified by their name, nick, integer value, optionally combined with "|",
|
* specified by their name, nick, integer value, optionally combined with "|",
|
||||||
* e.g. "GTK_VISIBLE|GTK_REALIZED") and colors (in a format understood by
|
* 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
|
* gdk_color_parse()). Pixbufs can be specified as a filename of an image file to load.
|
||||||
* specified as a filename of an image file to load. In general, GtkBuilder
|
* Objects can be referred to by their name and by default refer to objects declared
|
||||||
* allows forward references to objects — an object doesn't have to be
|
* in the local xml fragment and objects exposed via gtk_builder_expose_object().
|
||||||
* 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
|
* In general, GtkBuilder allows forward references to objects &mdash declared
|
||||||
* construct-only property.
|
* 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 <signal> element. The "name"
|
* Signal handlers are set up with the <signal> element. The "name"
|
||||||
* attribute specifies the name of the signal, and the "handler" attribute
|
* attribute specifies the name of the signal, and the "handler" attribute
|
||||||
@ -574,6 +576,24 @@ gtk_builder_get_internal_child (GtkBuilder *builder,
|
|||||||
return obj;
|
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 *
|
GObject *
|
||||||
_gtk_builder_construct (GtkBuilder *builder,
|
_gtk_builder_construct (GtkBuilder *builder,
|
||||||
ObjectInfo *info,
|
ObjectInfo *info,
|
||||||
@ -703,29 +723,16 @@ _gtk_builder_construct (GtkBuilder *builder,
|
|||||||
g_value_unset (¶m->value);
|
g_value_unset (¶m->value);
|
||||||
}
|
}
|
||||||
g_array_free (parameters, TRUE);
|
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. */
|
/* put it in the hash table. */
|
||||||
g_hash_table_insert (builder->priv->objects, g_strdup (info->id), obj);
|
_gtk_builder_add_object (builder, info->id, obj);
|
||||||
|
|
||||||
|
/* we already own a reference to obj. */
|
||||||
|
g_object_unref (obj);
|
||||||
|
|
||||||
return 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
|
void
|
||||||
_gtk_builder_add (GtkBuilder *builder,
|
_gtk_builder_add (GtkBuilder *builder,
|
||||||
ChildInfo *child_info)
|
ChildInfo *child_info)
|
||||||
@ -1340,6 +1347,39 @@ gtk_builder_get_translation_domain (GtkBuilder *builder)
|
|||||||
return builder->priv->domain;
|
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
|
||||||
|
* <external-object> is defined. It is similar to <object> 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 {
|
typedef struct {
|
||||||
GModule *module;
|
GModule *module;
|
||||||
gpointer data;
|
gpointer data;
|
||||||
|
|||||||
@ -141,6 +141,9 @@ guint gtk_builder_add_objects_from_string (GtkBuilder *builder,
|
|||||||
GObject* gtk_builder_get_object (GtkBuilder *builder,
|
GObject* gtk_builder_get_object (GtkBuilder *builder,
|
||||||
const gchar *name);
|
const gchar *name);
|
||||||
GSList* gtk_builder_get_objects (GtkBuilder *builder);
|
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,
|
void gtk_builder_connect_signals (GtkBuilder *builder,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
void gtk_builder_connect_signals_full (GtkBuilder *builder,
|
void gtk_builder_connect_signals_full (GtkBuilder *builder,
|
||||||
|
|||||||
@ -2715,6 +2715,56 @@ test_level_bar (void)
|
|||||||
g_object_unref (builder);
|
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
|
int
|
||||||
main (int argc, char **argv)
|
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/MessageDialog", test_message_dialog);
|
||||||
g_test_add_func ("/Builder/GMenu", test_gmenu);
|
g_test_add_func ("/Builder/GMenu", test_gmenu);
|
||||||
g_test_add_func ("/Builder/LevelBar", test_level_bar);
|
g_test_add_func ("/Builder/LevelBar", test_level_bar);
|
||||||
|
g_test_add_func ("/Builder/Expose Object", test_expose_object);
|
||||||
|
|
||||||
return g_test_run();
|
return g_test_run();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user