Gtk+.rst 8.54 KB
Newer Older
Adrien Plazas's avatar
Adrien Plazas committed
1 2

.. _gtk+:
3

David Boddie's avatar
David Boddie committed
4 5
.. note:: New advice on adaptive GTK+ applications development are regularly
          documented on this page.
6

Adrien Plazas's avatar
Adrien Plazas committed
7 8 9
GTK+
====

10
`GTK+ <GTK+ website_>`_ is the graphical application framework used to develop all GNOME applications. This section presents tips and tricks with GTK+ to help you develop great adaptive applications for GNOME, for general GTK+ and GNOME development resources please check the :ref:`gnome_resources` page.
11
Don't forget to check its `documentation <GTK+ 3 documentation_>`_ out.
Adrien Plazas's avatar
Adrien Plazas committed
12

13
`libhandy <libhandy website_>`_ is a widget library for GTK+. It contains widgets useful for both phone applications and adaptive applications and it is going to be used in that page as an extension to GTK+.
14
Don't forget to check its `documentation <libhandy documentation_>`_ out.
15

16
.. warning:: From now on, this section assumes you are familiar with the basics of GTK+ application development. It also assumes you are using GTK+ 3.24.1 or newer and libhandy 0.0.4 or newer as these versions received improvements required for adaptive apps to function properly.
17

Adrien Plazas's avatar
Adrien Plazas committed
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
The GTK+ Inspector
------------------

The `GTK+ Inspector`_ is a tool giving you direct and dynamic access to the internal state of the user interface of your GTK+ application at runtime. It is similar in concept to a web inspector.

The GTK+ Inspector is extremely convenient to debug your GTK+ application. To use it you first need to enable it via GSettings::

   $ gsettings set org.gtk.Settings.Debug enable-inspector-keybinding true

To trigger the inspector simply press `Control-Shift-I` or `Control-Shift-D` when running the application.

Alternatively you can set the ``GTK_DEBUG`` environment variable to ``interactive``::

   $ GTK_DEBUG=interactive your-application

33
.. note:: For the GTK+ Inspector to work in your flatpaked application, see how to `enable dconf access`_ in the the Flatpak documentation.
Adrien Plazas's avatar
Adrien Plazas committed
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48

Application Menu
----------------

GNOME applications are expected to have an application menu following the designs listed here: `application menu design`_.

To help you implement these, we created an `example application <application menu example application_>`_, just clone it in :ref:`gbuilder` and check the ``app-menu`` branch out.

Adaptive Labels
---------------

A GtkLabel_ can prevent your application's UI from reaching really small sizes, but there are simple tricks to make them do so. Consider using one of the following tricks on each of your labels!

Allowing your label to ellipsize will cut a part of your string when there isn't enough space for it, you can enable it and choose which part will be cut with the `GtkLabel ellipize property`_. Use it if you really need your label to be on a single line.

49 50 51
.. note:: If you allow your label to be ellipsized, make sure that its `xalign property <GtkLabel xalign property_>`_ matches its justification or your label may not be properly aligned when ellipsized: 0 for left, 1 for right, or 0.5 for center.

.. note:: If an ellipized label has an HdyLeaflet_ for ancestor and you want the label to be ellipsized before the leaflet folds itself, try wrapping your label in a GtkScrolledWindow_, optionally expanding the scrolled window horizontally. Don't worry, it won't surround your label with scrollbars but just trick the sizing system into doing what you expected it to do.
52

Adrien Plazas's avatar
Adrien Plazas committed
53 54 55 56 57
Letting your label wrap will preserve the integrity of the text at the expense of more height, you can enable it with the `GtkLabel wrap property`_ and choose how to wrap with the `GtkLabel wrap-mode property`_.

.. note:: By allowing the label to wrap, it will always request enough height when fully wrapped. Consider putting your label or a widget containing it into a scrollable window to avoid height becoming a problem.

To help you implement these, we created an `example application <adaptive labels example application_>`_, just clone it in :ref:`gbuilder` and check the ``adaptive-labels`` branch out.
58

59 60 61 62 63 64 65 66 67
Title Bars
----------

A GtkHeaderBar_ is meant to be used in a window's title bar, typically presenting to the user the application's title, various controls and a `close` button.

