## Migrating from GtkOptionMenu and GtkCombo to GtkComboBox and GtkComboBoxEntry

### Matthias Clasen

`<maclas@gmx.de>`

Prior to 2.4, GTK+ offered two widgets for the task of selecting one item from a list of options. GtkOptionMenu presents the list of options as a menu while GtkCombo presents them in a Windows-style list popup. The only difference between the two is that a GtkCombo allows to manually edit the selected value, while the GtkOptionMenu does not.

In GTK+ 2.4, a unified API for list selection was introduced, with GtkComboBox for the non-editable case and GtkComboBoxEntry for the editable case. The selection of the display style — menu or list — is no longer done at the API level, but has been made themeable via the style property GtkComboBox::appearance.

## Migrating from GtkOptionMenu to GtkComboBox

Here is an example of a simple, but typical use of GtkOptionMenu:

    GtkWidget *option_menu, *menu, *menu_item;

    option_menu = gtk_option_menu_new ();
    menu = gtk_menu_new ();

    menu_item = gtk_menu_item_new_with_label ("First Item");
    gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
    gtk_widget_show (menu_item);
    menu_item = gtk_menu_item_new_with_label ("Second Item");
    gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
    gtk_widget_show (menu_item);
    menu_item = gtk_menu_item_new_with_label ("Third Item");
    gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
    gtk_widget_show (menu_item);

    gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu);

In order to react to the user's selection, connect to the "changed" signal on the option menu and use `gtk_option_menu_get_history()` to retrieve the index of the selected item.

And here is how it would be done with a GtkComboBox:

    GtkWidget *combo_box;

    combo_box = gtk_combo_box_new_text ();

    gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), "First Item");
    gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), "Second Item");
    gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), "Third Item");

In order to react to the user's selection, connect to the "changed" signal on the combo box and use `gtk_combo_box_get_active()` to retrieve the index of the selected item.

A slightly more complex example involving images:

    GtkWidget *option_menu, *menu, *menu_item;

    option_menu = gtk_option_menu_new ();
    menu = gtk_menu_new ();

    menu_item = gtk_image_menu_item_new_with_label ("First Item");
    gtk_image_menu_item_set_image (gtk_image_new_from_pixbuf (pixbuf1));
    gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
    gtk_widget_show (menu_item);
    menu_item = gtk_image_menu_item_new_with_label ("Second Item");
    gtk_image_menu_item_set_image (gtk_image_new_from_pixbuf (pixbuf2));
    gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
    gtk_widget_show (menu_item);
    menu_item = gtk_image_menu_item_new_with_label ("Third Item");
    gtk_image_menu_item_set_image (gtk_image_new_from_pixbuf (pixbuf3));
    gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
    gtk_widget_show (menu_item);

    gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu);

can be done using a GtkComboBox as follows:

    GtkListStore *store;
    GtkTreeIter iter;
    GtkCellRenderer *renderer;
    GtkWidget *combo_box;

    store = gtk_list_store_new (2, GDK_TYPE_PIXBUF, G_TYPE_STRING);

    gtk_list_store_append (store, &iter);
    gtk_list_store_set (store, &iter, 0, pixbuf1, 1, "First Item", -1);
    gtk_list_store_append (store, &iter);
    gtk_list_store_set (store, &iter, 0, pixbuf2, 1, "Second Item", -1);
    gtk_list_store_append (store, &iter);
    gtk_list_store_set (store, &iter, 0, pixbuf3, 1, "Third Item", -1);

    combo_box = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));

    renderer = gtk_cell_renderer_pixbuf_new ();
    gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), renderer, FALSE);
    gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), renderer,
                                    "pixbuf", 0,
                                    NULL);

    renderer = gtk_cell_renderer_text_new ();
    gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), renderer, TRUE);
    gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), renderer,
                                    "text", 1,
                                    NULL);