[gtk+] GtkAssistant: an new style for assistants



commit c83e76fb1252831f6eec1287efe71e57e94d976c
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Apr 16 20:45:26 2011 -0400

    GtkAssistant: an new style for assistants
    
    GtkAssistant is widely recognized as a butt-ugly widget.
    
    This commit changes its style to look more modern. We
    deprecate the sidebar and header image properties and
    don't show them anymore. Instead, page titles are arranged
    in a sidebar, with the title of the current page shown
    in highlighted style.

 gtk/gtkassistant.c | 1036 ++++++++++++++++++----------------------------------
 gtk/gtkassistant.h |   56 ++--
 2 files changed, 389 insertions(+), 703 deletions(-)
---
diff --git a/gtk/gtkassistant.c b/gtk/gtkassistant.c
index 17ecf46..7e9b7d1 100644
--- a/gtk/gtkassistant.c
+++ b/gtk/gtkassistant.c
@@ -64,8 +64,9 @@
 
 #include "gtkaccessibleprivate.h"
 #include "gtkbutton.h"
-#include "gtkhbox.h"
-#include "gtkhbbox.h"
+#include "gtkbox.h"
+#include "gtkeventbox.h"
+#include "gtknotebook.h"
 #include "gtkimage.h"
 #include "gtklabel.h"
 #include "gtksizegroup.h"
@@ -84,12 +85,15 @@ typedef struct _GtkAssistantPage GtkAssistantPage;
 
 struct _GtkAssistantPage
 {
-  GtkWidget *page;
   GtkAssistantPageType type;
-  guint      complete : 1;
+  guint      complete     : 1;
   guint      complete_set : 1;
 
-  GtkWidget *title;
+  gchar *title;
+
+  GtkWidget *page;
+  GtkWidget *regular_title;
+  GtkWidget *current_title;
   GdkPixbuf *header_image;
   GdkPixbuf *sidebar_image;
 };
@@ -103,54 +107,37 @@ struct _GtkAssistantPrivate
   GtkWidget *close;
   GtkWidget *last;
 
-  GtkWidget *header_image;
-  GtkWidget *sidebar_image;
-
+  GtkWidget *sidebar;
+  GtkWidget *content;
   GtkWidget *action_area;
 
   GList     *pages;
-
-  GtkAssistantPage *current_page;
-
   GSList    *visited_pages;
+  GtkAssistantPage *current_page;
 
-  GtkSizeGroup *size_group;
+  GtkSizeGroup *button_size_group;
+  GtkSizeGroup *title_size_group;
 
   GtkAssistantPageFunc forward_function;
   gpointer forward_function_data;
   GDestroyNotify forward_data_destroy;
 
+  gint extra_buttons;
+
   guint committed : 1;
 };
 
 static void     gtk_assistant_class_init         (GtkAssistantClass *class);
 static void     gtk_assistant_init               (GtkAssistant      *assistant);
 static void     gtk_assistant_destroy            (GtkWidget         *widget);
-static void     gtk_assistant_style_updated      (GtkWidget         *widget);
-static void     gtk_assistant_get_preferred_width  (GtkWidget        *widget,
-                                                    gint             *minimum,
-                                                    gint             *natural);
-static void     gtk_assistant_get_preferred_height (GtkWidget        *widget,
-                                                    gint             *minimum,
-                                                    gint             *natural);
-static void     gtk_assistant_size_allocate      (GtkWidget         *widget,
-                                                  GtkAllocation     *allocation);
 static void     gtk_assistant_map                (GtkWidget         *widget);
 static void     gtk_assistant_unmap              (GtkWidget         *widget);
 static gboolean gtk_assistant_delete_event       (GtkWidget         *widget,
                                                   GdkEventAny       *event);
-static gboolean gtk_assistant_draw               (GtkWidget         *widget,
-                                                  cairo_t           *cr);
-static gboolean gtk_assistant_focus              (GtkWidget         *widget,
-                                                  GtkDirectionType   direction);
 static void     gtk_assistant_add                (GtkContainer      *container,
                                                   GtkWidget         *page);
 static void     gtk_assistant_remove             (GtkContainer      *container,
                                                   GtkWidget         *page);
-static void     gtk_assistant_forall             (GtkContainer      *container,
-                                                  gboolean           include_internals,
-                                                  GtkCallback        callback,
-                                                  gpointer           callback_data);
 static void     gtk_assistant_set_child_property (GtkContainer      *container,
                                                   GtkWidget         *child,
                                                   guint              property_id,
@@ -223,20 +210,13 @@ gtk_assistant_class_init (GtkAssistantClass *class)
   container_class = (GtkContainerClass *) class;
 
   widget_class->destroy = gtk_assistant_destroy;
-  widget_class->style_updated = gtk_assistant_style_updated;
-  widget_class->get_preferred_width = gtk_assistant_get_preferred_width;
-  widget_class->get_preferred_height = gtk_assistant_get_preferred_height;
-  widget_class->size_allocate = gtk_assistant_size_allocate;
   widget_class->map = gtk_assistant_map;
   widget_class->unmap = gtk_assistant_unmap;
   widget_class->delete_event = gtk_assistant_delete_event;
-  widget_class->draw = gtk_assistant_draw;
-  widget_class->focus = gtk_assistant_focus;
   widget_class->get_accessible = gtk_assistant_get_accessible;
 
   container_class->add = gtk_assistant_add;
   container_class->remove = gtk_assistant_remove;
-  container_class->forall = gtk_assistant_forall;
   container_class->set_child_property = gtk_assistant_set_child_property;
   container_class->get_child_property = gtk_assistant_get_child_property;
 
@@ -262,9 +242,11 @@ gtk_assistant_class_init (GtkAssistantClass *class)
    * @assistant: the #GtkAssistant
    * @page: the current page
    *
-   * The ::prepare 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.
+   * The ::prepare 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 preparations which are
+   * necessary before showing @page.
    *
    * Since: 2.10
    */
@@ -281,15 +263,17 @@ gtk_assistant_class_init (GtkAssistantClass *class)
    * GtkAssistant::apply:
    * @assistant: the #GtkAssistant
    *
-   * The ::apply signal is emitted when the apply 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.
+   * The ::apply signal is emitted when the apply 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 ::apply 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 putting a page of type %GTK_ASSISTANT_PAGE_PROGRESS
-   * after the confirmation page and handle this operation within the
-   * #GtkAssistant::prepare signal of the progress page.
+   * A handler for the ::apply 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 putting a page of type
+   * %GTK_ASSISTANT_PAGE_PROGRESS after the confirmation page and handle
+   * this operation within the #GtkAssistant::prepare signal of the progress
+   * page.
    *
    * Since: 2.10
    */
@@ -357,9 +341,7 @@ gtk_assistant_class_init (GtkAssistantClass *class)
   /**
    * GtkAssistant:title:
    *
-   * The title that is displayed in the page header.
-   *
-   * If title and header-image are both %NULL, no header is displayed.
+   * The title of the page.
    *
    * Since: 2.10
    */
@@ -374,11 +356,12 @@ gtk_assistant_class_init (GtkAssistantClass *class)
   /**
    * GtkAssistant:header-image:
    *
-   * The image that is displayed next to the title in the page header.
-   *
-   * If title and header-image are both %NULL, no header is displayed.
+   * This image used to be displayed in the page header.
    *
    * Since: 2.10
+   *
+   * Deprecated: 3.2: Since GTK+ 3.2, a header is no longer shown;
+   *     add your header decoration to the page content instead.
    */
   gtk_container_class_install_child_property (container_class,
                                               CHILD_PROP_PAGE_HEADER_IMAGE,
@@ -389,13 +372,13 @@ gtk_assistant_class_init (GtkAssistantClass *class)
                                                                    GTK_PARAM_READWRITE));
 
   /**
-   * GtkAssistant:header-image:
-   *
-   * The image that is displayed next to the page.
+   * GtkAssistant:sidebar-image:
    *
-   * Set this to %NULL to make the sidebar disappear.
+   * This image used to be displayed in the 'sidebar'.
    *
    * Since: 2.10
+   *
+   * Deprecated: 3.2: Since GTK+ 3.2, the sidebar image is no longer shown.
    */
   gtk_container_class_install_child_property (container_class,
                                               CHILD_PROP_PAGE_SIDEBAR_IMAGE,
@@ -404,12 +387,13 @@ gtk_assistant_class_init (GtkAssistantClass *class)
                                                                    P_("Sidebar image for the assistant page"),
                                                                    GDK_TYPE_PIXBUF,
                                                                    GTK_PARAM_READWRITE));
