8

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 )
AsymLabs
  • 933
  • 9
  • 15

4 Answers4

8

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>
AsymLabs
  • 933
  • 9
  • 15
3

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:

  1. Gtk.HeaderBar pack_start and pack_end
  2. Gtk.Container methods (add, add_with_properties...)

Example, in Vala, to add a Gtk.ColorButton using 1 and 2:

  1. header_bar.pack_start (new Gtk.ColorButton ());
  2. header_bar.add (new Gtk.ColorButton ());
José Fonte
  • 4,016
  • 2
  • 16
  • 28
  • 1
    Thank you for clarifying, José. We're arriving at the conclusion that, when using Genie with Templates and glib-compile-resources, the only widgets we need to identify programmatically are those that are subject to change. Everything else can be put it the ui files and can be finely tuned (w/respect to appearance and function) using Glade. That is why I wanted to see an xml ui example of packing - what it should look like. Genie is an extremely underrated language, it seems. – AsymLabs Feb 02 '18 at 12:04
  • 2
    @AsymLabs yes, Vala and Genie do not see much "love", specially Genie. Regarding the question itself. Yes, indeed, you name and mark as GtkChilds, those you will use or reference in your program. All other are redundant. They are there but don't need to be used, mostly containers. Check github for a bunch of GNOME applications, none in Genie i suppose but a few are in Vala. Good luck. Btw, feel free to accept the answer if it answers your question. – José Fonte Feb 02 '18 at 12:12
  • The rapidly evolving Gnome ecosystem Gnome-Builder / Glade / Vala / Genie / Meson / Flatpak has the potential to leap-frog all other competitive technologies and we are seriously considering officially adopting it. One problem we have, however, is that Glade is not very intuitive. Does Glade offer any pre-designed completely decorated windows that would allow the examination/inspection of the xml ui files? Or are there any that can be linked? – AsymLabs Feb 02 '18 at 12:37
  • 1
    @AsymLabs Well, Glade has been seeing some developing. Check this video https://www.youtube.com/watch?v=0krTtJCJ0Pg and also check the modern UI branch on Glade github repository. Predesigned windows i'm assuming default composite windows like File Chooser or Color Chooser, those exist. The best way to examine is to check an application you like and check how they were implemented. Also read the [GNOME Human Interface Guidelines](https://developer.gnome.org/hig/stable/) – José Fonte Feb 02 '18 at 12:49
  • 1
    You can look into the source code of your favorite GNOME applications for example glade ui files. – Jens Mühlenhoff Feb 02 '18 at 12:50
2

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.

Screenshot of Glade showing the position tab

The Glade preview also renders the 3rd button packed at the end, just like a call to pack_end() in code.

Screenshot of Glade preview

0

With GTK4, positioning widgets in an ActionBar is done with a type attribute on the child tag:

<object class="GtkActionBar">
    <child type="start">
        <object class="GtkButton">
            <property name="label">Start</property>
        </object>
    </child>
    <child type="center">
        <object class="GtkButton">
            <property name="label">Center</property>
        </object>
    </child>
    <child type="end">
        <object class="GtkButton">
            <property name="label">End</property>
        </object>
    </child>
</object>
Nicolas
  • 6,611
  • 3
  • 29
  • 73