Adaptive UI

As well as using standard GTK widgets for user interface elements, the application also uses the widgets and features provided by the libhandy library to make the application adapt to both large and small screen devices.

We start by looking at the basic user interface design before examining each element in more detail.

Basic Design

The basic design of the user interface is that of a sidebar list, with a list of locations on the left side of the window and the current forecast on the right.

The basic design of the user interface, showing the two elements side-by side

The basic design of the user interface, showing the two elements side-by side

On a small screen, it is expected that only one of these elements will be visible at any given time. Therefore, the user needs to be able to switch between them, and this is also something the application should do automatically in certain situations. For example, when the user selects a location in the list, we should automatically display the relevant forecast.

We can think of the two elements as pages: a locations page and a forecast page, each with a header at the top. We will design these pages separately and bring them together later.

Designing the Pages

The locations page is basically a scrolling list of locations with a header showing the name of the application. The header bar also contains a button allowing the user to search for places and add them to the favorites list.

The widgets used to make the locations page

The widgets used to make the locations page

The main part of the page is a Gtk.Box widget which contains a Gtk.ScrolledWindow, providing a view onto a Gtk.TreeView widget that holds an item for each of the user’s favorite places.

When an item is clicked, the forecast page will be populated with information downloaded from the remote weather service, then shown.

The forecast page has a header showing the name of the place the forecast is for, along with a back button that lets the user return to the list of locations. The back button is only shown if the forecast page is shown on its own, without the locations page alongside it – see below for the details.

The widgets used to make the forecast page

The widgets used to make the forecast page

In the main part of the page, another Gtk.Box widget is used to manage a Gtk.ScrolledWindow containing a collection of Gtk.Image and Gtk.Label widgets, and also a Gtk.Label page footer that does not scroll.

When the user selects the back button, the locations page is shown again.

Using Leaflets

In an adaptive user interface, key elements can either be shown individually or together, depending on the amount of screen space available. When they are shown individually, there should be ways to navigate between them. When shown together, any UI components that provide this navigation should be hidden because they are unnecessary and could be distracting to the user.

We manage the pages using two Handy.Leaflet widgets from the libhandy library. These containers work together to manage the dimensions of their children, showing and hiding widgets as necessary, to ensure that the UI behaves in the way described above.

Using leaflets to manage page headers and bodies

Using leaflets to manage page headers and bodies

When there is enough space, the pages are shown side-by-side. If there is not enough space, each leaflet is folded, and the pages are shown individually. The use of a back button in the forecast page lets the user return to the locations page when the leaflets are folded.

The Adaptive UI tutorial provides a basic introduction to leaflets.

Searching for Locations

When the user selects the search button in the header of the locations page, a Handy.SearchBar widget is shown, allowing the user to type a place name. Search suggestions appear in a Gtk.Popover widget that appears beneath the search bar.

The widgets used to implement searching and search suggestions

The widgets used to implement searching and search suggestions

The popover is given a fixed size and contains a Gtk.ScrolledWindow so that a reasonable number of suggestions can be displayed. The scrolling area contains a Gtk.Box that holds a collection of Gtk.ModelButton widgets for the matching place names. When the user selects one of these, the location it represents is added to the list of favorites and the forecast page is updated with the forecast for that location.

Removing Favorites

When the user performs a long press on an item in the favorites list, or right clicks on it when using a mouse instead of a touchscreen, a Gtk.Popover widget is used to give them the option of removing the item from the list.

The widget used to implement a menu for removing items

The widget used to implement a menu for removing items

The contents of the popover are obtained from a Gio.Menu object that contains a single “Remove Place” item. Selecting it causes the item to be removed from the list. Pressing elsewhere in the window cancels the popover.