+
   /**
    * GtkAssistant:complete:
    *
-   * Setting the "complete" child property to %TRUE marks a page as complete
-   * (i.e.: all the required fields are filled out). GTK+ uses this information
-   * to control the sensitivity of the navigation buttons.
+   * Setting the "complete" child property to %TRUE marks a page as
+   * complete (i.e.: all the required fields are filled out). GTK+ uses
+   * this information to control the sensitivity of the navigation buttons.
    *
    * Since: 2.10
    */
@@ -454,17 +438,23 @@ default_forward_function (gint current_page, gpointer data)
   return current_page;
 }
 
-static void
-compute_last_button_state (GtkAssistant *assistant)
+static gboolean
+last_button_visible (GtkAssistant *assistant, GtkAssistantPage *page)
 {
   GtkAssistantPrivate *priv = assistant->priv;
-  GtkAssistantPage *page_info, *current_page_info;
+  GtkAssistantPage *page_info;
   gint count, page_num, n_pages;
 
+  if (page == NULL)
+    return FALSE;
+
+  if (page->type != GTK_ASSISTANT_PAGE_CONTENT)
+    return FALSE;
+
   count = 0;
-  page_num = gtk_assistant_get_current_page (assistant);
-  n_pages  = gtk_assistant_get_n_pages (assistant);
-  current_page_info = page_info = g_list_nth_data (priv->pages, page_num);
+  page_num = g_list_index (priv->pages, page);
+  n_pages  = g_list_length (priv->pages);
+  page_info = page;
 
   while (page_num >= 0 && page_num < n_pages &&
          page_info->type == GTK_ASSISTANT_PAGE_CONTENT &&
@@ -477,63 +467,87 @@ compute_last_button_state (GtkAssistant *assistant)
       count++;
     }
 
-  /* make the last button visible if we can skip multiple
+  /* Make the last button visible if we can skip multiple
    * pages and end on a confirmation or summary page
    */
   if (count > 1 && page_info &&
       (page_info->type == GTK_ASSISTANT_PAGE_CONFIRM ||
        page_info->type == GTK_ASSISTANT_PAGE_SUMMARY))
-    {
-      gtk_widget_show (priv->last);
-      gtk_widget_set_sensitive (priv->last,
-                                current_page_info->complete);
-    }
+    return TRUE;
   else
-    gtk_widget_hide (priv->last);
+    return FALSE;
 }
 
 static void
-compute_progress_state (GtkAssistant *assistant)
+update_actions_size (GtkAssistant *assistant)
 {
   GtkAssistantPrivate *priv = assistant->priv;
-  gint page_num, n_pages;
+  GList *l;
+  GtkAssistantPage *page;
+  gint buttons, page_buttons;
 
-  n_pages = gtk_assistant_get_n_pages (assistant);
-  page_num = gtk_assistant_get_current_page (assistant);
+  if (!priv->current_page)
+    return;
 
-  page_num = (priv->forward_function) (page_num, priv->forward_function_data);
+  /* Some heuristics to find out how many buttons we should
+   * reserve space for. It is possible to trick this code
+   * with page forward functions and invisible pages, etc.
+   */
+  buttons = 0;
+  for (l = priv->pages; l; l = l->next)
+    {
+      page = l->data;
 
-  if (page_num >= 0 && page_num < n_pages)
-    gtk_widget_show (priv->forward);
-  else
-    gtk_widget_hide (priv->forward);
+      if (!gtk_widget_get_visible (page->page))
+        continue;
+
+      page_buttons = 2; /* cancel, forward/apply/close */
+      if (l != priv->pages)
+        page_buttons += 1; /* back */
+      if (last_button_visible (assistant, page))
+        page_buttons += 1; /* last */
+
+      buttons = MAX (buttons, page_buttons);
+    }
+
+  buttons += priv->extra_buttons;
+
+  gtk_widget_set_size_request (priv->action_area,
+                               buttons * gtk_widget_get_allocated_width (priv->cancel) + (buttons - 1) * 6,
+                               -1);
 }
 
 static void
-set_assistant_header_image (GtkAssistant *assistant)
+compute_last_button_state (GtkAssistant *assistant)
 {
   GtkAssistantPrivate *priv = assistant->priv;
 
-  gtk_image_set_from_pixbuf (GTK_IMAGE (priv->header_image),
-                             priv->current_page->header_image);
+  gtk_widget_set_sensitive (priv->last, priv->current_page->complete);
+  if (last_button_visible (assistant, priv->current_page))
+    gtk_widget_show (priv->last);
+  else
+    gtk_widget_hide (priv->last);
 }
 
 static void
-set_assistant_sidebar_image (GtkAssistant *assistant)
+compute_progress_state (GtkAssistant *assistant)
 {
   GtkAssistantPrivate *priv = assistant->priv;
+  gint page_num, n_pages;
+
+  n_pages = gtk_assistant_get_n_pages (assistant);
+  page_num = gtk_assistant_get_current_page (assistant);
 
-  gtk_image_set_from_pixbuf (GTK_IMAGE (priv->sidebar_image),
-                             priv->current_page->sidebar_image);
+  page_num = (priv->forward_function) (page_num, priv->forward_function_data);
 
-  if (priv->current_page->sidebar_image)
-    gtk_widget_show (priv->sidebar_image);
+  if (page_num >= 0 && page_num < n_pages)
+    gtk_widget_show (priv->forward);
   else
-    gtk_widget_hide (priv->sidebar_image);
+    gtk_widget_hide (priv->forward);
 }
 
 static void
-set_assistant_buttons_state (GtkAssistant *assistant)
+update_buttons_state (GtkAssistant *assistant)
 {
   GtkAssistantPrivate *priv = assistant->priv;
 
@@ -621,44 +635,94 @@ set_assistant_buttons_state (GtkAssistant *assistant)
     gtk_widget_hide (priv->back);
 }
 
