While having coffee with some friends a few weeks ago, I kept coming back to the thought that I need to be able to do small amounts of scripting within GtkBuilder. Especially if I'm going to switch to that from hard coding UIs in C. I figured it would take some hacking to GtkBuilder to do what I wanted. Well, it turns out not. I came to the revelation late last night, in bed, and hacked it up this morning.
First, we create GScriptJs which is a thin wrapper around Gjs. Mostly, just to be able to create an object from within the GtkBuilder file. Then, we create a custom connect func that will look for a given function in the script and attach it to the requested signal. All in all, very few lines of code. I'm pleasantly surprised.
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GScriptJs" id="script">
<property name="script">
const Gtk = imports.gi.Gtk;
function onClicked() {
let w = new Gtk.Window();
w.set_default_size(320, 240);
w.present();
}
function onQuit() {
Gtk.main_quit();
}
</property>
</object>
<object class="GtkWindow" id="window">
<signal name="delete-event" handler="onQuit" swapped="no"/>
static void
connect_func (GtkBuilder *builder,
GObject *object,
const gchar *signal_name,
const gchar *handler_name,
GObject *connect_object,
GConnectFlags flags,
gpointer user_data)
{
const gchar *script_name = user_data;
GScriptJs *script;
GClosure *closure;
g_return_if_fail(script_name != NULL);
g_return_if_fail(connect_object == NULL); /* TODO */
script = G_SCRIPT_JS(gtk_builder_get_object(builder, script_name));
if (!script) {
g_critical("Cannot locate script %s", script_name);
return;
}
closure = g_script_js_get_function(script, handler_name);
if (!closure) {
g_critical("Cannot locate function %s", handler_name);
return;
}
g_signal_connect_closure(object, signal_name, closure,
!!(flags & G_CONNECT_AFTER));
}
Get the code at https://github.com/chergert/gtkbuilderscript.
-- Christian Hergert 2011-04-24