Книга: Основы программирования в Linux
Меню GNOME
Разделы на этой странице:
Меню GNOME
Создание строки раскрывающихся меню в среде GNOME на удивление просто. Каждый пункт в строке меню представляется как массив структур GNOMEUIInfo
, причем каждый элемент массива соответствует одному пункту меню. Например, если у вас есть меню File (Файл), Edit (Правка) и View (Вид), то у вас будут три массива, описывающих содержимое каждого меню.
После определения отдельных меню создается строка меню как таковая с помощью ссылок на эти массивы в еще одном массиве структур GNOMEUIInfo
.
Структура GNOMEUIInfo
немного сложна и нуждается в дополнительных пояснениях.
typedef struct {
GnomeUIInfoType type;
gchar const *label;
gchar const *hint;
gpointer moreinfо;
gpointer user_data;
gpointer unused_data;
GnomeUIPixmapType pixmap_type;
gconstpointer pixmap_info;
guint accelerator_key;
GdkModifierType ac_mods;
GtkWidget *widget;
} GnomeUIInfo;
Первый элемент в структуре, type
, определяет тип элемента меню, который описывается далее. Он может быть одним из 11 типов GnomeUIInfоТуре
, определяемых средой GNOME и приведенных в табл. 16.3.
Таблица 16.3
Типы GnomeUIInfоТуре |
Описание |
---|---|
GNOME_APP_UI_ENDOFINFO |
Означает, что этот элемент — последний пункт меню в массиве |
GNOME_APP_UI_ITEM |
Обычный пункт меню или переключатель, если ему предшествует элемент GNOME_APP_UI_RADIOITEMS |
GNOME_APP_UI_TOGGLEITEM |
Пункт меню в виде кнопки-переключателя или кнопки-флажка |
GNOME_APP_UI_RADIOITEMS |
Группа переключателей или зависимых переключателей |
GNOME_APP_UI_SUBTREE | Означает, что данный элемент представляет собой подменю. Задайте moreinfo для указания на массив подменю |
GNOME_APP_UI_SEPARATOR |
Вставляет разделительную линию в меню |
GNOME_APP_UI_HELP |
Создает список тем справки для использования в меню Help (Справка) |
GNOME_APP_UI_BUILDER_DATA |
Задает данные построения (builder data) для следующих элементов |
GNOME_APP_UI_ITEM_CONFIGURABLE |
Настраиваемый пункт меню |
GNOME_APP_UI_SUBTREE_STOCK |
Такой же, как GNOME_APP_UI_SUBTREE за исключением того, что надписи следует искать в каталоге gnome-libs |
GNOME_APP_UI_INCLUDE |
Такой же, как GNOME_APP_UI_SUBTREE за исключением того, что пункты включены в текущее меню, а не в подменю |
Второй и третий элементы структуры определяют текст пункта меню и всплывающей подсказки. (Подсказка выводится в строке состояния, у нижнего края окна.)
Назначение элемента 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 определены макросы, устраняющие необходимость определения структур вручную. Эти макросы также вставляют пиктограммы и клавиатурные акселераторы для вас, и все даром. На самом деле редко возникают причины, заставляющие использовать вместо них что-то другое.
Существуют два набора макросов, первый из которых определяет отдельные пункты меню. Эти макросы принимают два параметра: указатель на функцию обратного вызова и данные пользователя.
#include <libgnomeui/libgnameui.h>
#define GNOMEUIINFO_MENU_OPEN_ITEM(cb, data)
#define GNOMEUIINFO_MENU_SAVE_ITEM(cb, data)
#define GNOMEUIINFO_MENU_SAVE_AS_IТЕМ(cb, data)
#define GNOMEUIINFO_MENU_PRINT_ITEM(cb, data)
#define GNOMEUIINFO_MENU_PRINT_SETUP_ITEM(cb, data)
#define GNOMEUIINFO_MENU_CLOSE_IТЕМ(cb, data)
#define GNOMEUIINFO_MENU_EXIT_IТЕМ(cb, data)
#define GNOMEUIINFO_MENU_QUIT_IТЕМ(cb, data)
#define GNOMEUIINFO_MENU_CUT_ITEM(cb, data)
#define GNOMEUIINFO_MENU_COPY_ITEM(cb, data)
#define GNOMEUIINFO_MENU_PASTE_ITEM(cb, data)
#define GNOMEUIINFO_MENU_SELECT_ALL_ITEM(cb, data)
...
Второй набор предназначен для определений верхнего уровня, в него вы просто передаете массив.
#define GNOMEUIINFO_MENU_FILE_TREE (tree)
#define GNOMEUIINFO_MENU_EDIT_TREE (tree)
#define GNOMEUIINFO_MENU_VIEW_TREE (tree)
#define GNOMEUIINFO_MENU_SETTINGS_TREE (tree)
#define GNOMEUIINFO_MENU_FILES_TREE (tree)
#define GNOMEUIINFO_MENU_WINDOWS_TREE (tree)
#define GNOMEUIINFO_MENU_HELP_TREE (tree)
#define GNOMEUIINFO_MENU_GAME_TREE (tree)
Выполните упражнение 16.10.
Упражнение 16.10. Меню с помощью макросов GNOME
В этом примере вы воспользуетесь уже заданными меню и посмотрите, как работают макросы. Внесите следующие изменения в программу menu1.с и назовите новый вариант menu2.c. Для простоты в этом примере для пунктов меню не определены функции обратного вызова. В данном случае наша задача — просто продемонстрировать удобство применения макросов GNOME, формирующих меню.
#include <gnome.h>
static GnomeUIInfo filemenu[] = {
GNOMEUIINFO_MENU_NEW_ITEM("New", "Menu Hint", NULL, NULL),
GNOMEUIINFO_MENU_OPEN_ITEM(NULL, NULL),
GNOMEUIINFO_MENU_SAVE_AS_ITEM(NULL, NULL),
GNOMEUIINFO_SEPARATOR,
GNOMEIINFO_MENU_EXIT_ITEM(NULL, NULL),
GNOMEUUINFO_END
};
static GnomeUUInfo editmenu[] =
GNOMEUIINFO_MENU_FIND_ITEM(NULL, NULL),
GNOMEUIINFO_END
};
static GnomeUIInfo menubar[] = {
GNOMEUIINFO_MENU_FILE_TREE(filemenu),
GNOMEUIINFO_MENU_EDIT_TREE(editmenu),
GNOMEUIINFO_END
};
int main(int argc, char *argv[]) {
GtkWidget *app, *toolbar;
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);
gnome_app_create_menus(GNOME_APP(app), menubar);
gtk_widget_show(app);
gtk_main();
return 0;
}
Применив макросы libgnomeui в menu2.c, вы значительно сократили код, который нужно набирать, и сделали его гораздо понятнее. Макросы экономят ваше время и усилия, предпринимаемые для создания меню и согласования текста меню, клавиатурных акселераторов и пиктограмм с другими приложениями GNOME. Старайтесь применять их в ваших приложениях при любой возможности.
На рис. 16.13 показана программа menu3.c в действии на сей раз со стандартизованными в среде GNOME пунктами меню.
Рис. 16.13
- 4.6. Центр управления GNOME
- Глава 25 Рабочая среда GNOME
- 1.4.4. Работа с файлами и каталогами с помощью оболочки GNOME
- Виджеты GNOME
- Часть IV Настройка внешнего вида и интерфейса GNOME
- Глава 31 Редактор настроек GNOME
- 4.7. Пиктограммы GNOME, или знакомство с редактором конфигурации
- 1.3.2.1. Главное меню
- 1.3.2. Работа с GNOME
- 1.3.3. Настройка GNOME
- Глава 27 Настройка меню GNOME
- 10.5. Транзакции и пути доступа меню