#include #include /* gcc -Wall `pkg-config --cflags --libs gtk+-2.0` -o widgetmenu widgetmenu.c */ void print_data (GtkWidget *widget, gpointer data) { g_printerr ("%s\n", (gchar *) data); } static void menuitem_unclickify (GtkWidget *mitem, gpointer data) { g_return_if_fail (GTK_IS_MENU_ITEM (mitem)); gdk_window_hide (GTK_MENU_ITEM (mitem)->event_window); } gboolean scale_button_event (GtkWidget *widget, GdkEventButton *bevent, gpointer data) { static guint handler = 0; if (bevent->type == GDK_BUTTON_PRESS) handler = g_signal_connect (data, "cancel", G_CALLBACK (g_signal_stop_emission_by_name), "cancel"); if (handler && bevent->type == GDK_BUTTON_RELEASE) { g_signal_handler_disconnect (data, handler); handler = 0; } return FALSE; } void open_menu (GtkButton *button, gpointer data) { static GtkWidget *menu = NULL; GtkWidget *mitem, *widget; if (!menu) { menu = g_object_new (GTK_TYPE_MENU, NULL); mitem = gtk_menu_item_new (); g_signal_connect_after (G_OBJECT (mitem), "map-event", G_CALLBACK (menuitem_unclickify), NULL); widget = gtk_hscale_new_with_range (0, 9, 1); g_signal_connect (G_OBJECT (widget), "value_changed", G_CALLBACK (print_data), "Value in menu changed"); g_signal_connect (G_OBJECT (widget), "button-press-event", G_CALLBACK (scale_button_event), menu); g_signal_connect (G_OBJECT (widget), "button-release-event", G_CALLBACK (scale_button_event), menu); gtk_container_add (GTK_CONTAINER (mitem), widget); gtk_menu_shell_append (GTK_MENU_SHELL (menu), mitem); gtk_widget_show_all (mitem); mitem = gtk_menu_item_new_with_label ("Menu Item"); gtk_menu_shell_append (GTK_MENU_SHELL (menu), mitem); g_signal_connect (G_OBJECT (mitem), "activate", G_CALLBACK (print_data), "item 2 activated"); gtk_widget_show_all (mitem); mitem = gtk_separator_menu_item_new(); gtk_menu_shell_append (GTK_MENU_SHELL (menu), mitem); gtk_widget_show_all (mitem); mitem = gtk_menu_item_new_with_label ("Menu Item 2"); gtk_menu_shell_append (GTK_MENU_SHELL (menu), mitem); g_signal_connect (G_OBJECT (mitem), "activate", G_CALLBACK (print_data), "item 3 activated"); gtk_widget_show_all (mitem); } gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 1, GDK_CURRENT_TIME); } gint main (gint argc, char **argv) { GtkWidget *widget, *window; gtk_init (&argc, &argv); widget = gtk_button_new_with_label ("Open Menu"); g_signal_connect (widget, "clicked", G_CALLBACK (open_menu), NULL); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_container_add (GTK_CONTAINER (window), widget); gtk_widget_show_all (window); gtk_main (); return 0; }