We are trialing Gtk3/Vala/Genie for the development of application user interfaces using Gnome-Builder/Meson/Glade/Flatpak. While there are many examples of Gtk.HeaderBar.pack_start( ... )
and Gtk.ActionBar.pack_start( ... )
within the Vala and other Gtk documentation, we have not been able to find examples of use within an xml ui file.
So the question is: how does one use pack_start/pack_end with the ui xml file? Are there any examples of a generated xml ui file or how to generate within Glade? Would this be entered as a property/attribute/child of the HeaderBar/ActionBar? What would this look like - what would be the general structure? If it is not a GtkChild
, then how does one access it within the Vala/Genie source file?
Supplying the following trivial xml file MainApplication.ui
, for example, how would one pack_start
and pack_end
a GtkColorButton
to the GtkHeaderBar
?
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.2 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="MainWindow" parent="GtkApplicationWindow">
<property name="can_focus">False</property>
<property name="default_width">1024</property>
<property name="default_height">768</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="header_bar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="title">Test Application</property>
<property name="subtitle">gnome.org</property>
<property name="show_close_button">True</property>
</object>
</child>
<child>
<object class="GtkBox" id="content_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<placeholder/>
</child>
<child>
<object class="GtkActionBar" id="action_bar">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</template>
</interface>
This is used within the source file MainApplication.gs
as follows:
[GtkTemplate (ui = "/org/gnome/application/ui/MainApplication.ui")]
class MainWindow : Gtk.ApplicationWindow
[GtkChild]
header_bar:Gtk.HeaderBar
[GtkChild]
action_bar:Gtk.ActionBar
construct ( application:Gtk.Application )
GLib.Object( application: application )
class MainApplication:Gtk.Application
construct( id:string, flags:GLib.ApplicationFlags )
/* set locale: ALL, "" */
Intl.setlocale()
/* set properties */
set_application_id( id )
set_flags( flags )
OK. Just for the purpose of completion, after playing around with Glade I have generated this structure for the ui xml file that illustrates how packing works in a HeaderBar. I simply could not find any examples of this nor could I find any source that contained this within the ui file - plenty doing it programmatically - but none so far showing it as xml. The magic occurs when a <packing></packing>
tag indicating position
(zero based) is included as part of the child element, ie:
<packing>
<property name="position">2</property>
</packing>
And it appears that there is no need to include the packing tag for the first zero indexed child.
For end packing, the magic occurs by use of a pack_type
property:
<packing>
<property name="pack_type">end</property>
<property name="position">1</property>
</packing>
So the equivalent xml for programmatic pack_start
and pack_end
is the pack_type
property.
In full context, the following illustrates use in a titlebar containing a GtkHeaderBar:
<child type="titlebar">
<object class="GtkHeaderBar" id="header_bar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="title">Test Application</property>
<property name="subtitle">gnome.org</property>
<property name="show_close_button">True</property>
<child>
<object class="GtkButton">
<property name="label">gtk-justify-fill</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<property name="always_show_image">True</property>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label">gtk-edit</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<property name="always_show_image">True</property>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton">
<property name="label">gtk-find</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
how does one use pack_start/pack_end with the ui xml file?
You don't. These methods are used to programmatically add child widgets to container widgets. Doing that using glade avoids the need to do it with code.
Are there any examples of a generated xml ui file or how to generate within Glade?
Not sure i understood the question here. Glade generates xml ui definition files. Using them with GtkBuilder would instantiate the widgets which you could then retrieve with Gtk.Builder get_object
method. There is another option, which you are using, called Gtk Composite Templates. This allows you to create composite widgets inside glade and map the widgets to your code class/class properties/fields and this will accelerate the coding process. You can read more here
Would this be entered as a property/attribute/child of the HeaderBar/ActionBar?
It's flexible enough to have a Window class with an header bar as a property/field and widgets within the header bar would also be properties of the window OR separate concerns and have an header bar as a composite widget and then add the header bar to the window. For this last option you would then need to set the header bar to the window programmatically unless you are ready to work on glade widget catalogs allowing you to have your own header bar composite widget available on the left widget palette in glade.
What would this look like - what would be the general structure? If it is not a GtkChild, then how does one access it within the Vala/Genie source file?
If it's not a child we would assume it's not inside the glade definition or does not live anywhere and so it would have to be instantiated programmatically and added to a container with Gtk.Container add
method or specific container add methods like pack_start/end
, etc.
Supplying the following trivial xml file MainApplication.ui, for example, how would one pack_start and pack_end a GtkColorButton to the GtkHeaderBar?
You can add a GtkColorButton with glade, name it, set it as a GtkChild and retrieve it. It would be a field of your composite widget (assuming your code and the use of templates).
If not, then you would create a new instance of Gtk.ColorButton and add it, programmatically, to the Gtk.HeaderBar. Since Gtk.HeaderBar is a container (inherits from Gtk.Container abstract class), you have some methods to add childs to it:
Example, in Vala, to add a Gtk.ColorButton
using 1 and 2:
header_bar.pack_start (new Gtk.ColorButton ());
header_bar.add (new Gtk.ColorButton ());
It's perfectly feasible in Glade as well by using the "position" tab.
See the attached image and notice that I positioned the 3rd button at the right-end of the headerbar. Select the button, click che position tab and select "end" as position.
The Glade preview also renders the 3rd button packed at the end, just like a call to pack_end() in code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With