-static void
-set_current_page (GtkAssistant     *assistant,
-                  GtkAssistantPage *page)
+static gboolean
+update_page_title_state (GtkAssistant *assistant, GList *list)
 {
+  GtkAssistantPage *page, *other;
   GtkAssistantPrivate *priv = assistant->priv;
-  GtkAssistantPage *old_page;
+  gboolean visible;
+  GList *l;
 
-  if (priv->current_page &&
-      gtk_widget_is_drawable (priv->current_page->page))
-    old_page = priv->current_page;
-  else
-    old_page = NULL;
+  page = list->data;
 
-  priv->current_page = page;
+  if (page->title == NULL || page->title[0] == 0)
+    visible = FALSE;
+  else
+    visible = gtk_widget_get_visible (page->page);
 
-  set_assistant_buttons_state (assistant);
-  set_assistant_header_image (assistant);
-  set_assistant_sidebar_image (assistant);
+  if (page == priv->current_page)
+    {
+      gtk_widget_set_visible (page->regular_title, FALSE);
+      gtk_widget_set_visible (page->current_title, visible);
+    }
+  else
+    {
+      /* If multiple consecutive pages have the same title,
+       * we only show it once, since it would otherwise look
+       * silly. We have to be a little careful, since we
+       * _always_ show the title of the current page.
+       */
+      if (list->prev)
+        {
+          other = list->prev->data;
+          if (g_strcmp0 (page->title, other->title) == 0)
+            visible = FALSE;
+        }
+      for (l = list->next; l; l = l->next)
+        {
+          other = l->data;
+          if (g_strcmp0 (page->title, other->title) != 0)
+            break;
 
-  g_signal_emit (assistant, signals [PREPARE], 0, priv->current_page->page);
+          if (other == priv->current_page)
+            {
+              visible = FALSE;
+              break;
+            }
+        }
 
-  if (gtk_widget_get_visible (priv->current_page->page) &&
-      gtk_widget_get_mapped (GTK_WIDGET (assistant)))
-    {
-      gtk_widget_set_child_visible (priv->current_page->page, TRUE);
-      gtk_widget_set_child_visible (priv->current_page->title, TRUE);
-      gtk_widget_map (priv->current_page->page);
-      gtk_widget_map (priv->current_page->title);
+      gtk_widget_set_visible (page->regular_title, visible);
+      gtk_widget_set_visible (page->current_title, FALSE);
     }
 
-  if (old_page && gtk_widget_get_mapped (old_page->page))
+  return visible;
+}
+
+static void
+update_title_state (GtkAssistant *assistant)
+{
+  GtkAssistantPrivate *priv = assistant->priv;
+  GList *l;
+  gboolean show_titles;
+
+  show_titles = FALSE;
+  for (l = priv->pages; l != NULL; l = l->next)
     {
-      gtk_widget_set_child_visible (old_page->page, FALSE);
-      gtk_widget_set_child_visible (old_page->title, FALSE);
-      gtk_widget_unmap (old_page->page);
-      gtk_widget_unmap (old_page->title);
+      if (update_page_title_state (assistant, l))
+        show_titles = TRUE;
     }
 
+  gtk_widget_set_visible (priv->sidebar, show_titles);
+}
+
+static void
+set_current_page (GtkAssistant *assistant,
+                  gint          page_num)
+{
+  GtkAssistantPrivate *priv = assistant->priv;
+
+  priv->current_page = (GtkAssistantPage *)g_list_nth_data (priv->pages, page_num);
+
+  g_signal_emit (assistant, signals [PREPARE], 0, priv->current_page->page);
+
+  update_title_state (assistant);
+
+  gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->content), page_num);
+
+  /* update buttons state, flow may have changed */
+  if (gtk_widget_get_mapped (GTK_WIDGET (assistant)))
+    update_buttons_state (assistant);
+
   if (!gtk_widget_child_focus (priv->current_page->page, GTK_DIR_TAB_FORWARD))
     {
       GtkWidget *button[6];
@@ -702,7 +766,7 @@ compute_next_step (GtkAssistant *assistant)
   if (next_page >= 0 && next_page < n_pages)
     {
       priv->visited_pages = g_slist_prepend (priv->visited_pages, page_info);
-      set_current_page (assistant, g_list_nth_data (priv->pages, next_page));
+      set_current_page (assistant, next_page);
 
       return TRUE;
     }
@@ -787,37 +851,46 @@ gtk_assistant_init (GtkAssistant *assistant)
 {
   GtkAssistantPrivate *priv;
   GtkStyleContext *context;
+  GtkWidget *main_box;
+  GtkWidget *content_box;
+  GtkWidget *side_box;
 
   assistant->priv = G_TYPE_INSTANCE_GET_PRIVATE (assistant,
                                                  GTK_TYPE_ASSISTANT,
                                                  GtkAssistantPrivate);
   priv = assistant->priv;
 
-  gtk_container_set_reallocate_redraws (GTK_CONTAINER (assistant), TRUE);
-  gtk_container_set_border_width (GTK_CONTAINER (assistant), 12);
+  /* use border on inner panes instead */
+  gtk_container_set_border_width (GTK_CONTAINER (assistant), 0);
 
   gtk_widget_push_composite_child ();
 
-  /* Header */
-  priv->header_image = gtk_image_new ();
-  gtk_misc_set_alignment (GTK_MISC (priv->header_image), 1., 0.5);
-  gtk_widget_set_parent (priv->header_image, GTK_WIDGET (assistant));
-  gtk_widget_show (priv->header_image);
-
-  context = gtk_widget_get_style_context (priv->header_image);
-  gtk_style_context_add_class (context, GTK_STYLE_CLASS_HIGHLIGHT);
-
-  /* Sidebar */
-  priv->sidebar_image = gtk_image_new ();
-  gtk_misc_set_alignment (GTK_MISC (priv->sidebar_image), 0., 0.);
-  gtk_widget_set_parent (priv->sidebar_image, GTK_WIDGET (assistant));
-  gtk_widget_show (priv->sidebar_image);
-
-  context = gtk_widget_get_style_context (priv->sidebar_image);
-  gtk_style_context_add_class (context, GTK_STYLE_CLASS_HIGHLIGHT);
-
-  /* Action area  */
-  priv->action_area  = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+  main_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
+  priv->sidebar = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+  gtk_container_set_border_width (GTK_CONTAINER (priv->sidebar), 12);
+  /* Add an event box so we can set the background */
+  side_box = gtk_event_box_new ();
+  context = gtk_widget_get_style_context (side_box);
+  gtk_style_context_add_class (context, GTK_STYLE_CLASS_SIDEBAR);
+
+  content_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
+  gtk_container_set_border_width (GTK_CONTAINER (content_box), 12);
+  priv->content = gtk_notebook_new ();
+  gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->content), FALSE);
+  gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->content), FALSE);
+  priv->action_area = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+
+  gtk_container_add (GTK_CONTAINER (side_box), priv->sidebar);
+  gtk_box_pack_start (GTK_BOX (main_box), side_box, FALSE, FALSE, 0);
+  gtk_box_pack_start (GTK_BOX (main_box), content_box, TRUE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (content_box), priv->content, TRUE, FALSE, 0);
+  gtk_box_pack_start (GTK_BOX (content_box), priv->action_area, FALSE, TRUE, 0);
+  gtk_widget_set_halign (priv->action_area, GTK_ALIGN_END);
+
+  gtk_widget_show_all (main_box);
+
+  gtk_widget_set_parent (main_box, GTK_WIDGET (assistant));
+  _gtk_bin_set_child (GTK_BIN (assistant), main_box);
 
   priv->close   = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
   priv->apply   = gtk_button_new_from_stock (GTK_STOCK_APPLY);
@@ -829,13 +902,13 @@ gtk_assistant_init (GtkAssistant *assistant)
   gtk_widget_set_can_default (priv->apply, TRUE);
   gtk_widget_set_can_default (priv->forward, TRUE);
 
-  priv->size_group   = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
-  gtk_size_group_add_widget (priv->size_group, priv->close);
-  gtk_size_group_add_widget (priv->size_group, priv->apply);
-  gtk_size_group_add_widget (priv->size_group, priv->forward);
-  gtk_size_group_add_widget (priv->size_group, priv->back);
-  gtk_size_group_add_widget (priv->size_group, priv->cancel);
-  gtk_size_group_add_widget (priv->size_group, priv->last);
+  priv->button_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+  gtk_size_group_add_widget (priv->button_size_group, priv->close);
+  gtk_size_group_add_widget (priv->button_size_group, priv->apply);
+  gtk_size_group_add_widget (priv->button_size_group, priv->forward);
+  gtk_size_group_add_widget (priv->button_size_group, priv->back);
+  gtk_size_group_add_widget (priv->button_size_group, priv->cancel);
+  gtk_size_group_add_widget (priv->button_size_group, priv->last);
 
   if (!alternative_button_order (assistant))
     {
@@ -856,7 +929,6 @@ gtk_assistant_init (GtkAssistant *assistant)
       gtk_box_pack_end (GTK_BOX (priv->action_area), priv->last, FALSE, FALSE, 0);
     }
 
-  gtk_widget_set_parent (priv->action_area, GTK_WIDGET (assistant));
   gtk_widget_show (priv->forward);
   gtk_widget_show (priv->back);
   gtk_widget_show (priv->cancel);
@@ -864,6 +936,8 @@ gtk_assistant_init (GtkAssistant *assistant)
 
   gtk_widget_pop_composite_child ();
 
+  priv->title_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+
   priv->pages = NULL;
   priv->current_page = NULL;
   priv->visited_pages = NULL;
