Skip to content

Examples

Examples of using Tuner widgets and bindings.

Simple entry

Let's add Tuner.Entry inside empty group:

blp
using Gtk 4.0;
using Tuner 1;

translation-domain "tuner-base";

Tuner.Page {
    title: _("New Page");
    icon-name: "computer-symbolic";

    Tuner.Group {

        Tuner.Entry { 
            title: _("Our cool entry"); 
            show-apply-button: true; 
        } 
    }
}

But that entry will not be displayed without binding, so add FileContent binding:

blp
Tuner.Entry {
    title: _("Our cool entry");
    show-apply-button: true;

    binding: Tuner.FileContent { 
        path: "~/1.txt"; 
    } 
}
Result

Entry with FileContent binding

sh
$ cat 1.txt
test

That entry now will by synced with 1.txt file inside current user home folder.
Property show-apply-button allows to save entered text only after pressing Enter or special apply button.

Better file content binding

Now let's create binding with custom behaviour.

vala
public class Base.SimpleJson : Tuner.Binding {
    public string path { get; set; }
    public string name { get; set; }
    public override Type expected_type { get { return Type.STRING; } }

    // Load json content to our entry
    public override bool get_value(ref Value value) {
        try {
            var parser = new Json.Parser();
            if (parser.load_from_file(Tuner.FileUtil.expand_home(path))) {
                var root = parser.get_root();
                if (root != null && root.get_object() != null && root.get_object().has_member(name)) {
                    var node = root.get_object().get_member(name);
                    if (node != null && node.get_string() != null) {
                        value.set_string(node.get_string());
                        return true;
                    }
                }
            }
        } catch (Error e) {
            warning("Error: %s\n", e.message);
        }

        return false;
    }

    // Write contents of our entry to file
    public override void set_value(Value value) {
        try {
            Json.Node target = null;

            var parser = new Json.Parser();
            if (parser.load_from_file(Tuner.FileUtil.expand_home(path))) {
                var root = parser.get_root();
                if (root != null && root.get_object() != null) {
                    root.get_object().set_string_member(name, value.get_string());
                    target = root;
                }
            }

            if (target == null) {
                target = new Json.Builder()
                    .begin_object()
                    .set_member_name(name)
                    .add_string_value(value.get_string())
                    .end_object()
                    .get_root();
            }

            var generator = new Json.Generator();
            generator.set_root(target);
            generator.to_file(Tuner.FileUtil.expand_home(path));
        } catch (Error e) {
            warning("Error creating/writing file: %s", e.message);
        }
    }
}

Don't forget to register the type if it will be used in markup!

vala
// Insert before calling add_from_resource
typeof(Base.SimpleJson).ensure();

Not let's use our binding in markup:

blp
using Gtk 4.0;
using Tuner 1;

translation-domain "tuner-base";

Tuner.Page {
    title: _("New Page");
    icon-name: "computer-symbolic";

    Tuner.Group {

        Tuner.Entry {
            title: "Name";
            show-apply-button: true;

            binding: $BaseSimpleJson {
                path: "~/1.json";
                name: "name";
            };
        }

        Tuner.Entry {
            title: "Surname";
            show-apply-button: true;

            binding: $BaseSimpleJson {
                path: "~/1.json";
                name: "surname";
            };
        }
    }
}

With that binding entry text will be written to file with specified path only to json member with specified name withot overriding other members.

Result

Two Entry with custom binding

sh
$ cat 1.json
{"name":"Lorem","surname":"Ipsum"}

Released under the GPL-3.0+ License. The content is available under CC BY-SA 4.0, unless stated otherwise.