a Wizard/Druid/Assistant widget for gtk



Over the last few days, I have started to work on a wizard widget for
GTK+, GtkAssistant. I looked at GnomeDruid, EggDruid and GtkNotebook for
prior art and at the Java LAF
(http://java.sun.com/products/jlf/at/book/index.html) for requirements.

The main difference to GnomeDruid is that I avoided GnomeDruidPage and
its subclasses. Instead, pages are arbitrary widgets, and their page
type (introduction page, content page, confirmation page, summary page
in the terminology of the Java LAF) is determined by a child property.

As a consequence, the ::back, ::next and other signals from
GnomeDruidPage are now signals on the assistant itself.

The assistant decides which buttons to display, based on the page type:

introduction page/initial content page: cancel, next
content page: cancel, back, next
confirmation page/final content page: cancel, back, finish
summary page: close

Simple linear wizards can be constructed by simply adding the required
pages with the default page type. More complicated nonlinear wizards can
be done in much the same way as with GnomeDruid, by setting the page
type appropriately on nonfinal pages which should act as confirmation
pages, and connecting to the ::next, ::back and ::finish signals. The
page types should allow to implement the LAF guidelines for wizards
faithfully. 

I'm not completely satisfied with the API yet (e.g. the decoration stuff
taken from EggDruid could be done as properties or child properties),
but I'd like to post it here for some feedback before tweaking it
further. The existing documentation is appended below. I'll attach an
inmplementation and examples to
http://bugzilla.gnome.org/show_bug.cgi?id=115348 when they're ready.

Matthias


struct _GtkAssistant
{
  GtkContainer container;

  /*< private >*/

  GtkAssistantPrivate *private_data;
};

struct _GtkAssistantClass
{
  GtkContainerClass parent_class;

  void     (*cancel)    (GtkAssistant *assistant, GtkWidget *page);
  void     (*prepare)   (GtkAssistant *assistant, GtkWidget *page);
  gboolean (*back)      (GtkAssistant *assistant, GtkWidget *page);
  gboolean (*next)      (GtkAssistant *assistant, GtkWidget *page);
  gboolean (*finish)    (GtkAssistant *assistant, GtkWidget *page);
  void     (*close)     (GtkAssistant *assistant, GtkWidget *page);

  /* Padding for future expansion */
  void (*_gtk_reserved1) (void);
  void (*_gtk_reserved2) (void);
  void (*_gtk_reserved3) (void);
  void (*_gtk_reserved4) (void);
};

typedef enum
{
  GTK_ASSISTANT_PAGE_CONTENT,
  GTK_ASSISTANT_PAGE_INTRO,
  GTK_ASSISTANT_PAGE_CONFIRM,
  GTK_ASSISTANT_PAGE_SUMMARY
} GtkAssistantPageType;


GtkWidget *gtk_assistant_new (void);

/* decoration */
void gtk_assistant_set_sidebar_image (GtkAssistant  *assistant,
                                      GdkPixbuf     *image);
void gtk_assistant_set_sidebar_image_alignment (GtkAssistant 
*assistant,
                                                gfloat        
alignment);
void gtk_assistant_set_sidebar_color (GtkAssistant  *assistant,
                                      GdkColor      *color);
void gtk_assistant_set_header_image (GtkAssistant  *assistant,
                                     GdkPixbuf     *image);
void gtk_assistant_set_header_color (GtkAssistant  *assistant,
                                     GdkColor      *color);
void gtk_assistant_set_header_text_color (GtkAssistant  *assistant,
                                          GdkColor      *color);
void gtk_assistant_set_buttons_sensitive (GtkAssistant  *assistant,
                                          gboolean       back_sensitive,
                                          gboolean      
forward_sensitive, 
                                          gboolean      
cancel_sensitive);

/* managing pages */
void gtk_assistant_insert_page (GtkAssistant  *assistant,
                                GtkWidget     *sibling,
                                GtkWidget     *page);
void gtk_assistant_append_page (GtkAssistant  *assistant,
                                GtkWidget     *page);
void gtk_assistant_prepend_page (GtkAssistant  *assistant,
                                 GtkWidget     *page);
gint gtk_assistant_get_n_pages (GtkAssistant  *assistant);
GtkWidget *gtk_assistant_get_nth_page (GtkAssistant  *assistant,
                                       gint           page_num);

/* current page */
void gtk_assistant_set_current_page (GtkAssistant  *assistant,
                                     GtkWidget     *page);

GtkWidget *gtk_assistant_get_current_page (GtkAssistant  *assistant);

void gtk_assistant_set_current_page_num (GtkAssistant  *assistant,
                                         gint           page_num);

gint gtk_assistant_get_current_page_num (GtkAssistant  *assistant);


/* child properties */
void gtk_assistant_set_page_type (GtkAssistant        *assistant,
                                  GtkWidget           *page,
                                  GtkAssistantPageType type);
GtkAssistantPageType gtk_assistant_get_page_type (GtkAssistant 
*assistant,
                                                  GtkWidget     *page);
void gtk_assistant_set_page_title (GtkAssistant  *assistant,
                                   GtkWidget     *page,
                                   const gchar   *title);
gchar *gtk_assistant_get_page_title (GtkAssistant  *assistant,
                                     GtkWidget     *page);


-------------------------------------------------------------------

  /**
   * GtkAssistant::cancel:
   * @assistant: the #GtkAssistant
   * @page: the current page
   *
   * The ::cancel signal is emitted when then the cancel button is 
   * clicked.
   */

  /**
   * GtkAssistant::prepare:
   * @assistant: the #GtkAssistant
   * @page: the current page
   *
   * The ::prepared signal is emitted when a new page is set as the 
   * assistant's current page, before making the new page visible. A 
   * handler for this signal can do any preparation which are necessary
   * before showing @page, e.g. use 
   * gtk_assistant_set_buttons_sensitive() to make the next button 
   * insensitive until some required fields are filled in.
   */

  /**
   * GtkAssistant::back:
   * @assistant: the @GtkAssistant
   * @page: the current page
   *
   * The ::back signal is emitted when the back button is clicked. The 
   * default behavior of the #GtkAssistant is to switch to the page 
   * before the current page. For more complicated, nonlinear wizards, 
   * a handler for this signal can use gtk_assistant_set_current_page() 
   * to go to a different page and return %TRUE to suppress the default 
   * behavior.
   *
   * Return value: %TRUE to suppress the default behavior
   */

  /**
   * GtkAssistant::next:
   * @assistant: the @GtkAssistant
   * @page: the current page
   *
   * The ::next signal is emitted when the next button is clicked. The 
   * default behavior of the #GtkAssistant is to switch to the page 
   * after the current page. For more complicated, nonlinear wizards,
   * a handler for this signal can use gtk_assistant_set_current_page() 
   * to go to a different page and return %TRUE to suppress the default 
   * behavior.
   *
   * Return value: %TRUE to suppress the default behavior
   */

  /**
   * GtkAssistant::finish:
   * @assistant: the @GtkAssistant
   * @page: the current page
   *
   * The ::finish signal is emitted when the finish button is clicked. 
   * The default behavior of the #GtkAssistant is to switch to the page 
   * after the current page, unless the current page is the last one.
   *
   * A handler for the ::finish signal should carry out the actions for
   * which the wizard has collected data. If the action takes a long 
   * time to complete, you might consider to put a page displaying the 
   * progress of the operation after the confirmation page with the 
   * finish button.
   *
   * Return value: %TRUE to suppress the default behavior
   */

  /**
   * GtkAssistant::close:
   * @assistant: the #GtkAssistant
   * @page: the current page
   *
   * The ::close signal is emitted when the close button is clicked.
   */

/**
 * gtk_assistant_new:
 * 
 * Creates a new #GtkAssistant.
 *
 * Return value: a newly created #GtkAssistant
 **/

/**
 * gtk_assistant_set_sidebar_image:
 * @assistant: a #GtkAssistant
 * @image: an image, or %NULL
 * 
 * Sets the sidebar image for @assistant. The image is displayed in
 * the sidebar on the left of the @assistant. If no image is set the 
 * sidebar area is hidden.
 *
 * In order to show a different sidebar image for each page, call this
 * function from the ::prepare signal handler. 
 **/

/**
 * gtk_assistant_set_sidebar_image_alignment:
 * @assistant: a #GtkAssistant
 * @alignment: the vertical alignment for the sidebar image, between 0
 *  (top) and 1 (bottom).
 * 
 * Changes the alignment of the sidebar image.
 **/

/**
 * gtk_assistant_set_sidebar_color:
 * @assistant: a #GtkAssistant
 * @color: a color
 * 
 * Changes the background color for the sidebar area.
 **/

/**
 * gtk_assistant_set_header_image:
 * @assistant: a #GtkAssistant
 * @image: an image
 * 
 * Sets the header image for @assistant. The image is displayed in
 * the header area at the top of the @assistant. 
 *
 * In order to show a different header image for each page, call this
 * function from the ::prepare signal handler. 
 **/

/**
 * gtk_assistant_set_header_color:
 * @assistant: a #GtkAssistant
 * @color: a color
 * 
 * Changes the background color for the header area. If you want to use 
 * the same background color in the sidebar, see 
 * gtk_assistant_set_sidebar_color().
 **/

/**
 * gtk_assistant_set_header_text_color:
 * @assistant: a #GtkAssistant
 * @color: a color
 * 
 * Sets the color in which the title and description are displayed in 
 * the header area of @assistant. You should make sure that the color 
 * contrasts with the background color of the header area, see
 * gtk_assistant_set_header_color().
 **/

/**
 * gtk_assistant_insert_page:
 * @assistant: a #GtkAssistant
 * @sibling: a #GtkWidget which is already added as a page of
@assistant, 
 *   or %NULL to insert @page at the end
 * @page: a widget to insert before @sibling 
 * 
 * Adds a page to a #GtkAssistant. The page is inserted before @sibling.
 **/

/**
 * gtk_assistant_append_page:
 * @assistant: a #GtkAssistant
 * @page: a widget to add as a page to @assistant
 * 
 * Adds a page to a #GtkAssistant. The page is put after all other pages
 * of @assistant.
 **/

/**
 * gtk_assistant_prepend_page:
 * @assistant: a #GtkAssistant
 * @page: a widget to add as a page to @assistant
 * 
 * Adds a page to a #GtkAssistant. The page is put before all other
pages 
 * of @assistant.
 **/

/**
 * gtk_assistant_set_current_page:
 * @assistant: a #GtkAssistant
 * @page: a #GtkWidget which has been added as a page of @assistant, or
%NULL 
 * 
 * Changes the currently displayed page of @assistant. 
 **/

/**
 * gtk_assistant_get_current_page:
 * @assistant: a #GtkAssistant
 * 
 * Returns the current page of @assistant.
 * 
 * Return value: the currently visible page 
 **/

/**
 * gtk_assistant_set_current_page_num:
 * @assistant: a #GtkAssistant
 * @page_num: a nonnegative integer less than the number of pages of 
 *            @assistant
 * 
 * Changes the currently displayed page of @assistant to the 
 * @page_num<!-- -->th page.
 **/

/**
 * gtk_assistant_get_current_page_num:
 * @assistant: a #GtkAssistant
 * 
 * Returns the position of the current page of @assistant.
 * 
 * Return value: the position of the current page
 **/

/**
 * gtk_assistant_get_n_pages:
 * @assistant: a #GtkAssistant
 * 
 * Returns the number of pages of @assistant.
 * 
 * Return value: the number of pages
 **/

/**
 * gtk_assistant_get_nth_page:
 * @assistant: a #GtkAssistant
 * @page_num: a nonnegative integer less than the number of pages of 
 *            @assistant
 * 
 * Returns the @page_num<!-- -->th page of @assistant.
 * 
 * Return value: the @page_num<!-- -->th page
 **/

/**
 * gtk_assistant_set_page_type:
 * @assistant: a #GtkAssistant
 * @page: a #GtkWidget which has been added as a page of @assistant
 * @type: the type of @page
 * 
 * Sets the page type of @page in @assistant.
 **/

/**
 * gtk_assistant_get_page_type:
 * @assistant: a #GtkAssistant
 * @page: a #GtkWidget which has been added as a page of @assistant
 * 
 * Gets the page type of @page in @assistant.
 *
 * Returns: the type of @page
 **/

/**
 * gtk_assistant_set_page_title:
 * @assistant: a #GtkAssistant
 * @page: a page of @assitant
 * @title: the new title for @page
 * 
 * Sets a title for @page. The title is displayed in the header
 * area of the assistant when @page is the current page.
 **/

/**
 * gtk_assistant_get_page_title:
 * @assistant: a #GtkAssistant
 * @page: a page of @assitant
 * 
 * Gets the title for @page. 
 * 
 * Return value: the title for @page.
 **/











[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]