Книга: Основы программирования в 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

Оглавление книги


Генерация: 1.598. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз