Introducing Blueprint: A New Way to Craft User Interfaces
02 December 2021

In a recent blog post, I presented my latest project, a markup language for creating GTK user interfaces. I’m excited to announce it’s now ready to use!

using Gtk 4.0;

template MyAppWindow : Gtk.ApplicationWindow {
  title: _("My App Title");

  [titlebar]
  HeaderBar header_bar {}

  Label {
    styles ["heading"]
    label: _("Hello, world!");
  }
}

Blueprint is a markup language that compiles to GtkBuilder XML. It’s designed to reflect GTK’s widget model in a straightforward, readable syntax, and is capable of almost everything GtkBuilder is. The compiler catches many types of errors early, so you can iterate faster and spend less time debugging.

Switching a project is simple: the compiler runs as part of your build, and your code stays the same. The interactive porting tool will walk you through most of the process.

The GNOME Builder plugin is a work in progress, but it provides completion, docs, diagnostics, and syntax highlighting. Here is my Builder branch if you want to try it out. I’m also working on a VS Code extension, but it’s not ready yet.

Future Plans

I plan to introduce reactive programming to Blueprint using Gtk.Expression, a feature that already exists in GTK 4. If you’ve used one of the half-billion Javascript frameworks out there, you’re probably familiar with reactive programming. In essence, it syncs your UI (view) with the underlying data (model) automatically, rather than imperatively updating the UI whenever the data changes.

To give a concrete example, you’ll be able to write this in your blueprint once:

Label file_size_label {
  label: bind this.item.file-size;
}

instead of this in your code every time the file size might have changed:

this.file_size_label.label = this.item.file_size;

All you have to do is make file-size a GObject property (not just a property or field in your chosen programming language). This is so it gets a notify signal.

There’s even more potential to expressions. Arithmetic and boolean operations, ternary/match statements, and function calls are all on the roadmap. In other areas, I plan to continue polishing the developer tooling, writing documentation, and examining how y’all use Blueprint in real apps so I can make it even better.

Developer Experience

This project is an exercise in developer experience. I’ve written about Linux platforms before, and good developer tooling is a critical part of any platform. Without app developers, you have no ecosystem. We want to give our developers everything they need to help our platform grow. Toward that end, I’ve put most of my effort in Blueprint toward good error checking and a comprehensive language server.


Previous

Implementing Vector Tile Support in Libshumate

It’s incredible how things that seem simple can be so complicated. Take a “simple” maps app. There’s geometry, design, typography, a 60-gigabyte database, and a lot of complicated algorithms. Every button you press has an astonishing maze of technology supporting it.