From 05f65a86a556b8ac7cf65c5617488d6c7be3f45f Mon Sep 17 00:00:00 2001 From: James Westman Date: Sat, 9 Jul 2022 15:58:49 -0500 Subject: [PATCH] WIP: Support GSettings bindings Fixes #66. --- .../language/gobject_property.py | 30 +++++++++++++++++-- tests/samples/bind_settings.blp | 5 ++++ tests/samples/bind_settings.ui | 7 +++++ tests/test_samples.py | 1 + 4 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 tests/samples/bind_settings.blp create mode 100644 tests/samples/bind_settings.ui diff --git a/blueprintcompiler/language/gobject_property.py b/blueprintcompiler/language/gobject_property.py index f0a2ef4..45db1ad 100644 --- a/blueprintcompiler/language/gobject_property.py +++ b/blueprintcompiler/language/gobject_property.py @@ -24,7 +24,6 @@ from .gtkbuilder_template import Template from .values import Value, TranslatedStringValue from .common import * - class Property(AstNode): grammar = AnyOf( [ @@ -42,6 +41,20 @@ class Property(AstNode): )), ";", ], + Statement( + UseIdent("name"), + ":", + Keyword("bind-settings"), + UseQuoted("bind_settings_schema"), + UseQuoted("bind_settings_key"), + ZeroOrMore(AnyOf( + Keyword("get"), + Keyword("set"), + Keyword("no-sensitivity"), + Keyword("get-no-changes"), + ["inverted", UseLiteral("inverted", True)], + )), + ), Statement( UseIdent("name"), UseLiteral("binding", True), @@ -96,7 +109,10 @@ class Property(AstNode): @validate("bind") def property_bindable(self): - if self.tokens["bind"] and self.gir_property is not None and self.gir_property.construct_only: + if ((self.tokens["bind"] or self.tokens["bind-setting"]) + and self.gir_property is not None + and self.gir_property.construct_only): + raise CompileError( f"{self.gir_property.full_name} can't be bound because it is construct-only", hints=["construct-only properties may only be set to a static value"] @@ -146,11 +162,21 @@ class Property(AstNode): bind_flags.append("invert-boolean") if self.tokens["bidirectional"]: bind_flags.append("bidirectional") + if self.tokens["get"]: + bind_flags.append("get") + if self.tokens["set"]: + bind_flags.append("set") + if self.tokens["no-sensitivity"]: + bind_flags.append("no-sensitivity") + if self.tokens["get-no-changes"]: + bind_flags.append("get-no-changes") bind_flags_str = "|".join(bind_flags) or None props = { "name": self.tokens["name"], "bind-source": self.tokens["bind_source"], + "bind-settings-schema": self.tokens["bind_settings_schema"], + "bind-settings-key": self.tokens["bind_settings_key"], "bind-property": self.tokens["bind_property"], "bind-flags": bind_flags_str, } diff --git a/tests/samples/bind_settings.blp b/tests/samples/bind_settings.blp new file mode 100644 index 0000000..d63d6a2 --- /dev/null +++ b/tests/samples/bind_settings.blp @@ -0,0 +1,5 @@ +using Gtk 4.0; + +Label { + label: bind-settings "org.example.Settings" "my-label" inverted get-no-changes; +} \ No newline at end of file diff --git a/tests/samples/bind_settings.ui b/tests/samples/bind_settings.ui new file mode 100644 index 0000000..72dd5b8 --- /dev/null +++ b/tests/samples/bind_settings.ui @@ -0,0 +1,7 @@ + + + + + + + diff --git a/tests/test_samples.py b/tests/test_samples.py index ea6b2ea..5ea5c27 100644 --- a/tests/test_samples.py +++ b/tests/test_samples.py @@ -132,6 +132,7 @@ class TestSamples(unittest.TestCase): self.assert_sample("accessibility") self.assert_sample("action_widgets") self.assert_sample("binding") + self.assert_sample("bind_settings") self.assert_sample("child_type") self.assert_sample("combo_box_text") self.assert_sample("comments")