Второй и третий элементы структуры определяют текст пункта меню и всплывающей подсказки. (Подсказка выводится в строке состояния, у нижнего края окна.)
Назначение элемента moreinfo зависит от типа. В случае ITEM и TOGGLEITEM он указывает на функцию обратного вызова, которую следует вызвать при активации пункта меню. Для RADIOITEMS он указывает на массив структур GnomeUIInfo, в которых группируются переключатели.
user_data — произвольный указатель, передаваемый в функцию обратного вызова. Элементы pixmap_type и pixmap_info позволяют добавить к пункту меню растровую пиктограмму, a accelerator_key и ac_mods помогут определить клавиатурный эквивалент пункта меню.
И наконец, элемент widget применяется для внутреннего хранения указателя на виджет пункта меню функцией создания меню.
Выполните упражнение 16.9.
Упражнение 16.9. Меню GNOME
Вы сможете опробовать меню с помощью данной короткой программы. Назовите ее menu1.с.
#include <gnome.h>
void closeApp(GtkWidget *window, gpointer data) {
gtk_main_quit();
}
1. Определите для пунктов меню функцию обратного вызова, названную item_clicked:
void item clicked(GtkWidget *widget, gpointer user_data) {
printf("Item Clicked!n");
}
2. Далее следуют определения меню. У вас есть подменю, меню верхнего уровня и массив строки меню:
static GnomeUIInfo submenu[] = {
{GNOME_APP_UI_ITEM, "SubMenu", "SubMenu Hint",
GTK_SIGNAL_FUNC(item_clicked), NULL, NULL, 0, NULL, 0, 0, NULL},
{GNOME_APP_UI_ENDOFINFO, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0, 0,
NULL}
};
static GnomeUIInfo menu[] = {
{GNOME_APP_UI_ITEM, "Menu Item 1", "Menu Hint",
NULL, NULL, NULL, 0, NULL, 0, 0, NULL},
{GNOME_APP_UI_SUBTREE, "Menu Item 2", "Menu Hint",
submenu, NULL, NULL, 0, NULL, 0, 0, NULL},
{GNOME_APP_UI_ENDOFINFO, NULL, NULL, null,
NULL, NULL, 0, NULL, 0, 0, NULL}
};
static GnomeUIInfo menubar[] = {
{GNOME_APP_UI_SUBTREE, "Toplevel Item", NULL,
menu, NULL, NULL, 0, NULL, 0, 0, NULL},
{GNOME_APP_UI_ENDOFINFO, NULL, NULL, NULL,
NULL, NULL, 0, NULL, 0, 0, NULL}
};
3. В функции main вы имеете дело с обычной инициализацией и затем создаете ваш виджет GnomeApp и задаете все меню:
int main (int argc, char *argv[]) {
GtkWidget *app;
gnome_program_init("gnome1", "0.1", LIBGNOMEUI_MODULE,
argc, argv, GNOME_PARAM_NONE);
app = gnome_app_new("gnome1", "Menus, menus, menus");
gtk_window_set_default_size(GTK_WINDOW(app), 300, 200);
g_signal_connect(GTK_OBJECT(app), "destroy",
GTK_SIGNAL_FUNC(closeApp), NULL);
gnome_app_create_menus(GNOME_APP(app), menubar);
gtk_widget_show(app);
gtk_main();
return 0;
}
Попробуйте выполнить menu1 и посмотрите в действии строку меню, подменю и меню GNOME обратного вызова, показанные на рис. 16.12.
Рис. 16.12
Структура GnomeUIInfo едва ли дружественная по отношению к программисту, если учесть, что она состоит из 11 элементов, большинство из которых обычно равно NULL или нулю. При их вводе очень легко допустить ошибку и трудно отличить одно поле от другого в длинном массиве элементов. Для улучшения сложившейся ситуации в среде GNOME определены макросы, устраняющие необходимость определения структур вручную. Эти макросы также вставляют пиктограммы и клавиатурные акселераторы для вас, и все даром. На самом деле редко возникают причины, заставляющие использовать вместо них что-то другое.
Существуют два набора макросов, первый из которых определяет отдельные пункты меню. Эти макросы принимают два параметра: указатель на функцию обратного вызова и данные пользователя.
<b>#include <libgnomeui/libgnameui.h></b>
<b>#define GNOMEUIINFO_MENU_OPEN_ITEM(cb, data)</b>
<b>#define GNOMEUIINFO_MENU_SAVE_ITEM(cb, data)</b>
<b>#define GNOMEUIINFO_MENU_SAVE_AS_IТЕМ(cb, data)</b>
<b>#define GNOMEUIINFO_MENU_PRINT_ITEM(cb, data)</b>
<b>#define GNOMEUIINFO_MENU_PRINT_SETUP_ITEM(cb, data)</b>
<b>#define GNOMEUIINFO_MENU_CLOSE_IТЕМ(cb, data)</b>
<b>#define GNOMEUIINFO_MENU_EXIT_IТЕМ(cb, data)</b>
<b>#define GNOMEUIINFO_MENU_QUIT_IТЕМ(cb, data)</b>
<b>#define GNOMEUIINFO_MENU_CUT_ITEM(cb, data)</b>
<b>#define GNOMEUIINFO_MENU_COPY_ITEM(cb, data)</b>
<b>#define GNOMEUIINFO_MENU_PASTE_ITEM(cb, data)</b>
<b>#define GNOMEUIINFO_MENU_SELECT_ALL_ITEM(cb, data)</b>
...