@@ -887,11 +961,11 @@ gtk_assistant_init (GtkAssistant *assistant)
 }
 
 static void
-gtk_assistant_set_child_property (GtkContainer    *container,
-                                  GtkWidget       *child,
-                                  guint            property_id,
-                                  const GValue    *value,
-                                  GParamSpec      *pspec)
+gtk_assistant_set_child_property (GtkContainer *container,
+                                  GtkWidget    *child,
+                                  guint         property_id,
+                                  const GValue *value,
+                                  GParamSpec   *pspec)
 {
   switch (property_id)
     {
@@ -963,9 +1037,11 @@ on_page_notify_visibility (GtkWidget  *widget,
 {
   GtkAssistant *assistant = GTK_ASSISTANT (data);
 
-  /* update buttons state, flow may have changed */
   if (gtk_widget_get_mapped (GTK_WIDGET (assistant)))
-    set_assistant_buttons_state (assistant);
+    {
+      update_buttons_state (assistant);
+      update_title_state (assistant);
+    }
 }
 
 static void
@@ -1002,21 +1078,28 @@ remove_page (GtkAssistant *assistant,
         }
     }
 
-  priv->pages = g_list_remove_link (priv->pages, element);
-  priv->visited_pages = g_slist_remove_all (priv->visited_pages, page_info);
-
   g_signal_handlers_disconnect_by_func (page_info->page, on_page_notify_visibility, assistant);
-  gtk_widget_unparent (page_info->page);
 
-  if (page_info->header_image)
-    g_object_unref (page_info->header_image);
+  gtk_size_group_remove_widget (priv->title_size_group, page_info->regular_title);
+  gtk_size_group_remove_widget (priv->title_size_group, page_info->current_title);
 
-  if (page_info->sidebar_image)
-    g_object_unref (page_info->sidebar_image);
+  gtk_container_remove (GTK_CONTAINER (priv->sidebar), page_info->regular_title);
+  gtk_container_remove (GTK_CONTAINER (priv->sidebar), page_info->current_title);
+
+  gtk_notebook_remove_page (GTK_NOTEBOOK (priv->content), gtk_notebook_page_num (GTK_NOTEBOOK (priv->content), page_info->page));
+  priv->pages = g_list_remove_link (priv->pages, element);
+  priv->visited_pages = g_slist_remove_all (priv->visited_pages, page_info);
+
+  g_free (page_info->title);
 
-  gtk_widget_destroy (page_info->title);
   g_slice_free (GtkAssistantPage, page_info);
   g_list_free_1 (element);
+
+  if (gtk_widget_get_mapped (GTK_WIDGET (assistant)))
+    {
+      update_buttons_state (assistant);
+      update_actions_size (assistant);
+    }
 }
 
 static void
@@ -1025,28 +1108,33 @@ gtk_assistant_destroy (GtkWidget *widget)
   GtkAssistant *assistant = GTK_ASSISTANT (widget);
   GtkAssistantPrivate *priv = assistant->priv;
 
-  if (priv->header_image)
-    {
-      gtk_widget_destroy (priv->header_image);
-      priv->header_image = NULL;
-    }
+  /* We set current to NULL so that the remove code doesn't try
+   * to do anything funny
+   */
+  priv->current_page = NULL;
 
-  if (priv->sidebar_image)
-    {
-      gtk_widget_destroy (priv->sidebar_image);
-      priv->sidebar_image = NULL;
-    }
+  while (priv->pages)
+    remove_page (assistant, priv->pages);
+
+  if (priv->sidebar)
+    priv->sidebar = NULL;
+
+  if (priv->content)
+    priv->content = NULL;
 
   if (priv->action_area)
+    priv->action_area = NULL;
+
+  if (priv->button_size_group)
     {
-      gtk_widget_destroy (priv->action_area);
-      priv->action_area = NULL;
+      g_object_unref (priv->button_size_group);
+      priv->button_size_group = NULL;
     }
 
-  if (priv->size_group)
+  if (priv->title_size_group)
     {
-      g_object_unref (priv->size_group);
-      priv->size_group = NULL;
+      g_object_unref (priv->title_size_group);
+      priv->title_size_group = NULL;
     }
 
   if (priv->forward_function)
@@ -1066,13 +1154,6 @@ gtk_assistant_destroy (GtkWidget *widget)
       priv->visited_pages = NULL;
     }
 
-  /* We set current to NULL so that the remove code doesn't try
-   * to do anything funny */
-  priv->current_page = NULL;
-
-  while (priv->pages)
-    remove_page (assistant, priv->pages);
-
   GTK_WIDGET_CLASS (gtk_assistant_parent_class)->destroy (widget);
 }
 
@@ -1096,271 +1177,37 @@ find_page (GtkAssistant  *assistant,
 }
 
 static void
