/* начало примера меню itemfactory.c */
#include <gtk/gtk.h>
#include <strings.h>
/* обязательный основной обратный вызов */
static void print_hello( gtkwidget *w,
gpointer data )
{
g_message ("hello, world!\n");
}
/* для контрольной кнопки */
static void print_toggle(gpointer callback_data,
guint callback_action,
gtkwidget *menu_item)
{
g_message ("состояние контрольной кнопки - %d\n",
gtk_check_menu_item(menu_item)->active);
}
/* для кнопки выбора */
static void print_selected(gpointer callback_data,
guint callback_action,
gtkwidget *menu_item)
{
if(gtk_check_menu_item(menu_item)->active)
g_message("кнопка выбора %d выбрана\n", callback_action);
}
/* наше меню, массив gtkitemfactoryentry структур которые определяют каждый пункт меню */
static gtkitemfactoryentry menu_items[] = {
{ "/_file", null, null, 0, "<branch>" },
{ "/file/_new", "<control>n", print_hello, 0, "<item>" },
{ "/file/_open", "<control>o", print_hello, 0, "<item>" },
{ "/file/_save", "<control>s", print_hello, 0, "<item>" },
{ "/file/save _as", null, null, 0, "<item>" },
{ "/file/sep1", null, null, 0, "<separator>" },
{ "/file/quit", "<control>q", gtk_main_quit, 0, "<item>" },
{ "/_options", null, null, 0, "<branch>" },
{ "/options/tear", null, null, 0, "<tearoff>" },
{ "/options/check", null, print_toggle, 1, "<checkitem>" },
{ "/options/sep", null, null, 0, "<separator>" },
{ "/options/rad1", null, print_selected, 1, "<radioitem>" },
{ "/options/rad2", null, print_selected, 2, "/options/rad1" },
{ "/options/rad3", null, print_selected, 3, "/options/rad1" },
{ "/_help", null, null, 0, "<lastbranch>" },
{ "/_help/about", null, null, 0, "<item>" },
};
static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
/* возвращает виджет панель меню, сделанный из вышеупомянутого меню */
gtkwidget *get_menubar_menu( gtkwidget *window)
{
gtkitemfactory *item_factory;
gtkaccelgroup *accel_group;
/* создаём группу акселераторов (shortcut keys) */
accel_group = gtk_accel_group_new ();
/* создаём itemfactory (строку меню) */
item_factory = gtk_item_factory_new (gtk_type_menu_bar, "<main>",
accel_group);
/* эта функция генерирует пункты меню. передает item factory,
номер пункта в массиве, массив непосредственно, а также любые
данные обратных вызовов для пунктов меню. */
gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, null);
/* прикрепляем новую группу акселераторов к окну. */
gtk_window_add_accel_group (gtk_window (window), accel_group);
/* возвращаем фактически созданную производством пунктов (item factory) панель меню. */
return gtk_item_factory_get_widget (item_factory, "<main>");
}
/* всплывающее меню при нажатии на всплывающую кнопку */
static gint popup_cb(gtkwidget *widget, gdkevent *event, gtkwidget *menu)
{
gdkeventbutton *bevent = (gdkeventbutton *)event;
/* только нажатие кнопки */
if(event->type != gdk_button_press)
return false;
/* отображаем меню */
gtk_menu_popup(gtk_menu(menu), null, null,
null, null, bevent->button, bevent->time);
return true;
}
/* тоже что и get_menubar_menu(), но возвращает кнопку с сигналом для всплывающего меню */
gtkwidget *get_popup_menu(void)
{
gtkitemfactory *item_factory;
gtkwidget *button, *menu;
/* тоже что и выше, но без акселераторов */
item_factory = gtk_item_factory_new (gtk_type_menu, "<main>",
null);
gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, null);
menu = gtk_item_factory_get_widget(item_factory, "<main>");
/* кнопка для активизации всплывающего меню */
button = gtk_button_new_with_label("popup");
/* создаём всплывающее меню при щелчке */
g_signal_connect(g_object(button),
"event",
g_callback(popup_cb),
(gpointer) menu);
return button;
}
/* то же самое, но возвращается меню опций */
gtkwidget *get_option_menu(void)
{
gtkitemfactory *item_factory;
gtkwidget *option_menu;
/* ещё раз, но без акселераторов */
item_factory = gtk_item_factory_new (gtk_type_option_menu, "<main>",
null);
gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, null);
option_menu = gtk_item_factory_get_widget(item_factory, "<main>");
return option_menu;
}
/* начальная функция */
int main( int argc,
char *argv[] )
{
gtkwidget *window;
gtkwidget *main_vbox;
gtkwidget *menubar, *option_menu, *popup_button;
/* инициализация gtk */
gtk_init (&argc, &argv);
/* создаём окно */
window = gtk_window_new (gtk_window_toplevel);
g_signal_connect (g_object (window), "destroy",
g_callback (gtk_main_quit),
null);
gtk_window_set_title (gtk_window(window), "item factory");
gtk_widget_set_size_request (gtk_widget(window), 300, 200);
/* создаём vbox для размещения меню */
main_vbox = gtk_vbox_new (false, 1);
gtk_container_set_border_width (gtk_container (main_vbox), 1);
gtk_container_add (gtk_container (window), main_vbox);
/* получаем три типа меню */
/* помните: все три меню созданы отдельно друг от друга */
menubar = get_menubar_menu (window);
popup_button = get_popup_menu();
option_menu = get_option_menu();
/* упаковываем всё вместе */
gtk_box_pack_start (gtk_box (main_vbox), menubar, false, true, 0);
gtk_box_pack_end (gtk_box (main_vbox), popup_button, false, true, 0);
gtk_box_pack_end (gtk_box (main_vbox), option_menu, false, true, 0);
/* отображаем виджет */
gtk_widget_show_all (window);
/* конец! */
gtk_main ();
return(0);
}
/* конец примера */
|