Last week, inspired by Tristan’s GtkComposite branch idea of embedding builder xml into widget classes together with the old eagerness of implementing Glade UI with Glade itself I started hacking Glade in glade!
The first step was to recreate GladeWindow widget hierarchy in Glade, that was quick and easy. Then I started replacing the hard coded widgets with it but since I wanted to use the very same executable I was hacking on to edit its own UI definition file I had to make sure I got the palette, design view, inspector and property editor properly working before removing the old code.
Later on I proceeded to remove the old menu that was implemented using GtkUIManager… big mistake! How was I supposed to edit the file if I was not able to save the file, so I revert it and moved it to the end of the window and keep it until the new menu had a working save menu item!
After this, Glade was functional and only had one regression. For some reason GtkAccelLabel does not show up the accelerator when used with a related action. But that seems to be a Gtk+ bug (see bugzilla report)
The only problem left to solve was the dependency GladeWindow had on the UI file. I really did not like the idea of a class depending on a file so I decided it was a good time to give GResource a try! GResource allows you to easily embed resources into your code. All you have to do is define all your resources in GResource xml format, in this case only one file glade.glade.
glade-resources.gresource.xml:
<?xml version="1.0" encoding="UTF-8"?> <gresources> <gresource prefix="/org/gnome/glade"> <file compressed="true">glade.glade</file> </gresource> </gresources> |
And compile it into source using glib-compile-resourses
tool, which can be done automatically with a couple of Makefile rules.
# Rules to compile resources %.h: %.gresource.xml $(GLIB_COMPILE_RESOURCES) --generate $< --target=$@ %.c: %.gresource.xml $(GLIB_COMPILE_RESOURCES) --generate $< --target=$@ # Dependencies rule, and do not forget to do a make after # editing the UI with glade! glade-resources.c glade-resources.h: \ glade-resources.gresource.xml \ $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies \ glade-resources.gresource.xml) |
Once you have the build system setup it is as simply as using the resource uri instead of a file path.
GtkBuilder *builder = gtk_builder_new (); GError *error = NULL; gtk_builder_add_from_resource (builder, "/org/gnome/glade/glade.glade", error); |
As usual you can find this in git master
git clone git://git.gnome.org/glade
That’s awesome!
I hadn’t heard GResource before, and its always cool to see “meta-development”:)
Since I hadn’t heard of this before I looked at the docs and they said that it was more typical to use –generate-source and –generate-header and then link directly rather than calling glib_compile_resources manually and then having to load the result. I was curious as to why you chose the later method.
Hi, I am actually generating source code and linking but I simply choose to load/unload resources manually just for the later.
You can see I specify the resource to be compress, that means it will be uncompress for you automatically when the resource is loaded. I did that so after unloading resources I get some memory back.
Hi xjuan,
Thanks for the response.
So the point is to be able to reclaim memory as fast as possible (since, as you say, you are deciding when to link/unlink)? Can you tell me when you think it makes sense to call the generators instead of handling it yourself? The docs really weren’t clear about the use cases for each.
Thanks,
Liam
Well, It really depends on what you are doing. In this case since I am only loading the main UI once it makes sense to unload resources after initialization.
I think it would be a good idea to split resources at least in two, one for every resource you need at init time and other for things you would usually use during the execution of you app.
You could merge the 2 Makefile rules into a single rule:
%.c %.h: %.gresource.xml
$(GLIB_COMPILE_RESOURCES) –generate $< –target=$@
Hmm, not really glib-compile-resources will only create one file, but if you really want just one rule you could add two lines, one with –generate-header and the other one with –generate-source