]> Pileus Git - ~andy/gtk/blob - examples/menu/menu.c
Fixes #136082 and #135265, patch by Morten Welinder.
[~andy/gtk] / examples / menu / menu.c
1
2 #include <config.h>
3 #include <stdio.h>
4 #include <gtk/gtk.h>
5
6 static gint button_press (GtkWidget *, GdkEvent *);
7 static void menuitem_response (gchar *);
8
9 int main( int   argc,
10           char *argv[] )
11 {
12
13     GtkWidget *window;
14     GtkWidget *menu;
15     GtkWidget *menu_bar;
16     GtkWidget *root_menu;
17     GtkWidget *menu_items;
18     GtkWidget *vbox;
19     GtkWidget *button;
20     char buf[128];
21     int i;
22
23     gtk_init (&argc, &argv);
24
25     /* create a new window */
26     window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
27     gtk_widget_set_size_request (GTK_WIDGET (window), 200, 100);
28     gtk_window_set_title (GTK_WINDOW (window), "GTK Menu Test");
29     g_signal_connect (G_OBJECT (window), "delete_event",
30                       G_CALLBACK (gtk_main_quit), NULL);
31
32     /* Init the menu-widget, and remember -- never
33      * gtk_show_widget() the menu widget!! 
34      * This is the menu that holds the menu items, the one that
35      * will pop up when you click on the "Root Menu" in the app */
36     menu = gtk_menu_new ();
37
38     /* Next we make a little loop that makes three menu-entries for "test-menu".
39      * Notice the call to gtk_menu_shell_append.  Here we are adding a list of
40      * menu items to our menu.  Normally, we'd also catch the "clicked"
41      * signal on each of the menu items and setup a callback for it,
42      * but it's omitted here to save space. */
43
44     for (i = 0; i < 3; i++)
45         {
46             /* Copy the names to the buf. */
47             sprintf (buf, "Test-undermenu - %d", i);
48
49             /* Create a new menu-item with a name... */
50             menu_items = gtk_menu_item_new_with_label (buf);
51
52             /* ...and add it to the menu. */
53             gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_items);
54
55             /* Do something interesting when the menuitem is selected */
56             g_signal_connect_swapped (G_OBJECT (menu_items), "activate",
57                                       G_CALLBACK (menuitem_response), 
58                                       (gpointer) g_strdup (buf));
59
60             /* Show the widget */
61             gtk_widget_show (menu_items);
62         }
63
64     /* This is the root menu, and will be the label
65      * displayed on the menu bar.  There won't be a signal handler attached,
66      * as it only pops up the rest of the menu when pressed. */
67     root_menu = gtk_menu_item_new_with_label ("Root Menu");
68
69     gtk_widget_show (root_menu);
70
71     /* Now we specify that we want our newly created "menu" to be the menu
72      * for the "root menu" */
73     gtk_menu_item_set_submenu (GTK_MENU_ITEM (root_menu), menu);
74
75     /* A vbox to put a menu and a button in: */
76     vbox = gtk_vbox_new (FALSE, 0);
77     gtk_container_add (GTK_CONTAINER (window), vbox);
78     gtk_widget_show (vbox);
79
80     /* Create a menu-bar to hold the menus and add it to our main window */
81     menu_bar = gtk_menu_bar_new ();
82     gtk_box_pack_start (GTK_BOX (vbox), menu_bar, FALSE, FALSE, 2);
83     gtk_widget_show (menu_bar);
84
85     /* Create a button to which to attach menu as a popup */
86     button = gtk_button_new_with_label ("press me");
87     g_signal_connect_swapped (G_OBJECT (button), "event",
88                               G_CALLBACK (button_press), 
89                               G_OBJECT (menu));
90     gtk_box_pack_end (GTK_BOX (vbox), button, TRUE, TRUE, 2);
91     gtk_widget_show (button);
92
93     /* And finally we append the menu-item to the menu-bar -- this is the
94      * "root" menu-item I have been raving about =) */
95     gtk_menu_shell_append (GTK_MENU_SHELL (menu_bar), root_menu);
96
97     /* always display the window as the last step so it all splashes on
98      * the screen at once. */
99     gtk_widget_show (window);
100
101     gtk_main ();
102
103     return 0;
104 }
105
106 /* Respond to a button-press by posting a menu passed in as widget.
107  *
108  * Note that the "widget" argument is the menu being posted, NOT
109  * the button that was pressed.
110  */
111
112 static gint button_press( GtkWidget *widget,
113                           GdkEvent *event )
114 {
115
116     if (event->type == GDK_BUTTON_PRESS) {
117         GdkEventButton *bevent = (GdkEventButton *) event; 
118         gtk_menu_popup (GTK_MENU (widget), NULL, NULL, NULL, NULL,
119                         bevent->button, bevent->time);
120         /* Tell calling code that we have handled this event; the buck
121          * stops here. */
122         return TRUE;
123     }
124
125     /* Tell calling code that we have not handled this event; pass it on. */
126     return FALSE;
127 }
128
129
130 /* Print a string when a menu item is selected */
131
132 static void menuitem_response( gchar *string )
133 {
134     printf ("%s\n", string);
135 }