* Boston, MA 02111-1307, USA.
*/
-#include <config.h>
+/**
+ * SECTION:gtkassistant
+ * @Short_description: A widget used to guide users through multi-step operations
+ * @Title: GtkAssistant
+ *
+ * A #GtkAssistant is a widget used to represent a generally complex
+ * operation splitted in several steps, guiding the user through its pages
+ * and controlling the page flow to collect the necessary data.
+ *
+ * The design of GtkAssistant is that it controls what buttons to show and
+ * to make sensitive, based on what it knows about the page sequence and
+ * the <link linkend="GtkAssistantPageType">type</link> of each page, in
+ * addition to state information like the page
+ * <link linkend="gtk-assistant-set-page-complete">completion</link> and
+ * <link linkend="gtk-assistant-commit">committed</link> status.
+ *
+ * <refsect2 id="GtkAssistant-BUILDER-UI">
+ * <title>GtkAssistant as GtkBuildable</title>
+ * <para>
+ * The GtkAssistant implementation of the GtkBuildable interface exposes the
+ * @action_area as internal children with the name "action_area".
+ *
+ * To add pages to an assistant in GtkBuilder, simply add it as a
+ * <child> to the GtkAssistant object, and set its child properties
+ * as necessary.
+ * </para>
+ * </refsect2>
+ */
+
+#include "config.h"
#include <atk/atk.h>
#include "gtkimage.h"
#include "gtklabel.h"
#include "gtksizegroup.h"
+#include "gtksizerequest.h"
#include "gtkstock.h"
#include "gtkintl.h"
#include "gtkprivate.h"
+#include "gtkbuildable.h"
-#include "gtkalias.h"
-
-#define GTK_ASSISTANT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_ASSISTANT, GtkAssistantPrivate))
#define HEADER_SPACING 12
#define ACTION_AREA_SPACING 12
{
GtkWidget *page;
GtkAssistantPageType type;
- gboolean complete;
+ guint complete : 1;
+ guint complete_set : 1;
GtkWidget *title;
GdkPixbuf *header_image;
struct _GtkAssistantPrivate
{
+ GtkWidget *cancel;
+ GtkWidget *forward;
+ GtkWidget *back;
+ GtkWidget *apply;
+ GtkWidget *close;
+ GtkWidget *last;
+
GtkWidget *header_image;
GtkWidget *sidebar_image;
GtkAssistantPageFunc forward_function;
gpointer forward_function_data;
GDestroyNotify forward_data_destroy;
+
+ guint committed : 1;
};
static void gtk_assistant_class_init (GtkAssistantClass *class);
static void gtk_assistant_init (GtkAssistant *assistant);
-static void gtk_assistant_destroy (GtkObject *object);
+static void gtk_assistant_destroy (GtkWidget *widget);
static void gtk_assistant_style_set (GtkWidget *widget,
GtkStyle *old_style);
-static void gtk_assistant_size_request (GtkWidget *widget,
- GtkRequisition *requisition);
+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_expose (GtkWidget *widget,
- GdkEventExpose *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,
static AtkObject *gtk_assistant_get_accessible (GtkWidget *widget);
+static void gtk_assistant_buildable_interface_init (GtkBuildableIface *iface);
+static GObject *gtk_assistant_buildable_get_internal_child (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ const gchar *childname);
+static gboolean gtk_assistant_buildable_custom_tag_start (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ GMarkupParser *parser,
+ gpointer *data);
+static void gtk_assistant_buildable_custom_finished (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ gpointer user_data);
+
+static GList* find_page (GtkAssistant *assistant,
+ GtkWidget *page);
+
enum
{
CHILD_PROP_0,
static guint signals [LAST_SIGNAL] = { 0 };
-G_DEFINE_TYPE (GtkAssistant, gtk_assistant, GTK_TYPE_WINDOW)
+G_DEFINE_TYPE_WITH_CODE (GtkAssistant, gtk_assistant, GTK_TYPE_WINDOW,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
+ gtk_assistant_buildable_interface_init))
static void
gtk_assistant_class_init (GtkAssistantClass *class)
{
GObjectClass *gobject_class;
- GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
GtkContainerClass *container_class;
gobject_class = (GObjectClass *) class;
- object_class = (GtkObjectClass *) class;
widget_class = (GtkWidgetClass *) class;
container_class = (GtkContainerClass *) class;
- object_class->destroy = gtk_assistant_destroy;
-
+ widget_class->destroy = gtk_assistant_destroy;
widget_class->style_set = gtk_assistant_style_set;
- widget_class->size_request = gtk_assistant_size_request;
+ 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->expose_event = gtk_assistant_expose;
+ widget_class->draw = gtk_assistant_draw;
widget_class->focus = gtk_assistant_focus;
widget_class->get_accessible = gtk_assistant_get_accessible;
* @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
+ * 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.
*
* Since: 2.10
/**
* GtkAssistant::apply:
- * @assistant: the @GtkAssistant
+ * @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.
+ * 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 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.
+ * 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
*/
*
* 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.
+ * page in the flow (of type %GTK_ASSISTANT_PAGE_CONFIRM) is clicked.
*
* Since: 2.10
*/
/**
* GtkAssistant:page-type:
*
- * The type of the assistant page.
+ * The type of the assistant page.
*
* Since: 2.10
*/
/**
* GtkAssistant:title:
*
- * The title that is displayed in the page header.
+ * The title that is displayed in the page header.
*
* If title and header-image are both %NULL, no header is displayed.
*
/**
* GtkAssistant:header-image:
*
- * The image that is displayed next to the page.
+ * The image that is displayed next to the page.
*
* Set this to %NULL to make the sidebar disappear.
*
page_info = (GtkAssistantPage *) page_node->data;
- while (page_node && !GTK_WIDGET_VISIBLE (page_info->page))
+ while (page_node && !gtk_widget_get_visible (page_info->page))
{
page_node = page_node->next;
current_page++;
page_info = g_list_nth_data (priv->pages, page_num);
count++;
-
- g_assert (page_info);
}
/* make the last button visible if we can skip multiple
- * pages and end on a confirmation or summary page
+ * pages and end on a confirmation or summary page
*/
- if (count > 1 &&
+ if (count > 1 && page_info &&
(page_info->type == GTK_ASSISTANT_PAGE_CONFIRM ||
page_info->type == GTK_ASSISTANT_PAGE_SUMMARY))
{
- gtk_widget_show (assistant->last);
- gtk_widget_set_sensitive (assistant->last,
+ gtk_widget_show (priv->last);
+ gtk_widget_set_sensitive (priv->last,
current_page_info->complete);
}
else
- gtk_widget_hide (assistant->last);
+ gtk_widget_hide (priv->last);
+}
+
+static void
+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);
+
+ page_num = (priv->forward_function) (page_num, priv->forward_function_data);
+
+ if (page_num >= 0 && page_num < n_pages)
+ gtk_widget_show (priv->forward);
+ else
+ gtk_widget_hide (priv->forward);
}
static void
switch (priv->current_page->type)
{
case GTK_ASSISTANT_PAGE_INTRO:
- gtk_widget_set_sensitive (assistant->cancel, TRUE);
- gtk_widget_set_sensitive (assistant->forward, priv->current_page->complete);
- gtk_widget_show (assistant->cancel);
- gtk_widget_show (assistant->forward);
- gtk_widget_hide (assistant->back);
- gtk_widget_hide (assistant->apply);
- gtk_widget_hide (assistant->close);
+ gtk_widget_set_sensitive (priv->cancel, TRUE);
+ gtk_widget_set_sensitive (priv->forward, priv->current_page->complete);
+ gtk_widget_grab_default (priv->forward);
+ gtk_widget_show (priv->forward);
+ gtk_widget_hide (priv->back);
+ gtk_widget_hide (priv->apply);
+ gtk_widget_hide (priv->close);
compute_last_button_state (assistant);
break;
case GTK_ASSISTANT_PAGE_CONFIRM:
- gtk_widget_set_sensitive (assistant->cancel, TRUE);
- gtk_widget_set_sensitive (assistant->back, TRUE);
- gtk_widget_set_sensitive (assistant->apply, priv->current_page->complete);
- gtk_widget_show (assistant->cancel);
- gtk_widget_show (assistant->back);
- gtk_widget_show (assistant->apply);
- gtk_widget_hide (assistant->forward);
- gtk_widget_hide (assistant->close);
- gtk_widget_hide (assistant->last);
+ gtk_widget_set_sensitive (priv->cancel, TRUE);
+ gtk_widget_set_sensitive (priv->back, TRUE);
+ gtk_widget_set_sensitive (priv->apply, priv->current_page->complete);
+ gtk_widget_grab_default (priv->apply);
+ gtk_widget_show (priv->back);
+ gtk_widget_show (priv->apply);
+ gtk_widget_hide (priv->forward);
+ gtk_widget_hide (priv->close);
+ gtk_widget_hide (priv->last);
break;
case GTK_ASSISTANT_PAGE_CONTENT:
- gtk_widget_set_sensitive (assistant->cancel, TRUE);
- gtk_widget_set_sensitive (assistant->back, TRUE);
- gtk_widget_set_sensitive (assistant->forward, priv->current_page->complete);
- gtk_widget_show (assistant->cancel);
- gtk_widget_show (assistant->back);
- gtk_widget_show (assistant->forward);
- gtk_widget_hide (assistant->apply);
- gtk_widget_hide (assistant->close);
+ gtk_widget_set_sensitive (priv->cancel, TRUE);
+ gtk_widget_set_sensitive (priv->back, TRUE);
+ gtk_widget_set_sensitive (priv->forward, priv->current_page->complete);
+ gtk_widget_grab_default (priv->forward);
+ gtk_widget_show (priv->back);
+ gtk_widget_show (priv->forward);
+ gtk_widget_hide (priv->apply);
+ gtk_widget_hide (priv->close);
compute_last_button_state (assistant);
break;
case GTK_ASSISTANT_PAGE_SUMMARY:
- gtk_widget_set_sensitive (assistant->close, TRUE);
- gtk_widget_show (assistant->close);
- gtk_widget_hide (assistant->cancel);
- gtk_widget_hide (assistant->back);
- gtk_widget_hide (assistant->forward);
- gtk_widget_hide (assistant->apply);
- gtk_widget_hide (assistant->last);
+ gtk_widget_set_sensitive (priv->close, priv->current_page->complete);
+ gtk_widget_grab_default (priv->close);
+ gtk_widget_show (priv->close);
+ gtk_widget_hide (priv->back);
+ gtk_widget_hide (priv->forward);
+ gtk_widget_hide (priv->apply);
+ gtk_widget_hide (priv->last);
break;
case GTK_ASSISTANT_PAGE_PROGRESS:
- gtk_widget_set_sensitive (assistant->cancel, priv->current_page->complete);
- gtk_widget_set_sensitive (assistant->back, priv->current_page->complete);
- gtk_widget_set_sensitive (assistant->forward, priv->current_page->complete);
- gtk_widget_show (assistant->cancel);
- gtk_widget_show (assistant->back);
- gtk_widget_show (assistant->forward);
- gtk_widget_hide (assistant->apply);
- gtk_widget_hide (assistant->close);
- gtk_widget_hide (assistant->last);
+ gtk_widget_set_sensitive (priv->cancel, priv->current_page->complete);
+ gtk_widget_set_sensitive (priv->back, priv->current_page->complete);
+ gtk_widget_set_sensitive (priv->forward, priv->current_page->complete);
+ gtk_widget_grab_default (priv->forward);
+ gtk_widget_show (priv->back);
+ gtk_widget_hide (priv->apply);
+ gtk_widget_hide (priv->close);
+ gtk_widget_hide (priv->last);
+ compute_progress_state (assistant);
+ break;
+ case GTK_ASSISTANT_PAGE_CUSTOM:
+ gtk_widget_hide (priv->cancel);
+ gtk_widget_hide (priv->back);
+ gtk_widget_hide (priv->forward);
+ gtk_widget_hide (priv->apply);
+ gtk_widget_hide (priv->last);
+ gtk_widget_hide (priv->close);
break;
default:
g_assert_not_reached ();
}
+ if (priv->committed)
+ gtk_widget_hide (priv->cancel);
+ else if (priv->current_page->type == GTK_ASSISTANT_PAGE_SUMMARY ||
+ priv->current_page->type == GTK_ASSISTANT_PAGE_CUSTOM)
+ gtk_widget_hide (priv->cancel);
+ else
+ gtk_widget_show (priv->cancel);
+
/* this is quite general, we don't want to
* go back if it's the first page */
if (!priv->visited_pages)
- gtk_widget_hide (assistant->back);
+ gtk_widget_hide (priv->back);
}
static void
GtkAssistantPage *old_page;
if (priv->current_page &&
- GTK_WIDGET_DRAWABLE (priv->current_page->page))
+ gtk_widget_is_drawable (priv->current_page->page))
old_page = priv->current_page;
else
old_page = NULL;
g_signal_emit (assistant, signals [PREPARE], 0, priv->current_page->page);
- if (GTK_WIDGET_VISIBLE (priv->current_page->page) && GTK_WIDGET_MAPPED (assistant))
+ 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_map (priv->current_page->page);
gtk_widget_map (priv->current_page->title);
}
- if (old_page && GTK_WIDGET_MAPPED (old_page->page))
+ if (old_page && gtk_widget_get_mapped (old_page->page))
{
gtk_widget_set_child_visible (old_page->page, FALSE);
gtk_widget_unmap (old_page->page);
gtk_widget_unmap (old_page->title);
}
+ if (!gtk_widget_child_focus (priv->current_page->page, GTK_DIR_TAB_FORWARD))
+ {
+ GtkWidget *button[6];
+ gint i;
+
+ /* find the best button to focus */
+ button[0] = priv->apply;
+ button[1] = priv->close;
+ button[2] = priv->forward;
+ button[3] = priv->back;
+ button[4] = priv->cancel;
+ button[5] = priv->last;
+ for (i = 0; i < 6; i++)
+ {
+ if (gtk_widget_get_visible (button[i]) && gtk_widget_get_sensitive (button[i]))
+ {
+ gtk_widget_grab_focus (button[i]);
+ break;
+ }
+ }
+ }
+
gtk_widget_queue_resize (GTK_WIDGET (assistant));
}
}
static void
-on_assistant_close (GtkWidget *widget, GtkAssistant *assistant)
+on_assistant_close (GtkWidget *widget,
+ GtkAssistant *assistant)
{
g_signal_emit (assistant, signals [CLOSE], 0, NULL);
}
static void
-on_assistant_apply (GtkWidget *widget, GtkAssistant *assistant)
+on_assistant_apply (GtkWidget *widget,
+ GtkAssistant *assistant)
{
- GtkAssistantPrivate *priv = assistant->priv;
gboolean success;
- success = compute_next_step (assistant);
+ g_signal_emit (assistant, signals [APPLY], 0);
- g_signal_emit (assistant, signals [APPLY], 0, priv->current_page->page);
+ success = compute_next_step (assistant);
/* if the assistant hasn't switched to another page, just emit
* the CLOSE signal, it't the last page in the assistant flow
*/
if (!success)
- g_signal_emit (assistant, signals [CLOSE], 0, priv->current_page->page);
+ g_signal_emit (assistant, signals [CLOSE], 0);
}
static void
-on_assistant_forward (GtkWidget *widget, GtkAssistant *assistant)
+on_assistant_forward (GtkWidget *widget,
+ GtkAssistant *assistant)
{
- if (!compute_next_step (assistant))
- g_critical ("Page flow is broken, you may want to end it with a page of "
- "type GTK_ASSISTANT_PAGE_CONFIRM or GTK_ASSISTANT_PAGE_SUMMARY");
+ gtk_assistant_next_page (assistant);
}
static void
-on_assistant_back (GtkWidget *widget, GtkAssistant *assistant)
+on_assistant_back (GtkWidget *widget,
+ GtkAssistant *assistant)
{
- GtkAssistantPrivate *priv = assistant->priv;
- GtkAssistantPage *page_info;
- GSList *page_node;
-
- /* skip the progress pages when going back */
- do
- {
- page_node = priv->visited_pages;
-
- g_return_if_fail (page_node != NULL);
-
- priv->visited_pages = priv->visited_pages->next;
- page_info = (GtkAssistantPage *) page_node->data;
- g_slist_free_1 (page_node);
- }
- while (page_info->type == GTK_ASSISTANT_PAGE_PROGRESS ||
- !GTK_WIDGET_VISIBLE (page_info->page));
-
- set_current_page (assistant, page_info);
+ gtk_assistant_previous_page (assistant);
}
static void
-on_assistant_cancel (GtkWidget *widget, GtkAssistant *assistant)
+on_assistant_cancel (GtkWidget *widget,
+ GtkAssistant *assistant)
{
g_signal_emit (assistant, signals [CANCEL], 0, NULL);
}
static void
-on_assistant_last (GtkWidget *widget, GtkAssistant *assistant)
+on_assistant_last (GtkWidget *widget,
+ GtkAssistant *assistant)
{
GtkAssistantPrivate *priv = assistant->priv;
{
GtkAssistantPrivate *priv;
- priv = assistant->priv = GTK_ASSISTANT_GET_PRIVATE (assistant);
+ 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);
gtk_widget_push_composite_child ();
gtk_widget_show (priv->sidebar_image);
/* Action area */
- priv->action_area = gtk_hbox_new (FALSE, 6);
-
- assistant->close = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
- assistant->apply = gtk_button_new_from_stock (GTK_STOCK_APPLY);
- assistant->forward = gtk_button_new_from_stock (GTK_STOCK_GO_FORWARD);
- assistant->back = gtk_button_new_from_stock (GTK_STOCK_GO_BACK);
- assistant->cancel = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
- assistant->last = gtk_button_new_from_stock (GTK_STOCK_GOTO_LAST);
+ priv->action_area = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+
+ priv->close = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
+ priv->apply = gtk_button_new_from_stock (GTK_STOCK_APPLY);
+ priv->forward = gtk_button_new_from_stock (GTK_STOCK_GO_FORWARD);
+ priv->back = gtk_button_new_from_stock (GTK_STOCK_GO_BACK);
+ priv->cancel = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
+ priv->last = gtk_button_new_from_stock (GTK_STOCK_GOTO_LAST);
+ gtk_widget_set_can_default (priv->close, TRUE);
+ 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, assistant->close);
- gtk_size_group_add_widget (priv->size_group, assistant->apply);
- gtk_size_group_add_widget (priv->size_group, assistant->forward);
- gtk_size_group_add_widget (priv->size_group, assistant->back);
- gtk_size_group_add_widget (priv->size_group, assistant->cancel);
- gtk_size_group_add_widget (priv->size_group, assistant->last);
+ 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);
if (!alternative_button_order (assistant))
{
- gtk_box_pack_end (GTK_BOX (priv->action_area), assistant->apply, FALSE, FALSE, 0);
- gtk_box_pack_end (GTK_BOX (priv->action_area), assistant->forward, FALSE, FALSE, 0);
- gtk_box_pack_end (GTK_BOX (priv->action_area), assistant->back, FALSE, FALSE, 0);
- gtk_box_pack_end (GTK_BOX (priv->action_area), assistant->last, FALSE, FALSE, 0);
- gtk_box_pack_end (GTK_BOX (priv->action_area), assistant->cancel, FALSE, FALSE, 0);
- gtk_box_pack_end (GTK_BOX (priv->action_area), assistant->close, FALSE, FALSE, 0);
+ gtk_box_pack_end (GTK_BOX (priv->action_area), priv->apply, FALSE, FALSE, 0);
+ gtk_box_pack_end (GTK_BOX (priv->action_area), priv->forward, FALSE, FALSE, 0);
+ gtk_box_pack_end (GTK_BOX (priv->action_area), priv->back, FALSE, FALSE, 0);
+ gtk_box_pack_end (GTK_BOX (priv->action_area), priv->last, FALSE, FALSE, 0);
+ gtk_box_pack_end (GTK_BOX (priv->action_area), priv->cancel, FALSE, FALSE, 0);
+ gtk_box_pack_end (GTK_BOX (priv->action_area), priv->close, FALSE, FALSE, 0);
}
else
{
- gtk_box_pack_end (GTK_BOX (priv->action_area), assistant->close, FALSE, FALSE, 0);
- gtk_box_pack_end (GTK_BOX (priv->action_area), assistant->cancel, FALSE, FALSE, 0);
- gtk_box_pack_end (GTK_BOX (priv->action_area), assistant->last, FALSE, FALSE, 0);
- gtk_box_pack_end (GTK_BOX (priv->action_area), assistant->back, FALSE, FALSE, 0);
- gtk_box_pack_end (GTK_BOX (priv->action_area), assistant->forward, FALSE, FALSE, 0);
- gtk_box_pack_end (GTK_BOX (priv->action_area), assistant->apply, FALSE, FALSE, 0);
+ gtk_box_pack_end (GTK_BOX (priv->action_area), priv->close, FALSE, FALSE, 0);
+ gtk_box_pack_end (GTK_BOX (priv->action_area), priv->cancel, FALSE, FALSE, 0);
+ gtk_box_pack_end (GTK_BOX (priv->action_area), priv->apply, FALSE, FALSE, 0);
+ gtk_box_pack_end (GTK_BOX (priv->action_area), priv->forward, FALSE, FALSE, 0);
+ gtk_box_pack_end (GTK_BOX (priv->action_area), priv->back, FALSE, FALSE, 0);
+ 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 (assistant->forward);
- gtk_widget_show (assistant->back);
- gtk_widget_show (assistant->cancel);
+ gtk_widget_show (priv->forward);
+ gtk_widget_show (priv->back);
+ gtk_widget_show (priv->cancel);
gtk_widget_show (priv->action_area);
gtk_widget_pop_composite_child ();
priv->forward_function_data = assistant;
priv->forward_data_destroy = NULL;
- g_signal_connect (G_OBJECT (assistant->close), "clicked",
+ g_signal_connect (G_OBJECT (priv->close), "clicked",
G_CALLBACK (on_assistant_close), assistant);
- g_signal_connect (G_OBJECT (assistant->apply), "clicked",
+ g_signal_connect (G_OBJECT (priv->apply), "clicked",
G_CALLBACK (on_assistant_apply), assistant);
- g_signal_connect (G_OBJECT (assistant->forward), "clicked",
+ g_signal_connect (G_OBJECT (priv->forward), "clicked",
G_CALLBACK (on_assistant_forward), assistant);
- g_signal_connect (G_OBJECT (assistant->back), "clicked",
+ g_signal_connect (G_OBJECT (priv->back), "clicked",
G_CALLBACK (on_assistant_back), assistant);
- g_signal_connect (G_OBJECT (assistant->cancel), "clicked",
+ g_signal_connect (G_OBJECT (priv->cancel), "clicked",
G_CALLBACK (on_assistant_cancel), assistant);
- g_signal_connect (G_OBJECT (assistant->last), "clicked",
+ g_signal_connect (G_OBJECT (priv->last), "clicked",
G_CALLBACK (on_assistant_last), assistant);
}
GtkAssistant *assistant = GTK_ASSISTANT (data);
/* update buttons state, flow may have changed */
- if (GTK_WIDGET_MAPPED (assistant))
+ if (gtk_widget_get_mapped (GTK_WIDGET (assistant)))
set_assistant_buttons_state (assistant);
}
*/
page_node = priv->pages;
- while (page_node && !GTK_WIDGET_VISIBLE (((GtkAssistantPage *) page_node->data)->page))
+ while (page_node && !gtk_widget_get_visible (((GtkAssistantPage *) page_node->data)->page))
page_node = page_node->next;
+ if (page_node == element)
+ page_node = page_node->next;
+
if (page_node)
priv->current_page = page_node->data;
else
g_object_unref (page_info->sidebar_image);
gtk_widget_destroy (page_info->title);
- g_free (page_info);
+ g_slice_free (GtkAssistantPage, page_info);
g_list_free_1 (element);
}
static void
-gtk_assistant_destroy (GtkObject *object)
+gtk_assistant_destroy (GtkWidget *widget)
{
- GtkAssistant *assistant = GTK_ASSISTANT (object);
+ GtkAssistant *assistant = GTK_ASSISTANT (widget);
GtkAssistantPrivate *priv = assistant->priv;
if (priv->header_image)
priv->current_page = NULL;
while (priv->pages)
- remove_page (GTK_ASSISTANT (object), priv->pages);
-
- GTK_OBJECT_CLASS (gtk_assistant_parent_class)->destroy (object);
+ remove_page (assistant, priv->pages);
+
+ GTK_WIDGET_CLASS (gtk_assistant_parent_class)->destroy (widget);
}
static GList*
gint size;
desc = pango_font_description_new ();
- size = pango_font_description_get_size (assistant->style->font_desc);
+ size = pango_font_description_get_size (gtk_widget_get_style (assistant)->font_desc);
pango_font_description_set_weight (desc, PANGO_WEIGHT_ULTRABOLD);
pango_font_description_set_size (desc, size * PANGO_SCALE_XX_LARGE);
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,
GtkAssistantPage *page = list->data;
gint w, h;
- gtk_widget_size_request (page->page, &child_requisition);
+ gtk_widget_get_preferred_size (page->page,
+ &child_requisition, NULL);
width = MAX (width, child_requisition.width);
height = MAX (height, child_requisition.height);
- gtk_widget_size_request (page->title, &child_requisition);
+ gtk_widget_get_preferred_size (page->title,
+ &child_requisition, NULL);
w = child_requisition.width;
h = child_requisition.height;
list = list->next;
}
- gtk_widget_size_request (priv->sidebar_image, &child_requisition);
+ 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_size_request (priv->header_image, &child_requisition);
+ 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_size_request (priv->action_area, &child_requisition);
+ gtk_widget_get_preferred_size (priv->action_area,
+ &child_requisition, NULL);
width = MAX (width, child_requisition.width);
height += child_requisition.height + ACTION_AREA_SPACING;
- width += GTK_CONTAINER (widget)->border_width * 2 + content_padding * 2;
- height += GTK_CONTAINER (widget)->border_width * 2 + content_padding * 2;
+ 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;
+ 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;
"content-padding", &content_padding,
NULL);
- widget->allocation = *allocation;
+ gtk_widget_set_allocation (widget, allocation);
+ border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
/* Header */
- gtk_widget_get_child_requisition (priv->header_image, &header_requisition);
+ gtk_widget_get_preferred_size (priv->header_image,
+ &header_requisition, NULL);
- header_allocation.x = allocation->x + GTK_CONTAINER (widget)->border_width + header_padding;
- header_allocation.y = allocation->y + GTK_CONTAINER (widget)->border_width + header_padding;
- header_allocation.width = allocation->width - 2 * GTK_CONTAINER (widget)->border_width - 2 * header_padding;
+ 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 */
- child_allocation.x = allocation->x + GTK_CONTAINER (widget)->border_width;
- child_allocation.y = allocation->y + allocation->height -
- GTK_CONTAINER (widget)->border_width - priv->action_area->requisition.height;
- child_allocation.width = allocation->width - 2 * GTK_CONTAINER (widget)->border_width;
- child_allocation.height = priv->action_area->requisition.height;
+ 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->x + allocation->width -
- GTK_CONTAINER (widget)->border_width - priv->sidebar_image->requisition.width;
+ child_allocation.x = allocation->width - border_width - sidebar_requisition.width;
else
- child_allocation.x = allocation->x + GTK_CONTAINER (widget)->border_width;
+ child_allocation.x = border_width;
- child_allocation.y = allocation->y + GTK_CONTAINER (widget)->border_width +
- priv->header_image->allocation.height + 2 * header_padding;
- child_allocation.width = priv->sidebar_image->requisition.width;
- child_allocation.height = allocation->height - 2 * GTK_CONTAINER (widget)->border_width -
- priv->header_image->allocation.height - 2 * header_padding - priv->action_area->allocation.height;
+ 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 = allocation->x + GTK_CONTAINER (widget)->border_width + content_padding;
- child_allocation.y = allocation->y + GTK_CONTAINER (widget)->border_width +
- priv->header_image->allocation.height + 2 * header_padding + content_padding;
- child_allocation.width = allocation->width - 2 * GTK_CONTAINER (widget)->border_width - 2 * content_padding;
- child_allocation.height = allocation->height - 2 * GTK_CONTAINER (widget)->border_width -
- priv->header_image->allocation.height - 2 * header_padding - ACTION_AREA_SPACING - priv->action_area->allocation.height - 2 * content_padding;
-
- if (GTK_WIDGET_VISIBLE (priv->sidebar_image))
+ 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 += priv->sidebar_image->allocation.width;
+ child_allocation.x += sidebar_image_allocation.width;
- child_allocation.width -= priv->sidebar_image->allocation.width;
+ child_allocation.width -= sidebar_image_allocation.width;
}
while (pages)
GtkAssistant *assistant = GTK_ASSISTANT (widget);
GtkAssistantPrivate *priv = assistant->priv;
GList *page_node;
+ GtkAssistantPage *page;
- GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
+ gtk_widget_set_mapped (widget, TRUE);
gtk_widget_map (priv->header_image);
gtk_widget_map (priv->action_area);
- if (GTK_WIDGET_VISIBLE (priv->sidebar_image) &&
- !GTK_WIDGET_MAPPED (priv->sidebar_image))
+ if (gtk_widget_get_visible (priv->sidebar_image) &&
+ !gtk_widget_get_mapped (priv->sidebar_image))
gtk_widget_map (priv->sidebar_image);
/* if there's no default page, pick the first one */
- if (!priv->current_page && priv->pages)
+ page = NULL;
+ if (!priv->current_page)
{
page_node = priv->pages;
- while (page_node && !GTK_WIDGET_VISIBLE (((GtkAssistantPage *) page_node->data)->page))
+ while (page_node && !gtk_widget_get_visible (((GtkAssistantPage *) page_node->data)->page))
page_node = page_node->next;
if (page_node)
- priv->current_page = page_node->data;
+ page = page_node->data;
}
- if (priv->current_page &&
- GTK_WIDGET_VISIBLE (priv->current_page->page) &&
- !GTK_WIDGET_MAPPED (priv->current_page->page))
- {
- set_assistant_buttons_state ((GtkAssistant *) widget);
- set_assistant_header_image ((GtkAssistant*) widget);
- set_assistant_sidebar_image ((GtkAssistant*) widget);
-
- g_signal_emit (widget, signals [PREPARE], 0, priv->current_page->page);
- gtk_widget_set_child_visible (priv->current_page->page, TRUE);
- gtk_widget_map (priv->current_page->page);
- gtk_widget_map (priv->current_page->title);
- }
+ if (page &&
+ gtk_widget_get_visible (page->page) &&
+ !gtk_widget_get_mapped (page->page))
+ set_current_page (assistant, page);
GTK_WIDGET_CLASS (gtk_assistant_parent_class)->map (widget);
}
GtkAssistant *assistant = GTK_ASSISTANT (widget);
GtkAssistantPrivate *priv = assistant->priv;
- GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
+ gtk_widget_set_mapped (widget, FALSE);
gtk_widget_unmap (priv->header_image);
gtk_widget_unmap (priv->action_area);
- if (GTK_WIDGET_DRAWABLE (priv->sidebar_image))
+ if (gtk_widget_is_drawable (priv->sidebar_image))
gtk_widget_unmap (priv->sidebar_image);
if (priv->current_page &&
- GTK_WIDGET_DRAWABLE (priv->current_page->page))
+ gtk_widget_is_drawable (priv->current_page->page))
gtk_widget_unmap (priv->current_page->page);
g_slist_free (priv->visited_pages);
}
static void
-assistant_paint_colored_box (GtkWidget *widget)
+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;
+ GtkStyle *style;
gint border_width, header_padding, content_padding;
- cairo_t *cr;
gint content_x, content_width;
gboolean rtl;
- cr = gdk_cairo_create (widget->window);
rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
"content-padding", &content_padding,
NULL);
+ style = gtk_widget_get_style (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 */
- gdk_cairo_set_source_color (cr, &widget->style->bg[GTK_STATE_SELECTED]);
+ gdk_cairo_set_source_color (cr, &style->bg[GTK_STATE_SELECTED]);
cairo_rectangle (cr,
border_width,
border_width,
- widget->allocation.width - 2 * border_width,
- widget->allocation.height - priv->action_area->allocation.height - 2 * border_width - ACTION_AREA_SPACING);
+ 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 = widget->allocation.width - 2 * content_padding - 2 * border_width;
+ content_width = allocation.width - 2 * content_padding - 2 * border_width;
- if (GTK_WIDGET_VISIBLE (priv->sidebar_image))
+ 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 += priv->sidebar_image->allocation.width;
- content_width -= priv->sidebar_image->allocation.width;
+ content_x += sidebar_image_allocation.width;
+ content_width -= sidebar_image_allocation.width;
}
-
- gdk_cairo_set_source_color (cr, &widget->style->bg[GTK_STATE_NORMAL]);
+
+ gdk_cairo_set_source_color (cr, &style->bg[GTK_STATE_NORMAL]);
cairo_rectangle (cr,
content_x,
- priv->header_image->allocation.height + content_padding + 2 * header_padding + border_width,
+ header_image_allocation.height + content_padding + 2 * header_padding + border_width,
content_width,
- widget->allocation.height - 2 * border_width - priv->action_area->allocation.height -
- priv->header_image->allocation.height - 2 * content_padding - 2 * header_padding - ACTION_AREA_SPACING);
+ 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);
-
- cairo_destroy (cr);
}
static gboolean
-gtk_assistant_expose (GtkWidget *widget,
- GdkEventExpose *event)
+gtk_assistant_draw (GtkWidget *widget,
+ cairo_t *cr)
{
GtkAssistant *assistant = GTK_ASSISTANT (widget);
GtkAssistantPrivate *priv = assistant->priv;
- GtkContainer *container;
+ GtkContainer *container = GTK_CONTAINER (widget);
- if (GTK_WIDGET_DRAWABLE (widget))
- {
- 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);
+ assistant_paint_colored_box (widget, cr);
- gtk_container_propagate_expose (container, priv->header_image, event);
- gtk_container_propagate_expose (container, priv->sidebar_image, event);
- gtk_container_propagate_expose (container, priv->action_area, event);
+ 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_expose (container, priv->current_page->page, event);
- gtk_container_propagate_expose (container, priv->current_page->title, event);
- }
+ 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;
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_container_get_focus_child (container) == priv->action_area)
{
if (!gtk_widget_child_focus (priv->action_area, direction) &&
(priv->current_page == NULL ||
gtk_assistant_add (GtkContainer *container,
GtkWidget *page)
{
- g_return_if_fail (GTK_IS_WIDGET (page));
-
gtk_assistant_append_page (GTK_ASSISTANT (container), page);
}
gtk_assistant_remove (GtkContainer *container,
GtkWidget *page)
{
- GtkAssistant *assistant;
+ GtkAssistant *assistant = (GtkAssistant*) container;
GList *element;
- assistant = (GtkAssistant*) container;
-
element = find_page (assistant, page);
if (element)
{
GtkWidget *assistant;
- assistant = g_object_new (GTK_TYPE_ASSISTANT,
- "border-width", 12,
- NULL);
+ assistant = g_object_new (GTK_TYPE_ASSISTANT, NULL);
+
return assistant;
}
if (page_num >= 0)
page = (GtkAssistantPage *) g_list_nth_data (priv->pages, page_num);
else
- page = (GtkAssistantPage *) g_list_last (priv->pages);
+ page = (GtkAssistantPage *) g_list_last (priv->pages)->data;
g_return_if_fail (page != NULL);
* initial page setting, for the cases where the
* initial page is != to 0
*/
- if (GTK_WIDGET_MAPPED (assistant))
- priv->visited_pages = g_slist_prepend (priv->visited_pages, page);
+ if (gtk_widget_get_mapped (GTK_WIDGET (assistant)))
+ priv->visited_pages = g_slist_prepend (priv->visited_pages,
+ priv->current_page);
set_current_page (assistant, page);
}
+/**
+ * gtk_assistant_next_page:
+ * @assistant: a #GtkAssistant
+ *
+ * Navigate to the next page. It is a programming
+ * error to call this function if there is no next page.
+ *
+ * This function is for use when creating pages of the
+ * #GTK_ASSISTANT_PAGE_CUSTOM type.
+ *
+ * Since: 3.0
+ **/
+void
+gtk_assistant_next_page (GtkAssistant *assistant)
+{
+ GtkAssistantPrivate *priv;
+
+ g_return_if_fail (GTK_IS_ASSISTANT (assistant));
+
+ priv = assistant->priv;
+
+ if (!compute_next_step (assistant))
+ g_critical ("Page flow is broken, you may want to end it with a page of "
+ "type GTK_ASSISTANT_PAGE_CONFIRM or GTK_ASSISTANT_PAGE_SUMMARY");
+}
+
+/**
+ * gtk_assistant_previous_page:
+ * @assistant: a #GtkAssistant
+ *
+ * Navigate to the previous visited page. It is a programming
+ * error to call this function if no previous page is
+ * available.
+ *
+ * This function is for use when creating pages of the
+ * #GTK_ASSISTANT_PAGE_CUSTOM type.
+ *
+ * Since: 3.0
+ **/
+void
+gtk_assistant_previous_page (GtkAssistant *assistant)
+{
+ GtkAssistantPrivate *priv;
+ GtkAssistantPage *page_info;
+ GSList *page_node;
+
+ g_return_if_fail (GTK_IS_ASSISTANT (assistant));
+
+ priv = assistant->priv;
+
+ /* skip the progress pages when going back */
+ do
+ {
+ page_node = priv->visited_pages;
+
+ g_return_if_fail (page_node != NULL);
+
+ priv->visited_pages = priv->visited_pages->next;
+ page_info = (GtkAssistantPage *) page_node->data;
+ g_slist_free_1 (page_node);
+ }
+ while (page_info->type == GTK_ASSISTANT_PAGE_PROGRESS ||
+ !gtk_widget_get_visible (page_info->page));
+
+ set_current_page (assistant, page_info);
+}
+
/**
* gtk_assistant_get_n_pages:
* @assistant: a #GtkAssistant
*
* Returns the child widget contained in page number @page_num.
*
- * Return value: The child widget, or %NULL if @page_num is out of bounds.
+ * Return value: (transfer none): The child widget, or %NULL
+ * if @page_num is out of bounds.
*
* Since: 2.10
**/
GList *elem;
g_return_val_if_fail (GTK_IS_ASSISTANT (assistant), NULL);
+ g_return_val_if_fail (page_num >= -1, NULL);
priv = assistant->priv;
- elem = g_list_nth (priv->pages, page_num);
+ if (page_num == -1)
+ elem = g_list_last (priv->pages);
+ else
+ elem = g_list_nth (priv->pages, page_num);
if (!elem)
return NULL;
g_return_val_if_fail (GTK_IS_ASSISTANT (assistant), 0);
g_return_val_if_fail (GTK_IS_WIDGET (page), 0);
- g_return_val_if_fail (page->parent == NULL, 0);
- g_return_val_if_fail (!GTK_WIDGET_TOPLEVEL (page), 0);
+ g_return_val_if_fail (gtk_widget_get_parent (page) == NULL, 0);
+ g_return_val_if_fail (!gtk_widget_is_toplevel (page), 0);
priv = assistant->priv;
- page_info = g_new0 (GtkAssistantPage, 1);
+ page_info = g_slice_new0 (GtkAssistantPage);
page_info->page = page;
page_info->title = gtk_label_new (NULL);
gtk_widget_set_parent (page_info->page, GTK_WIDGET (assistant));
gtk_widget_set_parent (page_info->title, GTK_WIDGET (assistant));
- if (GTK_WIDGET_REALIZED (GTK_WIDGET (assistant)))
+ if (gtk_widget_get_realized (GTK_WIDGET (assistant)))
{
gtk_widget_realize (page_info->page);
gtk_widget_realize (page_info->title);
/**
* gtk_assistant_set_forward_page_func:
* @assistant: a #GtkAssistant
- * @page_func: the #GtkAssistantPageFunc, or %NULL to use the default one
+ * @page_func: (allow-none): the #GtkAssistantPageFunc, or %NULL to use the default one
* @data: user data for @page_func
* @destroy: destroy notifier for @data
*
{
page_info->type = type;
+ /* backwards compatibility to the era before fixing bug 604289 */
+ if (type == GTK_ASSISTANT_PAGE_SUMMARY && !page_info->complete_set)
+ {
+ gtk_assistant_set_page_complete (assistant, page, TRUE);
+ page_info->complete_set = FALSE;
+ }
+
/* Always set buttons state, a change in a future page
might change current page buttons */
set_assistant_buttons_state (assistant);
* gtk_assistant_set_page_header_image:
* @assistant: a #GtkAssistant
* @page: a page of @assistant
- * @pixbuf: the new header image @page
- *
+ * @pixbuf: (allow-none): the new header image @page
+ *
* Sets a header image for @page. This image is displayed in the header
* area of the assistant when @page is the current page.
*
* gtk_assistant_get_page_header_image:
* @assistant: a #GtkAssistant
* @page: a page of @assistant
- *
- * Gets the header image for @page.
- *
- * Return value: the header image for @page, or %NULL
- * if there's no header image for the page.
+ *
+ * Gets the header image for @page.
+ *
+ * Return value: (transfer none): the header image for @page, or %NULL
+ * if there's no header image for the page.
*
* Since: 2.10
**/
* gtk_assistant_set_page_side_image:
* @assistant: a #GtkAssistant
* @page: a page of @assistant
- * @pixbuf: the new header image @page
- *
+ * @pixbuf: (allow-none): the new header image @page
+ *
* Sets a header image for @page. This image is displayed in the side
* area of the assistant when @page is the current page.
*
* gtk_assistant_get_page_side_image:
* @assistant: a #GtkAssistant
* @page: a page of @assistant
- *
- * Gets the header image for @page.
- *
- * Return value: the side image for @page, or %NULL
- * if there's no side image for the page.
+ *
+ * Gets the header 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
**/
if (complete != page_info->complete)
{
page_info->complete = complete;
+ page_info->complete_set = TRUE;
/* Always set buttons state, a change in a future page
might change current page buttons */
* @assistant: a #GtkAssistant
* @page: a page of @assistant
*
- * Gets whether @page is complete..
+ * Gets whether @page is complete.
*
* Return value: %TRUE if @page is complete.
*
set_assistant_buttons_state (assistant);
}
+/**
+ * gtk_assistant_commit:
+ * @assistant: a #GtkAssistant
+ *
+ * Erases the visited page history so the back button is not
+ * shown on the current page, and removes the cancel button
+ * from subsequent pages.
+ *
+ * Use this when the information provided up to the current
+ * page is hereafter deemed permanent and cannot be modified
+ * or undone. For example, showing a progress page to track
+ * a long-running, unreversible operation after the user has
+ * clicked apply on a confirmation page.
+ *
+ * Since: 2.22
+ **/
+void
+gtk_assistant_commit (GtkAssistant *assistant)
+{
+ g_return_if_fail (GTK_IS_ASSISTANT (assistant));
+
+ g_slist_free (assistant->priv->visited_pages);
+ assistant->priv->visited_pages = NULL;
+
+ assistant->priv->committed = TRUE;
+
+ set_assistant_buttons_state (assistant);
+}
+
/* accessible implementation */
GtkAssistant *assistant;
GtkWidget *widget;
- widget = GTK_ACCESSIBLE (accessible)->widget;
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
if (!widget)
return 0;
GtkWidget *widget, *child;
gint n_pages;
AtkObject *obj;
+ const gchar *title;
- widget = GTK_ACCESSIBLE (accessible)->widget;
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
if (!widget)
return NULL;
return NULL;
else if (index < n_pages)
{
- GtkAssistantPage *page = g_list_nth_data (priv->pages, index / 2);
+ GtkAssistantPage *page = g_list_nth_data (priv->pages, index);
child = page->page;
+ title = gtk_assistant_get_page_title (assistant, child);
}
else if (index == n_pages)
{
child = priv->action_area;
+ title = NULL;
}
else
return NULL;
obj = gtk_widget_get_accessible (child);
+ if (title)
+ atk_object_set_name (obj, title);
+
return g_object_ref (obj);
}
GType derived_type;
GTypeQuery query;
GType derived_atk_type;
-
+
derived_type = g_type_parent (GTK_TYPE_ASSISTANT);
factory = atk_registry_get_factory (atk_get_default_registry (),
derived_type);
derived_atk_type = atk_object_factory_get_accessible_type (factory);
g_type_query (derived_atk_type, &query);
-
- type = g_type_register_static_simple (derived_atk_type,
- I_("GtkAssistantAccessible"),
+
+ type = g_type_register_static_simple (derived_atk_type,
+ I_("GtkAssistantAccessible"),
query.class_size,
(GClassInitFunc) gtk_assistant_accessible_class_init,
query.instance_size,
g_return_val_if_fail (GTK_IS_ASSISTANT (obj), NULL);
- accessible = g_object_new (gtk_assistant_accessible_get_type (), NULL);
+ accessible = g_object_new (gtk_assistant_accessible_get_type (), NULL);
atk_object_initialize (accessible, obj);
-
+
return accessible;
}
{
static GType type = 0;
- if (!type)
+ if (!type)
{
- type = g_type_register_static_simple (ATK_TYPE_OBJECT_FACTORY,
+ type = g_type_register_static_simple (ATK_TYPE_OBJECT_FACTORY,
I_("GtkAssistantAccessibleFactory"),
sizeof (AtkObjectFactoryClass),
(GClassInitFunc) gtk_assistant_accessible_factory_class_init,
sizeof (AtkObjectFactory),
NULL, 0);
}
-
+
return type;
}
{
static gboolean first_time = TRUE;
- if (first_time)
+ if (first_time)
{
AtkObjectFactory *factory;
AtkRegistry *registry;
- GType derived_type;
- GType derived_atk_type;
+ GType derived_type;
+ GType derived_atk_type;
/*
* Figure out whether accessibility is enabled by looking at the
derived_atk_type = atk_object_factory_get_accessible_type (factory);
if (g_type_is_a (derived_atk_type, GTK_TYPE_ACCESSIBLE))
{
- atk_registry_set_factory_type (registry,
+ atk_registry_set_factory_type (registry,
GTK_TYPE_ASSISTANT,
gtk_assistant_accessible_factory_get_type ());
}
}
-#define __GTK_ASSISTANT_C__
-#include "gtkaliasdef.c"
+static GtkBuildableIface *parent_buildable_iface;
+
+static void
+gtk_assistant_buildable_interface_init (GtkBuildableIface *iface)
+{
+ parent_buildable_iface = g_type_interface_peek_parent (iface);
+ iface->get_internal_child = gtk_assistant_buildable_get_internal_child;
+ iface->custom_tag_start = gtk_assistant_buildable_custom_tag_start;
+ iface->custom_finished = gtk_assistant_buildable_custom_finished;
+}
+
+static GObject *
+gtk_assistant_buildable_get_internal_child (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ const gchar *childname)
+{
+ if (strcmp (childname, "action_area") == 0)
+ return G_OBJECT (GTK_ASSISTANT (buildable)->priv->action_area);
+
+ return parent_buildable_iface->get_internal_child (buildable,
+ builder,
+ childname);
+}
+
+gboolean
+gtk_assistant_buildable_custom_tag_start (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ GMarkupParser *parser,
+ gpointer *data)
+{
+ return parent_buildable_iface->custom_tag_start (buildable, builder, child,
+ tagname, parser, data);
+}
+
+static void
+gtk_assistant_buildable_custom_finished (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ gpointer user_data)
+{
+ parent_buildable_iface->custom_finished (buildable, builder, child,
+ tagname, user_data);
+}