[gtk/wip/otte/listview: 139/145] builder: Add gtk_builder_set_current_object()
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/listview: 139/145] builder: Add gtk_builder_set_current_object()
- Date: Mon, 2 Dec 2019 03:25:48 +0000 (UTC)
commit fa8faa8d23cb778b7c5e2edc099f3b635ff4941b
Author: Benjamin Otte <otte redhat com>
Date: Thu Nov 28 04:01:19 2019 +0100
builder: Add gtk_builder_set_current_object()
Use it as the default object for expression binds and when connecting
signals. It is intended to work kind of as the "this" object while
parsing. In fact, the term "current object" was stolen from the Java
docs and various C++ tutorials for the this pointer.
Set the current object in gtk_widget_init_template() and
GtkListItemBuilder.
This more-or-less replaces the object passed to
gtk_builder_connect_signals() in GTK3.
docs/reference/gtk/gtk4-sections.txt | 2 +
gtk/gtkbuilder.c | 95 +++++++++++++++++++++++++++++++++++-
gtk/gtkbuilder.h | 5 ++
gtk/gtkbuilderlistitemfactory.c | 2 +
gtk/gtkwidget.c | 22 +--------
5 files changed, 105 insertions(+), 21 deletions(-)
---
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index b3c3c62291..8c5b7161c9 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -667,6 +667,8 @@ gtk_builder_extend_with_template
gtk_builder_get_object
gtk_builder_get_objects
gtk_builder_expose_object
+gtk_builder_set_current_object
+gtk_builder_get_current_object
gtk_builder_set_translation_domain
gtk_builder_get_translation_domain
gtk_builder_get_type_from_name
diff --git a/gtk/gtkbuilder.c b/gtk/gtkbuilder.c
index 1b8b2a0a41..760b7a4d68 100644
--- a/gtk/gtkbuilder.c
+++ b/gtk/gtkbuilder.c
@@ -254,6 +254,7 @@ static void gtk_builder_get_property (GObject *object,
enum {
PROP_0,
+ PROP_CURRENT_OBJECT,
PROP_TRANSLATION_DOMAIN,
LAST_PROP
};
@@ -282,6 +283,7 @@ typedef struct
gchar *filename;
gchar *resource_prefix;
GType template_type;
+ GObject *current_object;
GtkBuilderClosureFunc closure_func;
gpointer closure_data;
@@ -290,11 +292,22 @@ typedef struct
G_DEFINE_TYPE_WITH_PRIVATE (GtkBuilder, gtk_builder, G_TYPE_OBJECT)
+static void
+gtk_builder_dispose (GObject *object)
+{
+ GtkBuilderPrivate *priv = gtk_builder_get_instance_private (GTK_BUILDER (object));
+
+ g_clear_object (&priv->current_object);
+
+ G_OBJECT_CLASS (gtk_builder_parent_class)->dispose (object);
+}
+
static void
gtk_builder_class_init (GtkBuilderClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->dispose = gtk_builder_dispose;
gobject_class->finalize = gtk_builder_finalize;
gobject_class->set_property = gtk_builder_set_property;
gobject_class->get_property = gtk_builder_get_property;
@@ -314,6 +327,18 @@ gtk_builder_class_init (GtkBuilderClass *klass)
NULL,
GTK_PARAM_READWRITE);
+ /**
+ * GtkBuilder:current-object:
+ *
+ * The object the builder is evaluating for.
+ */
+ builder_props[PROP_CURRENT_OBJECT] =
+ g_param_spec_object ("current-object",
+ P_("Current object"),
+ P_("The object the builder is evaluating for"),
+ G_TYPE_OBJECT,
+ GTK_PARAM_READWRITE);
+
g_object_class_install_properties (gobject_class, LAST_PROP, builder_props);
}
@@ -365,9 +390,14 @@ gtk_builder_set_property (GObject *object,
switch (prop_id)
{
+ case PROP_CURRENT_OBJECT:
+ gtk_builder_set_current_object (builder, g_value_get_object (value));
+ break;
+
case PROP_TRANSLATION_DOMAIN:
gtk_builder_set_translation_domain (builder, g_value_get_string (value));
break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -385,9 +415,14 @@ gtk_builder_get_property (GObject *object,
switch (prop_id)
{
+ case PROP_CURRENT_OBJECT:
+ g_value_set_object (value, priv->current_object);
+ break;
+
case PROP_TRANSLATION_DOMAIN:
g_value_set_string (value, priv->domain);
break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -1103,8 +1138,14 @@ gtk_builder_create_bindings (GtkBuilder *builder,
error = NULL;
result = FALSE;
}
+ else if (priv->current_object)
+ {
+ object = priv->current_object;
+ }
else
- object = info->target;
+ {
+ object = info->target;
+ }
if (object)
{
@@ -1725,6 +1766,54 @@ gtk_builder_expose_object (GtkBuilder *builder,
g_object_ref (object));
}
+/**
+ * gtk_builder_get_current_object:
+ * @self: a #GtkBuilder
+ *
+ * Gets the current object set via gtk_builder_set_current_object().
+ *
+ * Returns: (nullable) (transfer none): the current object
+ **/
+GObject *
+gtk_builder_get_current_object (GtkBuilder *self)
+{
+ GtkBuilderPrivate *priv = gtk_builder_get_instance_private (self);
+
+ g_return_val_if_fail (GTK_IS_BUILDER (self), NULL);
+
+ return priv->current_object;
+}
+
+/**
+ * gtk_builder_set_current_object:
+ * @self: a #GtkBuilder
+ * @current_object: (nullable) (transfer none): the new current object or
+ * %NULL for none
+ *
+ * Sets the current object for the @self. The current object can be
+ * tought of as the `this` object that the builder is working for and
+ * will often be used as the default object when an object is optional.
+ *
+ * gtk_widget_init_template() for example will set the current object to
+ * the widget the template is inited for.
+ * For functions like gtk_builder_new_from_resource(), the current object
+ * will be %NULL.
+ **/
+void
+gtk_builder_set_current_object (GtkBuilder *self,
+ GObject *current_object)
+{
+ GtkBuilderPrivate *priv = gtk_builder_get_instance_private (self);
+
+ g_return_if_fail (GTK_IS_BUILDER (self));
+ g_return_if_fail (current_object || G_IS_OBJECT (current_object));
+
+ if (!g_set_object (&priv->current_object, current_object))
+ return;
+
+ g_object_notify_by_pspec (G_OBJECT (self), builder_props[PROP_CURRENT_OBJECT]);
+}
+
/**
* GtkBuilderClosureFunc:
* @builder: a #GtkBuilder
@@ -2749,8 +2838,12 @@ gtk_builder_create_closure_for_funcptr (GtkBuilder *builder,
gboolean swapped,
GObject *object)
{
+ GtkBuilderPrivate *priv = gtk_builder_get_instance_private (builder);
GClosure *closure;
+ if (object == NULL)
+ object = priv->current_object;
+
if (object)
{
if (swapped)
diff --git a/gtk/gtkbuilder.h b/gtk/gtkbuilder.h
index 697a301405..2c90da40f4 100644
--- a/gtk/gtkbuilder.h
+++ b/gtk/gtkbuilder.h
@@ -142,6 +142,11 @@ void gtk_builder_expose_object (GtkBuilder *builder,
const gchar *name,
GObject *object);
GDK_AVAILABLE_IN_ALL
+GObject * gtk_builder_get_current_object (GtkBuilder *self);
+GDK_AVAILABLE_IN_ALL
+void gtk_builder_set_current_object (GtkBuilder *self,
+ GObject *current_object);
+GDK_AVAILABLE_IN_ALL
void gtk_builder_set_translation_domain (GtkBuilder *builder,
const gchar *domain);
GDK_AVAILABLE_IN_ALL
diff --git a/gtk/gtkbuilderlistitemfactory.c b/gtk/gtkbuilderlistitemfactory.c
index a9f4ada420..16483c6509 100644
--- a/gtk/gtkbuilderlistitemfactory.c
+++ b/gtk/gtkbuilderlistitemfactory.c
@@ -64,6 +64,8 @@ gtk_builder_list_item_factory_setup (GtkListItemFactory *factory,
builder = gtk_builder_new ();
+ gtk_builder_set_current_object (builder, G_OBJECT (list_item));
+
if (!gtk_builder_extend_with_template (builder, G_OBJECT (list_item), GTK_TYPE_LIST_ITEM,
(const gchar *)g_bytes_get_data (self->bytes, NULL),
g_bytes_get_size (self->bytes),
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 79dae06c57..85239e4c74 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -12116,24 +12116,6 @@ setup_template_child (GtkWidgetTemplate *template_data,
return TRUE;
}
-static GClosure *
-gtk_widget_template_closure_func (GtkBuilder *builder,
- const char *function_name,
- gboolean swapped,
- GObject *object,
- gpointer user_data,
- GError **error)
-{
- if (object == NULL)
- object = user_data;
-
- return gtk_builder_create_cclosure (builder,
- function_name,
- swapped,
- object,
- error);
-}
-
/**
* gtk_widget_init_template:
* @widget: a #GtkWidget
@@ -12175,6 +12157,8 @@ gtk_widget_init_template (GtkWidget *widget)
builder = gtk_builder_new ();
+ gtk_builder_set_current_object (builder, G_OBJECT (widget));
+
/* Setup closure handling. All signal data from a template receive the
* template instance as user data automatically.
*
@@ -12183,8 +12167,6 @@ gtk_widget_init_template (GtkWidget *widget)
*/
if (template->closure_func)
gtk_builder_set_closure_func (builder, template->closure_func, template->closure_data, NULL);
- else
- gtk_builder_set_closure_func (builder, gtk_widget_template_closure_func, widget, NULL);
/* Add any callback symbols declared for this GType to the GtkBuilder namespace */
for (l = template->callbacks; l; l = l->next)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]