Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com
Answertopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions
Privacy Policy

  




 

 

Gtk+/Gnome Application Development
Prev Home Next

Menus and Toolbars with GnomeUIInfo

It's tedious to create large menus, especially if they have features such as icons and keyboard accelerators. Gnome provides a simple solution. You assemble a GnomeUIInfo struct as a template for each menu item, simply listing its characteristics: name, icon, accelerator, and so on. The Gnome libraries can automatically create menus from arrays of GnomeUIInfo templates. The same method works with toolbars.

Here's the declaration of struct GnomeUIInfo.


typedef struct {
  GnomeUIInfoType type;
  gchar* label;
  gchar* hint;  
  gpointer moreinfo;    
  gpointer user_data;
  gpointer unused_data;
  GnomeUIPixmapType pixmap_type;
  gpointer pixmap_info;
  guint accelerator_key;
  GdkModifierType ac_mods;
  GtkWidget* widget;
} GnomeUIInfo;

A static initializer is the most convenient way to fill in the struct (but of course you can create it dynamically if you prefer). Gnome's routines accept an array of GnomeUIInfo, and macros are provided to simplify and standardize the most common static initializers. Here's a typical example, a File menu:


static GnomeUIInfo file_menu[] = {
  GNOMEUIINFO_MENU_NEW_ITEM(N_("_New Window"),
                            N_("Create a new text viewer window"), 
                            new_app_cb, NULL),
  GNOMEUIINFO_MENU_OPEN_ITEM(open_cb,NULL),
  GNOMEUIINFO_MENU_SAVE_AS_ITEM(save_as_cb,NULL),
  GNOMEUIINFO_SEPARATOR,
  GNOMEUIINFO_MENU_CLOSE_ITEM(close_cb,NULL),
  GNOMEUIINFO_MENU_EXIT_ITEM(exit_cb,NULL),
  GNOMEUIINFO_END
};

There isn't always a nice macro for the menu item you want, so sometimes you must manually specify each element of the struct:


{ 
  GNOME_APP_UI_ITEM, N_("_Select All"),
  N_("Select all cells in the spreadsheet"), 
  select_all_cb, NULL,
  NULL, 0, 0, 'a', GDK_CONTROL_MASK 
}

By now you're probably wondering what the struct members mean. Simple enough. Here's a breakdown:

  • type is a type marker from the GnomeUIInfoType enumeration. See Table 1.

  • label is the text of the menu or toolbar button. It should be marked for internationalization with the N_() macro.

  • hint is a long description of the item's function. For toolbar buttons, it will appear in a tooltip; for menus, it can be made to appear in the statusbar.

  • moreinfo depends on the type of the item. See Table 1.

  • user_data will be passed to your callback function, if this item type has a callback.

  • unused_data should be set to NULL, and is not used yet. It may be used in future versions of Gnome.

  • pixmap_type is a value from the GnomeUIPixmapType enumeration; its purpose is to specify the type of the next member, pixmap_info.

  • pixmap_info can be raw pixmap data, a filename, or the name of a Gnome stock pixmap.

  • accelerator_key is the key to be used as an accelerator for this item . You can use a character such as 'a', or a value from gdk/gdkkeysyms.h.

  • ac_mods is a modifier mask to be used with the accelerator.

  • widget should be NULL; Gnome fills it in when it creates the menu item or toolbar button. You can then retrieve it, if you need to manipulate the widget in some way.

You might also be wondering why the menu item names contain an underscore. The underscore is used to mark the key shortcut for the menu item; translators can move it around as needed to make it intuitive in their language. Gnome will parse the menu item name to obtain the accelerator, then remove the underscore.

Table 1 summarizes the possible values for the type field of a GnomeUIInfo struct. See libgnomeui/gnome-app-helper.h for more details. There are actually a few more possible values, but the others are used internally by the library. The values in Table 1 should be sufficient for application code.

Table 1. GnomeUIInfoType Values

