* 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>
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,
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;
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)
+ 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);
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)
{
- 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_get_visible (page_info->page));
-
- set_current_page (assistant, page_info);
+ gtk_assistant_previous_page (assistant);
}
static void
gtk_widget_show (priv->sidebar_image);
/* Action area */
- priv->action_area = gtk_hbox_new (FALSE, 6);
-
+ 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);
}
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*
GtkAssistantPage *page = list->data;
gint w, h;
- gtk_size_request_get_size (GTK_SIZE_REQUEST (page->page),
- &child_requisition, NULL);
+ gtk_widget_get_preferred_size (page->page,
+ &child_requisition, NULL);
width = MAX (width, child_requisition.width);
height = MAX (height, child_requisition.height);
- gtk_size_request_get_size (GTK_SIZE_REQUEST (page->title),
- &child_requisition, NULL);
+ gtk_widget_get_preferred_size (page->title,
+ &child_requisition, NULL);
w = child_requisition.width;
h = child_requisition.height;
list = list->next;
}
- gtk_size_request_get_size (GTK_SIZE_REQUEST (priv->sidebar_image),
- &child_requisition, NULL);
+ 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_size_request_get_size (GTK_SIZE_REQUEST (priv->header_image),
- &child_requisition, NULL);
+ 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_size_request_get_size (GTK_SIZE_REQUEST (priv->action_area),
- &child_requisition, NULL);
+ gtk_widget_get_preferred_size (priv->action_area,
+ &child_requisition, NULL);
width = MAX (width, child_requisition.width);
height += child_requisition.height + ACTION_AREA_SPACING;
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,
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
/* Header */
- gtk_size_request_get_size (GTK_SIZE_REQUEST (priv->header_image),
- &header_requisition, NULL);
+ 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;
gtk_widget_size_allocate (priv->header_image, &header_allocation);
/* Action area */
- gtk_size_request_get_size (GTK_SIZE_REQUEST (priv->action_area),
- &action_requisition, NULL);
+ 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;
gtk_widget_get_allocation (priv->action_area, &action_area_allocation);
/* Sidebar */
- gtk_size_request_get_size (GTK_SIZE_REQUEST (priv->sidebar_image),
- &sidebar_requisition, NULL);
+ gtk_widget_get_preferred_size (priv->sidebar_image,
+ &sidebar_requisition, NULL);
if (rtl)
child_allocation.x = allocation->width - border_width - sidebar_requisition.width;
}
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 (gtk_widget_get_window (widget));
rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
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_is_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;
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
**/
* 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_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
**/