[gtk/wip/otte/listview: 25/27] expression: Allow passing a this object to bind()



commit 687c05b71fb2dbd00371015e5cb400010b16604c
Author: Benjamin Otte <otte redhat com>
Date:   Thu Nov 28 02:32:12 2019 +0100

    expression: Allow passing a this object to bind()
    
    This gives a bit more control over the arguments passed to expressions.

 demos/gtk-demo/listview_clocks.c |  6 +++---
 gtk/gtkbuilder.c                 | 38 +++++++++++++++++++++++++++++++-------
 gtk/gtkbuilderparser.c           |  6 +++++-
 gtk/gtkbuilderprivate.h          |  1 +
 gtk/gtkexpression.c              |  5 ++++-
 gtk/gtkexpression.h              |  1 +
 6 files changed, 45 insertions(+), 12 deletions(-)
---
diff --git a/demos/gtk-demo/listview_clocks.c b/demos/gtk-demo/listview_clocks.c
index b463839051..25d8c2e340 100644
--- a/demos/gtk-demo/listview_clocks.c
+++ b/demos/gtk-demo/listview_clocks.c
@@ -401,7 +401,7 @@ setup_listitem_cb (GtkListItemFactory *factory,
                                             "location");
   /* Now create the label and bind the expression to it. */
   location_label = gtk_label_new (NULL);
-  gtk_expression_bind (expression, location_label, "label");
+  gtk_expression_bind (expression, location_label, location_label, "label");
   gtk_container_add (GTK_CONTAINER (box), location_label);
 
 
