2 * GTK - The GIMP Toolkit
3 * Copyright (C) 1999 Red Hat, Inc.
4 * Copyright (C) 2002 Anders Carlsson <andersca@gnu.org>
5 * Copyright (C) 2003 Matthias Clasen <mclasen@redhat.com>
6 * Copyright (C) 2005 Carlos Garnacho Parro <carlosg@gnome.org>
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the
22 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 * Boston, MA 02111-1307, USA.
28 #include "gtkassistant.h"
30 #include "gtkbutton.h"
35 #include "gtksizegroup.h"
39 #include "gtkprivate.h"
43 #define GTK_ASSISTANT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_ASSISTANT, GtkAssistantPrivate))
45 #define HEADER_SPACING 12
47 typedef struct _GtkAssistantPage GtkAssistantPage;
49 struct _GtkAssistantPage
52 GtkAssistantPageType type;
56 GdkPixbuf *header_image;
57 GdkPixbuf *sidebar_image;
60 struct _GtkAssistantPrivate
62 GtkWidget *header_image;
63 GtkWidget *sidebar_image;
65 GtkWidget *action_area;
69 GtkAssistantPage *current_page;
71 GSList *visited_pages;
73 GtkSizeGroup *size_group;
75 GtkAssistantPageFunc forward_function;
76 gpointer forward_function_data;
77 GDestroyNotify forward_data_destroy;
80 static void gtk_assistant_class_init (GtkAssistantClass *class);
81 static void gtk_assistant_init (GtkAssistant *assistant);
82 static void gtk_assistant_destroy (GtkObject *object);
83 static void gtk_assistant_style_set (GtkWidget *widget,
85 static void gtk_assistant_size_request (GtkWidget *widget,
86 GtkRequisition *requisition);
87 static void gtk_assistant_size_allocate (GtkWidget *widget,
88 GtkAllocation *allocation);
89 static void gtk_assistant_map (GtkWidget *widget);
90 static void gtk_assistant_unmap (GtkWidget *widget);
91 static gboolean gtk_assistant_delete_event (GtkWidget *widget,
93 static gboolean gtk_assistant_expose (GtkWidget *widget,
94 GdkEventExpose *event);
95 static gboolean gtk_assistant_focus (GtkWidget *widget,
96 GtkDirectionType direction);
97 static void gtk_assistant_add (GtkContainer *container,
99 static void gtk_assistant_remove (GtkContainer *container,
101 static void gtk_assistant_forall (GtkContainer *container,
102 gboolean include_internals,
103 GtkCallback callback,
104 gpointer callback_data);
105 static void gtk_assistant_set_child_property (GtkContainer *container,
110 static void gtk_assistant_get_child_property (GtkContainer *container,
119 CHILD_PROP_PAGE_TYPE,
120 CHILD_PROP_PAGE_TITLE,
121 CHILD_PROP_PAGE_HEADER_IMAGE,
122 CHILD_PROP_PAGE_SIDEBAR_IMAGE,
123 CHILD_PROP_PAGE_COMPLETE
135 static guint signals [LAST_SIGNAL] = { 0 };
138 G_DEFINE_TYPE (GtkAssistant, gtk_assistant, GTK_TYPE_WINDOW);
142 gtk_assistant_class_init (GtkAssistantClass *class)
144 GObjectClass *gobject_class;
145 GtkObjectClass *object_class;
146 GtkWidgetClass *widget_class;
147 GtkContainerClass *container_class;
149 gobject_class = (GObjectClass *) class;
150 object_class = (GtkObjectClass *) class;
151 widget_class = (GtkWidgetClass *) class;
152 container_class = (GtkContainerClass *) class;
154 object_class->destroy = gtk_assistant_destroy;
156 widget_class->style_set = gtk_assistant_style_set;
157 widget_class->size_request = gtk_assistant_size_request;
158 widget_class->size_allocate = gtk_assistant_size_allocate;
159 widget_class->map = gtk_assistant_map;
160 widget_class->unmap = gtk_assistant_unmap;
161 widget_class->delete_event = gtk_assistant_delete_event;
162 widget_class->expose_event = gtk_assistant_expose;
163 widget_class->focus = gtk_assistant_focus;
165 container_class->add = gtk_assistant_add;
166 container_class->remove = gtk_assistant_remove;
167 container_class->forall = gtk_assistant_forall;
168 container_class->set_child_property = gtk_assistant_set_child_property;
169 container_class->get_child_property = gtk_assistant_get_child_property;
172 * GtkAssistant::cancel:
173 * @assistant: the #GtkAssistant
175 * The ::cancel signal is emitted when then the cancel button is clicked.
180 g_signal_new (I_("cancel"),
181 G_TYPE_FROM_CLASS (gobject_class),
183 G_STRUCT_OFFSET (GtkAssistantClass, cancel),
185 g_cclosure_marshal_VOID__VOID,
189 * GtkAssistant::prepare:
190 * @assistant: the #GtkAssistant
191 * @page: the current page
193 * The ::prepared signal is emitted when a new page is set as the assistant's
194 * current page, before making the new page visible. A handler for this signal
195 * can do any preparation which are necessary before showing @page.
200 g_signal_new (I_("prepare"),
201 G_TYPE_FROM_CLASS (gobject_class),
203 G_STRUCT_OFFSET (GtkAssistantClass, prepare),
205 g_cclosure_marshal_VOID__OBJECT,
206 G_TYPE_NONE, 1, GTK_TYPE_WIDGET);
209 * GtkAssistant::apply:
210 * @assistant: the @GtkAssistant
212 * The ::apply signal is emitted when the apply button is clicked. The default
213 * behavior of the #GtkAssistant is to switch to the page after the current page,
214 * unless the current page is the last one.
216 * A handler for the ::apply signal should carry out the actions for which the
217 * wizard has collected data. If the action takes a long time to complete, you
218 * might consider to put a page of type GTK_ASSISTANT_PAGE_PROGRESS after the
219 * confirmation page and handle this operation within the "prepare" signal of
225 g_signal_new (I_("apply"),
226 G_TYPE_FROM_CLASS (gobject_class),
228 G_STRUCT_OFFSET (GtkAssistantClass, apply),
230 g_cclosure_marshal_VOID__VOID,
234 * GtkAssistant::close:
235 * @assistant: the #GtkAssistant
237 * The ::close signal is emitted either when the close button of
238 * a summary page is clicked, or when the apply button in the last
239 * page in the flow (of type GTK_ASSISTANT_PAGE_CONFIRM) is clicked.
244 g_signal_new (I_("close"),
245 G_TYPE_FROM_CLASS (gobject_class),
247 G_STRUCT_OFFSET (GtkAssistantClass, close),
249 g_cclosure_marshal_VOID__VOID,
252 gtk_widget_class_install_style_property (widget_class,
253 g_param_spec_int ("header-padding",
254 P_("Header Padding"),
255 P_("Number of pixels around the header."),
259 GTK_PARAM_READABLE));
260 gtk_widget_class_install_style_property (widget_class,
261 g_param_spec_int ("content-padding",
262 P_("Content Padding"),
263 P_("Number of pixels around the content pages."),
267 GTK_PARAM_READABLE));
270 * GtkAssistant:page-type:
272 * The type of the assistant page.
276 gtk_container_class_install_child_property (container_class,
277 CHILD_PROP_PAGE_TYPE,
278 g_param_spec_enum ("page-type",
280 P_("The type of the assistant page"),
281 GTK_TYPE_ASSISTANT_PAGE_TYPE,
282 GTK_ASSISTANT_PAGE_CONTENT,
283 GTK_PARAM_READWRITE));
286 * GtkAssistant:title:
288 * The title that is displayed in the page header.
290 * If title and header-image are both %NULL, no header is displayed.
294 gtk_container_class_install_child_property (container_class,
295 CHILD_PROP_PAGE_TITLE,
296 g_param_spec_string ("title",
298 P_("The title of the assistant page"),
300 GTK_PARAM_READWRITE));
303 * GtkAssistant:header-image:
305 * The image that is displayed next to the title in the page header.
307 * If title and header-image are both %NULL, no header is displayed.
311 gtk_container_class_install_child_property (container_class,
312 CHILD_PROP_PAGE_HEADER_IMAGE,
313 g_param_spec_object ("header-image",
315 P_("Header image for the assistant page"),
317 GTK_PARAM_READWRITE));
320 * GtkAssistant:header-image:
322 * The image that is displayed next to the page.
324 * Set this to %NULL to make the sidebar disappear.
328 gtk_container_class_install_child_property (container_class,
329 CHILD_PROP_PAGE_SIDEBAR_IMAGE,
330 g_param_spec_object ("sidebar-image",
332 P_("Sidebar image for the assistant page"),
334 GTK_PARAM_READWRITE));
336 * GtkAssistant:complete:
338 * Setting the "complete" child property to %TRUE marks a page as complete
339 * (i.e.: all the required fields are filled out). GTK+ uses this information
340 * to control the sensitivity of the navigation buttons.
344 gtk_container_class_install_child_property (container_class,
345 CHILD_PROP_PAGE_COMPLETE,
346 g_param_spec_boolean ("complete",
348 P_("Whether all required fields on the page have been filled out"),
352 g_type_class_add_private (gobject_class, sizeof (GtkAssistantPrivate));
356 default_forward_function (gint current_page, gpointer data)
358 GtkAssistant *assistant;
359 GtkAssistantPrivate *priv;
360 GtkAssistantPage *page_info;
363 assistant = GTK_ASSISTANT (data);
364 priv = assistant->priv;
366 page_node = g_list_nth (priv->pages, ++current_page);
371 page_info = (GtkAssistantPage *) page_node->data;
373 while (page_node && !GTK_WIDGET_VISIBLE (page_info->page))
375 page_node = page_node->next;
379 page_info = (GtkAssistantPage *) page_node->data;
386 compute_last_button_state (GtkAssistant *assistant)
388 GtkAssistantPrivate *priv = assistant->priv;
389 GtkAssistantPage *page_info, *current_page_info;
390 gint count, page_num, n_pages;
393 page_num = gtk_assistant_get_current_page (assistant);
394 n_pages = gtk_assistant_get_n_pages (assistant);
395 current_page_info = page_info = g_list_nth_data (priv->pages, page_num);
397 while (page_num >= 0 && page_num < n_pages &&
398 page_info->type == GTK_ASSISTANT_PAGE_CONTENT &&
399 (count == 0 || page_info->complete) &&
402 page_num = (priv->forward_function) (page_num, priv->forward_function_data);
403 page_info = g_list_nth_data (priv->pages, page_num);
407 g_assert (page_info);
410 /* make the last button visible if we can skip multiple
411 * pages and end on a confirmation or summary page
414 (page_info->type == GTK_ASSISTANT_PAGE_CONFIRM ||
415 page_info->type == GTK_ASSISTANT_PAGE_SUMMARY))
417 gtk_widget_show (assistant->last);
418 gtk_widget_set_sensitive (assistant->last,
419 current_page_info->complete);
422 gtk_widget_hide (assistant->last);
426 _set_assistant_header_image (GtkAssistant *assistant)
428 GtkAssistantPrivate *priv = assistant->priv;
430 gtk_image_set_from_pixbuf (GTK_IMAGE (priv->header_image),
431 priv->current_page->header_image);
435 _set_assistant_sidebar_image (GtkAssistant *assistant)
437 GtkAssistantPrivate *priv = assistant->priv;
439 gtk_image_set_from_pixbuf (GTK_IMAGE (priv->sidebar_image),
440 priv->current_page->sidebar_image);
442 if (priv->current_page->sidebar_image)
443 gtk_widget_show (priv->sidebar_image);
445 gtk_widget_hide (priv->sidebar_image);
449 _set_assistant_buttons_state (GtkAssistant *assistant)
451 GtkAssistantPrivate *priv = assistant->priv;
453 switch (priv->current_page->type)
455 case GTK_ASSISTANT_PAGE_INTRO:
456 gtk_widget_set_sensitive (assistant->cancel, TRUE);
457 gtk_widget_set_sensitive (assistant->forward, priv->current_page->complete);
458 gtk_widget_show (assistant->cancel);
459 gtk_widget_show (assistant->forward);
460 gtk_widget_hide (assistant->back);
461 gtk_widget_hide (assistant->apply);
462 gtk_widget_hide (assistant->close);
463 compute_last_button_state (assistant);
465 case GTK_ASSISTANT_PAGE_CONFIRM:
466 gtk_widget_set_sensitive (assistant->cancel, TRUE);
467 gtk_widget_set_sensitive (assistant->back, TRUE);
468 gtk_widget_set_sensitive (assistant->apply, priv->current_page->complete);
469 gtk_widget_show (assistant->cancel);
470 gtk_widget_show (assistant->back);
471 gtk_widget_show (assistant->apply);
472 gtk_widget_hide (assistant->forward);
473 gtk_widget_hide (assistant->close);
474 gtk_widget_hide (assistant->last);
476 case GTK_ASSISTANT_PAGE_CONTENT:
477 gtk_widget_set_sensitive (assistant->cancel, TRUE);
478 gtk_widget_set_sensitive (assistant->back, TRUE);
479 gtk_widget_set_sensitive (assistant->forward, priv->current_page->complete);
480 gtk_widget_show (assistant->cancel);
481 gtk_widget_show (assistant->back);
482 gtk_widget_show (assistant->forward);
483 gtk_widget_hide (assistant->apply);
484 gtk_widget_hide (assistant->close);
485 compute_last_button_state (assistant);
487 case GTK_ASSISTANT_PAGE_SUMMARY:
488 gtk_widget_set_sensitive (assistant->close, TRUE);
489 gtk_widget_show (assistant->close);
490 gtk_widget_hide (assistant->cancel);
491 gtk_widget_hide (assistant->back);
492 gtk_widget_hide (assistant->forward);
493 gtk_widget_hide (assistant->apply);
494 gtk_widget_hide (assistant->last);
496 case GTK_ASSISTANT_PAGE_PROGRESS:
497 gtk_widget_set_sensitive (assistant->cancel, priv->current_page->complete);
498 gtk_widget_set_sensitive (assistant->back, priv->current_page->complete);
499 gtk_widget_set_sensitive (assistant->forward, priv->current_page->complete);
500 gtk_widget_show (assistant->cancel);
501 gtk_widget_show (assistant->back);
502 gtk_widget_show (assistant->forward);
503 gtk_widget_hide (assistant->apply);
504 gtk_widget_hide (assistant->close);
505 gtk_widget_hide (assistant->last);
508 g_assert_not_reached ();
511 /* this is quite general, we don't want to
512 * go back if it's the first page */
513 if (!priv->visited_pages)
514 gtk_widget_hide (assistant->back);
518 _set_current_page (GtkAssistant *assistant,
519 GtkAssistantPage *page)
521 GtkAssistantPrivate *priv = assistant->priv;
522 GtkAssistantPage *old_page;
524 if (priv->current_page &&
525 GTK_WIDGET_DRAWABLE (priv->current_page->page))
526 old_page = priv->current_page;
530 priv->current_page = page;
532 _set_assistant_buttons_state (assistant);
533 _set_assistant_header_image (assistant);
534 _set_assistant_sidebar_image (assistant);
536 g_signal_emit (assistant, signals [PREPARE], 0, priv->current_page->page);
538 if (GTK_WIDGET_VISIBLE (priv->current_page->page) && GTK_WIDGET_MAPPED (assistant))
540 gtk_widget_map (priv->current_page->page);
541 gtk_widget_map (priv->current_page->title);
544 if (old_page && GTK_WIDGET_MAPPED (old_page->page))
546 gtk_widget_unmap (old_page->page);
547 gtk_widget_unmap (old_page->title);
550 gtk_widget_queue_resize (GTK_WIDGET (assistant));
554 compute_next_step (GtkAssistant *assistant)
556 GtkAssistantPrivate *priv = assistant->priv;
557 GtkAssistantPage *page_info;
558 gint current_page, n_pages, next_page;
560 current_page = gtk_assistant_get_current_page (assistant);
561 page_info = priv->current_page;
562 n_pages = gtk_assistant_get_n_pages (assistant);
564 next_page = (priv->forward_function) (current_page,
565 priv->forward_function_data);
567 if (next_page >= 0 && next_page < n_pages)
569 priv->visited_pages = g_slist_prepend (priv->visited_pages, page_info);
570 _set_current_page (assistant, g_list_nth_data (priv->pages, next_page));
579 on_assistant_close (GtkWidget *widget, GtkAssistant *assistant)
581 g_signal_emit (assistant, signals [CLOSE], 0, NULL);
585 on_assistant_apply (GtkWidget *widget, GtkAssistant *assistant)
587 GtkAssistantPrivate *priv = assistant->priv;
590 success = compute_next_step (assistant);
592 g_signal_emit (assistant, signals [APPLY], 0, priv->current_page->page);
594 /* if the assistant hasn't switched to another page, just emit
595 * the CLOSE signal, it't the last page in the assistant flow
598 g_signal_emit (assistant, signals [CLOSE], 0, priv->current_page->page);
602 on_assistant_forward (GtkWidget *widget, GtkAssistant *assistant)
604 if (!compute_next_step (assistant))
605 g_critical ("Page flow is broken, you may want to end it with a page of "
606 "type GTK_ASSISTANT_PAGE_CONFIRM or GTK_ASSISTANT_PAGE_SUMMARY");
610 on_assistant_back (GtkWidget *widget, GtkAssistant *assistant)
612 GtkAssistantPrivate *priv = assistant->priv;
613 GtkAssistantPage *page_info;
616 /* skip the progress pages when going back */
619 page_node = priv->visited_pages;
621 g_return_if_fail (page_node != NULL);
623 priv->visited_pages = priv->visited_pages->next;
624 page_info = (GtkAssistantPage *) page_node->data;
625 g_slist_free_1 (page_node);
627 while (page_info->type == GTK_ASSISTANT_PAGE_PROGRESS ||
628 !GTK_WIDGET_VISIBLE (page_info->page));
630 _set_current_page (assistant, page_info);
634 on_assistant_cancel (GtkWidget *widget, GtkAssistant *assistant)
636 g_signal_emit (assistant, signals [CANCEL], 0, NULL);
640 on_assistant_last (GtkWidget *widget, GtkAssistant *assistant)
642 GtkAssistantPrivate *priv = assistant->priv;
644 while (priv->current_page->type == GTK_ASSISTANT_PAGE_CONTENT &&
645 priv->current_page->complete)
646 compute_next_step (assistant);
650 alternative_button_order (GtkAssistant *assistant)
652 GtkSettings *settings;
656 screen = gtk_widget_get_screen (GTK_WIDGET (assistant));
657 settings = gtk_settings_get_for_screen (screen);
659 g_object_get (settings,
660 "gtk-alternative-button-order", &result,
666 gtk_assistant_init (GtkAssistant *assistant)
668 GtkAssistantPrivate *priv;
670 priv = assistant->priv = GTK_ASSISTANT_GET_PRIVATE (assistant);
672 gtk_widget_push_composite_child ();
675 priv->header_image = gtk_image_new ();
676 gtk_misc_set_alignment (GTK_MISC (priv->header_image), 1., 0.5);
677 gtk_widget_set_parent (priv->header_image, GTK_WIDGET (assistant));
678 gtk_widget_show (priv->header_image);
681 priv->sidebar_image = gtk_image_new ();
682 gtk_misc_set_alignment (GTK_MISC (priv->sidebar_image), 0., 0.);
683 gtk_widget_set_parent (priv->sidebar_image, GTK_WIDGET (assistant));
684 gtk_widget_show (priv->sidebar_image);
687 priv->action_area = gtk_hbox_new (FALSE, 6);
688 gtk_container_set_border_width (GTK_CONTAINER (priv->action_area), 12);
690 assistant->close = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
691 assistant->apply = gtk_button_new_from_stock (GTK_STOCK_APPLY);
692 assistant->forward = gtk_button_new_from_stock (GTK_STOCK_GO_FORWARD);
693 assistant->back = gtk_button_new_from_stock (GTK_STOCK_GO_BACK);
694 assistant->cancel = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
695 assistant->last = gtk_button_new_from_stock (GTK_STOCK_GOTO_LAST);
697 priv->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
698 gtk_size_group_add_widget (priv->size_group, assistant->close);
699 gtk_size_group_add_widget (priv->size_group, assistant->apply);
700 gtk_size_group_add_widget (priv->size_group, assistant->forward);
701 gtk_size_group_add_widget (priv->size_group, assistant->back);
702 gtk_size_group_add_widget (priv->size_group, assistant->cancel);
703 gtk_size_group_add_widget (priv->size_group, assistant->last);
705 if (!alternative_button_order (assistant))
707 gtk_box_pack_end (GTK_BOX (priv->action_area), assistant->apply, FALSE, FALSE, 0);
708 gtk_box_pack_end (GTK_BOX (priv->action_area), assistant->last, FALSE, FALSE, 0);
709 gtk_box_pack_end (GTK_BOX (priv->action_area), assistant->forward, FALSE, FALSE, 0);
710 gtk_box_pack_end (GTK_BOX (priv->action_area), assistant->back, FALSE, FALSE, 0);
711 gtk_box_pack_end (GTK_BOX (priv->action_area), assistant->cancel, FALSE, FALSE, 0);
712 gtk_box_pack_end (GTK_BOX (priv->action_area), assistant->close, FALSE, FALSE, 0);
716 gtk_box_pack_end (GTK_BOX (priv->action_area), assistant->close, FALSE, FALSE, 0);
717 gtk_box_pack_end (GTK_BOX (priv->action_area), assistant->cancel, FALSE, FALSE, 0);
718 gtk_box_pack_end (GTK_BOX (priv->action_area), assistant->back, FALSE, FALSE, 0);
719 gtk_box_pack_end (GTK_BOX (priv->action_area), assistant->forward, FALSE, FALSE, 0);
720 gtk_box_pack_end (GTK_BOX (priv->action_area), assistant->last, FALSE, FALSE, 0);
721 gtk_box_pack_end (GTK_BOX (priv->action_area), assistant->apply, FALSE, FALSE, 0);
724 gtk_widget_set_parent (priv->action_area, GTK_WIDGET (assistant));
725 gtk_widget_show (assistant->forward);
726 gtk_widget_show (assistant->back);
727 gtk_widget_show (assistant->cancel);
728 gtk_widget_show (priv->action_area);
730 gtk_widget_pop_composite_child ();
733 priv->current_page = NULL;
734 priv->visited_pages = NULL;
736 priv->forward_function = default_forward_function;
737 priv->forward_function_data = assistant;
738 priv->forward_data_destroy = NULL;
740 g_signal_connect (G_OBJECT (assistant->close), "clicked",
741 G_CALLBACK (on_assistant_close), assistant);
742 g_signal_connect (G_OBJECT (assistant->apply), "clicked",
743 G_CALLBACK (on_assistant_apply), assistant);
744 g_signal_connect (G_OBJECT (assistant->forward), "clicked",
745 G_CALLBACK (on_assistant_forward), assistant);
746 g_signal_connect (G_OBJECT (assistant->back), "clicked",
747 G_CALLBACK (on_assistant_back), assistant);
748 g_signal_connect (G_OBJECT (assistant->cancel), "clicked",
749 G_CALLBACK (on_assistant_cancel), assistant);
750 g_signal_connect (G_OBJECT (assistant->last), "clicked",
751 G_CALLBACK (on_assistant_last), assistant);
755 gtk_assistant_set_child_property (GtkContainer *container,
763 case CHILD_PROP_PAGE_TYPE:
764 gtk_assistant_set_page_type (GTK_ASSISTANT (container), child,
765 g_value_get_enum (value));
767 case CHILD_PROP_PAGE_TITLE:
768 gtk_assistant_set_page_title (GTK_ASSISTANT (container), child,
769 g_value_get_string (value));
771 case CHILD_PROP_PAGE_HEADER_IMAGE:
772 gtk_assistant_set_page_header_image (GTK_ASSISTANT (container), child,
773 g_value_get_object (value));
775 case CHILD_PROP_PAGE_SIDEBAR_IMAGE:
776 gtk_assistant_set_page_side_image (GTK_ASSISTANT (container), child,
777 g_value_get_object (value));
779 case CHILD_PROP_PAGE_COMPLETE:
780 gtk_assistant_set_page_complete (GTK_ASSISTANT (container), child,
781 g_value_get_boolean (value));
784 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
790 gtk_assistant_get_child_property (GtkContainer *container,
798 case CHILD_PROP_PAGE_TYPE:
799 g_value_set_enum (value,
800 gtk_assistant_get_page_type (GTK_ASSISTANT (container), child));
802 case CHILD_PROP_PAGE_TITLE:
803 g_value_set_string (value,
804 gtk_assistant_get_page_title (GTK_ASSISTANT (container), child));
806 case CHILD_PROP_PAGE_HEADER_IMAGE:
807 g_value_set_object (value,
808 gtk_assistant_get_page_header_image (GTK_ASSISTANT (container), child));
810 case CHILD_PROP_PAGE_SIDEBAR_IMAGE:
811 g_value_set_object (value,
812 gtk_assistant_get_page_side_image (GTK_ASSISTANT (container), child));
814 case CHILD_PROP_PAGE_COMPLETE:
815 g_value_set_boolean (value,
816 gtk_assistant_get_page_complete (GTK_ASSISTANT (container), child));
819 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
825 remove_page (GtkAssistant *assistant,
828 GtkAssistantPrivate *priv = assistant->priv;
829 GtkAssistantPage *page_info;
831 page_info = element->data;
833 /* If we are mapped and visible, we want to deal with changing the page. */
834 if ((GTK_WIDGET_MAPPED (page_info->page)) && (page_info == priv->current_page))
835 compute_next_step (assistant);
837 priv->pages = g_list_remove_link (priv->pages, element);
839 priv->visited_pages = g_slist_remove_all (priv->visited_pages, page_info);
840 gtk_widget_unparent (page_info->page);
842 if (page_info->header_image)
843 g_object_unref (page_info->header_image);
845 if (page_info->sidebar_image)
846 g_object_unref (page_info->sidebar_image);
848 gtk_widget_destroy (page_info->title);
850 g_list_free_1 (element);
854 gtk_assistant_destroy (GtkObject *object)
856 GtkAssistant *assistant = GTK_ASSISTANT (object);
857 GtkAssistantPrivate *priv = assistant->priv;
859 if (priv->header_image)
861 gtk_widget_destroy (priv->header_image);
862 priv->header_image = NULL;
865 if (priv->sidebar_image)
867 gtk_widget_destroy (priv->sidebar_image);
868 priv->sidebar_image = NULL;
871 if (priv->action_area)
873 gtk_widget_destroy (priv->action_area);
874 priv->action_area = NULL;
877 if (priv->size_group)
879 g_object_unref (priv->size_group);
880 priv->size_group = NULL;
883 if (priv->forward_function)
885 if (priv->forward_function_data &&
886 priv->forward_data_destroy)
887 priv->forward_data_destroy (priv->forward_function_data);
889 priv->forward_function = NULL;
890 priv->forward_function_data = NULL;
891 priv->forward_data_destroy = NULL;
894 if (priv->visited_pages)
896 g_slist_free (priv->visited_pages);
897 priv->visited_pages = NULL;
900 /* We set current to NULL so that the remove code doesn't try
901 * to do anything funny */
902 priv->current_page = NULL;
905 remove_page (GTK_ASSISTANT (object), priv->pages);
907 GTK_OBJECT_CLASS (gtk_assistant_parent_class)->destroy (object);
911 find_page (GtkAssistant *assistant,
914 GtkAssistantPrivate *priv = assistant->priv;
915 GList *child = priv->pages;
919 GtkAssistantPage *page_info = child->data;
920 if (page_info->page == page)
930 set_title_colors (GtkWidget *assistant,
931 GtkWidget *title_label)
935 gtk_widget_ensure_style (assistant);
936 style = gtk_widget_get_style (assistant);
938 /* change colors schema, for making the header text visible */
939 gtk_widget_modify_bg (title_label, GTK_STATE_NORMAL, &style->bg[GTK_STATE_SELECTED]);
940 gtk_widget_modify_fg (title_label, GTK_STATE_NORMAL, &style->fg[GTK_STATE_SELECTED]);
944 set_title_font (GtkWidget *assistant,
945 GtkWidget *title_label)
947 PangoFontDescription *desc;
950 desc = pango_font_description_new ();
951 size = pango_font_description_get_size (assistant->style->font_desc);
953 pango_font_description_set_weight (desc, PANGO_WEIGHT_ULTRABOLD);
954 pango_font_description_set_size (desc, size * PANGO_SCALE_XX_LARGE);
956 gtk_widget_modify_font (title_label, desc);
957 pango_font_description_free (desc);
961 gtk_assistant_style_set (GtkWidget *widget,
964 GtkAssistant *assistant = GTK_ASSISTANT (widget);
965 GtkAssistantPrivate *priv = assistant->priv;
972 GtkAssistantPage *page = list->data;
974 set_title_colors (widget, page->title);
975 set_title_font (widget, page->title);
982 gtk_assistant_size_request (GtkWidget *widget,
983 GtkRequisition *requisition)
985 GtkAssistant *assistant = GTK_ASSISTANT (widget);
986 GtkAssistantPrivate *priv = assistant->priv;
987 GtkRequisition child_requisition;
988 gint header_padding, content_padding;
989 gint width, height, header_width, header_height;
992 gtk_widget_style_get (widget,
993 "header-padding", &header_padding,
994 "content-padding", &content_padding,
997 header_width = header_height = 0;
1002 GtkAssistantPage *page = list->data;
1005 gtk_widget_size_request (page->page, &child_requisition);
1006 width = MAX (width, child_requisition.width);
1007 height = MAX (height, child_requisition.height);
1009 gtk_widget_size_request (page->title, &child_requisition);
1010 w = child_requisition.width;
1011 h = child_requisition.height;
1013 if (page->header_image)
1015 w += gdk_pixbuf_get_width (page->header_image) + HEADER_SPACING;
1016 h = MAX (h, gdk_pixbuf_get_height (page->header_image));
1019 header_width = MAX (header_width, w);
1020 header_height = MAX (header_height, h);
1025 gtk_widget_size_request (priv->sidebar_image, &child_requisition);
1026 width += child_requisition.width;
1027 height = MAX (height, child_requisition.height);
1029 gtk_widget_set_size_request (priv->header_image, header_width, header_height);
1030 gtk_widget_size_request (priv->header_image, &child_requisition);
1031 width = MAX (width, header_width) + 2 * header_padding;
1032 height += header_height + 2 * header_padding;
1034 gtk_widget_size_request (priv->action_area, &child_requisition);
1035 width = MAX (width, child_requisition.width);
1036 height += child_requisition.height;
1038 width += GTK_CONTAINER (widget)->border_width * 2 + content_padding * 2;
1039 height += GTK_CONTAINER (widget)->border_width * 2 + content_padding * 2;
1041 requisition->width = width;
1042 requisition->height = height;
1046 gtk_assistant_size_allocate (GtkWidget *widget,
1047 GtkAllocation *allocation)
1049 GtkAssistant *assistant = GTK_ASSISTANT (widget);
1050 GtkAssistantPrivate *priv = assistant->priv;
1051 GtkRequisition header_requisition;
1052 GtkAllocation child_allocation, header_allocation;
1053 gint header_padding, content_padding;
1057 rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
1058 pages = priv->pages;
1060 gtk_widget_style_get (widget,
1061 "header-padding", &header_padding,
1062 "content-padding", &content_padding,
1065 widget->allocation = *allocation;
1068 gtk_widget_get_child_requisition (priv->header_image, &header_requisition);
1070 header_allocation.x = allocation->x + GTK_CONTAINER (widget)->border_width + header_padding;
1071 header_allocation.y = allocation->y + GTK_CONTAINER (widget)->border_width + header_padding;
1072 header_allocation.width = allocation->width - 2 * GTK_CONTAINER (widget)->border_width - 2 * header_padding;
1073 header_allocation.height = header_requisition.height;
1075 gtk_widget_size_allocate (priv->header_image, &header_allocation);
1078 child_allocation.x = allocation->x + GTK_CONTAINER (widget)->border_width;
1079 child_allocation.y = allocation->y + allocation->height -
1080 GTK_CONTAINER (widget)->border_width - priv->action_area->requisition.height;
1081 child_allocation.width = allocation->width - 2 * GTK_CONTAINER (widget)->border_width;
1082 child_allocation.height = priv->action_area->requisition.height;
1084 gtk_widget_size_allocate (priv->action_area, &child_allocation);
1088 child_allocation.x = allocation->x + allocation->width -
1089 GTK_CONTAINER (widget)->border_width - priv->sidebar_image->requisition.width;
1091 child_allocation.x = allocation->x + GTK_CONTAINER (widget)->border_width;
1093 child_allocation.y = allocation->y + GTK_CONTAINER (widget)->border_width +
1094 priv->header_image->allocation.height + 2 * header_padding;
1095 child_allocation.width = priv->sidebar_image->requisition.width;
1096 child_allocation.height = allocation->height - 2 * GTK_CONTAINER (widget)->border_width -
1097 priv->header_image->allocation.height - 2 * header_padding - priv->action_area->allocation.height;
1099 gtk_widget_size_allocate (priv->sidebar_image, &child_allocation);
1102 child_allocation.x = allocation->x + GTK_CONTAINER (widget)->border_width + content_padding;
1103 child_allocation.y = allocation->y + GTK_CONTAINER (widget)->border_width +
1104 priv->header_image->allocation.height + 2 * header_padding + content_padding;
1105 child_allocation.width = allocation->width - 2 * GTK_CONTAINER (widget)->border_width - 2 * content_padding;
1106 child_allocation.height = allocation->height - 2 * GTK_CONTAINER (widget)->border_width -
1107 priv->header_image->allocation.height - 2 * header_padding - priv->action_area->allocation.height - 2 * content_padding;
1109 if (GTK_WIDGET_VISIBLE (priv->sidebar_image))
1112 child_allocation.x += priv->sidebar_image->allocation.width;
1114 child_allocation.width -= priv->sidebar_image->allocation.width;
1119 GtkAssistantPage *page = pages->data;
1121 gtk_widget_size_allocate (page->page, &child_allocation);
1122 gtk_widget_size_allocate (page->title, &header_allocation);
1123 pages = pages->next;
1128 gtk_assistant_map (GtkWidget *widget)
1130 GtkAssistant *assistant = GTK_ASSISTANT (widget);
1131 GtkAssistantPrivate *priv = assistant->priv;
1134 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
1136 gtk_widget_map (priv->header_image);
1137 gtk_widget_map (priv->action_area);
1139 if (GTK_WIDGET_VISIBLE (priv->sidebar_image) &&
1140 !GTK_WIDGET_MAPPED (priv->sidebar_image))
1141 gtk_widget_map (priv->sidebar_image);
1143 /* if there's no default page, pick the first one */
1144 if (!priv->current_page && priv->pages)
1146 page_node = priv->pages;
1148 while (page_node && !GTK_WIDGET_VISIBLE (((GtkAssistantPage *) page_node->data)->page))
1149 page_node = page_node->next;
1152 priv->current_page = page_node->data;
1155 if (priv->current_page &&
1156 GTK_WIDGET_VISIBLE (priv->current_page->page) &&
1157 !GTK_WIDGET_MAPPED (priv->current_page->page))
1159 _set_assistant_buttons_state ((GtkAssistant *) widget);
1160 _set_assistant_header_image ((GtkAssistant*) widget);
1161 _set_assistant_sidebar_image ((GtkAssistant*) widget);
1163 g_signal_emit (widget, signals [PREPARE], 0, priv->current_page->page);
1164 gtk_widget_map (priv->current_page->page);
1165 gtk_widget_map (priv->current_page->title);
1168 GTK_WIDGET_CLASS (gtk_assistant_parent_class)->map (widget);
1172 gtk_assistant_unmap (GtkWidget *widget)
1174 GtkAssistant *assistant = GTK_ASSISTANT (widget);
1175 GtkAssistantPrivate *priv = assistant->priv;
1177 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
1179 gtk_widget_unmap (priv->header_image);
1180 gtk_widget_unmap (priv->action_area);
1182 if (GTK_WIDGET_DRAWABLE (priv->sidebar_image))
1183 gtk_widget_unmap (priv->sidebar_image);
1185 if (priv->current_page &&
1186 GTK_WIDGET_DRAWABLE (priv->current_page->page))
1187 gtk_widget_unmap (priv->current_page->page);
1189 g_slist_free (priv->visited_pages);
1190 priv->visited_pages = NULL;
1191 priv->current_page = NULL;
1193 GTK_WIDGET_CLASS (gtk_assistant_parent_class)->unmap (widget);
1197 gtk_assistant_delete_event (GtkWidget *widget,
1200 GtkAssistant *assistant = GTK_ASSISTANT (widget);
1201 GtkAssistantPrivate *priv = assistant->priv;
1203 /* Do not allow cancelling in the middle of a progress page */
1204 if (priv->current_page &&
1205 (priv->current_page->type != GTK_ASSISTANT_PAGE_PROGRESS ||
1206 priv->current_page->complete))
1207 g_signal_emit (widget, signals [CANCEL], 0, NULL);
1213 assistant_paint_colored_box (GtkWidget *widget)
1215 GtkAssistant *assistant = GTK_ASSISTANT (widget);
1216 GtkAssistantPrivate *priv = assistant->priv;
1217 gint header_padding, content_padding;
1219 gint content_x, content_width;
1222 cr = gdk_cairo_create (widget->window);
1223 rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
1225 gtk_widget_style_get (widget,
1226 "header-padding", &header_padding,
1227 "content-padding", &content_padding,
1231 gdk_cairo_set_source_color (cr, &widget->style->bg[GTK_STATE_SELECTED]);
1232 cairo_rectangle (cr,
1234 widget->allocation.width,
1235 widget->allocation.height - priv->action_area->allocation.height);
1239 content_x = content_padding;
1240 content_width = widget->allocation.width - 2 * content_padding;
1242 if (GTK_WIDGET_VISIBLE (priv->sidebar_image))
1245 content_x += priv->sidebar_image->allocation.width;
1246 content_width -= priv->sidebar_image->allocation.width;
1249 gdk_cairo_set_source_color (cr, &widget->style->bg[GTK_STATE_NORMAL]);
1251 cairo_rectangle (cr,
1253 priv->header_image->allocation.height + content_padding + 2 * header_padding,
1255 widget->allocation.height - priv->action_area->allocation.height -
1256 priv->header_image->allocation.height - 2 * content_padding - 2 * header_padding);
1263 gtk_assistant_expose (GtkWidget *widget,
1264 GdkEventExpose *event)
1266 GtkAssistant *assistant = GTK_ASSISTANT (widget);
1267 GtkAssistantPrivate *priv = assistant->priv;
1268 GtkContainer *container;
1270 if (GTK_WIDGET_DRAWABLE (widget))
1272 container = GTK_CONTAINER (widget);
1274 assistant_paint_colored_box (widget);
1276 gtk_container_propagate_expose (container, priv->header_image, event);
1277 gtk_container_propagate_expose (container, priv->sidebar_image, event);
1278 gtk_container_propagate_expose (container, priv->action_area, event);
1280 if (priv->current_page)
1282 gtk_container_propagate_expose (container, priv->current_page->page, event);
1283 gtk_container_propagate_expose (container, priv->current_page->title, event);
1291 gtk_assistant_focus (GtkWidget *widget,
1292 GtkDirectionType direction)
1294 GtkAssistantPrivate *priv;
1295 GtkContainer *container;
1297 container = GTK_CONTAINER (widget);
1298 priv = GTK_ASSISTANT (widget)->priv;
1300 /* we only have to care about 2 widgets, action area and the current page */
1301 if (container->focus_child == priv->action_area)
1303 if (!gtk_widget_child_focus (priv->action_area, direction) &&
1304 !gtk_widget_child_focus (priv->current_page->page, direction))
1306 /* if we're leaving the action area and the current page hasn't
1307 any focusable widget, clear focus and go back to the action area */
1308 gtk_container_set_focus_child (GTK_CONTAINER (priv->action_area), NULL);
1309 gtk_widget_child_focus (priv->action_area, direction);
1314 if (!gtk_widget_child_focus (priv->current_page->page, direction) &&
1315 !gtk_widget_child_focus (priv->action_area, direction))
1317 /* if we're leaving the current page and there isn't nothing focusable
1318 in the action area, try to clear focus and go back to the page */
1319 gtk_window_set_focus (GTK_WINDOW (widget), NULL);
1320 gtk_widget_child_focus (priv->current_page->page, direction);
1328 gtk_assistant_add (GtkContainer *container,
1331 g_return_if_fail (GTK_IS_WIDGET (page));
1333 gtk_assistant_append_page (GTK_ASSISTANT (container), page);
1337 gtk_assistant_remove (GtkContainer *container,
1340 GtkAssistant *assistant;
1343 assistant = (GtkAssistant*) container;
1345 element = find_page (assistant, page);
1349 remove_page (assistant, element);
1350 gtk_widget_queue_resize ((GtkWidget *) container);
1355 gtk_assistant_forall (GtkContainer *container,
1356 gboolean include_internals,
1357 GtkCallback callback,
1358 gpointer callback_data)
1360 GtkAssistant *assistant = (GtkAssistant*) container;
1361 GtkAssistantPrivate *priv = assistant->priv;
1364 if (include_internals)
1366 (*callback) (priv->header_image, callback_data);
1367 (*callback) (priv->sidebar_image, callback_data);
1368 (*callback) (priv->action_area, callback_data);
1371 pages = priv->pages;
1375 GtkAssistantPage *page = (GtkAssistantPage *) pages->data;
1377 (*callback) (page->page, callback_data);
1379 if (include_internals)
1380 (*callback) (page->title, callback_data);
1382 pages = pages->next;
1387 * gtk_assistant_new:
1389 * Creates a new #GtkAssistant.
1391 * Return value: a newly created #GtkAssistant
1396 gtk_assistant_new (void)
1398 GtkWidget *assistant;
1400 assistant = g_object_new (GTK_TYPE_ASSISTANT, NULL);
1406 * gtk_assistant_get_current_page:
1407 * @assistant: a #GtkAssistant
1409 * Returns the page number of the current page
1411 * Return value: The index (starting from 0) of the current page in
1412 * the @assistant, if the @assistant has no pages, -1 will be returned
1417 gtk_assistant_get_current_page (GtkAssistant *assistant)
1419 GtkAssistantPrivate *priv;
1421 g_return_val_if_fail (GTK_IS_ASSISTANT (assistant), -1);
1423 priv = assistant->priv;
1425 if (!priv->pages || !priv->current_page)
1428 return g_list_index (priv->pages, priv->current_page);
1432 * gtk_assistant_set_current_page:
1433 * @assistant: a #GtkAssistant
1434 * @page_num: index of the page to switch to, starting from 0.
1435 * If negative, the last page will be used. If greater
1436 * than the number of pages in the @assistant, nothing
1439 * Switches the page to @page_num. Note that this will only be necessary
1440 * in custom buttons, as the @assistant flow can be set with
1441 * gtk_assistant_set_forward_page_func().
1446 gtk_assistant_set_current_page (GtkAssistant *assistant,
1449 GtkAssistantPrivate *priv;
1450 GtkAssistantPage *page;
1452 g_return_if_fail (GTK_IS_ASSISTANT (assistant));
1454 priv = assistant->priv;
1457 page = (GtkAssistantPage *) g_list_nth_data (priv->pages, page_num);
1459 page = (GtkAssistantPage *) g_list_last (priv->pages);
1461 g_return_if_fail (page != NULL);
1463 if (priv->current_page == page)
1466 /* only add the page to the visited list if the
1467 * assistant is mapped, if not, just use it as an
1468 * initial page setting, for the cases where the
1469 * initial page is != to 0
1471 if (GTK_WIDGET_MAPPED (assistant))
1472 priv->visited_pages = g_slist_prepend (priv->visited_pages, page);
1474 _set_current_page (assistant, page);
1478 * gtk_assistant_get_n_pages:
1479 * @assistant: a #GtkAssistant
1481 * Returns the number of pages in the @assistant
1483 * Return value: The number of pages in the @assistant.
1488 gtk_assistant_get_n_pages (GtkAssistant *assistant)
1490 GtkAssistantPrivate *priv;
1492 g_return_val_if_fail (GTK_IS_ASSISTANT (assistant), 0);
1494 priv = assistant->priv;
1496 return g_list_length (priv->pages);
1500 * gtk_assistant_get_nth_page:
1501 * @assistant: a #GtkAssistant
1502 * @page_num: The index of a page in the @assistant, or -1 to get the last page;
1504 * Returns the child widget contained in page number @page_num.
1506 * Return value: The child widget, or %NULL if @page_num is out of bounds.
1511 gtk_assistant_get_nth_page (GtkAssistant *assistant,
1514 GtkAssistantPrivate *priv;
1515 GtkAssistantPage *page;
1518 g_return_val_if_fail (GTK_IS_ASSISTANT (assistant), NULL);
1520 priv = assistant->priv;
1522 elem = g_list_nth (priv->pages, page_num);
1527 page = (GtkAssistantPage *) elem->data;
1533 * gtk_assistant_prepend_page:
1534 * @assistant: a #GtkAssistant
1535 * @page: a #GtkWidget
1537 * Prepends a page to the @assistant.
1539 * Return value: the index (starting at 0) of the inserted page
1544 gtk_assistant_prepend_page (GtkAssistant *assistant,
1547 g_return_val_if_fail (GTK_IS_ASSISTANT (assistant), 0);
1548 g_return_val_if_fail (GTK_IS_WIDGET (page), 0);
1550 return gtk_assistant_insert_page (assistant, page, 0);
1554 * gtk_assistant_append_page:
1555 * @assistant: a #GtkAssistant
1556 * @page: a #GtkWidget
1558 * Appends a page to the @assistant.
1560 * Return value: the index (starting at 0) of the inserted page
1565 gtk_assistant_append_page (GtkAssistant *assistant,
1568 g_return_val_if_fail (GTK_IS_ASSISTANT (assistant), 0);
1569 g_return_val_if_fail (GTK_IS_WIDGET (page), 0);
1571 return gtk_assistant_insert_page (assistant, page, -1);
1575 * gtk_assistant_insert_page:
1576 * @assistant: a #GtkAssistant
1577 * @page: a #GtkWidget
1578 * @position: the index (starting at 0) at which to insert the page,
1579 * or -1 to append the page to the @assistant
1581 * Inserts a page in the @assistant at a given position.
1583 * Return value: the index (starting from 0) of the inserted page
1588 gtk_assistant_insert_page (GtkAssistant *assistant,
1592 GtkAssistantPrivate *priv;
1593 GtkAssistantPage *page_info;
1596 g_return_val_if_fail (GTK_IS_ASSISTANT (assistant), 0);
1597 g_return_val_if_fail (GTK_IS_WIDGET (page), 0);
1598 g_return_val_if_fail (page->parent == NULL, 0);
1599 g_return_val_if_fail (!GTK_WIDGET_TOPLEVEL (page), 0);
1601 priv = assistant->priv;
1603 page_info = g_new0 (GtkAssistantPage, 1);
1604 page_info->page = page;
1605 page_info->title = gtk_label_new (NULL);
1607 gtk_misc_set_alignment (GTK_MISC (page_info->title), 0.,0.5);
1608 set_title_colors (GTK_WIDGET (assistant), page_info->title);
1609 set_title_font (GTK_WIDGET (assistant), page_info->title);
1610 gtk_widget_show (page_info->title);
1612 n_pages = g_list_length (priv->pages);
1614 if (position < 0 || position > n_pages)
1617 priv->pages = g_list_insert (priv->pages, page_info, position);
1619 gtk_widget_set_parent (page_info->page, GTK_WIDGET (assistant));
1620 gtk_widget_set_parent (page_info->title, GTK_WIDGET (assistant));
1622 if (GTK_WIDGET_REALIZED (GTK_WIDGET (assistant)))
1624 gtk_widget_realize (page_info->page);
1625 gtk_widget_realize (page_info->title);
1628 gtk_widget_queue_resize (GTK_WIDGET (assistant));
1634 * gtk_assistant_set_forward_page_func:
1635 * @assistant: a #GtkAssistant
1636 * @page_func: the #GtkAssistantPageFunc, or %NULL to use the default one
1637 * @data: user data for @page_func
1638 * @destroy: destroy notifier for @data
1640 * Sets the page forwarding function to be @page_func, this function will
1641 * be used to determine what will be the next page when the user presses
1642 * the forward button. Setting @page_func to %NULL will make the assistant
1643 * to use the default forward function, which just goes to the next visible
1649 gtk_assistant_set_forward_page_func (GtkAssistant *assistant,
1650 GtkAssistantPageFunc page_func,
1652 GDestroyNotify destroy)
1654 GtkAssistantPrivate *priv;
1656 g_return_if_fail (GTK_IS_ASSISTANT (assistant));
1658 priv = assistant->priv;
1660 if (priv->forward_data_destroy &&
1661 priv->forward_function_data)
1662 (*priv->forward_data_destroy) (priv->forward_function_data);
1666 priv->forward_function = page_func;
1667 priv->forward_function_data = data;
1668 priv->forward_data_destroy = destroy;
1672 priv->forward_function = default_forward_function;
1673 priv->forward_function_data = assistant;
1674 priv->forward_data_destroy = NULL;
1677 /* Page flow has possibly changed, so the
1678 buttons state might need to change too */
1679 if (priv->current_page)
1680 _set_assistant_buttons_state (assistant);
1684 * gtk_assistant_add_action_widget:
1685 * @assistant: a #GtkAssistant
1686 * @child: a #GtkWidget
1688 * Adds a widget to the action area of a #GtkAssistant.
1693 gtk_assistant_add_action_widget (GtkAssistant *assistant,
1696 GtkAssistantPrivate *priv;
1698 g_return_if_fail (GTK_IS_ASSISTANT (assistant));
1699 g_return_if_fail (GTK_IS_WIDGET (child));
1701 priv = assistant->priv;
1703 if (GTK_IS_BUTTON (child))
1704 gtk_size_group_add_widget (priv->size_group, child);
1706 gtk_box_pack_end (GTK_BOX (priv->action_area), child, FALSE, FALSE, 0);
1710 * gtk_assistant_remove_action_widget:
1711 * @assistant: a #GtkAssistant
1712 * @child: a #GtkWidget
1714 * Removes a widget from the action area of a #GtkAssistant.
1719 gtk_assistant_remove_action_widget (GtkAssistant *assistant,
1722 GtkAssistantPrivate *priv;
1724 g_return_if_fail (GTK_IS_ASSISTANT (assistant));
1725 g_return_if_fail (GTK_IS_WIDGET (child));
1727 priv = assistant->priv;
1729 if (GTK_IS_BUTTON (child))
1730 gtk_size_group_remove_widget (priv->size_group, child);
1732 gtk_container_remove (GTK_CONTAINER (priv->action_area), child);
1736 * gtk_assistant_set_page_title:
1737 * @assistant: a #GtkAssistant
1738 * @page: a page of @assitant
1739 * @title: the new title for @page
1741 * Sets a title for @page. The title is displayed in the header
1742 * area of the assistant when @page is the current page.
1747 gtk_assistant_set_page_title (GtkAssistant *assistant,
1751 GtkAssistantPrivate *priv;
1752 GtkAssistantPage *page_info;
1755 g_return_if_fail (GTK_IS_ASSISTANT (assistant));
1756 g_return_if_fail (GTK_IS_WIDGET (page));
1758 priv = assistant->priv;
1759 child = find_page (assistant, page);
1761 g_return_if_fail (child != NULL);
1763 page_info = (GtkAssistantPage*) child->data;
1765 gtk_label_set_text ((GtkLabel*) page_info->title, title);
1766 gtk_widget_queue_resize (GTK_WIDGET (assistant));
1767 gtk_widget_child_notify (page, "title");
1771 * gtk_assistant_get_page_title:
1772 * @assistant: a #GtkAssistant
1773 * @page: a page of @assistant
1775 * Gets the title for @page.
1777 * Return value: the title for @page.
1781 G_CONST_RETURN gchar*
1782 gtk_assistant_get_page_title (GtkAssistant *assistant,
1785 GtkAssistantPrivate *priv;
1786 GtkAssistantPage *page_info;
1789 g_return_val_if_fail (GTK_IS_ASSISTANT (assistant), NULL);
1790 g_return_val_if_fail (GTK_IS_WIDGET (page), NULL);
1792 priv = assistant->priv;
1793 child = find_page (assistant, page);
1795 g_return_val_if_fail (child != NULL, NULL);
1797 page_info = (GtkAssistantPage*) child->data;
1799 return gtk_label_get_text ((GtkLabel*) page_info->title);
1803 * gtk_assistant_set_page_type:
1804 * @assistant: a #GtkAssistant
1805 * @page: a page of @assitant
1806 * @type: the new type for @page
1808 * Sets the page type for @page. The page type determines the page
1809 * behavior in the @assistant.
1814 gtk_assistant_set_page_type (GtkAssistant *assistant,
1816 GtkAssistantPageType type)
1818 GtkAssistantPrivate *priv;
1819 GtkAssistantPage *page_info;
1822 g_return_if_fail (GTK_IS_ASSISTANT (assistant));
1823 g_return_if_fail (GTK_IS_WIDGET (page));
1825 priv = assistant->priv;
1826 child = find_page (assistant, page);
1828 g_return_if_fail (child != NULL);
1830 page_info = (GtkAssistantPage*) child->data;
1832 if (type != page_info->type)
1834 page_info->type = type;
1836 /* Always set buttons state, a change in a future page
1837 might change current page buttons */
1838 if (priv->current_page)
1839 _set_assistant_buttons_state (assistant);
1841 gtk_widget_child_notify (page, "page-type");
1846 * gtk_assistant_get_page_type:
1847 * @assistant: a #GtkAssistant
1848 * @page: a page of @assistant
1850 * Gets the page type of @page.
1852 * Return value: the page type of @page.
1856 GtkAssistantPageType
1857 gtk_assistant_get_page_type (GtkAssistant *assistant,
1860 GtkAssistantPrivate *priv;
1861 GtkAssistantPage *page_info;
1864 g_return_val_if_fail (GTK_IS_ASSISTANT (assistant), GTK_ASSISTANT_PAGE_CONTENT);
1865 g_return_val_if_fail (GTK_IS_WIDGET (page), GTK_ASSISTANT_PAGE_CONTENT);
1867 priv = assistant->priv;
1868 child = find_page (assistant, page);
1870 g_return_val_if_fail (child != NULL, GTK_ASSISTANT_PAGE_CONTENT);
1872 page_info = (GtkAssistantPage*) child->data;
1874 return page_info->type;
1878 * gtk_assistant_set_page_header_image:
1879 * @assistant: a #GtkAssistant
1880 * @page: a page of @assitant
1881 * @pixbuf: the new header image @page
1883 * Sets a header image for @page. This image is displayed in the header
1884 * area of the assistant when @page is the current page.
1889 gtk_assistant_set_page_header_image (GtkAssistant *assistant,
1893 GtkAssistantPrivate *priv;
1894 GtkAssistantPage *page_info;
1897 g_return_if_fail (GTK_IS_ASSISTANT (assistant));
1898 g_return_if_fail (GTK_IS_WIDGET (page));
1899 g_return_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf));
1901 priv = assistant->priv;
1902 child = find_page (assistant, page);
1904 g_return_if_fail (child != NULL);
1906 page_info = (GtkAssistantPage*) child->data;
1908 if (pixbuf != page_info->header_image)
1910 if (page_info->header_image)
1912 g_object_unref (page_info->header_image);
1913 page_info->header_image = NULL;
1917 page_info->header_image = g_object_ref (pixbuf);
1919 if (page_info == priv->current_page)
1920 _set_assistant_header_image (assistant);
1922 gtk_widget_child_notify (page, "header-image");
1927 * gtk_assistant_get_page_header_image:
1928 * @assistant: a #GtkAssistant
1929 * @page: a page of @assistant
1931 * Gets the header image for @page.
1933 * Return value: the header image for @page, or %NULL
1934 * if there's no header image for the page.
1939 gtk_assistant_get_page_header_image (GtkAssistant *assistant,
1942 GtkAssistantPrivate *priv;
1943 GtkAssistantPage *page_info;
1946 g_return_val_if_fail (GTK_IS_ASSISTANT (assistant), NULL);
1947 g_return_val_if_fail (GTK_IS_WIDGET (page), NULL);
1949 priv = assistant->priv;
1950 child = find_page (assistant, page);
1952 g_return_val_if_fail (child != NULL, NULL);
1954 page_info = (GtkAssistantPage*) child->data;
1956 return page_info->header_image;
1960 * gtk_assistant_set_page_side_image:
1961 * @assistant: a #GtkAssistant
1962 * @page: a page of @assitant
1963 * @pixbuf: the new header image @page
1965 * Sets a header image for @page. This image is displayed in the side
1966 * area of the assistant when @page is the current page.
1971 gtk_assistant_set_page_side_image (GtkAssistant *assistant,
1975 GtkAssistantPrivate *priv;
1976 GtkAssistantPage *page_info;
1979 g_return_if_fail (GTK_IS_ASSISTANT (assistant));
1980 g_return_if_fail (GTK_IS_WIDGET (page));
1981 g_return_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf));
1983 priv = assistant->priv;
1984 child = find_page (assistant, page);
1986 g_return_if_fail (child != NULL);
1988 page_info = (GtkAssistantPage*) child->data;
1990 if (pixbuf != page_info->sidebar_image)
1992 if (page_info->sidebar_image)
1994 g_object_unref (page_info->sidebar_image);
1995 page_info->sidebar_image = NULL;
1999 page_info->sidebar_image = g_object_ref (pixbuf);
2001 if (page_info == priv->current_page)
2002 _set_assistant_sidebar_image (assistant);
2004 gtk_widget_child_notify (page, "sidebar-image");
2009 * gtk_assistant_get_page_side_image:
2010 * @assistant: a #GtkAssistant
2011 * @page: a page of @assistant
2013 * Gets the header image for @page.
2015 * Return value: the side image for @page, or %NULL
2016 * if there's no side image for the page.
2021 gtk_assistant_get_page_side_image (GtkAssistant *assistant,
2024 GtkAssistantPrivate *priv;
2025 GtkAssistantPage *page_info;
2028 g_return_val_if_fail (GTK_IS_ASSISTANT (assistant), NULL);
2029 g_return_val_if_fail (GTK_IS_WIDGET (page), NULL);
2031 priv = assistant->priv;
2032 child = find_page (assistant, page);
2034 g_return_val_if_fail (child != NULL, NULL);
2036 page_info = (GtkAssistantPage*) child->data;
2038 return page_info->sidebar_image;
2042 * gtk_assistant_set_page_complete:
2043 * @assistant: a #GtkAssistant
2044 * @page: a page of @assitant
2045 * @complete: the completeness status of the page
2047 * Sets whether @page contents are complete. This will make
2048 * @assistant update the buttons state to be able to continue the task.
2053 gtk_assistant_set_page_complete (GtkAssistant *assistant,
2057 GtkAssistantPrivate *priv;
2058 GtkAssistantPage *page_info;
2061 g_return_if_fail (GTK_IS_ASSISTANT (assistant));
2062 g_return_if_fail (GTK_IS_WIDGET (page));
2064 priv = assistant->priv;
2065 child = find_page (assistant, page);
2067 g_return_if_fail (child != NULL);
2069 page_info = (GtkAssistantPage*) child->data;
2071 if (complete != page_info->complete)
2073 page_info->complete = complete;
2075 /* Always set buttons state, a change in a future page
2076 might change current page buttons */
2077 if (priv->current_page)
2078 _set_assistant_buttons_state (assistant);
2080 gtk_widget_child_notify (page, "complete");
2085 * gtk_assistant_get_page_complete:
2086 * @assistant: a #GtkAssistant
2087 * @page: a page of @assistant
2089 * Gets whether @page is complete..
2091 * Return value: %TRUE if @page is complete.
2096 gtk_assistant_get_page_complete (GtkAssistant *assistant,
2099 GtkAssistantPrivate *priv;
2100 GtkAssistantPage *page_info;
2103 g_return_val_if_fail (GTK_IS_ASSISTANT (assistant), FALSE);
2104 g_return_val_if_fail (GTK_IS_WIDGET (page), FALSE);
2106 priv = assistant->priv;
2107 child = find_page (assistant, page);
2109 g_return_val_if_fail (child != NULL, FALSE);
2111 page_info = (GtkAssistantPage*) child->data;
2113 return page_info->complete;
2117 #define __GTK_ASSISTANT_C__
2118 #include "gtkaliasdef.c"