attribute values in gtkaml
Rule of the thumb: when you don’t enclose your attribute values in {}’s, something magic is going to happen.
That is because gtkaml tries to make your life easier. Let’s take the first example,
Properties
<Window title="my window" type="{WindowType.TOPLEVEL}" ...
The difference between using and not using curly braces is obvious: if you use {}, you get to write a valid code expression. Otherwise, gtkaml tries to guess a literal for you: in this case, title being a string property, the value <<my window>> gets translated to <<”my window”">> in Vala.
This would be the equivalent of title=’{“my window”}’ (you have to use the alternate single-quotes of xml for this).If the property is bool, you get exactly the “false” or “true” literal, and if the property is an integer, the same.
Actually, whatever the property is that is not a string, you get what you typed – the “magic” happens only for string properties.
Alternate ’spellings’ for the code above are possible, along the lines of:
<Window>
<title>my window</title>
<type>{WindowType.TOPLEVEL}</type>
</Window>
or if your value contains invalid xml characters:
<title><![CDATA[my window >= your window]]></title>
Signals
<Window destroy="{Gtk.main_quit}" />
<Window delete_event="Gtk.main_quit()" />
<Window delete_event="{ widget => { Gtk.main_quit (); }" />
The difference is that the first is an expression of type “function” (an expression that returns a function), while the second is executable code. The generated Vala source is like this:
//with curly braces:
this.destroy += Gtk.main_quit;
//without curly braces
this.delete_event += (target, event) => { Gtk.main_quit(); };
//third way - just like the first
this.delete_event += widget => { Gtk.main_quit (); };
Second, the value without curly braces does the “magic” of creating an anonymous function and to automatically fill the signal parameters for you. This can be helpful if you want to write short executable code in a simple attribute; otherwise you can write a ‘full-blow’ function body in a CDATA section:
<Window>
<delete_event><![CDATA[{
widget => {
Gtk.main_quit ();
}
}]]> </delete_event>
</Window>
Notice, however, that you have to use curly braces two times: one for the method body, the other for gtkaml to know not to do any ‘magic’.As you can see, no matter how you specify the signal, gtkaml adds the last “;”.
Construct
gtkaml 0.2 (svn version as we speak) features two new properties, named gtkaml:construct and preconstruct. This is because gtkaml creates the class construct for you (where it sets up the attributes, adds children to containers etc), but you might need to add yourself code there. You can use gtkaml:preconstruct and gtkaml:preconstruct on all tags:
- preconstruct is executed just after the object is instantiated, before setting the other properties
- construct is executed just before the object is added to it’s parent container
As a side effect, the root tag has ‘preconstruct’ executed before all others preconstructs and the ‘construct’ after all other constructs.
These attributes are to be used exactly like a signal: you write code, and you have the “target” parameter (the widget)
In the case of using {}, you can directly assign an existing function that receives a widget or void as parameter, or write a lambda expression in-place.
Example:
<Window
class:preconstruct="{view_init}"
class:construct="post_init(target)" />
As with the signals above, the first attribute simply sets “view_init” as the method to be called, and the second method actually wraps the call into a lambda function defined like target => { post_init (target); };
There isn’t much to do with the target parameter in this example: you can always use this. instead. But it may be very useful if you want to modify an unnamed widget.