@@ -411,7 +411,7 @@ setup_listitem_cb (GtkListItemFactory *factory,
   expression = gtk_expression_ref (clock_expression);
   /* Now create the widget and bind the expression to it. */
   picture = gtk_picture_new ();
-  gtk_expression_bind (expression, picture, "paintable");
+  gtk_expression_bind (expression, picture, picture, "paintable");
   gtk_container_add (GTK_CONTAINER (box), picture);
 
 
@@ -430,7 +430,7 @@ setup_listitem_cb (GtkListItemFactory *factory,
                                             NULL, NULL);
   /* Now create the label and bind the expression to it. */
   time_label = gtk_label_new (NULL);
-  gtk_expression_bind (expression, time_label, "label");
+  gtk_expression_bind (expression, time_label, time_label, "label");
   gtk_container_add (GTK_CONTAINER (box), time_label);
 
   gtk_expression_unref (clock_expression);
diff --git a/gtk/gtkbuilder.c b/gtk/gtkbuilder.c
index 518b046110..c5df7b5c9d 100644
--- a/gtk/gtkbuilder.c
+++ b/gtk/gtkbuilder.c
@@ -1055,11 +1055,13 @@ gtk_builder_create_bindings (GtkBuilder  *builder,
           BindingInfo *info = l->data;
           GObject *source;
 
-          source = _gtk_builder_lookup_object (builder, info->source, info->line, info->col);
+          source = gtk_builder_lookup_object (builder, info->source, info->line, info->col, error);
           if (source)
             g_object_bind_property (source, info->source_property,
                                     info->target, info->target_pspec->name,
                                     info->flags);
+          else
+            error = NULL;
 
           _free_binding_info (info, NULL);
         }
@@ -1067,17 +1069,39 @@ gtk_builder_create_bindings (GtkBuilder  *builder,
         {
           BindingExpressionInfo *info = l->data;
           GtkExpression *expression;
+          GObject *object;
 
-          expression = expression_info_construct (builder, info->expr, error);
-          if (expression == NULL)
+          if (info->object_name)
+            {
+              object = gtk_builder_lookup_object (builder, info->object_name, info->line, info->col, error);
+              if (object == NULL)
+                {
+                  error = NULL;
+                  result = FALSE;
+                }
+            }
+          else if (priv->current_object)
             {
-              g_prefix_error (error, "%s:%d:%d: ", priv->filename, info->line, info->col);
-              error = NULL;
-              result = FALSE;
+              object = priv->current_object;
             }
           else
             {
-              gtk_expression_bind (expression, info->target, info->target_pspec->name);
+              object = info->target;
+            }
+
+          if (object)
+            {
+              expression = expression_info_construct (builder, info->expr, error);
+              if (expression == NULL)
+                {
+                  g_prefix_error (error, "%s:%d:%d: ", priv->filename, info->line, info->col);
+                  error = NULL;
+                  result = FALSE;
+                }
+              else
+                {
+                  gtk_expression_bind (expression, info->target, object, info->target_pspec->name);
+                }
             }
 
           free_binding_expression_info (info);
diff --git a/gtk/gtkbuilderparser.c b/gtk/gtkbuilderparser.c
index e0f305dbc4..4bdb0af82b 100644
--- a/gtk/gtkbuilderparser.c
+++ b/gtk/gtkbuilderparser.c
@@ -954,7 +954,8 @@ parse_binding (ParserData   *data,
                GError      **error)
 {
   BindingExpressionInfo *info;
-  const gchar *name = NULL;
+  const char *name = NULL;
+  const char *object_name = NULL;
   ObjectInfo *object_info;
   GParamSpec *pspec = NULL;
 
@@ -969,6 +970,7 @@ parse_binding (ParserData   *data,
 
   if (!g_markup_collect_attributes (element_name, names, values, error,
                                     G_MARKUP_COLLECT_STRING, "name", &name,
+                                    G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "object", 
&object_name,
                                     G_MARKUP_COLLECT_INVALID))
     {
       _gtk_builder_prefix_error (data->builder, &data->ctx, error);
@@ -1013,6 +1015,7 @@ parse_binding (ParserData   *data,
   info->tag_type = TAG_BINDING_EXPRESSION;
   info->target = NULL;
   info->target_pspec = pspec;
+  info->object_name = g_strdup (object_name);
   gtk_buildable_parse_context_get_position (&data->ctx, &info->line, &info->col);
 
   state_push (data, info);
@@ -1506,6 +1509,7 @@ free_binding_expression_info (BindingExpressionInfo *info)
 {
   if (info->expr)
     free_expression_info (info->expr);
+  g_free (info->object_name);
   g_slice_free (BindingExpressionInfo, info);
 }
 
diff --git a/gtk/gtkbuilderprivate.h b/gtk/gtkbuilderprivate.h
index a5e1f22861..8e690e0c88 100644
--- a/gtk/gtkbuilderprivate.h
+++ b/gtk/gtkbuilderprivate.h
@@ -133,6 +133,7 @@ typedef struct
   guint tag_type;
   GObject *target;
   GParamSpec *target_pspec;
+  char *object_name;
   ExpressionInfo *expr;
   gint line;
   gint col;
diff --git a/gtk/gtkexpression.c b/gtk/gtkexpression.c
index 493d29da9d..19e3a4341c 100644
--- a/gtk/gtkexpression.c
+++ b/gtk/gtkexpression.c
@@ -1333,6 +1333,8 @@ gtk_expression_bind_notify (gpointer data)
  * gtk_expression_bind:
  * @self: (transfer full): a #GtkExpression
  * @object: (transfer none) (type GObject): the object to bind
+ * @this_: (transfer none) (type GObject): the this argument for
+ *     the evaluation of @self
  * @property: name of the property to bind to
  *
  * Bind @object's property named @property to @self.
@@ -1353,6 +1355,7 @@ gtk_expression_bind_notify (gpointer data)
 GtkExpressionWatch *
 gtk_expression_bind (GtkExpression *self,
                      gpointer       object,
+                     gpointer       this_,
                      const char    *property)
 {
   GtkExpressionBind *bind;
@@ -1384,7 +1387,7 @@ gtk_expression_bind (GtkExpression *self,
   bind->object = object;
   bind->pspec = pspec;
   bind->watch = gtk_expression_watch (self,
-                                      object,
+                                      this_,
                                       gtk_expression_bind_notify,
                                       bind,
                                       gtk_expression_bind_free);
diff --git a/gtk/gtkexpression.h b/gtk/gtkexpression.h
index bac7762561..d7916be716 100644
--- a/gtk/gtkexpression.h
+++ b/gtk/gtkexpression.h
@@ -59,6 +59,7 @@ GtkExpressionWatch *    gtk_expression_watch                    (GtkExpression
 GDK_AVAILABLE_IN_ALL
 GtkExpressionWatch *    gtk_expression_bind                     (GtkExpression                  *self,
                                                                  gpointer                        object,
+                                                                 gpointer                        this_,
                                                                  const char *                    property);
 
 GDK_AVAILABLE_IN_ALL


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