Nerd wannabe

lazy weblog

how gtkaml works

with 5 comments

If you are writing something based on GTK+ / GObject then you should be interested by this:

  • Vala is a very productivity-boosting language based on GObject OOP-ness, which translates to C and therefore can export GObject classes and interfaces from shared libraries.
  • gtkaml is a thin SAX Parser on top of Vala that allows you to write XML user interface descriptions

This is how a minimal Vala class described with gtkaml looks like:

<VBox class:name="MyVBox"
      xmlns="Gtk" xmlns:class="http://gtkaml.org/0.1">
        <Label label="Hi_story"
               expand="false" fill="false" padding="0" />
</VBox>

This code creates a class named MyVBox that extends VBox and contains a Label. The label has the value “History”, it does not expand or fill its box and is not padded.Easy, no?

But GtkLabel doesn’t have expand, fill, or padding properties! I hear you say. Yes, but the pack_start () method has them as parameters.

Which leads us to the first subject:

Container Add Methods

gtkaml uses a file named implicits.ini to determine which containers have which add methods. This is for “implicit” decisions it makes based on your UI layout.

For the example above, it simply finds this:

[Gtk.Container]
adds=add_with_properties
[Gtk.Box]
adds = pack_start;pack_end;pack_start_defaults;pack_end_defaults

This simply lists all the functions that one can use to add widgets to a Box and to a Container. Since VBox is a Box and Box is a Container, gtkaml finds these two entries ‘significant’ and merges them in this order (most specialized first):

pack_start;pack_end;pack_start_defaults;pack_end_defaults;add_with_properties

Then it loops over these methods – in this order – finds the first matching one and ‘picks’ the parameters from the child widget tag: that is, it removes “expand”, “fill” and “padding” from the Label and makes a note to use their value when adding the label in the VBox.

What if I want to use another add method?

Well, in that case simply specify the method’s name as an attribute of the child tag, with the value “true”:

<Label pack_end="true" label="Hi_story"
               expand="false" fill="false" padding="0" />

Creation methods

In this same example we notice that the label contains an underscore: this is intended to show up as a “mnemonic” (an keyboard shortcut) or simply as “History”.

Looking again at the GtkLabel documentation we notice that the only ways to get a mnemonic is to use either gtk_label_set_text_with_mnemonic () or gtk_label_new_with_mnemonic (). But since gtkaml can only help you with public fields, properties and signals, and not with function calls, how does one specify a mnemonic?

The answer is that you can select a “creation method”, and gtk_label_new_with_mnemonic () is not an ordinary function but a creation method. That is, a method that does not require the object as the first parameter but returns a new object.

So simply specify the creation method name as an attribute with a value of “true”: with_mnemonic=”true”.

Wait, but how about the creation method’s parameters? with_mnemonic has one parameter named str..

Well, usually Gtk widgets’ creation methods have their parameters named after the field/property they are initializing. gtkaml recognizes them from the specified attributes.

In this case, though, str is not a field or parameter of GtkLabel. But we know that it actually refers to the label property.

So what gtkaml does is to specify, again, in implicits.ini, the attributes that will go as parameters to the creation method:

[Gtk.Label]
new = label
new.with_mnemonic = label

So the code becomes:

<Label pack_end="true" with_mnemonic="true" label="Hi_story"
               expand="false" fill="false" padding="0" />

That’s it! – more on what gtkaml 0.2 will do for you in a future article.

p.s. as I am writing this, gtkaml was accepted on freshmeat.net! yay!

Advertisements

Written by vlad

February 7, 2008 at 3:06 pm

Posted in gtkaml, trivia

5 Responses

Subscribe to comments with RSS.

  1. Thank you for all your effort, by why not just use GtkBuilder[1], that’s part of GTK+ and supported by large parts of the GNOME community?

    [1] http://library.gnome.org/devel/gtk/stable/GtkBuilder.html

    Mathias Hasselmann

    March 25, 2008 at 9:01 am

  2. Why should anyone use gtkaml over gtkbuilder.
    Mixing code and XML is a bad idea, even more if it merges ui layout and ui behavior again.
    There are many of tools for nice, clean and separate ui definitions.
    Those are simply superior cause you don’t need to recompile to change the ui layout.

    Some things are meant to be orthogonal – ui behavior and ui layout are some of those.

    Ronny Pfannschmidt

    March 25, 2008 at 9:10 am

  3. @Mathias:
    > by why not just use GtkBuilder
    I want to write UI easily and as close to the Gtk+ API I can get.
    GtkBuilder is a superior option for runtime UI parsing/constructing, while Gtkaml is only another way of writing in Gtk+Vala.

    @Ronny
    > Mixing code and XML is a bad idea
    Of course. But rapid prototyping is one of the first steps. Then you go for UI behaviour/layout separation. But eventually, 90% of UI evolves into being defined dynamically.
    Gtkaml allows you to do that rapid prototyping and then gradually replace hardcoded widgets with dynamically generated ones.

    That being said, I see Gtkaml as code, much like the C code from a custom widget is still code.

    I also have tried porting a glade example ( http://www.michaelwerle.name/Programming/CSharp/SimpleViewer2.glade ) to Gtkaml ( http://code.google.com/p/gtkaml/source/browse/trunk/examples/SimpleViewer2/SimpleViewer2.gtkaml ). The 248 lines of generated UI description shrunk to 54 lines of handwritten markup.

    That’s why I say it’s about rapid prototyping:)

    vlad

    March 25, 2008 at 9:25 am

  4. i see a big problem with handwriting ui definitions
    i prefer the interactive design process ui designers allow me to use, cause its more rapid than handwriting xml and i don’t have to compile/run to see the results

    i don’t see how gtkaml is more rapid than glade + libglade

    Ronny Pfannschmidt

    March 25, 2008 at 9:49 am

  5. You can use glade/gtkbuilder with gtkaml/vala too, of course. For example, writing a custom widgets library in gtkaml, and using them from glade.
    As you said, they are orthogonal:)

    vlad

    March 25, 2008 at 10:28 am


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: