Special Dialog Types

This section describes some special kinds of dialog that exist for your convenience, and for UI consistency. Of course nearly everything said so far about GnomeDialog also applies to its subclasses.

GnomeAbout

Gnome applications should have an "About Foo" menu item which displays this widget (where "Foo" is the name of your application). Using it is ridiculously easy; there's only one function involved, gnome_about_new() (Figure 7). The arguments are, respectively: the title of your application, the version of your application, a one-line copyright notice, a NULL-terminated vector of author's names, a short paragraph saying anything you want to say, and an image filename to display as your application's logo. Only the authors argument is required; the others can be NULL, but your dialog will look fairly strange if all of them are.

       #include <libgnomeui/gnome-about.h>
      

GtkWidget* gnome_about_new(const gchar* title, const gchar* version, const gchar* copyright, const gchar** authors, const gchar* comments, const gchar* logo);

Figure 7. GnomeAbout

GnomeAbout automatically closes when clicked, so you don't really need to worry about it; just create and show the dialog. Remember to ensure only one instance exists at any given time, as explained in the section called Finishing Touches.

Here's a menu item callback to show an about dialog, from the Gnome calendar application:


static void
about_calendar_cmd (GtkWidget *widget, void *data)
{
   GtkWidget *about;
   const gchar *authors[] = {
     "Miguel de Icaza <[email protected]>",
     "Federico Mena <[email protected]>",
     "Arturo Espinosa <[email protected]>",
     NULL
   };

   about = gnome_about_new (_("Gnome Calendar"), VERSION,
                            "(C) 1998 the Free Software Foundation",
                            authors,
                            _("The GNOME personal calendar and schedule manager."),
                            NULL);
   gtk_window_set_modal (GTK_WINDOW (about), TRUE);

   gtk_widget_show (about);
}
      

Note that the authors give both their name and email address; that way people can use the dialog to decide where to send hate mail and bug reports. (Or thank you notes!) The VERSION macro comes from config.h, and is defined by configure. The Gnome Calendar authors chose to prevent multiple dialog instances by making the dialog modal---the user can't re-select the menu item while the dialog is open. It is probably better to use the technique described in the section called Finishing Touches, so the dialog is deiconified and raised if the user reselects the menu item.

GnomePropertyBox

GnomePropertyBox is used for application preferences, or to edit the properties of a user-visible object. It's a dialog with a GtkNotebook inside, and four buttons: "OK," "Apply," "Close," and "Help." The "OK" button is equivalent in all respects to clicking "Apply" followed by "Close." "Apply" should immediately make any changes the user has requested using the widgets you've placed in the GnomePropertyBox. Unsurprisingly, "Help" should display help. "OK" and "Close" are handled automatically by the property box, so you can ignore them.

You don't need to deal with the property box's buttons directly; instead GnomePropertyBox emits "apply" and "help" signals. Handlers for these should look like:


void handler(GtkWidget* propertybox, gint page_num, gpointer data);

      

page_num is the currently-active page of the GtkNotebook inside the dialog. (GtkNotebook pages are numbered from front to back, starting with 0; the front page is the first one you add to the notebook.) For "help", the page number lets you provide context-sensitive help. When the user clicks the "Apply" or "OK" button, the "apply" signal is emitted once per page, then emitted a final time with -1 as the page_num value. The multiple emissions of "apply" are something of an anachronism, because it has become de facto standard behavior to simply apply all pages when the -1 page number is received.

To create a property box, you first create the dialog, then create each page and add it. Creating a GnomePropertyBox is straightforward; gnome_property_box_new() takes no arguments.

       #include <libgnomeui/gnome-propertybox.h>
      

GtkWidget* gnome_property_box_new(void);

gint gnome_property_box_append_page(GnomePropertyBox* pb, GtkWidget* page, GtkWidget* tab);

Figure 8. GnomePropertyBox

You then create a widget for each page (probably a container with a number of controls inside), and append it to the property box with gnome_property_box_append_page() (Figure 8). Its page argument is the widget to place inside the new notebook page, and tab is a widget to use on the notebook tab. The page number of the newly-added page is returned, so you don't have to keep a count yourself.

It's your responsibility to keep track of any user interaction with the contents of each page. When the user changes a setting, you must notify the property box; it uses this information to set the "Apply" and "OK" buttons sensitive if and only if there are unapplied changes. The relevant routines are in Figure 9.

       #include <libgnomeui/gnome-propertybox.h>
      

void gnome_property_box_changed(GnomePropertyBox* pb);

void gnome_property_box_set_state(GnomePropertyBox* pb, gboolean setting);

Figure 9. Property Box State

gnome_property_box_changed() tells the property box about changes; the property box will automatically unset its internal "changes pending" flag when "apply" is emitted. If you need to change that internal flag for some reason (unlikely), you can use gnome_property_box_set_state().

GnomeMessageBox

A GnomeMessageBox is a GnomeDialog subclass that conveys a short message or asks a simple question. Gnome provides several "types" of message box; they have different icons next to the text, and corresponding titles. The icons look nice, and allow users to quickly classify the message being presented.

The API is very simple; there are no functions specific to GnomeMessageBox other than the constructor, in Figure 10. The first argument is the message to display; the second is a string encoding the message box type. Then you can list any buttons, just as you would with gnome_dialog_new(). Unlike the unadorned GnomeDialog, GnomeMessageBox closes on any button click by default. Of course you can change this behavior using gnome_dialog_set_close().

       #include <libgnomeui/gnome-messagebox.h>
      

GtkWidget* gnome_message_box_new (const gchar* message, const gchar* messagebox_type, ...);

Figure 10. Message Box Constructor

Macros are provided for the available message box types.

Here's how you might use GnomeMessageBox:


  GtkWidget * mbox;

  mbox = gnome_message_box_new (message, 
                                GNOME_MESSAGE_BOX_INFO,
                                GNOME_STOCK_BUTTON_OK, 
                                NULL);
  
  gtk_widget_show (mbox);
      

Notice that GnomeMessageBox, like most GnomeDialog subclasses but not GnomeDialog itself, automatically closes when clicked. So there is no need to destroy it by hand.