[gtk/ebassi/settings-builder: 1/3] Support binding properties to GSettings keys in GtkBuilder
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/ebassi/settings-builder: 1/3] Support binding properties to GSettings keys in GtkBuilder
- Date: Thu, 9 Sep 2021 18:23:27 +0000 (UTC)
commit 181fce834207df4ba845078fa61bf7246418e204
Author: Emmanuele Bassi <ebassi gnome org>
Date: Thu Sep 9 19:12:40 2021 +0100
Support binding properties to GSettings keys in GtkBuilder
We already support binding properties; by adding new attributes to the
`property` element we can automatically call g_settings_bind() on the
object ourselves.
gtk/gtkbuilder.c | 16 +++++++++++
gtk/gtkbuilderparser.c | 76 ++++++++++++++++++++++++++++++++++++++++++-------
gtk/gtkbuilderprivate.h | 14 +++++++++
3 files changed, 96 insertions(+), 10 deletions(-)
---
diff --git a/gtk/gtkbuilder.c b/gtk/gtkbuilder.c
index 9d85e6f2ed..5139b36df1 100644
--- a/gtk/gtkbuilder.c
+++ b/gtk/gtkbuilder.c
@@ -719,6 +719,11 @@ gtk_builder_take_bindings (GtkBuilder *builder,
BindingExpressionInfo *info = l->data;
info->target = target;
}
+ else if (common_info->tag_type == TAG_BINDING_SETTING)
+ {
+ BindingSettingsInfo *info = l->data;
+ info->target = target;
+ }
else
{
g_assert_not_reached ();
@@ -1146,6 +1151,17 @@ gtk_builder_create_bindings (GtkBuilder *builder,
free_binding_expression_info (info);
}
+ else if (common_info->tag_type == TAG_BINDING_SETTING)
+ {
+ BindingSettingsInfo *info = l->data;
+ GSettings *settings;
+
+ settings = g_settings_new (info->schema);
+ g_settings_bind (settings, info->key, info->target, info->target_pspec->name, info->flags);
+ g_object_unref (settings);
+
+ free_binding_settings_info (info);
+ }
else
g_assert_not_reached ();
}
diff --git a/gtk/gtkbuilderparser.c b/gtk/gtkbuilderparser.c
index b9efb13fae..8185b5e3df 100644
--- a/gtk/gtkbuilderparser.c
+++ b/gtk/gtkbuilderparser.c
@@ -874,7 +874,8 @@ parse_property (ParserData *data,
const char *bind_source = NULL;
const char *bind_property = NULL;
const char *bind_flags_str = NULL;
- GBindingFlags bind_flags = G_BINDING_DEFAULT;
+ const char *bind_schema = NULL;
+ const char *bind_key = NULL;
gboolean translatable = FALSE;
ObjectInfo *object_info;
GParamSpec *pspec = NULL;
@@ -897,6 +898,8 @@ parse_property (ParserData *data,
G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "bind-source",
&bind_source,
G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "bind-property",
&bind_property,
G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "bind-flags",
&bind_flags_str,
+ G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL,
"bind-settings-schema", &bind_schema,
+ G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "bind-settings-key",
&bind_key,
G_MARKUP_COLLECT_INVALID))
{
_gtk_builder_prefix_error (data->builder, &data->ctx, error);
@@ -916,21 +919,59 @@ parse_property (ParserData *data,
return;
}
- if (bind_flags_str)
+ gtk_buildable_parse_context_get_position (&data->ctx, &line, &col);
+
+ if (bind_schema != NULL)
{
- if (!_gtk_builder_flags_from_string (G_TYPE_BINDING_FLAGS, NULL, bind_flags_str, &bind_flags, error))
+ GSettingsBindFlags bind_flags = G_SETTINGS_BIND_DEFAULT;
+
+ if (bind_flags_str)
{
- _gtk_builder_prefix_error (data->builder, &data->ctx, error);
- return;
+ if (!_gtk_builder_flags_from_string (G_TYPE_SETTINGS_BIND_FLAGS, NULL, bind_flags_str,
&bind_flags, error))
+ {
+ _gtk_builder_prefix_error (data->builder, &data->ctx, error);
+ return;
+ }
}
- }
- gtk_buildable_parse_context_get_position (&data->ctx, &line, &col);
+ if (bind_key != NULL)
+ {
+ BindingSettingsInfo *binfo;
+
+ binfo = g_slice_new0 (BindingSettingsInfo);
+ binfo->tag_type = TAG_BINDING_SETTING;
+ binfo->target = NULL;
+ binfo->target_pspec = pspec;
+ binfo->schema = g_strdup (bind_schema);
+ binfo->key = g_strdup (bind_key);
+ binfo->flags = bind_flags;
+ binfo->line = line;
+ binfo->col = col;
- if (bind_source)
+ object_info->bindings = g_slist_prepend (object_info->bindings, binfo);
+ }
+ else
+ {
+ error_missing_attribute (data, element_name,
+ "bind-settings-key",
+ error);
+ return;
+ }
+ }
+ else if (bind_source != NULL)
{
+ GBindingFlags bind_flags = G_BINDING_DEFAULT;
BindingInfo *binfo;
+ if (bind_flags_str)
+ {
+ if (!_gtk_builder_flags_from_string (G_TYPE_BINDING_FLAGS, NULL, bind_flags_str, &bind_flags,
error))
+ {
+ _gtk_builder_prefix_error (data->builder, &data->ctx, error);
+ return;
+ }
+ }
+
binfo = g_slice_new0 (BindingInfo);
binfo->tag_type = TAG_BINDING;
binfo->target = NULL;
@@ -943,7 +984,14 @@ parse_property (ParserData *data,
object_info->bindings = g_slist_prepend (object_info->bindings, binfo);
}
- else if (bind_property)
+ else if (bind_key != NULL)
+ {
+ error_missing_attribute (data, element_name,
+ "bind-settings-schema",
+ error);
+ return;
+ }
+ else if (bind_property != NULL)
{
error_missing_attribute (data, element_name,
"bind-source",
@@ -956,7 +1004,7 @@ parse_property (ParserData *data,
info->pspec = pspec;
info->text = g_string_new ("");
info->translatable = translatable;
- info->bound = bind_source != NULL;
+ info->bound = bind_source != NULL || bind_schema != NULL;
info->context = g_strdup (context);
info->line = line;
info->col = col;
@@ -1563,6 +1611,14 @@ free_binding_expression_info (BindingExpressionInfo *info)
g_slice_free (BindingExpressionInfo, info);
}
+void
+free_binding_settings_info (BindingSettingsInfo *info)
+{
+ g_free (info->schema);
+ g_free (info->key);
+ g_slice_free (BindingSettingsInfo, info);
+}
+
static void
free_requires_info (RequiresInfo *info,
gpointer user_data)
diff --git a/gtk/gtkbuilderprivate.h b/gtk/gtkbuilderprivate.h
index 34a48dd454..8dd2c7df52 100644
--- a/gtk/gtkbuilderprivate.h
+++ b/gtk/gtkbuilderprivate.h
@@ -27,6 +27,7 @@ enum {
TAG_PROPERTY,
TAG_BINDING,
TAG_BINDING_EXPRESSION,
+ TAG_BINDING_SETTING,
TAG_REQUIRES,
TAG_OBJECT,
TAG_CHILD,
@@ -141,6 +142,18 @@ typedef struct
int col;
} BindingExpressionInfo;
+typedef struct
+{
+ guint tag_type;
+ GObject *target;
+ GParamSpec *target_pspec;
+ char *schema;
+ char *key;
+ GSettingsBindFlags flags;
+ int line;
+ int col;
+} BindingSettingsInfo;
+
typedef struct {
guint tag_type;
char *library;
@@ -228,6 +241,7 @@ void _free_signal_info (SignalInfo *info,
void _free_binding_info (BindingInfo *info,
gpointer user_data);
void free_binding_expression_info (BindingExpressionInfo *info);
+void free_binding_settings_info (BindingSettingsInfo *info);
GtkExpression * expression_info_construct (GtkBuilder *builder,
ExpressionInfo *info,
GError **error);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]