summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--ChangeLog.pre-2-1010
-rw-r--r--demos/gtk-demo/Makefile.am1
-rw-r--r--demos/gtk-demo/assistant.c165
-rw-r--r--docs/reference/ChangeLog6
-rw-r--r--docs/reference/gtk/gtk-docs.sgml2
-rw-r--r--docs/reference/gtk/migrating-GtkAssistant.sgml170
-rw-r--r--docs/reference/gtk/tmpl/gtkassistant.sgml315
-rw-r--r--gtk/gtkassistant.c91
9 files changed, 749 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index f30f8154e0..55cab24d3b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2006-01-28 Matthias Clasen <mclasen@redhat.com>
+
+ More work on GtkAssistant by Carlos Garnacho:
+
+ * demos/gtk-demo/Makefile.am:
+ * demos/gtk-demo/assistant.c: Add a GtkAssistant demo.
+
+ * gtk/gtkassistant.c: Handle focus, several small fixes to the
+ flow computations.
+
2006-01-27 Federico Mena Quintero <federico@ximian.com>
Fixes bug #328820:
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index f30f8154e0..55cab24d3b 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,3 +1,13 @@
+2006-01-28 Matthias Clasen <mclasen@redhat.com>
+
+ More work on GtkAssistant by Carlos Garnacho:
+
+ * demos/gtk-demo/Makefile.am:
+ * demos/gtk-demo/assistant.c: Add a GtkAssistant demo.
+
+ * gtk/gtkassistant.c: Handle focus, several small fixes to the
+ flow computations.
+
2006-01-27 Federico Mena Quintero <federico@ximian.com>
Fixes bug #328820:
diff --git a/demos/gtk-demo/Makefile.am b/demos/gtk-demo/Makefile.am
index 04038edb74..c3bd17f55f 100644
--- a/demos/gtk-demo/Makefile.am
+++ b/demos/gtk-demo/Makefile.am
@@ -6,6 +6,7 @@ democodedir=$(datadir)/gtk-2.0/demo
## demo app, which means alphabetized by demo title, not filename
demos = \
appwindow.c \
+ assistant.c \
button_box.c \
changedisplay.c \
clipboard.c \
diff --git a/demos/gtk-demo/assistant.c b/demos/gtk-demo/assistant.c
new file mode 100644
index 0000000000..f5c69dd021
--- /dev/null
+++ b/demos/gtk-demo/assistant.c
@@ -0,0 +1,165 @@
+/* Assistant
+ *
+ * Demonstrates a sample multistep assistant. Assistants are used to divide
+ * an operation into several simpler sequential steps, and to guide the user
+ * through these steps.
+ */
+
+#include <gtk/gtk.h>
+#include "demo-common.h"
+
+static GtkWidget *assistant = NULL;
+
+static void
+on_assistant_apply (GtkWidget *widget, gpointer data)
+{
+ /* Apply here changes, this is a fictional
+ example, so we just do nothing here */
+}
+
+static void
+on_assistant_close_cancel (GtkWidget *widget, gpointer data)
+{
+ GtkWidget **assistant = (GtkWidget **) data;
+
+ gtk_widget_destroy (*assistant);
+ *assistant = NULL;
+}
+
+static void
+on_assistant_prepare (GtkWidget *widget, GtkWidget *page, gpointer data)
+{
+ gint current_page, n_pages;
+ gchar *title;
+
+ current_page = gtk_assistant_get_current_page (GTK_ASSISTANT (widget));
+ n_pages = gtk_assistant_get_n_pages (GTK_ASSISTANT (widget));
+
+ title = g_strdup_printf ("Sample assistant (%d of %d)", current_page + 1, n_pages);
+ gtk_window_set_title (GTK_WINDOW (widget), title);
+ g_free (title);
+}
+
+static void
+on_entry_changed (GtkWidget *widget, gpointer data)
+{
+ GtkAssistant *assistant = GTK_ASSISTANT (data);
+ GtkWidget *current_page;
+ gint page_number;
+ const gchar *text;
+
+ page_number = gtk_assistant_get_current_page (assistant);
+ current_page = gtk_assistant_get_nth_page (assistant, page_number);
+ text = gtk_entry_get_text (GTK_ENTRY (widget));
+
+ if (text && *text)
+ gtk_assistant_set_page_complete (assistant, current_page, TRUE);
+ else
+ gtk_assistant_set_page_complete (assistant, current_page, FALSE);
+}
+
+static void
+create_page1 (GtkWidget *assistant)
+{
+ GtkWidget *box, *label, *entry;
+ GdkPixbuf *pixbuf;
+
+ box = gtk_hbox_new (FALSE, 12);
+ gtk_container_set_border_width (GTK_CONTAINER (box), 12);
+
+ label = gtk_label_new ("You must fill out this entry to continue:");
+ gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
+
+ entry = gtk_entry_new ();
+ gtk_box_pack_start (GTK_BOX (box), entry, TRUE, TRUE, 0);
+ g_signal_connect (G_OBJECT (entry), "changed",
+ G_CALLBACK (on_entry_changed), assistant);
+
+ gtk_widget_show_all (box);
+ gtk_assistant_append_page (GTK_ASSISTANT (assistant), box);
+ gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), box, "Page 1");
+ gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), box, GTK_ASSISTANT_PAGE_INTRO);
+
+ pixbuf = gtk_widget_render_icon (assistant, GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG, NULL);
+ gtk_assistant_set_page_header_image (GTK_ASSISTANT (assistant), box, pixbuf);
+ g_object_unref (pixbuf);
+}
+
+static void
+create_page2 (GtkWidget *assistant)
+{
+ GtkWidget *box, *checkbutton;
+ GdkPixbuf *pixbuf;
+
+ box = gtk_vbox_new (12, FALSE);
+ gtk_container_set_border_width (GTK_CONTAINER (box), 12);
+
+ checkbutton = gtk_check_button_new_with_label ("This is optional data, you may continue "
+ "even if you do not check this");
+ gtk_box_pack_start (GTK_BOX (box), checkbutton, FALSE, FALSE, 0);
+
+ gtk_widget_show_all (box);
+ gtk_assistant_append_page (GTK_ASSISTANT (assistant), box);
+ gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), box, TRUE);
+ gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), box, "Page 2");
+
+ pixbuf = gtk_widget_render_icon (assistant, GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG, NULL);
+ gtk_assistant_set_page_header_image (GTK_ASSISTANT (assistant), box, pixbuf);
+ g_object_unref (pixbuf);
+}
+
+static void
+create_page3 (GtkWidget *assistant)
+{
+ GtkWidget *label;
+ GdkPixbuf *pixbuf;
+
+ label = gtk_label_new ("This is a confirmation page, press 'Apply' to apply changes");
+
+ gtk_widget_show (label);
+ gtk_assistant_append_page (GTK_ASSISTANT (assistant), label);
+ gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), label, GTK_ASSISTANT_PAGE_CONFIRM);
+ gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), label, TRUE);
+ gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), label, "Confirmation");
+
+ pixbuf = gtk_widget_render_icon (assistant, GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG, NULL);
+ gtk_assistant_set_page_header_image (GTK_ASSISTANT (assistant), label, pixbuf);
+ g_object_unref (pixbuf);
+}
+
+GtkWidget*
+do_assistant (GtkWidget *do_widget)
+{
+ if (!assistant)
+ {
+ assistant = gtk_assistant_new ();
+
+ gtk_window_set_default_size (GTK_WINDOW (assistant), -1, 300);
+
+ gtk_window_set_screen (GTK_WINDOW (assistant),
+ gtk_widget_get_screen (do_widget));
+
+ create_page1 (assistant);
+ create_page2 (assistant);
+ create_page3 (assistant);
+
+ g_signal_connect (G_OBJECT (assistant), "cancel",
+ G_CALLBACK (on_assistant_close_cancel), &assistant);
+ g_signal_connect (G_OBJECT (assistant), "close",
+ G_CALLBACK (on_assistant_close_cancel), &assistant);
+ g_signal_connect (G_OBJECT (assistant), "apply",
+ G_CALLBACK (on_assistant_apply), NULL);
+ g_signal_connect (G_OBJECT (assistant), "prepare",
+ G_CALLBACK (on_assistant_prepare), NULL);
+ }
+
+ if (!GTK_WIDGET_VISIBLE (assistant))
+ gtk_widget_show (assistant);
+ else
+ {
+ gtk_widget_destroy (assistant);
+ assistant = NULL;
+ }
+
+ return assistant;
+}
diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog
index c987c4e041..3654f95c51 100644
--- a/docs/reference/ChangeLog
+++ b/docs/reference/ChangeLog
@@ -1,3 +1,9 @@
+2006-01-28 Matthias Clasen <mclasen@redhat.com>
+
+ * gtk/gtk-docs.sgml:
+ * gtk/migrating-GtkAssistant.sgml: Add a migration guide
+ GnomeDruid --> GtkAssistant. (Carlos Garnacho)
+
2006-01-27 Federico Mena Quintero <federico@ximian.com>
* gtk/tmpl/gtkfilechooser.sgml: Mention that ~ is also a default
diff --git a/docs/reference/gtk/gtk-docs.sgml b/docs/reference/gtk/gtk-docs.sgml
index b0f0116360..145d586f04 100644
--- a/docs/reference/gtk/gtk-docs.sgml
+++ b/docs/reference/gtk/gtk-docs.sgml
@@ -199,6 +199,7 @@
<!ENTITY gtk-migrating-GtkIconView SYSTEM "xml/migrating-GtkIconView.sgml">
<!ENTITY gtk-migrating-GtkAboutDialog SYSTEM "xml/migrating-GtkAboutDialog.sgml">
<!ENTITY gtk-migrating-GtkColorButton SYSTEM "xml/migrating-GtkColorButton.sgml">
+<!ENTITY gtk-migrating-GtkAssistant SYSTEM "xml/migrating-GtkAssistant.sgml">
<!ENTITY version SYSTEM "version.xml">
<!ENTITY gtk-query-immodules SYSTEM "gtk-query-immodules-2.0.xml">
<!ENTITY gtk-update-icon-cache SYSTEM "gtk-update-icon-cache.xml">
@@ -589,6 +590,7 @@ that is, GUI components such as <link linkend="GtkButton">GtkButton</link> or
&gtk-migrating-GtkIconView;
&gtk-migrating-GtkAboutDialog;
&gtk-migrating-GtkColorButton;
+ &gtk-migrating-GtkAssistant;
</part>
<part>
diff --git a/docs/reference/gtk/migrating-GtkAssistant.sgml b/docs/reference/gtk/migrating-GtkAssistant.sgml
new file mode 100644
index 0000000000..d5ee6e8bd2
--- /dev/null
+++ b/docs/reference/gtk/migrating-GtkAssistant.sgml
@@ -0,0 +1,170 @@
+<chapter id="gtk-migrating-GtkAssistant">
+ <chapterinfo>
+ <author>
+ <firstname>Carlos</firstname>
+ <surname>Garnacho</surname>
+ <affiliation>
+ <address>
+ <email>carlosg@gnome.org</email>
+ </address>
+ </affiliation>
+ </author>
+ </chapterinfo>
+
+ <title>Migrating from GnomeDruid to GtkAssistant</title>
+
+ <para>
+ Since version 2.10, GTK+ provides the GtkAssistant widget as a replacement
+ for the <structname>GnomeDruid</structname> widget in the libgnomeui library.
+ </para>
+
+ <para>
+ Conceptually, both <structname>GtkAssistant</structname> and <structname>GnomeDruid</structname>
+ 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.
+ </para>
+
+ <section id="inserting-pages">
+ <title>Inserting pages</title>
+
+ <para>
+ <structname>GnomeDruid</structname> was implemented as a container for
+ <structname>GnomeDruidPage</structname> abstract objects, which are implemented by the
+ <structname>GnomeDruidPageEdge</structname> and <structname>GnomeDruidPageStandard</structname>
+ widgets. Instead, <structname>GtkAssistant</structname> allows any widget to be a page, and implements
+ per-page settings (such as page type or title) as child properties. So instead of:
+ </para>
+
+ <programlisting>
+/* 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));
+ </programlisting>
+
+ <para>
+ You have to write:
+ </para>
+
+ <programlisting>
+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");
+ </programlisting>
+ </section>
+
+ <section id="decorating-the-assistant-pages">
+ <title>Decorating the assistant pages</title>
+
+ <para>
+ To decorate your assistant pages, <structname>GtkAssistant</structname> provides similar functions
+ to <structname>GnomeDruid</structname>, so you have to transform code like this:
+ </para>
+
+ <programlisting>
+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);
+ </programlisting>
+
+ <para>
+ Into this:
+ </para>
+
+ <programlisting>
+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);
+ </programlisting>
+
+ <para>
+ Where page_widget is the widget used as a page.
+ </para>
+ </section>
+
+ <section id="setting-the-page-flow">
+ <title>Setting the page flow</title>
+
+ <para>
+ Here is the area where <structname>GtkAssistant</structname> and <structname>GnomeDruid</structname>
+ differ the most. While <structname>GnomeDruid</structname> used the "next" and "back" signals from the
+ <structname>GnomeDruidPage</structname>, <structname>GtkAssistant</structname> uses the following
+ techniques:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>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.</para>
+ </listitem>
+ <listitem>
+ <para>gtk_assistant_set_page_complete (): Lets the assistant know whether the specified page is complete
+ or not, updating buttons state accordingly.</para>
+ </listitem>
+ <listitem>
+ <para>gtk_assistant_set_page_type (): Lets the assistant know the page role and update the buttons
+ state accordingly. Pages can have the following roles:</para>
+ <simplelist>
+ <member>Intro</member>
+ <member>Content</member>
+ <member>Progress</member>
+ <member>Confirmation</member>
+ <member>Summary</member>
+ </simplelist>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ A sample GtkAssistantPageFunc could look like this:
+ </para>
+
+ <programlisting>
+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;
+ }
+}
+ </programlisting>
+
+ </section>
+</chapter>
+
+<!--
+Local variables:
+mode: sgml
+sgml-parent-document: ("gtk-docs.sgml" "book" "part" "chapter")
+End:
+-->
diff --git a/docs/reference/gtk/tmpl/gtkassistant.sgml b/docs/reference/gtk/tmpl/gtkassistant.sgml
new file mode 100644
index 0000000000..6a1a77e75f
--- /dev/null
+++ b/docs/reference/gtk/tmpl/gtkassistant.sgml
@@ -0,0 +1,315 @@
+<!-- ##### SECTION Title ##### -->
+GtkAssistant
+
+<!-- ##### SECTION Short_Description ##### -->
+guiding users through multi-step operations
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT GtkAssistant ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SIGNAL GtkAssistant::apply ##### -->
+<para>
+
+</para>
+
+@assistant: the object which received the signal.
+
+<!-- ##### SIGNAL GtkAssistant::cancel ##### -->
+<para>
+
+</para>
+
+@assistant: the object which received the signal.
+
+<!-- ##### SIGNAL GtkAssistant::close ##### -->
+<para>
+
+</para>
+
+@assistant: the object which received the signal.
+
+<!-- ##### SIGNAL GtkAssistant::prepare ##### -->
+<para>
+
+</para>
+
+@assistant: the object which received the signal.
+@widget:
+
+<!-- ##### ARG GtkAssistant:complete ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG GtkAssistant:header-image ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG GtkAssistant:page-type ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG GtkAssistant:sidebar-image ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG GtkAssistant:title ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG GtkAssistant:content-padding ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG GtkAssistant:header-padding ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION gtk_assistant_new ##### -->
+<para>
+
+</para>
+
+@Returns:
+
+
+<!-- ##### FUNCTION gtk_assistant_get_current_page ##### -->
+<para>
+
+</para>
+
+@assistant:
+@Returns:
+
+
+<!-- ##### FUNCTION gtk_assistant_set_current_page ##### -->
+<para>
+
+</para>
+
+@assistant:
+@page_num:
+
+
+<!-- ##### FUNCTION gtk_assistant_get_n_pages ##### -->
+<para>
+
+</para>
+
+@assistant:
+@Returns:
+
+
+<!-- ##### FUNCTION gtk_assistant_get_nth_page ##### -->
+<para>
+
+</para>
+
+@assistant:
+@page_num:
+@Returns:
+
+
+<!-- ##### FUNCTION gtk_assistant_prepend_page ##### -->
+<para>
+
+</para>
+
+@assistant:
+@page:
+@Returns:
+
+
+<!-- ##### FUNCTION gtk_assistant_append_page ##### -->
+<para>
+
+</para>
+
+@assistant:
+@page:
+@Returns:
+
+
+<!-- ##### FUNCTION gtk_assistant_insert_page ##### -->
+<para>
+
+</para>
+
+@assistant:
+@page:
+@position:
+@Returns:
+
+
+<!-- ##### USER_FUNCTION GtkAssistantPageFunc ##### -->
+<para>
+
+</para>
+
+@current_page:
+@data:
+@Returns:
+
+
+<!-- ##### FUNCTION gtk_assistant_set_forward_page_func ##### -->
+<para>
+
+</para>
+
+@assistant:
+@page_func:
+@data:
+@destroy:
+
+
+<!-- ##### ENUM GtkAssistantPageType ##### -->
+<para>
+
+</para>
+
+@GTK_ASSISTANT_PAGE_CONTENT:
+@GTK_ASSISTANT_PAGE_INTRO:
+@GTK_ASSISTANT_PAGE_CONFIRM:
+@GTK_ASSISTANT_PAGE_SUMMARY:
+@GTK_ASSISTANT_PAGE_PROGRESS:
+
+<!-- ##### FUNCTION gtk_assistant_set_page_type ##### -->
+<para>
+
+</para>
+
+@assistant:
+@page:
+@type:
+
+
+<!-- ##### FUNCTION gtk_assistant_get_page_type ##### -->
+<para>
+
+</para>
+
+@assistant:
+@page:
+@Returns:
+
+
+<!-- ##### FUNCTION gtk_assistant_set_page_title ##### -->
+<para>
+
+</para>
+
+@assistant:
+@page:
+@title:
+
+
+<!-- ##### FUNCTION gtk_assistant_get_page_title ##### -->
+<para>
+
+</para>
+
+@assistant:
+@page:
+@Returns:
+
+
+<!-- ##### FUNCTION gtk_assistant_set_page_header_image ##### -->
+<para>
+
+</para>
+
+@assistant:
+@page:
+@pixbuf:
+
+
+<!-- ##### FUNCTION gtk_assistant_get_page_header_image ##### -->
+<para>
+
+</para>
+
+@assistant:
+@page:
+@Returns:
+
+
+<!-- ##### FUNCTION gtk_assistant_set_page_side_image ##### -->
+<para>
+
+</para>
+
+@assistant:
+@page:
+@pixbuf:
+
+
+<!-- ##### FUNCTION gtk_assistant_get_page_side_image ##### -->
+<para>
+
+</para>
+
+@assistant:
+@page:
+@Returns:
+
+
+<!-- ##### FUNCTION gtk_assistant_set_page_complete ##### -->
+<para>
+
+</para>
+
+@assistant:
+@page:
+@complete:
+
+
+<!-- ##### FUNCTION gtk_assistant_get_page_complete ##### -->
+<para>
+
+</para>
+
+@assistant:
+@page:
+@Returns:
+
+
+<!-- ##### FUNCTION gtk_assistant_add_action_widget ##### -->
+<para>
+
+</para>
+
+@assistant:
+@child:
+
+
+<!-- ##### FUNCTION gtk_assistant_remove_action_widget ##### -->
+<para>
+
+</para>
+
+@assistant:
+@child:
+
+
diff --git a/gtk/gtkassistant.c b/gtk/gtkassistant.c
index 18a1c69a7a..1100456166 100644
--- a/gtk/gtkassistant.c
+++ b/gtk/gtkassistant.c
@@ -92,6 +92,8 @@ static gboolean gtk_assistant_delete_event (GtkWidget *widget,
GdkEventAny *event);
static gboolean gtk_assistant_expose (GtkWidget *widget,
GdkEventExpose *event);
+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,
@@ -158,6 +160,7 @@ gtk_assistant_class_init (GtkAssistantClass *class)
widget_class->unmap = gtk_assistant_unmap;
widget_class->delete_event = gtk_assistant_delete_event;
widget_class->expose_event = gtk_assistant_expose;
+ widget_class->focus = gtk_assistant_focus;
container_class->add = gtk_assistant_add;
container_class->remove = gtk_assistant_remove;
@@ -212,10 +215,9 @@ gtk_assistant_class_init (GtkAssistantClass *class)
*
* 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 to put a page displaying the progress of the operation after the
- * confirmation page with the apply button.
- *
- * Return value: %TRUE to suppress the default behavior
+ * might consider to put a page of type GTK_ASSISTANT_PAGE_PROGRESS after the
+ * confirmation page and handle this operation within the "prepare" signal of
+ * the progress page.
*
* Since: 2.10
*/
@@ -232,7 +234,9 @@ gtk_assistant_class_init (GtkAssistantClass *class)
* GtkAssistant::close:
* @assistant: the #GtkAssistant
*
- * The ::close signal is emitted when the close button is clicked.
+ * The ::close signal is emitted either when the close button of
+ * a summary page is clicked, or when the apply button in the last
+ * page in the flow (of type GTK_ASSISTANT_PAGE_CONFIRM) is clicked.
*
* Since: 2.10
*/
@@ -366,11 +370,13 @@ default_forward_function (gint current_page, gpointer data)
page_info = (GtkAssistantPage *) page_node->data;
- while (!GTK_WIDGET_VISIBLE (page_info->page))
+ while (page_node && !GTK_WIDGET_VISIBLE (page_info->page))
{
page_node = page_node->next;
- page_info = (GtkAssistantPage *) page_node->data;
current_page++;
+
+ if (page_node)
+ page_info = (GtkAssistantPage *) page_node->data;
}
return current_page;
@@ -380,17 +386,18 @@ static void
compute_last_button_state (GtkAssistant *assistant)
{
GtkAssistantPrivate *priv = assistant->priv;
- GtkAssistantPage *page_info;
+ GtkAssistantPage *page_info, *current_page_info;
gint count, page_num, n_pages;
count = 0;
page_num = gtk_assistant_get_current_page (assistant);
n_pages = gtk_assistant_get_n_pages (assistant);
- page_info = g_list_nth_data (priv->pages, page_num);
+ current_page_info = page_info = g_list_nth_data (priv->pages, page_num);
while (page_num >= 0 && page_num < n_pages &&
- (page_info->type == GTK_ASSISTANT_PAGE_CONTENT) &&
- page_info->complete && count < n_pages)
+ page_info->type == GTK_ASSISTANT_PAGE_CONTENT &&
+ (count == 0 || page_info->complete) &&
+ count < n_pages)
{
page_num = (priv->forward_function) (page_num, priv->forward_function_data);
page_info = g_list_nth_data (priv->pages, page_num);
@@ -406,7 +413,11 @@ compute_last_button_state (GtkAssistant *assistant)
if (count > 1 &&
(page_info->type == GTK_ASSISTANT_PAGE_CONFIRM ||
page_info->type == GTK_ASSISTANT_PAGE_SUMMARY))
- gtk_widget_show (assistant->last);
+ {
+ gtk_widget_show (assistant->last);
+ gtk_widget_set_sensitive (assistant->last,
+ current_page_info->complete);
+ }
else
gtk_widget_hide (assistant->last);
}
@@ -1134,7 +1145,7 @@ gtk_assistant_map (GtkWidget *widget)
{
page_node = priv->pages;
- while (!GTK_WIDGET_VISIBLE (((GtkAssistantPage *) page_node->data)->page))
+ while (page_node && !GTK_WIDGET_VISIBLE (((GtkAssistantPage *) page_node->data)->page))
page_node = page_node->next;
if (page_node)
@@ -1276,6 +1287,43 @@ gtk_assistant_expose (GtkWidget *widget,
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 (container->focus_child == priv->action_area)
+ {
+ if (!gtk_widget_child_focus (priv->action_area, direction) &&
+ !gtk_widget_child_focus (priv->current_page->page, direction))
+ {
+ /* if we're leaving the action area and the current page hasn't
+ any 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 (!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);
+ gtk_widget_child_focus (priv->current_page->page, direction);
+ }
+ }
+
+ return TRUE;
+}
+
static void
gtk_assistant_add (GtkContainer *container,
GtkWidget *page)
@@ -1625,11 +1673,16 @@ gtk_assistant_set_forward_page_func (GtkAssistant *assistant,
priv->forward_function_data = assistant;
priv->forward_data_destroy = NULL;
}
+
+ /* Page flow has possibly changed, so the
+ buttons state might need to change too */
+ if (priv->current_page)
+ _set_assistant_buttons_state (assistant);
}
/**
* gtk_assistant_add_action_widget:
- * @dialog: a #GtkAssistant
+ * @assistant: a #GtkAssistant
* @child: a #GtkWidget
*
* Adds a widget to the action area of a #GtkAssistant.
@@ -1655,7 +1708,7 @@ gtk_assistant_add_action_widget (GtkAssistant *assistant,
/**
* gtk_assistant_remove_action_widget:
- * @dialog: a #GtkAssistant
+ * @assistant: a #GtkAssistant
* @child: a #GtkWidget
*
* Removes a widget from the action area of a #GtkAssistant.
@@ -1989,7 +2042,7 @@ gtk_assistant_get_page_side_image (GtkAssistant *assistant,
* gtk_assistant_set_page_complete:
* @assistant: a #GtkAssistant
* @page: a page of @assitant
- * @pixbuf: the new header image @page
+ * @complete: the completeness status of the page
*
* Sets whether @page contents are complete. This will make
* @assistant update the buttons state to be able to continue the task.
@@ -2022,11 +2075,7 @@ gtk_assistant_set_page_complete (GtkAssistant *assistant,
/* Always set buttons state, a change in a future page
might change current page buttons */
if (priv->current_page)
- {
- /* Always set buttons state, a change in a future page
- might change current page buttons */
- _set_assistant_buttons_state (assistant);
- }
+ _set_assistant_buttons_state (assistant);
gtk_widget_child_notify (page, "complete");
}