HdyTitleBar_ is a simple container that takes care of the look of the title bar.
It is a very convenient widget as it allows header bars to look good when animated by ensuring they don't draw the title bar's background themselves, which is a requirement for adaptive apps, and it simplifies common operations like setting the selection mode a lot.

Some title bars are composed of multiple header bars, in such a case it is advised to separate them with a GtkSeparator_ with the `sidebar` style class.
68
To help spreading the window decoration across all header bars as if they were only one, just show the close button on all of your header bars and put them into a HdyHeaderGroup_ in the same order they appear in the title bar.
69

David Boddie's avatar
David Boddie committed
70 71 72
Here is an simple `GtkBuilder` example showing this section's advice:

.. literalinclude:: /Apps/_files/window.ui
73 74 75 76 77 78 79

Selection Mode
--------------

As per the GNOME human interface guidelines, applications may enter a special `selection mode`_. Setting the selection mode to an application in previous versions of GTK+ was complicated as it implied having to manually add or remove the `selection-mode` style class to each of your header bars, while their separators were condamned to look ugly as they were not styled accordingly.

HdyTitleBar_ and recent improvements in the default theme of GTK+ simplifies that a lot, simply toggle the `selection-mode` boolean property of HdyTitleBar_ for their descendants to be styled accordingly, including separators with the `sidebar` style class.
80

81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
Adaptive Grid Layout
--------------------

Some applications have a grid layout where several panels sit side-by-side and extend to the title bar.
To make an application with a adaptive grid layout, follow these steps:

The basic layout:
 * In the title bar put a HdyTitleBar_, put a HdyLeaflet_ in it in which you will put your sidebar's GtkHeaderBar_, a GtkSeparator_ and your content's GtkHeaderBar_.
 * In the window put a HdyLeaflet_ in which you will put your sidebar widget, a GtkSeparator_ and your content widget.
 * Add the `sidebar` style class to the separators from the titelbar and the window.
 * Make the close buttons of your header bars visible.

Make it a grid:
 * Put your sidebar widget and its header bar into the same horizontal `GtkSizeGroup` to ensure they request the same minimum width.
 * Put your separators into the same horizontal `GtkSizeGroup` to ensure they request the same minimum width.
 * Put your content widget and its header bar into the same horizontal `GtkSizeGroup` to ensure they request the same minimum width.
 * Horizontally expand the content widget and the content header bar.

Solidify the layout:
 * Give the `sidebar` child name to your sidebar widget and its header bar.
 * Give the `content` child name to your content widget and its header bar.
 * Make your header bar leaflet's child and mode transitions to `slide` to improve spacial navigation semantics.
 * Bind your window's leaflet's visible child name and your child and mode transitions (duration and type) to your header bar leaflet's in a bidirectional way to ensure they always appear as a single unified panel.
 * When the leaflets are folded, make the header group focus on the currently visible header bar, make it focus on nothing otherwise.

Navigate in the layout:
 * Add a back button at the start of your content header bar.
 * When your header bar leaflet is folded, make the back button visible, make it invisible otherwise.
 * When the back button is clicked, make the sidebar the visible child of the leaflets.
 * When an entry of your sidebar is clicked, make the content visible.

.. image:: images/adaptive-grid-layout.png
113 114 115 116
   :width: 600px
   :height: 300px
   :align: center

117
To help you implement these, we created an `example application <adaptive grid layout example application_>`_, just clone it in :ref:`gbuilder` and check the ``adaptive-grid-layout-0-0-3`` branch out.
118 119 120 121 122 123 124 125 126

.. include:: ../../links.rst

.. _selection mode : https://developer.gnome.org/hig/stable/selection-mode.html.en
.. _enable dconf access : http://docs.flatpak.org/en/latest/sandbox-permissions.html#dconf-access
.. _application menu design : https://gitlab.gnome.org/Community/Design/os-mockups/tree/master/app-menu
.. _application menu example application : https://source.puri.sm/Librem5/purism-gtk-3-examples/tree/app-menu
.. _adaptive labels example application : https://source.puri.sm/Librem5/purism-gtk-3-examples/tree/adaptive-labels
.. _adaptive grid layout example application : https://source.puri.sm/Librem5/purism-gtk-3-examples/tree/adaptive-grid-layout-0-0-4