GTK+ 2.0 Tutorial

<<< Previous

Menu Widget

Next >>>


Использование ItemFactory

После рассмотрения сложного пути создания меню, рассмотрим как это же можно сделать при помощи вызова функции gtk_item_factory.

ItemFactory создаёт меню из массива записей  ItemFactory.  Это означает, что вы можете определить ваше меню в его самой простой форме и затем создать виджеты (меню/строки) меню с минимумом запросов функции.

ItemFactory записи

В ядре ItemFactory находится ItemFactoryEntry.  Эта структура определяет один пункт меню и когда массив этих записей определен, целое меню сформировано. Структура записей ItemFactory выглядит так:

struct _GtkItemFactoryEntry { gchar *path; gchar *accelerator; GtkItemFactoryCallback callback; guint callback_action; gchar *item_type; };

Каждая строка определяет часть пункта меню.

*path - определяет путь и название пункта меню, например: "/File/Open" было бы именем пункта меню который подходит для записи ItemFactory с путём "/File". Однако пункт "/File/Open" был бы показан в меню File как "Open", потому что первые "/" используются для определения пути и не могут присутствовать в имени пункта. Символ, которому предшествует символ подчеркивания, указывает акселератор (сокращенная клавиша) в открытом меню.

*accelerator  является строкой, которая указывает ключевую комбинацию клавиш и используется как ярлык к пункту меню. Строка может состоять из единичного символа или комбинации модификаторов и символов.

Модификаторами клавиш могут быть:

"<ALT> - alt "<CTL>" или "<CTRL>" или "<CONTROL>" - control "<MOD1>" до "<MOD5>" - modn "<SHFT>" или "<SHIFT>" - shift

Пример:

"<ConTroL>a" "<SHFT><ALT><CONTROL>X"

callback - функция вызываемая при создании пунктом меню сигнала "activate". Форма обратного вызова описана в разделе Callback Description.

Значение callback_action помещается в функцию обратного вызова. Прототип функции смотрите в разделе Callback Description.

item_type - является строкой, которая определяет тип виджета упакованного в контейнер пунктов меню. Возможные значения:

NULL или "" или "<Item>" - создаёт простой пункт "<Title>" - создаёт заголовочный пункт "<CheckItem>" - создаёт контрольный пункт "<ToggleItem>" - создаёт переключающий пункт "<RadioItem>" - создаёт основной (root) выборочный пункт "Path" - создаёт вторичный выборочный пункт "<Tearoff>" - создаёт разрыв "<Separator>" - создаёт разделитель "<Branch>" - создаёт пункт содержащий суб меню (optional) "<LastBranch>" - создаёт выровненный по правому краю переход

Отметьте, что <LastBranch> полезен только для одного подменю строки меню.

Описание обратного вызова (Callback Description)

Обратный вызов для  ItemFactory entry может иметь две формы. Если callback_action равен 0 (zero), он имеет следующую форму:

void callback(void)

другая форма:

void callback(gpointer callback_data, guint callback_action, GtkWidget *widget)

callback_data - является указателем на произвольную часть данных и установлен вызовом gtk_item_factory_create_items().

callback_action - некоторое значение callback_action в ItemFactory записях.

*widget - указатель на виджет пункта меню (подробности в Manual Menu Creation).

ItemFactory entry examples

Создаём простой пункт меню:

GtkItemFactoryEntry entry = {"/_File/_Open...", "<CTRL>O", print_hello, 0, "<Item>"};

Здесь создаётся простой пункт меню "/File/Open" (отображается как "Open"), внутри строки меню "/File". Он имеет акселератор (shortcut) control+'O' при нажатии которого вызывается функция print_hello(). print_hello() имеет форму void print_hello(void) так как callback_action имеет значение zero. Если 'O' в "Open" подчеркнута, то при открытом меню и нажатой клавише 'O' пункт будет активизирован. Заметьте, что "File/_Open" может быть использован как путь вместо "/_File/_Open".

Создание входа с более сложным обратным вызовом (callback):

GtkItemFactoryEntry entry = {"/_View/Display _FPS", NULL, print_state, 7,"<CheckItem>"};

Это определяет новый пункт меню отображаемый как "Display FPS" в вышестоящем пункте меню "View". При нажатии вызывается функция print_state(). Так как callback_action не равно zero print_state() имеет форму:

void print_state(gpointer callback_data, guint callback_action, GtkWidget *widget)

с callback_action равным 7.

Создаём установку кнопки выбора:

