Glade Catalog Tutorial

For some time now Glade allows to add custom widgets and objects to an interface file by making a catalog. Many people are asking how exactly it can be done. I did not see any hands on guide, step by step howto, or just any plain example of a custom widget catalog yet. Recently I’ve found some spare hours to play with Glade and experiment with the feature. It happens to be not that hard after all, and I decided it would be beneficial to share the experience by writing this little tutorial.

Before anything I must note that sometimes all you need is to “fake” a class in the catalog. To get an idea you can read a little post in the blog of one of the Glade developers. It provides you a tiny example of a catalog. In general though, you need to build a shared library containing all your classes to make them available to Glade at the run time. Let’s take as an example the clock face widget from the ancient Gnome Journal February 16, 2006 issue and try add it to a Glade file. The sources ain’t clearly marked with any license, but I’m sure the author wouldn’t mind.

The first step is to make a working directory, download the files, give the sources appropriate names, and see if all of this works together:

mkdir eggclock
cd eggclock
wget http://www.gnome.org/~davyd/gnome-journal-cairo-article/clock-ex5.c
wget http://www.gnome.org/~davyd/gnome-journal-cairo-article/clock-ex5.h
wget http://www.gnome.org/~davyd/gnome-journal-cairo-article/main-ex5.c
wget http://www.gnome.org/~davyd/gnome-journal-cairo-article/clock-marshallers.list
wget http://www.gnome.org/~davyd/gnome-journal-cairo-article/Makefile
mv clock-ex5.c clock.c
mv clock-ex5.h clock.h
mv main-ex5.c main.c
make

I took the freedom to put it all in a single archive to ease your pain of going through the above steps. Assuming you have all appropriate development libraries installed you should have a working application now, and can run it in usual manner:

./clock

The second step is to modify the Makefile to create a shared library. The widget is named EggClockFace for a reason unclear to me, but whatever this “egg” stands for it is a namespace, so let’s give the library unsophisticated name libegg.so and replace the single rule for making executable with something like this:

clock: main.o libegg.so
gcc -g -rdynamic -o clock `pkg-config --libs gtk+-2.0` $^
main.o: main.c clock.h
gcc -g -c `pkg-config --cflags gtk+-2.0` $<
libegg.so: clock.o clock-marshallers.o
gcc -g -shared -o libegg.so `pkg-config --libs gtk+-2.0` $^
clock.o: clock.c clock.h clock-marshallers.h
gcc -fpic -g -c `pkg-config --cflags gtk+-2.0` $<
clock-marshallers.o: clock-marshallers.c
gcc -fpic -g -c `pkg-config --cflags gtk+-2.0` $<

Don’t forget that all command lines should start with a tab. Actually you should give your library proper soname, install it in in a proper location, and all that stuff, but I’m leaving that for you as an exercise. For the tutorial purposes this quick and dirty approach would do just fine, and it is sufficient to start the application setting the working directory as the library path directly from the command line:

LD_LIBRARY_PATH=. ./clock

The third step is to create the catalog file as simple as this:

<?xml version="1.0" encoding="UTF-8"?>
<glade-catalog name="egg" library="libegg.so" depends="gtk+">

<glade-widget-classes>
<glade-widget-class name="EggClockFace" generic-name="clockface" title="Clock Face" />
</glade-widget-classes>
<glade-widget-group name="egg-widgets" title="Egg Widgets">
<glade-widget-class-ref name="EggClockFace"/>
</glade-widget-group>
</glade-catalog>

Save it again in the working directory and invoke Glade in this manner:

GLADE_CATALOG_PATH=. GLADE_MODULE_PATH=. glade-3

Now you should see “Egg Widgets” group in the palette and a little iconless button under it. That would be our clock face widget. Create a top level window and put it in there:

Custom widget in Glade

All that is left for the final step is to is to save this file and modify the main.c to make use of it. Let’s set the “visible” property for the window to true, set gtk_main_quit as its “delete-event” handler and time_changed_cb as the handler for the clock face “time-changed” signal, give it a simple name clock.ui and replace the code of the main function in the main.c with the following:

GtkBuilder *builder;
gtk_init (&argc, &argv);
builder = gtk_builder_new ();
gtk_builder_add_from_file (builder, "clock.ui", NULL);
gtk_builder_connect_signals (builder, NULL);
g_object_unref (builder);
gtk_main ();
return 0;

Also you’d need to remove “static” from time_changed_cb definition, so GtkBuilder would be able to find the handler. And that’s about it. Now you’re ready to clutter your user interface with multitude of random clocks in all sizes and alignments, and all of them going to be ticking right inside the Glade window. In case you need to see complete sources, just download and extract the final archive.

As you can see, you have to do very little to make your own Glade catalog, so start hacking, file any bugs you have found, and by all means share your work. Feel free to ask any questions on the mailing list, but read the documentation first. Mind though, that with general programming questions you probably would be better off at GTK forums. Any comments regarding this tutorial are also appreciated.

This entry was posted in Linux, Programming and tagged , . Bookmark the permalink.

One Response to Glade Catalog Tutorial

  1. klopotec says:

    Thank you for nice and useful tutorial.
    However, it is not so simple how may looks at first glance.

    I get widget in glade under Egg Widgets tab and yes, clock is ticking when placed to GUI :) even several times.
    But I can’t get it in my (any) project.
    If I include Clock Face Widget to my project my window appears blank no matter if Clock Face is alone on them or with other controls. Do I have to put libegg.so at some specific place or what else can cause this? Or I should include something to my gtk+ project options what I don’t included, or set some switch in compiler?

    Additionally, I would like to know more informations about “marshallers” used here after creating dynamic library.
    Why is this for?
    And related, would this work as well on windows?

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA image
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>