Lange war es eine der größeren Herausforderungen in der Anwendungsentwicklung: Native Programme mit graphischen Oberflächen, die nicht für jede Plattform separat entwickelt werden müssen. Entweder verwendete man die graphischen Widgets (Fenster, Label, Buttons, Eingabeelemente und so weiter) des jeweiligen Betriebssystems. Diese nativen GUI-Apps passten sich sehr gut in die restlichen Apps für das OS ein, boten eine bessere Peformance und andere Vorteile - aber in der Regel musste man eine Version für Windows, eine Version für Mac, eine Version für Linux und so weiter separat entwickeln. Die Alternative waren plattformübergreifende Toolkits wie beispielsweise Swing oder JavaFX unter Java. Damit erstellte Programme laufen im Prinzip überall, wo es eine Java Runtime Engine gibt, aber sie sind eben nicht nativ und bieten nicht die damit verbundenen Vorteile.
Mittlerweile gibt es jedoch einen Ansatz, der (zumindest in Teilen) die Vorteile aus beiden Welten verbindet: libui beziehungsweise libui-ng. Diese GUI-Bibliothek funktioniert unter Windows (ab Vista SP2 mit Platform Update), Unix/Linux (ab GTK+ 3.10) und Mac OS X (ab OS X 10.8). Auf jedem dieser Systeme werden die jeweils nativen Widgets benutzen. Das bedeutet, ein Programm, das libui-ng verwendet, sieht auf Linux aus wie ein Linux-Programm, auf Windows wie ein Windows-Programm und so weiter. Die Bibliothek ist zwar noch eher im Alpha-Stadium, aber es lässt sich schon einiges damit anfangen.
libui-ng als solches ist eine Bibliothek für C, aber es gibt Bindings von C++ über Haskell, JavaScript oder Lua bis Python, Rust oder Swift. In diesem Blogbeitrag soll jedoch (wer diesen Blog schon etwas länger folgt, wird es sich denken können) die Verwendung von libui-ng mit Ruby im Fokus stehen.
Denn eines von mehreren Bindings für Ruby is Glimmer DSL for LibUI. Glimmer ist eine Ruby-basierte Beschreibungssprache für graphische Oberflächen, die es für eine Reihe von Toolkits gibt, von SWT über Tk und GTK bis zu Webinterfaces, und eben auch für LibUI.
Die Beschreibungssprache von Glimmer ist ausgesprochen eingängig. Für ein Fenster braucht es beispielsweise nichts weiter als das Gem glimmer-dsl-libui und
require 'glimmer-dsl-libui'
class MyApp
include Glimmer
window {
title 'Hello, world'
}.show
end
Will man das Fenster um ein Label ergänzen, verschachtelt man einfach ein label:
require 'glimmer-dsl-libui'
class MyApp
include Glimmer
window {
title 'Hello, world'
label {
text 'Hello, world'
}
}.show
end
Ein anderes Beispiel ist ein Button, der eine Meldung auslöst:
require 'glimmer-dsl-libui'
class MyApp
include Glimmer
window {
title 'Hello, world'
button {
text 'Greet'
on_clicked do
msg_box('Greeting', 'Hello!')
end
}
}
end
Deklarative Strukturen werden üblicherweise mit geschweiften Klammern ausgedrückt, imperative Strukturen (wie im obigen Beispiel das on_clicked) mit do…end.
Einen Nachteil gibt es bei Glimmer aktuell jedoch: Die Dokumentation lässt noch zu wünschen übrig. Aktuell muss man sich die Details aus den Beispielen im GitHub-Repository selbst zusammensuchen, oder aus den diversen mitgefiltem Vorträgen und Workshops, in denen Glimmer-Entwickler Andy Maleh seine Arbeit vorstellt. Der Workshop von RubyConf 2024 ist eine gute Grundlage. Nichtsdestotrotz wird Glimmer DSL for LibUI bereits für “echte” Anwendungen genutzt, beispielsweise für die Administrations-UI für Sidekiq namens Kuiq.
Glimmer DSL for LibUI ist also ein sehr vielversprechendes Projekt, das aktuell Entwicklern aber noch einiges an Eigeninitative abverlangt.