GtkItemFactoryEntry entry1 = {"/_View/_Low Resolution", NULL, change_resolution, 1, "<RadioButton>"}; GtkItemFactoryEntry entry2 = {"/_View/_High Resolution", NULL, change_resolution, 2, "/View/Low Resolution"};

entry1 определяет одиночную кнопку выбора которая переключает вызов функции change_resolution() с параметром callback_action равным 1. change_resolution() имеет форму:

void change_resolution(gpointer callback_data, guint callback_action, GtkWidget *widget)

entry2 определяет кнопку выбора которая принадлежит группе в которой находится  entry1. Она вызывает туже самую функцию при переключении, но параметр callback_action равен 2. Обратите внимание на отсутствие акселераторов. Если бы потребовалась ещё одна кнопка выбора для переключения, то её можно было бы создать таким же образом в этой же группе с item_type равным "/View/Low Resolution".

ItemFactoryEntry массивы

 Массив записей для определения меню. Ниже приведен пример объявления массива:

static GtkItemFactoryEntry entries[] = { { "/_File", NULL, NULL, 0, "<Branch>" }, { "/File/tear1", NULL, NULL, 0, "<Tearoff>" }, { "/File/_New", "<CTRL>N", new_file, 1, "<Item>" }, { "/File/_Open...", "<CTRL>O", open_file, 1, "<Item>" }, { "/File/sep1", NULL, NULL, 0, "<Seperator>" }, { "/File/_Quit", "<CTRL>Q", quit_program, 0, "<Item>"} };

Создание ItemFactory

Массив GtkItemFactoryEntry пунктов определяет меню. Функция выглядит так:

GtkItemFactory* gtk_item_factory_new( GtkType container_type, const gchar *path, GtkAccelGroup *accel_group );

container_type может иметь следующие значения:

GTK_TYPE_MENU GTK_TYPE_MENU_BAR GTK_TYPE_OPTION_MENU

container_type определяет тип нужного вам меню, например - всплывающее меню, панель меню или меню опций (как поле со списком но  с выпавшим меню).

path определяет путь к основному меню. В основном уникальное имя основного меню должно быть заключено в треугольные скобки "<>".  Это важно для обозначения акселераторов.  Оно должно быть уникальным и для каждого меню и для каждой программы. Например программа с именем 'foo', может иметь главное меню "<FooMain>", а всплывающее меню "<FooImagePopUp>", или нечто похожее. Главное чтобы они были уникальны.

accel_group указатель на gtk_accel_group. Таблицы акселераторов устанавливаются в то время как генерируется меню. Новая группа акселераторов создаётся функцией gtk_accel_group_new().

Но это - только первый шаг.  Чтобы преобразовывать массив информации GtkItemFactoryEntry в виджеты, используется следующая функция :

void gtk_item_factory_create_items( GtkItemFactory *ifactory, guint n_entries, GtkItemFactoryEntry *entries, gpointer callback_data );

*ifactory - указатель на вышеупомянутое созданное производство пунктов.

n_entries -  является числом входов в массив GtkItemFactoryEntry..

*entries - указатель на массив GtkItemFactoryEntry.

callback_data - является тем, что передают во все функции обратного вызова для всех входов с callback_action != 0.

Группа акселераторов создана, теперь нужно прикрепить меню к окну:

void gtk_window_add_accel_group( GtkWindow *window, GtkAccelGroup *accel_group);

Использование меню и его пунктов

Следующая функция извлекает виджеты из ItemFactory:

GtkWidget* gtk_item_factory_get_widget( GtkItemFactory *ifactory, const gchar *path );

Например, если ItemFactory имеет две записи "/File", и "/file/new", используя дорожку "/File" извлечётся виджет menu из ItemFactory. Используя путь "/File/New" извлечётся виджет menu item. Это позволяет установить начальное состояние пунктов меню. Например для установки по умолчанию кнопки выбора в путь "/Shape/Oval", код будет выглядеть так:

gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (item_factory, "/Shape/Oval")), TRUE);

Для извлечения основного меню используется функция gtk_item_factory_get_item() с путем "<main>" (в независимости от использованного пути в gtk_item_factory_new()).  В случае ItemFactory, создаваемого с типом GTK_TYPE_MENU_BAR, возвращается виджет панели меню. Если тип GTK_TYPE_MENU возвращается виджет меню. Если тип GTK_TYPE_OPTION_MENU возвращается виджет меню опций.

Помните: вход определенный путем "/_File" фактически путь "/File".

Теперь вы имеете строку меню или меню и можете манипулировать ими как обсуждалось в разделе Manual Menu Creation.


<<< Previous

Home

Next >>>

Manual Menu Example

Up

Item Factory Example