-set_title_font (GtkWidget *assistant,
-                GtkWidget *title_label)
-{
-  PangoFontDescription *desc;
-  GtkStyleContext *context;
-  gint size;
-
-  gtk_widget_override_font (title_label, NULL);
-
-  desc = pango_font_description_new ();
-  context = gtk_widget_get_style_context (title_label);
-  size = pango_font_description_get_size (gtk_style_context_get_font (context, 0));
-
-  pango_font_description_set_weight (desc, PANGO_WEIGHT_ULTRABOLD);
-  pango_font_description_set_size   (desc, size * PANGO_SCALE_XX_LARGE);
-
-  gtk_widget_override_font (title_label, desc);
-  pango_font_description_free (desc);
-}
-
-static void
-gtk_assistant_style_updated (GtkWidget *widget)
-{
-  GtkAssistant *assistant = GTK_ASSISTANT (widget);
-  GtkAssistantPrivate *priv = assistant->priv;
-  GList *list;
-
-  GTK_WIDGET_CLASS (gtk_assistant_parent_class)->style_updated (widget);
-
-  list = priv->pages;
-
-  while (list)
-    {
-      GtkAssistantPage *page = list->data;
-
-      set_title_font (widget, page->title);
-      list = list->next;
-    }
-}
-
-static void
-gtk_assistant_size_request (GtkWidget      *widget,
-                            GtkRequisition *requisition)
-{
-  GtkAssistant *assistant = GTK_ASSISTANT (widget);
-  GtkAssistantPrivate *priv = assistant->priv;
-  GtkRequisition child_requisition;
-  gint header_padding, content_padding;
-  gint width, height, header_width, header_height;
-  guint border_width;
-  GList *list;
-
-  gtk_widget_style_get (widget,
-                        "header-padding", &header_padding,
-                        "content-padding", &content_padding,
-                        NULL);
-  width = height = 0;
-  header_width = header_height = 0;
-  list  = priv->pages;
-
-  while (list)
-    {
-      GtkAssistantPage *page = list->data;
-      gint w, h;
-
-      gtk_widget_get_preferred_size (page->page,
-                                     &child_requisition, NULL);
-      width  = MAX (width,  child_requisition.width);
-      height = MAX (height, child_requisition.height);
-
-      gtk_widget_get_preferred_size (page->title,
-                                     &child_requisition, NULL);
-      w = child_requisition.width;
-      h = child_requisition.height;
-
-      if (page->header_image)
-        {
-          w += gdk_pixbuf_get_width (page->header_image) + HEADER_SPACING;
-          h  = MAX (h, gdk_pixbuf_get_height (page->header_image));
-        }
-
-      header_width  = MAX (header_width, w);
-      header_height = MAX (header_height, h);
-
-      list = list->next;
-    }
-
-  gtk_widget_get_preferred_size (priv->sidebar_image,
-                                 &child_requisition, NULL);
-  width  += child_requisition.width;
-  height  = MAX (height, child_requisition.height);
-
-  gtk_widget_set_size_request (priv->header_image, header_width, header_height);
-  gtk_widget_get_preferred_size (priv->header_image,
-                                 &child_requisition, NULL);
-  width   = MAX (width, header_width) + 2 * header_padding;
-  height += header_height + 2 * header_padding;
-
-  gtk_widget_get_preferred_size (priv->action_area,
-                                 &child_requisition, NULL);
-  width   = MAX (width, child_requisition.width);
-  height += child_requisition.height + ACTION_AREA_SPACING;
-
-  border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
-  width += border_width * 2 + content_padding * 2;
-  height += border_width * 2 + content_padding * 2;
-
-  requisition->width = width;
-  requisition->height = height;
-}
-
-static void
-gtk_assistant_get_preferred_width (GtkWidget *widget,
-                                   gint      *minimum,
-                                   gint      *natural)
-{
-  GtkRequisition requisition;
-
-  gtk_assistant_size_request (widget, &requisition);
-
-  *minimum = *natural = requisition.width;
-}
-
-static void
-gtk_assistant_get_preferred_height (GtkWidget *widget,
-                                    gint      *minimum,
-                                    gint      *natural)
-{
-  GtkRequisition requisition;
-
-  gtk_assistant_size_request (widget, &requisition);
-
-  *minimum = *natural = requisition.height;
-}
-
-static void
-gtk_assistant_size_allocate (GtkWidget      *widget,
-                             GtkAllocation  *allocation)
-{
-  GtkAssistant *assistant = GTK_ASSISTANT (widget);
-  GtkAssistantPrivate *priv = assistant->priv;
-  GtkRequisition header_requisition, action_requisition, sidebar_requisition;
-  GtkAllocation child_allocation, header_allocation;
-  GtkAllocation action_area_allocation, header_image_allocation;
-  gint header_padding, content_padding;
-  guint border_width;
-  gboolean rtl;
-  GList *pages;
-
-  rtl   = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
-  pages = priv->pages;
-
-  gtk_widget_style_get (widget,
-                        "header-padding", &header_padding,
-                        "content-padding", &content_padding,
-                        NULL);
-
-  gtk_widget_set_allocation (widget, allocation);
-  border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
-
-  /* Header */
-  gtk_widget_get_preferred_size (priv->header_image,
-                                 &header_requisition, NULL);
-
-  header_allocation.x = border_width + header_padding;
-  header_allocation.y = border_width + header_padding;
-  header_allocation.width  = allocation->width - 2 * border_width - 2 * header_padding;
-  header_allocation.height = header_requisition.height;
-
-  gtk_widget_size_allocate (priv->header_image, &header_allocation);
-
-  /* Action area */
-  gtk_widget_get_preferred_size (priv->action_area,
-                                 &action_requisition, NULL);
-
-  child_allocation.x = border_width;
-  child_allocation.y = allocation->height - border_width - action_requisition.height;
-  child_allocation.width  = allocation->width - 2 * border_width;
-  child_allocation.height = action_requisition.height;
-
-  gtk_widget_size_allocate (priv->action_area, &child_allocation);
-
-  gtk_widget_get_allocation (priv->header_image, &header_image_allocation);
-  gtk_widget_get_allocation (priv->action_area, &action_area_allocation);
-
-  /* Sidebar */
-  gtk_widget_get_preferred_size (priv->sidebar_image,
-                                 &sidebar_requisition, NULL);
-
-  if (rtl)
-    child_allocation.x = allocation->width - border_width - sidebar_requisition.width;
-  else
-    child_allocation.x = border_width;
-
-  child_allocation.y = border_width + header_image_allocation.height + 2 * header_padding;
-  child_allocation.width = sidebar_requisition.width;
-  child_allocation.height = allocation->height - 2 * border_width -
-    header_image_allocation.height - 2 * header_padding - action_area_allocation.height;
-
-  gtk_widget_size_allocate (priv->sidebar_image, &child_allocation);
-
-  /* Pages */
-  child_allocation.x = border_width + content_padding;
-  child_allocation.y = border_width +
-    header_image_allocation.height + 2 * header_padding + content_padding;
-  child_allocation.width  = allocation->width - 2 * border_width - 2 * content_padding;
-  child_allocation.height = allocation->height - 2 * border_width -
-    header_image_allocation.height - 2 * header_padding - ACTION_AREA_SPACING - action_area_allocation.height - 2 * content_padding;
-
-  if (gtk_widget_get_visible (priv->sidebar_image))
-    {
-      GtkAllocation sidebar_image_allocation;
-
-      gtk_widget_get_allocation (priv->sidebar_image, &sidebar_image_allocation);
-
-      if (!rtl)
-        child_allocation.x += sidebar_image_allocation.width;
-
-      child_allocation.width -= sidebar_image_allocation.width;
-    }
-
-  while (pages)
-    {
-      GtkAssistantPage *page = pages->data;
-
-      gtk_widget_size_allocate (page->page, &child_allocation);
-      gtk_widget_size_allocate (page->title, &header_allocation);
-      pages = pages->next;
-    }
-}
-
-static void
 gtk_assistant_map (GtkWidget *widget)
 {
   GtkAssistant *assistant = GTK_ASSISTANT (widget);
   GtkAssistantPrivate *priv = assistant->priv;
   GList *page_node;
   GtkAssistantPage *page;
-
-  gtk_widget_set_mapped (widget, TRUE);
-
-  gtk_widget_map (priv->header_image);
-  gtk_widget_map (priv->action_area);
-
-  if (gtk_widget_get_visible (priv->sidebar_image) &&
-      !gtk_widget_get_mapped (priv->sidebar_image))
-    gtk_widget_map (priv->sidebar_image);
+  gint page_num;
 
   /* if there's no default page, pick the first one */
   page = NULL;
+  page_num = 0;
   if (!priv->current_page)
     {
       page_node = priv->pages;
 
       while (page_node && !gtk_widget_get_visible (((GtkAssistantPage *) page_node->data)->page))
-        page_node = page_node->next;
+        {
+          page_node = page_node->next;
+          page_num++;
+        }
 
       if (page_node)
         page = page_node->data;
     }
 
-  if (page &&
-      gtk_widget_get_visible (page->page) &&
-      !gtk_widget_get_mapped (page->page))
-    set_current_page (assistant, page);
+  if (page && gtk_widget_get_visible (page->page))
+    set_current_page (assistant, page_num);
+
+  update_buttons_state (assistant);
+  update_actions_size (assistant);
+  update_title_state (assistant);
 
   GTK_WIDGET_CLASS (gtk_assistant_parent_class)->map (widget);
 }
@@ -1371,23 +1218,6 @@ gtk_assistant_unmap (GtkWidget *widget)
   GtkAssistant *assistant = GTK_ASSISTANT (widget);
   GtkAssistantPrivate *priv = assistant->priv;
 
-  gtk_widget_set_mapped (widget, FALSE);
-
-  gtk_widget_unmap (priv->header_image);
-  gtk_widget_unmap (priv->action_area);
-
-  if (gtk_widget_is_drawable (priv->sidebar_image))
-    gtk_widget_unmap (priv->sidebar_image);
-
-  if (priv->current_page &&
-      gtk_widget_is_drawable (priv->current_page->page))
-    {
-      gtk_widget_set_child_visible (priv->current_page->page, FALSE);
-      gtk_widget_set_child_visible (priv->current_page->title, FALSE);
-      gtk_widget_unmap (priv->current_page->title);
-      gtk_widget_unmap (priv->current_page->page);
-    }
-
   g_slist_free (priv->visited_pages);
   priv->visited_pages = NULL;
   priv->current_page  = NULL;
@@ -1412,147 +1242,6 @@ gtk_assistant_delete_event (GtkWidget   *widget,
 }
 
 static void
