Vala reactive programming
Tags: vala, gtk, linux
Published: 2021-12-06 20:03:52

I've been doing some web programming using [preact](https://preactjs.com/) these last weeks and one of the things that impressed the most was the way logic and UI are split in code. When doing functional components this is specially explicit. Your function returns whatever should be displayed by the component and receives a `props` object containing all the information the components need to render. A component rerenders when some of its `props` are changed, either because an external component made changes or in response to an event. 

IMHO, this really helps to organize code and separate concerns. All the logic is written in terms of the components' properties. The GUI is updated in response to changes in the properties in order to synchronize the component state with what is shown on screen. 

We can also achieve this in Vala using `properties` and `bindings` from GLib. In this article we will produce a login screen that validates the username and password fields. All code is available at [Github](https://github.com/igordsm/reactive-gtk-vala).


![GUI form that validates input](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/91jxzwas4pgnjtzb9jtk.gif)

**Important**: The repo contains many iterations of the code presented in this article. A comment containing the name of the original file is shown at the top of each code listing.  

Let's start with the basic code to build the form above. This is just standard GTK code: all the ui elements are created in the `construct` method. The original file (*v1/main.vala*) also contains a `Gtk.Application` subclass that handles initialization and showing our form. 

**Vala tip**: the `construct` block runs during an object's creation and after named constructors are called. 

```c# 
// excerpt from v1.vala

class LoginForm : Gtk.Grid {
    // ......
    
    construct {
        width_request = 300;
        margin = 10;
        column_homogeneous = false;
        expand = false;
        valign = Gtk.Align.CENTER;
        halign = Gtk.Align.CENTER;
        
        var username_field = new Gtk.Entry () {
            hexpand = true,
            margin = 4
        };
        var password_field = new Gtk.Entry () {
            hexpand = true,
            margin = 4
        };
        var validation_warning = new Gtk.Label ("") {
            wrap = true,
            height_request = 50
        };
        var login_btn = new Gtk.Button.with_label ("Login") {
            expand = false,
            halign = Gtk.Align.END
        };
        attach (new Gtk.Label ("Username"), 0, 0);
        attach (username_field, 1, 0);
        attach (password_field, 1, 1);
        attach (new Gtk.Label ("Password"), 0, 1);
        attach (validation_warning, 1, 2);
        attach (login_btn, 1, 3);

        show_all ();
    }
}
```

There's no interactivity in this form yet. In fact, it already starts in an inconsistent state: the `Login` button is enabled even though block fields are empty. We could fix this simply by setting `sensitive=false` in `login_btn` initialization, but we won't. Instead we will create a property called `is_valid` and **bind** its value to `login_btn.sensitive`. Every time one of the values change the other is instantly updated. Bindings can also be created with many values as long as a cicle is not introduced. 

Let's use this now in our program: first we create a property `is_valid` and then we use [bind_property](https://valadoc.org/gobject-2.0/GLib.Object.bind_property.html) to **bind** its value to `login_btn.sensitive`. Our [binding flags](https://valadoc.org/gobject-2.0/GLib.BindingFlags.html) indicate that the binding is *bidirectional* and that the value is _synchronized when the binding is created_. 

```c#
// excerpt from v2.vala

class LoginForm : Gtk.Grid {
    public bool is_valid { get; set; default = false; }
    
    construct {
        // GUI creation code
        
        bind_property ("is_valid", login_btn, "sensitive", BindingFlags.BIDIRECTIONAL | BindingFlags.SYNC_CREATE);
    }
```

Now the login button is disabled when the app starts and will remain so until we set `is_valid=true`. Unfortunately this never happens, so let's add a property `username` and bind it to `username_field.text`. When `username` is set we check if its length is larger than 0 and set `is_valid` accordingly.

```c#
// excerpt from v3.vala

class LoginForm : Gtk.Grid {
    public bool is_valid { get; set; default = false; }
    
    private string _username = "";
    public string username { get {
        return _username;
    }
    set {
        _username = value;
        if (value.length > 0) {
            is_valid = true;
        }
        else {
            is_valid = false;
        }
    }}
    
    construct {
        // GUI creation code
        
        bind_property ("is_valid", login_btn, "sensitive", BindingFlags.BIDIRECTIONAL | BindingFlags.SYNC_CREATE);
        bind_property ("username", username_field, "text", BindingFlags.BIDIRECTIONAL | BindingFlags.SYNC_CREATE);
    }
```

Run the app and test the new validation: the login button should be disable when the app starts and respond to `is_valid`. IMHO, the impressive part of this code is that all GUI code is on `construct` and our logic is written only in terms of properties. When we update the Widget's properties the UI will update in response, so our application state is always consistent.

Now the final step is to set `validation_error` to a meaningful message. We can do this with another property binding. To make code more readble we also refactor all our validation code into a function `void validate_form ()`.

```c#
// excerpt from v4.vala

class LoginForm : Gtk.Grid {
    public string validation_error { get; set; default = ""; }
    public string username { get {
        return _username;
    }
    set {
        _username = value;
        validate_form ();
    } }

    //....
    
    construct {
        // ....
        
        bind_property ("validation_error", validation_warning, "label", BindingFlags.DEFAULT | BindingFlags.SYNC_CREATE);
    }
    
    private void validate_form () {
        if (_username.length == 0) {
            is_valid = false;
            validation_error = "Empty username";
            return;
        }
        is_valid = true;
        validation_error = "";
    }
```

And that's it for the `username` field. We can do exactly the same for the `password` field and arrive at the final code available at `final.vala` in the [example repository](https://github.com/igordsm/reactive-gtk-vala).

Another interesting project is [Blueprint compiler](https://gitlab.gnome.org/jwestman/blueprint-compiler), which creates a sort of DSL for _Gtk_ components. So, what do you think about this style of *Gtk* programming? Join the conversation in the comments ;)