Adding a Status Bar

Adding a status bar is simple enough. Simply call the aptly-named gnome_app_set_statusbar function (Figure 5) with your statusbar widget as the second argument.

However, there are some additional things to keep in mind. First, you can use either GtkStatusbar or GnomeAppBar as a statusbar. Second, you probably want to use the statusbar to display help about menu items as the user moves over them; Gnome comes with convenience functions to do this. This section describes the two status bar widgets; the section called Online Help discusses using the statusbar to display menu item help.

#include <libgnomeui/gnome-app.h>

void gnome_app_set_statusbar(GnomeApp* app, GtkWidget* statusbar);

Figure 5. Installing a Statusbar

GnomeAppBar

There's no real reason to prefer GnomeAppBar or GtkStatusbar; they simply have different APIs. The GnomeAppBar widget was written later, with several goals in mind:

To create a GnomeAppBar, use gnome_appbar_new() (Figure 6). The constructor lets you configure the capabilities of GnomeAppBar: it can have a progress bar (or not), have a status text area (or not), and be interactive (or not). You must have either a status text area or a progress bar. GnomePreferencesType is a kind of extended boolean value:

In Gnome 1.0, interactivity is incompletely implemented; so avoid GNOME_PREFERENCES_ALWAYS. There are some experimental Gnome functions which provide an abstraction of certain user interactions, allowing users to choose between dialogs and the Emacs-style minibuffer approach; when these are more developed, GNOME_PREFERENCES_USER will make sense even if you don't explicitly use the interactivity. So GNOME_PREFERENCES_USER is the recommended setting.

#include <libgnomeui/gnome-appbar.h>

GtkWidget* gnome_appbar_new(gboolean has_progress, gboolean has_status, GnomePreferencesType interactivity);

Figure 6. GnomeAppBar Constructor

Using a GnomeAppBar is simple. The progress-bar element presents a GtkProgress interface; to use it, simply extract the GtkProgress with gnome_appbar_get_progress() (Figure 7) and use the GtkProgress functions. Note that you should not make assumptions about the particular subclass of GtkProgress; in particular, do not cast it to GtkProgressBar.

#include <libgnomeui/gnome-appbar.h>

GtkProgress* gnome_appbar_get_progress(GnomeAppBar* appbar);

Figure 7. Extracting GtkProgress

Status texts are stored in a stack; when the bar is refreshed, the top item of the stack is displayed. The bar is refreshed anytime you manipulate the stack. So pushing some text onto the status stack will display that text.

There are two other sources for the status text. You can set some "default" text; this is displayed if the stack is empty. The default default text is "". You can also set the status text without changing the stack; this "transient" text is immediately displayed, but not stored. On the next refresh (the next time you push, pop, or set the default), the text disappears forever, replaced by the top of the stack.

Figure 8 lists the functions to manipulate the status text. gnome_appbar_set_status() is used to set the transient status text; gnome_appbar_refresh() forces a refresh without changing the stack---this is useful to be sure any transient text has been cleared. The other functions should be obvious.

Note that you can use the GnomeAppBar as a simple label---one message at a time, always replacing the previous message---just stick to either setting the default or setting the transient text, and never use the stack.

#include <libgnomeui/gnome-appbar.h>

void gnome_appbar_set_status(GnomeAppBar* appbar, const gchar* status);

void gnome_appbar_set_default(GnomeAppBar* appbar, const gchar* default_status);

void gnome_appbar_push(GnomeAppBar* appbar, const gchar* status);

void gnome_appbar_pop(GnomeAppBar* appbar);

void gnome_appbar_clear_stack(GnomeAppBar* appbar);

void gnome_appbar_refresh(GnomeAppBar* appbar);

Figure 8. Setting GnomeAppBar Text

GtkStatusbar

GtkStatusbar has no default text or "transient" text, as in GnomeAppBar; it only has a message stack. However, each message is tagged with a "context" identified by a string. When you pop a message off the stack, you must specify a context; the topmost message in that context is popped. If there are no messages in the context you specify, no text is popped. In essence, the GtkStatusbar "pop" operation works only within namespaces. There's no way to unconditionally pop all messages or unconditionally pop the topmost message.

In principle this lets different parts of the program use the statusbar without interfering with one another. However, in my experience there's no need for this. For example, Netscape doesn't even have a stack for its statusbar; its statusbar is simply a label. In general it is poor interface design to make anything essential appear in the statusbar, since the user might not notice it. Accidentally deleting a message should not be a major worry.

Figure 9 shows the GtkStatusbar functions.

To use the statusbar:

  1. First obtain a context ID with gtk_statusbar_get_context_id(); the context_description argument can be any string you like.

  2. Push a message onto the statusbar using gtk_statusbar_push(); the message is tagged with the given context ID. The return value is a message ID you can use to remove the message. (Unlike GnomeAppBar, GtkStatusbar lets you remove a message that isn't on top of the stack.)

  3. Eventually remove the message with gtk_statusbar_remove() or gtk_statusbar_pop(). The former refers to a specific message by ID, the latter removes the topmost message in the supplied context.

Note that gtk_statusbar_push() pushes a message on top of all other messages, even those in other contexts; but gtk_statusbar_pop() will only pop from the context supplied. Contexts do not refer to separate stacks, they merely restrict which messages you are permitted to pop.

#include <gtk/gtkstatusbar.h>

GtkWidget* gtk_statusbar_new(void);

guint gtk_statusbar_get_context_id(GtkStatusbar* statusbar, const gchar* context_description);

guint gtk_statusbar_push(GtkStatusbar* statusbar, guint context_id, const gchar* text);

void gtk_statusbar_pop(GtkStatusbar* statusbar, guint context_id);

void gtk_statusbar_remove(GtkStatusbar* statusbar, guint context_id, guint message_id);

Figure 9. GtkStatusbar