-assistant_paint_colored_box (GtkWidget *widget,
-                             cairo_t   *cr)
-{
-  GtkAssistant *assistant = GTK_ASSISTANT (widget);
-  GtkAssistantPrivate *priv = assistant->priv;
-  GtkAllocation allocation, action_area_allocation, header_image_allocation;
-  GtkStyleContext *context;
-  GtkStateFlags state;
-  GdkRGBA color;
-  gint border_width, header_padding, content_padding;
-  gint content_x, content_width;
-  gboolean rtl;
-
-  rtl  = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
-  border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
-
-  gtk_widget_style_get (widget,
-                        "header-padding",  &header_padding,
-                        "content-padding", &content_padding,
-                        NULL);
-
-  context = gtk_widget_get_style_context (widget);
-  state = gtk_widget_get_state_flags (widget);
-
-  gtk_widget_get_allocation (widget, &allocation);
-  gtk_widget_get_allocation (priv->action_area, &action_area_allocation);
-  gtk_widget_get_allocation (priv->header_image, &header_image_allocation);
-
-  /* colored box */
-  gtk_style_context_save (context);
-  gtk_style_context_add_class (context, GTK_STYLE_CLASS_HIGHLIGHT);
-
-  gtk_style_context_get_background_color (context, state, &color);
-  gdk_cairo_set_source_rgba (cr, &color);
-
-  cairo_rectangle (cr,
-                   border_width,
-                   border_width,
-                   allocation.width - 2 * border_width,
-                   allocation.height - action_area_allocation.height - 2 * border_width - ACTION_AREA_SPACING);
-  cairo_fill (cr);
-
-  /* content box */
-  content_x = content_padding + border_width;
-  content_width = allocation.width - 2 * content_padding - 2 * border_width;
-
-  if (gtk_widget_get_visible (priv->sidebar_image))
-    {
-      GtkAllocation sidebar_image_allocation;
-
-      gtk_widget_get_allocation (priv->sidebar_image, &sidebar_image_allocation);
-
-      if (!rtl)
-        content_x += sidebar_image_allocation.width;
-      content_width -= sidebar_image_allocation.width;
-    }
-
-  gtk_style_context_restore (context);
-
-  gtk_style_context_get_background_color (context, state, &color);
-  gdk_cairo_set_source_rgba (cr, &color);
-
-  cairo_rectangle (cr,
-                   content_x,
-                   header_image_allocation.height + content_padding + 2 * header_padding + border_width,
-                   content_width,
-                   allocation.height - 2 * border_width - action_area_allocation.height -
-                   header_image_allocation.height - 2 * content_padding - 2 * header_padding - ACTION_AREA_SPACING);
-  cairo_fill (cr);
-}
-
-static gboolean
-gtk_assistant_draw (GtkWidget *widget,
-                    cairo_t   *cr)
-{
-  GtkAssistant *assistant = GTK_ASSISTANT (widget);
-  GtkAssistantPrivate *priv = assistant->priv;
-  GtkContainer *container = GTK_CONTAINER (widget);
-
-  if (GTK_WIDGET_CLASS (gtk_assistant_parent_class)->draw)
-    GTK_WIDGET_CLASS (gtk_assistant_parent_class)->draw (widget, cr);
-
-  assistant_paint_colored_box (widget, cr);
-
-  gtk_container_propagate_draw (container, priv->header_image, cr);
-  gtk_container_propagate_draw (container, priv->sidebar_image, cr);
-  gtk_container_propagate_draw (container, priv->action_area, cr);
-
-  if (priv->current_page)
-    {
-      gtk_container_propagate_draw (container, priv->current_page->page, cr);
-      gtk_container_propagate_draw (container, priv->current_page->title, cr);
-    }
-
-  return FALSE;
-}
-
-static gboolean
-gtk_assistant_focus (GtkWidget        *widget,
-                     GtkDirectionType  direction)
-{
-  GtkAssistantPrivate *priv;
-  GtkContainer *container;
-
-  container = GTK_CONTAINER (widget);
-  priv = GTK_ASSISTANT (widget)->priv;
-
-  /* we only have to care about 2 widgets, action area and the current page */
-  if (gtk_container_get_focus_child (container) == priv->action_area)
-    {
-      if (!gtk_widget_child_focus (priv->action_area, direction) &&
-          (priv->current_page == NULL ||
-           !gtk_widget_child_focus (priv->current_page->page, direction)))
-        {
-          /* if we're leaving the action area and the current page has no
-           * focusable widget, clear focus and go back to the action area
-           */
-          gtk_container_set_focus_child (GTK_CONTAINER (priv->action_area), NULL);
-          gtk_widget_child_focus (priv->action_area, direction);
-        }
-    }
-  else
-    {
-      if ((priv->current_page ==  NULL ||
-           !gtk_widget_child_focus (priv->current_page->page, direction)) &&
-          !gtk_widget_child_focus (priv->action_area, direction))
-        {
-          /* if we're leaving the current page and there isn't nothing
-           * focusable in the action area, try to clear focus and go back
-           * to the page
-           */
-          gtk_window_set_focus (GTK_WINDOW (widget), NULL);
-          if (priv->current_page != NULL)
-            gtk_widget_child_focus (priv->current_page->page, direction);
-        }
-    }
-
-  return TRUE;
-}
-
-static void
 gtk_assistant_add (GtkContainer *container,
                    GtkWidget    *page)
 {
@@ -1575,38 +1264,6 @@ gtk_assistant_remove (GtkContainer *container,
     }
 }
 
-static void
-gtk_assistant_forall (GtkContainer *container,
-                      gboolean      include_internals,
-                      GtkCallback   callback,
-                      gpointer      callback_data)
-{
-  GtkAssistant *assistant = (GtkAssistant*) container;
-  GtkAssistantPrivate *priv = assistant->priv;
-  GList *pages;
-
-  if (include_internals)
-    {
-      (*callback) (priv->header_image, callback_data);
-      (*callback) (priv->sidebar_image, callback_data);
-      (*callback) (priv->action_area, callback_data);
-    }
-
-  pages = priv->pages;
-
-  while (pages)
-    {
-      GtkAssistantPage *page = (GtkAssistantPage *) pages->data;
-
-      (*callback) (page->page, callback_data);
-
-      if (include_internals)
-        (*callback) (page->title, callback_data);
-
-      pages = pages->next;
-    }
-}
-
 /**
  * gtk_assistant_new:
  *
@@ -1630,11 +1287,11 @@ gtk_assistant_new (void)
  * gtk_assistant_get_current_page:
  * @assistant: a #GtkAssistant
  *
- * Returns the page number of the current page
+ * Returns the page number of the current page.
  *
  * Return value: The index (starting from 0) of the current
- *     page in the @assistant, if the @assistant has no pages,
- *     -1 will be returned
+ *     page in the @assistant, or -1 if the @assistant has no pages,
+ *     or no current page.
  *
  * Since: 2.10
  */
