Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gtk HeaderBar ActionBar pack_start pack_end within UI xml file

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 )
like image 234
AsymLabs Avatar asked Feb 02 '18 10:02

AsymLabs


3 Answers

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>
like image 163
AsymLabs Avatar answered Nov 05 '22 15:11

AsymLabs


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 ());
like image 28
José Fonte Avatar answered Nov 05 '22 13:11

José Fonte


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

like image 2
Francesco Garbin Avatar answered Nov 05 '22 15:11

Francesco Garbin