]> Pileus Git - ~andy/gtk/blob - examples/menu/itemfactory.c
937a665752530b10d52820d0a6d3602741216215
[~andy/gtk] / examples / menu / itemfactory.c
1
2 #include <gtk/gtk.h>
3
4 /* Obligatory basic callback */
5 static void print_hello( GtkWidget *w,
6                          gpointer   data )
7 {
8   g_message ("Hello, World!\n");
9 }
10
11 /* For the check button */
12 static void print_toggle( gpointer   callback_data,
13                           guint      callback_action,
14                           GtkWidget *menu_item )
15 {
16    g_message ("Check button state - %d\n",
17               GTK_CHECK_MENU_ITEM (menu_item)->active);
18 }
19
20 /* For the radio buttons */
21 static void print_selected( gpointer   callback_data,
22                             guint      callback_action,
23                             GtkWidget *menu_item )
24 {
25    if(GTK_CHECK_MENU_ITEM(menu_item)->active)
26      g_message ("Radio button %d selected\n", callback_action);
27 }
28
29 /* Our menu, an array of GtkItemFactoryEntry structures that defines each menu item */
30 static GtkItemFactoryEntry menu_items[] = {
31   { "/_File",         NULL,         NULL,           0, "<Branch>" },
32   { "/File/_New",     "<control>N", print_hello,    0, "<StockItem>", GTK_STOCK_NEW },
33   { "/File/_Open",    "<control>O", print_hello,    0, "<StockItem>", GTK_STOCK_OPEN },
34   { "/File/_Save",    "<control>S", print_hello,    0, "<StockItem>", GTK_STOCK_SAVE },
35   { "/File/Save _As", NULL,         NULL,           0, "<Item>" },
36   { "/File/sep1",     NULL,         NULL,           0, "<Separator>" },
37   { "/File/_Quit",    "<CTRL>Q", gtk_main_quit, 0, "<StockItem>", GTK_STOCK_QUIT },
38   { "/_Options",      NULL,         NULL,           0, "<Branch>" },
39   { "/Options/tear",  NULL,         NULL,           0, "<Tearoff>" },
40   { "/Options/Check", NULL,         print_toggle,   1, "<CheckItem>" },
41   { "/Options/sep",   NULL,         NULL,           0, "<Separator>" },
42   { "/Options/Rad1",  NULL,         print_selected, 1, "<RadioItem>" },
43   { "/Options/Rad2",  NULL,         print_selected, 2, "/Options/Rad1" },
44   { "/Options/Rad3",  NULL,         print_selected, 3, "/Options/Rad1" },
45   { "/_Help",         NULL,         NULL,           0, "<LastBranch>" },
46   { "/_Help/About",   NULL,         NULL,           0, "<Item>" },
47 };
48
49 static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
50
51 /* Returns a menubar widget made from the above menu */
52 static GtkWidget *get_menubar_menu( GtkWidget  *window )
53 {
54   GtkItemFactory *item_factory;
55   GtkAccelGroup *accel_group;
56
57   /* Make an accelerator group (shortcut keys) */
58   accel_group = gtk_accel_group_new ();
59
60   /* Make an ItemFactory (that makes a menubar) */
61   item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>",
62                                        accel_group);
63
64   /* This function generates the menu items. Pass the item factory,
65      the number of items in the array, the array itself, and any
66      callback data for the the menu items. */
67   gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);
68
69   /* Attach the new accelerator group to the window. */
70   gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
71
72   /* Finally, return the actual menu bar created by the item factory. */
73   return gtk_item_factory_get_widget (item_factory, "<main>");
74 }
75
76 /* Popup the menu when the popup button is pressed */
77 static gboolean popup_cb( GtkWidget *widget,
78                           GdkEvent *event,
79                           GtkWidget *menu )
80 {
81    GdkEventButton *bevent = (GdkEventButton *)event;
82   
83    /* Only take button presses */
84    if (event->type != GDK_BUTTON_PRESS)
85      return FALSE;
86   
87    /* Show the menu */
88    gtk_menu_popup (GTK_MENU(menu), NULL, NULL,
89                    NULL, NULL, bevent->button, bevent->time);
90   
91    return TRUE;
92 }
93
94 /* Same as with get_menubar_menu() but just return a button with a signal to
95    call a popup menu */
96 GtkWidget *get_popup_menu( void )
97 {
98    GtkItemFactory *item_factory;
99    GtkWidget *button, *menu;
100   
101    /* Same as before but don't bother with the accelerators */
102    item_factory = gtk_item_factory_new (GTK_TYPE_MENU, "<main>",
103                                         NULL);
104    gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);
105    menu = gtk_item_factory_get_widget (item_factory, "<main>");
106   
107    /* Make a button to activate the popup menu */
108    button = gtk_button_new_with_label ("Popup");
109    /* Make the menu popup when clicked */
110    g_signal_connect (G_OBJECT(button),
111                      "event",
112                      G_CALLBACK(popup_cb),
113                      (gpointer) menu);
114
115    return button;
116 }
117
118 /* Same again but return an option menu */
119 GtkWidget *get_option_menu( void )
120 {
121    GtkItemFactory *item_factory;
122    GtkWidget *option_menu;
123   
124    /* Same again, not bothering with the accelerators */
125    item_factory = gtk_item_factory_new (GTK_TYPE_OPTION_MENU, "<main>",
126                                         NULL);
127    gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);
128    option_menu = gtk_item_factory_get_widget (item_factory, "<main>");
129
130    return option_menu;
131 }
132
133 /* You have to start somewhere */
134 int main( int argc,
135           char *argv[] )
136 {
137   GtkWidget *window;
138   GtkWidget *main_vbox;
139   GtkWidget *menubar, *option_menu, *popup_button;
140  
141   /* Initialize GTK */
142   gtk_init (&argc, &argv);
143  
144   /* Make a window */
145   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
146   g_signal_connect (G_OBJECT (window), "destroy",
147                     G_CALLBACK (gtk_main_quit),
148                     NULL);
149   gtk_window_set_title (GTK_WINDOW(window), "Item Factory");
150   gtk_widget_set_size_request (GTK_WIDGET(window), 300, 200);
151  
152   /* Make a vbox to put the three menus in */
153   main_vbox = gtk_vbox_new (FALSE, 1);
154   gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 1);
155   gtk_container_add (GTK_CONTAINER (window), main_vbox);
156  
157   /* Get the three types of menu */
158   /* Note: all three menus are separately created, so they are not the
159      same menu */
160   menubar = get_menubar_menu (window);
161   popup_button = get_popup_menu ();
162   option_menu = get_option_menu ();
163   
164   /* Pack it all together */
165   gtk_box_pack_start (GTK_BOX (main_vbox), menubar, FALSE, TRUE, 0);
166   gtk_box_pack_end (GTK_BOX (main_vbox), popup_button, FALSE, TRUE, 0);
167   gtk_box_pack_end (GTK_BOX (main_vbox), option_menu, FALSE, TRUE, 0);
168
169   /* Show the widgets */
170   gtk_widget_show_all (window);
171   
172   /* Finished! */
173   gtk_main ();
174  
175   return 0;
176 }