@@ -1683,7 +1340,10 @@ gtk_assistant_set_current_page (GtkAssistant *assistant,
   if (page_num >= 0)
     page = (GtkAssistantPage *) g_list_nth_data (priv->pages, page_num);
   else
-    page = (GtkAssistantPage *) g_list_last (priv->pages)->data;
+    {
+      page = (GtkAssistantPage *) g_list_last (priv->pages)->data;
+      page_num = g_list_length (priv->pages);
+    }
 
   g_return_if_fail (page != NULL);
 
@@ -1698,7 +1358,7 @@ gtk_assistant_set_current_page (GtkAssistant *assistant,
     priv->visited_pages = g_slist_prepend (priv->visited_pages,
                                            priv->current_page);
 
-  set_current_page (assistant, page);
+  set_current_page (assistant, page_num);
 }
 
 /**
@@ -1765,7 +1425,7 @@ gtk_assistant_previous_page (GtkAssistant *assistant)
   while (page_info->type == GTK_ASSISTANT_PAGE_PROGRESS ||
          !gtk_widget_get_visible (page_info->page));
 
-  set_current_page (assistant, page_info);
+  set_current_page (assistant, g_list_index (priv->pages, page_info));
 }
 
 /**
@@ -1891,8 +1551,8 @@ gtk_assistant_insert_page (GtkAssistant *assistant,
 {
   GtkAssistantPrivate *priv;
   GtkAssistantPage *page_info;
-  GtkStyleContext *context;
   gint n_pages;
+  GtkStyleContext *context;
 
   g_return_val_if_fail (GTK_IS_ASSISTANT (assistant), 0);
   g_return_val_if_fail (GTK_IS_WIDGET (page), 0);
@@ -1903,17 +1563,24 @@ gtk_assistant_insert_page (GtkAssistant *assistant,
 
   page_info = g_slice_new0 (GtkAssistantPage);
   page_info->page  = page;
-  page_info->title = gtk_label_new (NULL);
+  page_info->regular_title = gtk_label_new (NULL);
+  page_info->current_title = gtk_label_new (NULL);
 
-  g_signal_connect (G_OBJECT (page), "notify::visible",
-                    G_CALLBACK (on_page_notify_visibility), assistant);
+  gtk_misc_set_alignment (GTK_MISC (page_info->regular_title), 0.,0.5);
+  gtk_widget_show (page_info->regular_title);
 
-  gtk_misc_set_alignment (GTK_MISC (page_info->title), 0.,0.5);
-  set_title_font   (GTK_WIDGET (assistant), page_info->title);
-  gtk_widget_show  (page_info->title);
+  gtk_misc_set_alignment (GTK_MISC (page_info->current_title), 0.,0.5);
+  gtk_widget_hide (page_info->current_title);
 
-  context = gtk_widget_get_style_context (page_info->title);
+  context = gtk_widget_get_style_context (page_info->current_title);
   gtk_style_context_add_class (context, GTK_STYLE_CLASS_HIGHLIGHT);
+  gtk_widget_reset_style (page_info->current_title);
+
+  gtk_size_group_add_widget (priv->title_size_group, page_info->regular_title);
+  gtk_size_group_add_widget (priv->title_size_group, page_info->current_title);
+
+  g_signal_connect (G_OBJECT (page), "notify::visible",
+                    G_CALLBACK (on_page_notify_visibility), assistant);
 
   n_pages = g_list_length (priv->pages);
 
@@ -1922,19 +1589,19 @@ gtk_assistant_insert_page (GtkAssistant *assistant,
 
   priv->pages = g_list_insert (priv->pages, page_info, position);
 
-  gtk_widget_set_child_visible (page_info->page, FALSE);
-  gtk_widget_set_child_visible (page_info->title, FALSE);
-  gtk_widget_set_parent (page_info->page,  GTK_WIDGET (assistant));
-  gtk_widget_set_parent (page_info->title, GTK_WIDGET (assistant));
+  gtk_box_pack_start (GTK_BOX (priv->sidebar), page_info->regular_title, FALSE, FALSE, 0);
+  gtk_box_pack_start (GTK_BOX (priv->sidebar), page_info->current_title, FALSE, FALSE, 0);
+  gtk_box_reorder_child (GTK_BOX (priv->sidebar), page_info->regular_title, 2 * position);
+  gtk_box_reorder_child (GTK_BOX (priv->sidebar), page_info->current_title, 2 * position + 1);
 
-  if (gtk_widget_get_realized (GTK_WIDGET (assistant)))
+  gtk_notebook_insert_page (GTK_NOTEBOOK (priv->content), page, NULL, position);
+
+  if (gtk_widget_get_mapped (GTK_WIDGET (assistant)))
     {
-      gtk_widget_realize (page_info->page);
-      gtk_widget_realize (page_info->title);
+      update_buttons_state (assistant);
+      update_actions_size (assistant);
     }
 
-  gtk_widget_queue_resize (GTK_WIDGET (assistant));
-
   return position;
 }
 
@@ -1988,7 +1655,8 @@ gtk_assistant_set_forward_page_func (GtkAssistant         *assistant,
   /* Page flow has possibly changed, so the
    * buttons state might need to change too
    */
-  set_assistant_buttons_state (assistant);
+  if (gtk_widget_get_mapped (GTK_WIDGET (assistant)))
+    update_buttons_state (assistant);
 }
 
 /**
@@ -2012,7 +1680,12 @@ gtk_assistant_add_action_widget (GtkAssistant *assistant,
   priv = assistant->priv;
 
   if (GTK_IS_BUTTON (child))
-    gtk_size_group_add_widget (priv->size_group, child);
+    {
+      gtk_size_group_add_widget (priv->button_size_group, child);
+      priv->extra_buttons += 1;
+      if (gtk_widget_get_mapped (GTK_WIDGET (assistant)))
+        update_actions_size (assistant);
+    }
 
   gtk_box_pack_end (GTK_BOX (priv->action_area), child, FALSE, FALSE, 0);
 }
@@ -2038,7 +1711,12 @@ gtk_assistant_remove_action_widget (GtkAssistant *assistant,
   priv = assistant->priv;
 
   if (GTK_IS_BUTTON (child))
-    gtk_size_group_remove_widget (priv->size_group, child);
+    {
+      gtk_size_group_remove_widget (priv->button_size_group, child);
+      priv->extra_buttons -= 1;
+      if (gtk_widget_get_mapped (GTK_WIDGET (assistant)))
+        update_actions_size (assistant);
+    }
 
   gtk_container_remove (GTK_CONTAINER (priv->action_area), child);
 }
@@ -2073,9 +1751,14 @@ gtk_assistant_set_page_title (GtkAssistant *assistant,
 
   page_info = (GtkAssistantPage*) child->data;
 
-  gtk_label_set_text ((GtkLabel*) page_info->title, title);
+  g_free (page_info->title);
+  page_info->title = g_strdup (title);
+
+  gtk_label_set_text ((GtkLabel*) page_info->regular_title, title);
+  gtk_label_set_text ((GtkLabel*) page_info->current_title, title);
+
   gtk_widget_queue_resize (GTK_WIDGET (assistant));
-  gtk_widget_child_notify (page, "title");
+  gtk_container_child_notify (GTK_CONTAINER (assistant), page, "title");
 }
 
 /**
@@ -2105,7 +1788,7 @@ gtk_assistant_get_page_title (GtkAssistant *assistant,
 
   page_info = (GtkAssistantPage*) child->data;
 
-  return gtk_label_get_text ((GtkLabel*) page_info->title);
+  return page_info->title;
 }
 
 /**
@@ -2151,9 +1834,9 @@ gtk_assistant_set_page_type (GtkAssistant         *assistant,
       /* Always set buttons state, a change in a future page
        * might change current page buttons
        */
-      set_assistant_buttons_state (assistant);
+      update_buttons_state (assistant);
 
-      gtk_widget_child_notify (page, "page-type");
+      gtk_container_child_notify (GTK_CONTAINER (assistant), page, "page-type");
     }
 }
 
@@ -2195,17 +1878,16 @@ gtk_assistant_get_page_type (GtkAssistant *assistant,
  *
  * Sets a header image for @page.
  *
- * This image is displayed in the header area of the assistant
- * when @page is the current page.
- *
  * Since: 2.10
+ *
+ * Deprecated: 3.2: Since GTK+ 3.2, a header is no longer shown;
+ *     add your header decoration to the page content instead.
  */
 void
 gtk_assistant_set_page_header_image (GtkAssistant *assistant,
                                      GtkWidget    *page,
                                      GdkPixbuf    *pixbuf)
 {
-  GtkAssistantPrivate *priv;
   GtkAssistantPage *page_info;
   GList *child;
 
@@ -2213,7 +1895,6 @@ gtk_assistant_set_page_header_image (GtkAssistant *assistant,
   g_return_if_fail (GTK_IS_WIDGET (page));
   g_return_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf));
 
-  priv = assistant->priv;
   child = find_page (assistant, page);
 
   g_return_if_fail (child != NULL);
@@ -2231,10 +1912,7 @@ gtk_assistant_set_page_header_image (GtkAssistant *assistant,
       if (pixbuf)
         page_info->header_image = g_object_ref (pixbuf);
 
-      if (page_info == priv->current_page)
-        set_assistant_header_image (assistant);
-
-      gtk_widget_child_notify (page, "header-image");
+      gtk_container_child_notify (GTK_CONTAINER (assistant), page, "header-image");
     }
 }
 
