GEP 6: Toolbar

I have put together a GEP to discuss requirements for an updated GtkToolbar widget. Discussion should take place on gtk-devel-list gnome org There is a prototype for the new toolbar in libegg that will be updated as this GEP progresses.

The GEP follows.


Email: james daa com au              |
WWW: | Jan 22-25 Perth, Western Australia.

The current |GtkToolbar| widget lacks a number of features which are desirable to applications. This GEP discusses the requirements for an updated toolbar widget.

 1. Administrivia

Document Owner
James Henstridge <mailto:james daa com au>Posted
September 12, 2002Discussion Period Ends
October 1, 2002Status
PendingDiscussion List
gtk-devel-list gnome org <mailto:gtk-devel-list gnome org>Responsible Persons
   James Henstridge <mailto:james daa com au>, Anders Carlsson
   <mailto:andersca gnu org>, Owen Taylor <mailto:otaylor redhat com>,
Michael Meeks <mailto:michael ximian com>

 2. Requirements

Due to a number of inadequacies, the |GtkToolbar| widget is passed over for alternatives (such as |BonoboUIToolbar|) in various programs. There are a number of down sides to this arrangement:

   * The toolbars on different applications act differently.
   * Keyboard navigation and accessibility may not be implemented to
     the same level as |GtkToolbar|, or may be inconsistent.
   * /think of some more reasons why this is bad/

Some of the reasons why replacement toolbars have been developed include:

   * Toolbar buttons are difficult to manipulate. As they are not
     widgets in their own right (just a structure pointing at the
     |GtkButton|, label and icon that make them up), it is difficult to
     move buttons within a toolbar, or between toolbars.
   * No way to specify that a toolbar item should expand to fill
     available space (eg. the location bar in Nautilus), or be right
     aligned (eg. a throbber).
   * Separators are not quite like other toolbar items. On occasions,
     you might want to hide some buttons on the toolbar. However, there
     is no way to hide the separators other than removing them. This
     could be solved by making them widgets like the other items.
   * Overflow is not handled. The current |GtkToolbar| sets its
     requested minimum width (or height for vertical toolbars) wide
     enough to display all items. In some cases, it is desirable to
     allocate less space to the toolbar (eg. small screens, or the user
     resizing the window). It would be nice to have the toolbar handle
     the overflowing items.
   * Difficult to implement toolbar customisation in terms of the
     existing API.
   * No support for "priority text" mode. For some applications, it is
     desirable to display text labels next to some icons, but not
     others. This is done on a number of Windows applications, and

From these experiences, we can put together a list of requirements for an updated toolbar:

  1. Must provide consistent handling of different children types,
     including buttons, separators and other widgets.
  2. Must provide packing options for items, including "expand" and
     "pack end" behaviour.
  3. Must handle overflow items.
  4. Must support "priority text" mode.
  5. Must meet accessibility and keyboard navigation requirements and
     work in right to left environments.
  6. Must provide enough features to satisfy Bonobo's needs.
  7. Should make toolbar customisation possible/easy.
  8. Should stay compatible with the existing GtkToolbar widget.

A sample implementation is being maintained in the |libegg <>| module, and will be updated as the GEP progresses.

   2.1 Toolbar Children as Widgets

Unlike other container widgets in GTK, |GtkToolbar| provides functions that create and add toolbar items to the toolbar in a single step. This is in contrast to other container widgets, where children are constructed first, then added to the parent.

This is because toolbar items are generic |GtkButton| widgets with some callbacks attached. The only way the callbacks can be attached is by creating the button with one of the provided |GtkToolbar| APIs.

As the widget has evolved, the number of methods used to add items has grown to 17.

By having specialised toolbar child widgets that managed their own appearance (in contrast to the way |GtkToolbar| currently maintains it), we could reduce the number of APIs substantially. Other than the standard |GtkContainer| |add| and |remove| method, we could make do with an |insert| method something like this:

void gtk_toolbar_insert_toolitem (GtkToolbar  *toolbar,
                                 GtkToolItem *item,
                                 gint         position);
Such a function could be used for |append| and |prepend| operations, by passing -1 or 0 for the |position| argument respectively. If desired, actual functions could be provided as well.

By treating separators as toolbar items too, we get rid of the need for special APIs to add/remove them, and can manipulate them as with any other item (changing the visibility, in particular).

   2.2 Packing Options

There are a number of real world examples where "expand" and "pack end" options would be useful.

