# Migrating from GnomeDruid to GtkAssistant

Since version 2.10, GTK+ provides the GtkAssistant widget as a replacement for the GnomeDruid widget in the libgnomeui library.

Conceptually, both GtkAssistant and GnomeDruid do the same task, but there are several areas where the API has been completely redesigned, so this chapter covers the main changes between both widgets.

## Inserting pages

GnomeDruid was implemented as a container for GnomeDruidPage abstract objects, which are implemented by the GnomeDruidPageEdge and GnomeDruidPageStandard widgets. Instead, GtkAssistant allows any widget to be a page, and implements per-page settings (such as page type or title) as child properties. So instead of:

    /* Page 1 */
    page = gnome_druid_page_edge_new (GNOME_EDGE_START);
    gnome_druid_page_edge_set_test (GNOME_DRUID_PAGE_EDGE (page),
                                    "Welcome to the assistant, it will make your life easier");
    gtk_widget_show (page);
    gnome_druid_append_page (GNOME_DRUID (druid), GNOME_DRUID_PAGE (page));

    /* Page 2 */
    page = gnome_druid_page_standard_new ();
    gtk_container_add (GTK_CONTAINER (GNOME_DRUID_PAGE_STANDARD (page)->vbox,
                       create_page1 ());
    gtk_widget_show_all (page);
    gnome_druid_append_page (GNOME_DRUID (druid), GNOME_DRUID_PAGE (page));

    /* Page 3 */
    page = gnome_druid_page_edge_new (GNOME_EDGE_FINISH);
    gnome_druid_page_edge_set_test (GNOME_DRUID_PAGE_EDGE (page),
                                    "Now you are done, your life is easier");
    gtk_widget_show (page);
    gnome_druid_append_page (GNOME_DRUID (druid), GNOME_DRUID_PAGE (page));

You have to write:

    gtk_assistant_append_page (GTK_ASSISTANT (assistant),
                               gtk_label_new ("Welcome to the assistant, it will make your life easier"));
    gtk_assistant_append_page (GTK_ASSISTANT (assistant),
                               create_page1 ());
    gtk_assistant_append_page (GTK_ASSISTANT (assistant),
                               gtk_label_new ("Now you are done, your life is easier");

## Decorating the assistant pages

To decorate your assistant pages, GtkAssistant provides similar functions to GnomeDruid, so you have to transform code like this:

    gnome_druid_page_edge_set_title (GNOME_DRUID_PAGE_EDGE (page), "Welcome");
    gnome_druid_page_edge_set_logo (GNOME_DRUID_PAGE_EDGE (page), logo_pixbuf);
    gnome_druid_page_edge_set_watermark (GNOME_DRUID_PAGE_EDGE (page), watermark_pixbuf);

Into this:

    gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page_widget, "Welcome");
    gtk_assistant_set_page_header_image (GTK_ASSISTANT (assistant), page_widget, logo_pixbuf);
    gtk_assistant_set_page_side_image (GTK_ASSISTANT (assistant), page_widget, watermark_pixbuf);

Where page_widget is the widget used as a page.

## Setting the page flow

Here is the area where GtkAssistant and GnomeDruid differ the most. While GnomeDruid used the "next" and "back" signals from the GnomeDruidPage, GtkAssistant uses the following techniques:

- gtk_assistant_set_forward_page_func (): Allows to define a GtkAssistantPageFunc to let the assistant know which will be the following page given the current page.

- gtk_assistant_set_page_complete (): Lets the assistant know whether the specified page is complete or not, updating buttons state accordingly.

- gtk_assistant_set_page_type (): Lets the assistant know the page role and update the buttons state accordingly. Pages can have the following roles:

  - Intro
  - Content
  - Progress
  - Confirmation
  - Summary

A sample GtkAssistantPageFunc could look like this:

    static gint
    forward_page_function (gint     current_page,
                           gpointer data)
    {
      switch (current_page)
        {
        case 0:
          return 1;
        case 1:
          if (check_page1_data ())
    	   return 2;
    	 else
    	   return 3;
        case 2:
          return 3;
        default:
          return -1;
        }
    }