@@ -2249,6 +1927,9 @@ gtk_assistant_set_page_header_image (GtkAssistant *assistant,
  *     or %NULL if there's no header image for the page
  *
  * Since: 2.10
+ *
+ * Deprecated: 3.2: Since GTK+ 3.2, a header is no longer shown;
+ *     add your header decoration to the page content instead.
  */
 GdkPixbuf*
 gtk_assistant_get_page_header_image (GtkAssistant *assistant,
@@ -2273,21 +1954,23 @@ gtk_assistant_get_page_header_image (GtkAssistant *assistant,
  * gtk_assistant_set_page_side_image:
  * @assistant: a #GtkAssistant
  * @page: a page of @assistant
- * @pixbuf: (allow-none): the new header image @page
+ * @pixbuf: (allow-none): the new side image @page
  *
- * Sets a header image for @page.
+ * Sets a side image for @page.
  *
- * This image is displayed in the side area of the assistant
+ * This image used to be displayed in the side area of the assistant
  * when @page is the current page.
  *
  * Since: 2.10
+ *
+ * Deprecated: 3.2: Since GTK+ 3.2, sidebar images are not
+ *     shown anymore.
  */
 void
 gtk_assistant_set_page_side_image (GtkAssistant *assistant,
                                    GtkWidget    *page,
                                    GdkPixbuf    *pixbuf)
 {
-  GtkAssistantPrivate *priv;
   GtkAssistantPage *page_info;
   GList *child;
 
@@ -2295,7 +1978,6 @@ gtk_assistant_set_page_side_image (GtkAssistant *assistant,
   g_return_if_fail (GTK_IS_WIDGET (page));
   g_return_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf));
 
-  priv = assistant->priv;
   child = find_page (assistant, page);
 
   g_return_if_fail (child != NULL);
@@ -2313,10 +1995,7 @@ gtk_assistant_set_page_side_image (GtkAssistant *assistant,
       if (pixbuf)
         page_info->sidebar_image = g_object_ref (pixbuf);
 
-      if (page_info == priv->current_page)
-        set_assistant_sidebar_image (assistant);
-
-      gtk_widget_child_notify (page, "sidebar-image");
+      gtk_container_child_notify (GTK_CONTAINER (assistant), page, "sidebar-image");
     }
 }
 
@@ -2325,12 +2004,15 @@ gtk_assistant_set_page_side_image (GtkAssistant *assistant,
  * @assistant: a #GtkAssistant
  * @page: a page of @assistant
  *
- * Gets the header image for @page.
+ * Gets the side image for @page.
  *
  * Return value: (transfer none): the side image for @page,
  *     or %NULL if there's no side image for the page
  *
  * Since: 2.10
+ *
+ * Deprecated: 3.2: Since GTK+ 3.2, sidebar images are not
+ *     shown anymore.
  */
 GdkPixbuf*
 gtk_assistant_get_page_side_image (GtkAssistant *assistant,
@@ -2389,9 +2071,9 @@ gtk_assistant_set_page_complete (GtkAssistant *assistant,
       /* Always set buttons state, a change in a future page
        * might change current page buttons
        */
-      set_assistant_buttons_state (assistant);
+      update_buttons_state (assistant);
 
-      gtk_widget_child_notify (page, "complete");
+      gtk_container_child_notify (GTK_CONTAINER (assistant), page, "complete");
     }
 }
 
@@ -2446,7 +2128,7 @@ gtk_assistant_update_buttons_state (GtkAssistant *assistant)
 {
   g_return_if_fail (GTK_IS_ASSISTANT (assistant));
 
-  set_assistant_buttons_state (assistant);
+  update_buttons_state (assistant);
 }
 
 /**
@@ -2475,7 +2157,7 @@ gtk_assistant_commit (GtkAssistant *assistant)
 
   assistant->priv->committed = TRUE;
 
-  set_assistant_buttons_state (assistant);
+  update_buttons_state (assistant);
 }
 
 static AtkObject *
diff --git a/gtk/gtkassistant.h b/gtk/gtkassistant.h
index 62f9ead..e380f83 100644
--- a/gtk/gtkassistant.h
+++ b/gtk/gtkassistant.h
@@ -128,50 +128,54 @@ void                  gtk_assistant_next_page             (GtkAssistant
 void                  gtk_assistant_previous_page         (GtkAssistant         *assistant);
 gint                  gtk_assistant_get_current_page      (GtkAssistant         *assistant);
 void                  gtk_assistant_set_current_page      (GtkAssistant         *assistant,
-							   gint                  page_num);
+                                                           gint                  page_num);
 gint                  gtk_assistant_get_n_pages           (GtkAssistant         *assistant);
 GtkWidget            *gtk_assistant_get_nth_page          (GtkAssistant         *assistant,
-							   gint                  page_num);
+                                                           gint                  page_num);
 gint                  gtk_assistant_prepend_page          (GtkAssistant         *assistant,
-							   GtkWidget            *page);
+                                                           GtkWidget            *page);
 gint                  gtk_assistant_append_page           (GtkAssistant         *assistant,
-							   GtkWidget            *page);
+                                                           GtkWidget            *page);
 gint                  gtk_assistant_insert_page           (GtkAssistant         *assistant,
-							   GtkWidget            *page,
-							   gint                  position);
+                                                           GtkWidget            *page,
+                                                           gint                  position);
 void                  gtk_assistant_set_forward_page_func (GtkAssistant         *assistant,
-							   GtkAssistantPageFunc  page_func,
-							   gpointer              data,
-							   GDestroyNotify        destroy);
+                                                           GtkAssistantPageFunc  page_func,
+                                                           gpointer              data,
+                                                           GDestroyNotify        destroy);
 void                  gtk_assistant_set_page_type         (GtkAssistant         *assistant,
-							   GtkWidget            *page,
-							   GtkAssistantPageType  type);
+                                                           GtkWidget            *page,
+                                                           GtkAssistantPageType  type);
 GtkAssistantPageType  gtk_assistant_get_page_type         (GtkAssistant         *assistant,
-							   GtkWidget            *page);
+                                                           GtkWidget            *page);
 void                  gtk_assistant_set_page_title        (GtkAssistant         *assistant,
-							   GtkWidget            *page,
-							   const gchar          *title);
+                                                           GtkWidget            *page,
+                                                           const gchar          *title);
 G_CONST_RETURN gchar *gtk_assistant_get_page_title        (GtkAssistant         *assistant,
-							   GtkWidget            *page);
+                                                           GtkWidget            *page);
+
+#if !defined (GTK_DISABLE_DEPRECATED) || defined (GTK_COMPILATION)
 void                  gtk_assistant_set_page_header_image (GtkAssistant         *assistant,
-							   GtkWidget            *page,
-							   GdkPixbuf            *pixbuf);
+                                                           GtkWidget            *page,
+                                                           GdkPixbuf            *pixbuf);
 GdkPixbuf            *gtk_assistant_get_page_header_image (GtkAssistant         *assistant,
-							   GtkWidget            *page);
+                                                           GtkWidget            *page);
 void                  gtk_assistant_set_page_side_image   (GtkAssistant         *assistant,
-							   GtkWidget            *page,
-							   GdkPixbuf            *pixbuf);
+                                                           GtkWidget            *page,
+                                                           GdkPixbuf            *pixbuf);
 GdkPixbuf            *gtk_assistant_get_page_side_image   (GtkAssistant         *assistant,
-							   GtkWidget            *page);
+                                                           GtkWidget            *page);
+#endif
+
 void                  gtk_assistant_set_page_complete     (GtkAssistant         *assistant,
-							   GtkWidget            *page,
-							   gboolean              complete);
+                                                           GtkWidget            *page,
+                                                           gboolean              complete);
 gboolean              gtk_assistant_get_page_complete     (GtkAssistant         *assistant,
-							   GtkWidget            *page);
+                                                           GtkWidget            *page);
 void                  gtk_assistant_add_action_widget     (GtkAssistant         *assistant,
-							   GtkWidget            *child);
+                                                           GtkWidget            *child);
 void                  gtk_assistant_remove_action_widget  (GtkAssistant         *assistant,
-							   GtkWidget            *child);
+                                                           GtkWidget            *child);
 
 void                  gtk_assistant_update_buttons_state  (GtkAssistant *assistant);
 void                  gtk_assistant_commit                (GtkAssistant *assistant);



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