GnomeUIInfoType Description moreinfo Field
GNOME_APP_UI_ENDOFINFO Terminates a table of GnomeUIInfo None
GNOME_APP_UI_ITEM Normal item (or radio item inside radio group) Callback function
GNOME_APP_UI_TOGGLEITEM Toggle/check item Callback function
GNOME_APP_UI_RADIOITEMS Radio item group Array of radio items in the group
GNOME_APP_UI_SUBTREE Submenu Array of GnomeUIInfo in the subtree
GNOME_APP_UI_SEPARATOR Separator None
GNOME_APP_UI_HELP Help item Help node to load

To create an entire menu tree, you include pointers to previous menu tables using the GNOMEUIINFO_SUBTREE() macro:


static GnomeUIInfo main_menu[] = {
  GNOMEUIINFO_SUBTREE(N_("_File"), file_menu),
  GNOMEUIINFO_END
};

In this particular case, there is a better macro to use, however:


static GnomeUIInfo main_menu[] = {
  GNOMEUIINFO_MENU_FILE_TREE(file_menu),
  GNOMEUIINFO_END
};

The main advantage of this macro is standardization; it ensures that all Gnome file menus use the same key shortcut and have the same name. There are quite a few analagous macros; see libgnomeui/gnome-app-helper.h for the complete list.

Converting GnomeUIInfo to a Widget

Once you have a menu table, Gnome will process it and convert it to a widget. The functions are listed in Figure 4

#include <libgnomeui/gnome-app-helper.h>

void gnome_app_create_menus(GnomeApp* app, GnomeUIInfo* uiinfo);

void gnome_app_create_menus_with_data(GnomeApp* app, GnomeUIInfo* uiinfo, gpointer user_data);

void gnome_app_create_toolbar(GnomeApp* app, GnomeUIInfo* uiinfo);

void gnome_app_create_toolbar_with_data(GnomeApp* app, GnomeUIInfo* uiinfo, gpointer user_data);

void gnome_app_fill_toolbar(GtkToolbar* toolbar, GnomeUIInfo* uiinfo, GtkAccelGroup* accel_group);

void gnome_app_fill_toolbar_with_data(GtkToolbar* toolbar, GnomeUIInfo* uiinfo, GtkAccelGroup* accel_group, gpointer data);

void gnome_app_fill_menu(GtkMenuShell* menushell, GnomeUIInfo* uiinfo, GtkAccelGroup* accel_group, gboolean uline_accels, gint pos);

void gnome_app_fill_menu_with_data(GtkMenuShell* menushell, GnomeUIInfo* uiinfo, GtkAccelGroup* accel_group, gboolean uline_accels, gint pos, gpointer user_data);

Figure 4. Creating Widgets from GnomeUIInfo

If you are using the GnomeApp widget, gnome_app_create_menus() and gnome_app_create_toolbar() create a menubar or toolbar from the GnomeUIInfo table you provide, then attach that to the GnomeApp. Most of the time these are the functions you want to use; they do everything automatically. There is a _with_data() variant of each function which overrides the user_data field of GnomeUIInfo.

If you have more specialized needs, you can manually fill a menubar or toolbar and then add it to the container of your choice. The fill functions require you to specify an accelerator group to add accelerators to; for GnomeApp, an accelerator group already exists in the widget struct (the accel_group member). The fill functions for menus take two additional arguments: you can toggle whether to parse the underscores in menu item labels to extract accelerators, and you can specify at which position in the GtkMenuShell the function will begin inserting menu items.

(GtkMenuShell is simply the base class for GtkMenuBar and GtkMenu, i.e. it is a widget that contains menu items. An accelerator group is just a collection of accelerators, normally attached to a GtkWindow; use GNOME_APP(widget)->accel_group in this case.)

When you use a GnomeUIInfo table to create a menubar or toolbar, pointers to the individual menu item or toolbar button widgets are placed in the widget member of each GnomeUIInfo struct. You can use these pointers to access the individual widgets; for example, if you create a check menu item you might want to set the state of the check. The pointer is also useful if you want to manually create some part of the menu; you can create an empty subtree item, for example, and manually build the contents of the subtree.

Gtk+/Gnome Application Development
Prev Home Next

 
 
  Published under free license. Design by Interspire