Reputation: 12404
I am currently fiddliny around with my menubar in GTK+3. Until now I had some CheckMenuItems with a label and an accelerator shortcut displayed:
GtkWidget *create_menubar(void)
{
GtkWidget *menubar = gtk_menu_bar_new();
const static guint num_keys[] = {GDK_KEY_1, GDK_KEY_2, GDK_KEY_3, GDK_KEY_4, GDK_KEY_5, GDK_KEY_6, GDK_KEY_7, GDK_KEY_8, GDK_KEY_9, GDK_KEY_0};
// Create a GtkAccelGroup and add it to the window.
GtkAccelGroup *accel_group = gtk_accel_group_new();
gtk_window_add_accel_group(GTK_WINDOW(window_main), accel_group);
// submenu show colors
GtkWidget *colors_Mi = gtk_menu_item_new_with_label("colors");
GtkWidget *colors_Menu = gtk_menu_new();
gtk_menu_shell_append(GTK_MENU_SHELL(menubar), colors_Mi);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(colors_Mi), colors_Menu);
for (int i = 0; i < NUM_COLORS; i++)
{
char name[10];
sprintf(name, "col %d", i+1);
// <<<<<<<<<<<<<<<<< cut mark...
GtkWidget *show_color_Mi = gtk_check_menu_item_new_with_label(name);
// <<<<<<<<<<<<<<<<< cut mark...
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(show_color_Mi), show_color[i]);
if (i < 10)
{
gtk_widget_add_accelerator(show_color_Mi, "activate", accel_group, num_keys[i], GDK_MOD1_MASK, GTK_ACCEL_VISIBLE);
}
gtk_menu_shell_append(GTK_MENU_SHELL(colors_Menu), show_color_Mi);
g_signal_connect(G_OBJECT(show_color_Mi), "toggled", G_CALLBACK(on_menu_show_colors_toggled), &show_color[i]);
}
return menubar;
}
This works fine so far. The program displays several sets of data with a different color for each. The entries in this menu are used to enable or disable a set of data. Now I want to add some indication which set of data is drawn in which color.
To do this I changed creation of the MenuItem. Now I create a horizontal box, where an image and a label is enclosed.
The lines between the cut marks (<<<<<<<<<<<<) are replaced with this:
// <<<<<<<<<<<<<<<<<
GtkWidget *show_color_Mi = gtk_check_menu_item_new();
GtkWidget *menubox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
GtkWidget *image = gtk_image_new();
GtkWidget *menulabel = gtk_label_new(name);
cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, 20, 15);
cairo_t *cr = cairo_create(surface);
cairo_set_source_rgb(cr, colors[i].r, colors[i].g, colors[i].b);
cairo_paint(cr);
cairo_destroy(cr);
gtk_image_set_from_surface(GTK_IMAGE(image), surface);
gtk_container_add(GTK_CONTAINER(show_color_Mi), menubox);
gtk_box_pack_start(GTK_BOX(menubox), image, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(menubox), menulabel, FALSE, FALSE, 0);
// <<<<<<<<<<<<<<<<<
Now I have CheckMenuItems which contain a colored rectangle and the same text as before my change. This is the good thing...
The bad thing is that for some reason the accelerator keys are not shown any longer.
Any suggestions what I am doing wrong there?
Edit:
In updated according to José Fonte's answer and in general it works. But in the meantime I found some other strange effect. I am running my program on some Ubuntu 14.04 machines with XFCE and it works as expected. I also run it in Ubuntu 16.04 in VirtualBox and it works fine, too. But on another Ubuntu 14.04 machine in VmWare behaves different. The colored rectangles are missing but the accelerators are shown even when I use the incorrect label type. This is getting a bit weird...
Now I checked on which machine it works or not and which version of libgtk-3-bin is installed:
Ubuntu 16.04 (VirtualBox) 3.18.9-1ubuntu3.1 OK
Raspbian Jessie (Raspberry Pi) 3.14.5-1+deb8u1rpi1rpig OK
Ubuntu 14.04, XFCE (native) 3.10.8-0ubuntu1.6 OK
Ubuntu 14.04, Unity (VmWare) 3.10.8-0ubuntu1.6 FAIL
Upvotes: 0
Views: 193
Reputation: 4114
your problem is that you are using a normal GtkLabel instead of GtkAccelLabel.
You must change to look like this:
[stuff deleted]
...
GtkWidget *menulabel = gtk_accel_label_new(name);
gtk_accel_label_set_accel_widget(GTK_ACCEL_LABEL(menulabel), show_color_Mi);
...
gtk_box_pack_start(GTK_BOX(menubox), menulabel, TRUE, TRUE, 0);
Conclusion: Use an gtk_accel_label instead of a gtk_label, then set the accel widget which should be the menu item that contains it and change the fill and expand flags on gtk_box_pack_start to allow for extra space. This should solve your problem.
Upvotes: 1