The most obvious use for an "expand" option is for things like the Mozilla and Nautilus toolbars, where the location entry box should expand to fill any extra space.

The "pack end" option is useful for toolbar items such as throbbers/spinners found in web browsers.

   2.3 Overflow

On some displays, a toolbar may not be able to display all items in the width of the screen. The toolbar should handle this gracefully, rather than forcing the window to be wider than the screen. The common way to handle this is to omit the last items in the toolbar and provide a small arrow button at the end of the toolbar that can be used to access the extra items.

Two methods of presenting the additional toolbar items include:

   * The |BonoboUIToolbar| method, which pops up a panel containing the
     extra toolbar items.
   * The method used on Qt, Windows and Mac OS X, where a menu is
     popped up that contains menu items representing the extra items.

The |BonoboUIToolbar| method has the benefit of not requiring additional support from toolbar items. In contrast, the second is more consistent with other popular user interfaces so has the benefit of familiarity.

Final say on how overflow items should be presented should probably be made by the usability team.

   2.4 Priority Text

For some toolbars, the number of items makes it impractical to display text labels for all items, as it would cause many items to overflow. However, it may be desirable to display labels for some items.

This is achieved by another toolbar style known as "priority text" mode in the |BonoboUIToolbar| code. In this mode, most items only display an icon, while some display a text label next to the icon. This makes it easier to identify important toolbar items, and provides a larger target for use with the mouse.

   2.5 Accessibility and Internationalisation Requirements

The updated toolbar should meet accessibility requirements. The main one that must be implemented within the toolbar code itself is keyboard navigation. The draft set of key bindings for toolbars is available at the GNOME Accessibility Project web site: On the i18n front, the toolbar should work well in right-to-left environments, like other GTK widgets. This includes:

   * laying out items from the right edge of the toolbar
   * packing "pack end" items at the left edge
   * when in "both_horiz" or "priority text" toolbar modes, display
     text labels to the left of their icons.

   2.6 Satisfy Bonobo's Requirements

The |BonoboUIToolbar| widget was developed because the |GtkToolbar| widget could not do everything that was needed. It is desirable that the updated toolbar widget be satisfy Bonobo's requirements, so that the |BonoboUIToolbar| widget can be deprecated in a future version.

The main requirement not mentioned elsewhere is the ability to insert Bonobo controls into a toolbar. This should be possible to do through the use of a toolbar item wrapper around the control.

   2.7 Toolbar Customisation

Customisable toolbars are a desirable feature for many applications. Having toolbar items as first class objects that can be added and removed from toolbars should make implementation of this feature a lot easier.

There are three main toolbar customisation user interfaces in use in modern applications:

*Direct manipulation*
   As in Microsoft Office. Toolbar items are dragged from a palette
   onto the actual toolbars. To rearrange items, they are simply
   dragged to the new position. To remove items, they are dragged back
   to the palette. This method is good for customising multiple
toolbars at once.*Mac OS X Style*
   A copy of the toolbar and a palette of toolbar items are displayed
in a single dialog. This interface is better suited for single toolbars.*Internet Explorer Style*
   This is another user interface suitable for customising a single
   toolbar. It has a dialog with two list boxes: one of available
   toolbar items, and another with the toolbar items currently on the
   toolbar. There are buttons for moving items up and down in the list,
   and to move items between the two lists. Items can also be
added/removed with drag and drop.

Decision on the preferred interface should be up to the usability project and/or accessibility project.

Whether the toolbar should include code to help customise the toolbar or not is open to discussion. The toolbar should definitely not get in the way of such code though.

   2.8 Compatibility Concerns

Compatibility with the existing |GtkToolbar| is desirable, as it eliminates the need to deprecate the widget.

By using specialised widgets in the toolbar, the existing methods used to create toolbar buttons could be deprecated in favour of a simpler API, as outlined in Section 2.1.

Although no fields are marked with /*< public >*/, the |num_children| and |children| fields are mentioned in the GTK documentation. These members appear to be used by AbiWord, so can not be ignored. It should be fairly easy to write compatibility code in the deprecated toolbar item creation code. If an app uses the new APIs, the contents of these members would not be defined.

Additional fields could be stored in a private structure accessed with |g_object_get_data()|, so as to not grow the structure size.

 3. Issues Raised During Discussion

None yet.

 4. Decision and Rationale

None yet.

 5. Amendments and Clarifications

None yet.

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]