static void gnome_druid_remove (GtkContainer *widget, GtkWidget *child) { GnomeDruid *druid; GList *list; g_return_if_fail (widget != NULL); g_return_if_fail (GNOME_IS_DRUID (widget)); g_return_if_fail (child != NULL); druid = GNOME_DRUID (widget); list = g_list_find (druid->_priv->children, child); /* Is it a page? */ if (list != NULL) { /* If we are mapped and visible, we want to deal with changing the page. */ if ((GTK_WIDGET_MAPPED (GTK_WIDGET (widget))) && (list->data == (gpointer) druid->_priv->current)) { if (list->next != NULL) gnome_druid_set_page (druid, GNOME_DRUID_PAGE (list->next->data)); else if (list->prev != NULL) gnome_druid_set_page (druid, GNOME_DRUID_PAGE (list->prev->data)); else /* Removing the only child, just set current to NULL */ druid->_priv->current = NULL; } } druid->_priv->children = g_list_remove (druid->_priv->children, child); gtk_widget_unparent (child); }
/** * gnome_druid_set_page: * @druid: A #GnomeDruid widget. * @page: The #GnomeDruidPage to be brought to the foreground. * * Description: This will make @page the currently showing page in the druid. * @page must already be in the druid. **/ void gnome_druid_set_page (GnomeDruid *druid, GnomeDruidPage *page) { GList *list; GtkWidget *old = NULL; g_return_if_fail (druid != NULL); g_return_if_fail (GNOME_IS_DRUID (druid)); g_return_if_fail (page != NULL); g_return_if_fail (GNOME_IS_DRUID_PAGE (page)); if (druid->_priv->current == page) return; list = g_list_find (druid->_priv->children, page); g_return_if_fail (list != NULL); if ((druid->_priv->current) && (GTK_WIDGET_VISIBLE (druid->_priv->current)) && (GTK_WIDGET_MAPPED (druid))) { old = GTK_WIDGET (druid->_priv->current); } druid->_priv->current = GNOME_DRUID_PAGE (list->data); gnome_druid_page_prepare (druid->_priv->current); if (GTK_WIDGET_VISIBLE (druid->_priv->current) && (GTK_WIDGET_MAPPED (druid))) { gtk_widget_map (GTK_WIDGET (druid->_priv->current)); gtk_widget_set_sensitive (GTK_WIDGET (druid->_priv->current), TRUE); } if (old && GTK_WIDGET_MAPPED (old)) { gtk_widget_unmap (old); gtk_widget_set_sensitive (old, FALSE); } }
static void gnome_druid_unmap (GtkWidget *widget) { GnomeDruid *druid; g_return_if_fail (widget != NULL); g_return_if_fail (GNOME_IS_DRUID (widget)); druid = GNOME_DRUID (widget); GTK_WIDGET_UNSET_FLAGS (druid, GTK_MAPPED); #if 0 gtk_widget_unmap (druid->back); if (druid->_priv->show_finish) gtk_widget_unmap (druid->finish); else gtk_widget_unmap (druid->next); gtk_widget_unmap (druid->cancel); if (druid->_priv->show_help) gtk_widget_unmap (druid->help); #endif gtk_widget_unmap (druid->_priv->bbox); if (druid->_priv->current && GTK_WIDGET_VISIBLE (druid->_priv->current) && GTK_WIDGET_MAPPED (druid->_priv->current)) gtk_widget_unmap (GTK_WIDGET (druid->_priv->current)); }
static void gb_gnome_druid_insert_page_before (GtkWidget * menuitem, GnomeDruidPage *page) { GtkWidget *parent, *new_page; GnomeDruidPage *prev_page; GList *children, *elem; parent = GTK_WIDGET (page)->parent; g_return_if_fail (GNOME_IS_DRUID (parent)); children = gtk_container_get_children (GTK_CONTAINER (parent)); elem = g_list_find (children, page); g_return_if_fail (elem != NULL); new_page = gb_widget_new ("GnomeDruidPageStandard", parent); gtk_widget_show_all (new_page); if (elem->prev) prev_page = GNOME_DRUID_PAGE (elem->prev->data); else prev_page = NULL; g_list_free (children); gnome_druid_insert_page (GNOME_DRUID (parent), prev_page, GNOME_DRUID_PAGE (new_page)); gb_gnome_druid_show_page (parent, new_page); gnome_druid_set_page (GNOME_DRUID (parent), GNOME_DRUID_PAGE (new_page)); tree_add_widget (GTK_WIDGET (new_page)); }
static void gnome_druid_destroy (GtkObject *object) { GnomeDruid *druid; /* remember, destroy can be run multiple times! */ g_return_if_fail (object != NULL); g_return_if_fail (GNOME_IS_DRUID (object)); druid = GNOME_DRUID (object); if(druid->_priv->bbox) { gtk_widget_destroy (druid->_priv->bbox); druid->_priv->bbox = NULL; druid->back = NULL; druid->next = NULL; druid->cancel = NULL; druid->finish = NULL; druid->help = NULL; } /* Remove all children, we set current to NULL so * that the remove code doesn't try to do anything funny */ druid->_priv->current = NULL; while (druid->_priv->children != NULL) { GnomeDruidPage *child = druid->_priv->children->data; gtk_container_remove (GTK_CONTAINER (druid), GTK_WIDGET(child)); } GNOME_CALL_PARENT (GTK_OBJECT_CLASS, destroy, (object)); }
static void gnome_druid_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data) { GnomeDruid *druid; GnomeDruidPage *child; GList *children; g_return_if_fail (container != NULL); g_return_if_fail (GNOME_IS_DRUID (container)); g_return_if_fail (callback != NULL); druid = GNOME_DRUID (container); children = druid->_priv->children; while (children) { child = children->data; children = children->next; (* callback) (GTK_WIDGET (child), callback_data); } if (include_internals) { /* FIXME: should this be gtk_contianer_forall() ? */ (* callback) (druid->_priv->bbox, callback_data); #if 0 (* callback) (druid->back, callback_data); (* callback) (druid->next, callback_data); (* callback) (druid->cancel, callback_data); (* callback) (druid->finish, callback_data); (* callback) (druid->help, callback_data); #endif } }
static void gnome_druid_add (GtkContainer *widget, GtkWidget *page) { g_return_if_fail (widget != NULL); g_return_if_fail (GNOME_IS_DRUID (widget)); g_return_if_fail (page != NULL); g_return_if_fail (GNOME_IS_DRUID_PAGE (page)); gnome_druid_append_page (GNOME_DRUID (widget), GNOME_DRUID_PAGE (page)); }
/** * gnome_druid_prepend_page: * @druid: A Druid widget. * @page: The page to be inserted. * * Description: This will prepend a GnomeDruidPage into the internal list of * pages that the @druid has. Since #GnomeDruid is just a container, you will * need to also call gtk_widget_show() on the page, otherwise the page will not * be shown. **/ void gnome_druid_prepend_page (GnomeDruid *druid, GnomeDruidPage *page) { g_return_if_fail (druid != NULL); g_return_if_fail (GNOME_IS_DRUID (druid)); g_return_if_fail (page != NULL); g_return_if_fail (GNOME_IS_DRUID_PAGE (page)); gnome_druid_insert_page (druid, NULL, page); }
static AtkObject * gnome_druid_accessible_new (GObject *obj) { AtkObject *accessible; g_return_val_if_fail (GNOME_IS_DRUID (obj), NULL); accessible = g_object_new (gnome_druid_accessible_get_type (), NULL); atk_object_initialize (accessible, obj); return accessible; }
/** * gnome_druid_construct_with_window: * @druid: The #GnomeDruid. * @title: A title of the window. * @parent: The parent of this window (transient_for). * @close_on_cancel: %TRUE if the window should be closed when cancel is * pressed. * @window: Optional return of the #GtkWindow created. * * Description: Creates a new toplevel window with the title of @title (which * can be %NULL) and a parent of @parent (which also can be %NULL). The @druid * will be placed inside this window. The window and the druid will both be * shown. If you need the window widget pointer you can optionally get it * through the last argument. When the druid gets destroyed, so will the * window that is created here. * * See also gnome_druid_new_with_window(). **/ void gnome_druid_construct_with_window (GnomeDruid *druid, const char *title, GtkWindow *parent, gboolean close_on_cancel, GtkWidget **window) { GtkWidget *win; /* make sure we always set window to NULL, even in * case of precondition errors */ if (window != NULL) *window = NULL; g_return_if_fail (druid != NULL); g_return_if_fail (GNOME_IS_DRUID (druid)); g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent)); win = gtk_window_new (GTK_WINDOW_TOPLEVEL); if (title != NULL) gtk_window_set_title (GTK_WINDOW (win), title); if (parent != NULL) gtk_window_set_transient_for (GTK_WINDOW (win), parent); gtk_widget_show (GTK_WIDGET (druid)); gtk_container_add (GTK_CONTAINER (win), GTK_WIDGET (druid)); gtk_widget_show (win); if (close_on_cancel) { g_signal_connect_object (druid, "cancel", G_CALLBACK (gtk_widget_destroy), win, G_CONNECT_SWAPPED); } /* When the druid gets destroyed so does the window */ g_signal_connect_object (druid, "destroy", G_CALLBACK (gtk_widget_destroy), win, G_CONNECT_SWAPPED); /* return the window */ if (window != NULL) *window = win; }
static void gnome_druid_finalize (GObject *object) { GnomeDruid *druid; g_return_if_fail (object != NULL); g_return_if_fail (GNOME_IS_DRUID (object)); druid = GNOME_DRUID (object); g_free(druid->_priv); druid->_priv = NULL; GNOME_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); }
void gnome_druid_set_buttons_sensitive (GnomeDruid *druid, gboolean back_sensitive, gboolean next_sensitive, gboolean cancel_sensitive, gboolean help_sensitive) { g_return_if_fail (druid != NULL); g_return_if_fail (GNOME_IS_DRUID (druid)); gtk_widget_set_sensitive (druid->back, back_sensitive); gtk_widget_set_sensitive (druid->next, next_sensitive); gtk_widget_set_sensitive (druid->cancel, cancel_sensitive); gtk_widget_set_sensitive (druid->help, help_sensitive); }
/** * gnome_druid_set_show_help * @druid: A #GnomeDruid. * @show_help: %TRUE, if the "Help" button is to be shown, %FALSE otherwise. * * Sets the "Help" button on the druid to be visible in the lower left corner of * the widget, if @show_help is %TRUE. **/ void gnome_druid_set_show_help (GnomeDruid *druid, gboolean show_help) { g_return_if_fail (GNOME_IS_DRUID (druid)); if ((show_help?TRUE:FALSE) == druid->_priv->show_help) return; if (show_help) { gtk_widget_show (druid->help); } else { gtk_widget_hide (druid->help); } druid->_priv->show_help = show_help?TRUE:FALSE; }
/** * gnome_druid_append_page: * @druid: A #GnomeDruid widget. * @page: The #GnomeDruidPage to be appended. * * Description: This will append @page onto the end of the internal list. * Since #GnomeDruid is just a container, you will need to also call * gtk_widget_show() on the page, otherwise the page will not be shown. **/ void gnome_druid_append_page (GnomeDruid *druid, GnomeDruidPage *page) { GList *list; g_return_if_fail (druid != NULL); g_return_if_fail (GNOME_IS_DRUID (druid)); g_return_if_fail (page != NULL); g_return_if_fail (GNOME_IS_DRUID_PAGE (page)); list = g_list_last (druid->_priv->children); if (list) { gnome_druid_insert_page (druid, GNOME_DRUID_PAGE (list->data), page); } else { gnome_druid_insert_page (druid, NULL, page); } }
/** * gnome_druid_set_show_finish * @druid: A #GnomeDruid widget. * @show_finish: If %TRUE, then the "Next" button is changed to be "Finish" * * Used to specify if @druid is currently showing the last page of the sequence * (and hence should display "Finish", rather than "Next"). **/ void gnome_druid_set_show_finish (GnomeDruid *druid, gboolean show_finish) { g_return_if_fail (GNOME_IS_DRUID (druid)); if ((show_finish?TRUE:FALSE) == druid->_priv->show_finish) return; if (show_finish) { gtk_widget_hide (druid->next); gtk_widget_show (druid->finish); } else { gtk_widget_hide (druid->finish); gtk_widget_show (druid->next); } druid->_priv->show_finish = show_finish?TRUE:FALSE; }
static void gb_gnome_druid_insert_page_after (GtkWidget * menuitem, GnomeDruidPage *page) { GtkWidget *parent, *new_page; parent = GTK_WIDGET (page)->parent; g_return_if_fail (GNOME_IS_DRUID (parent)); new_page = gb_widget_new ("GnomeDruidPageStandard", parent); gtk_widget_show_all (new_page); gnome_druid_insert_page (GNOME_DRUID (parent), GNOME_DRUID_PAGE (page), GNOME_DRUID_PAGE (new_page)); gb_gnome_druid_show_page (parent, new_page); gnome_druid_set_page (GNOME_DRUID (parent), GNOME_DRUID_PAGE (new_page)); tree_add_widget (GTK_WIDGET (new_page)); }
static gint gnome_druid_expose (GtkWidget *widget, GdkEventExpose *event) { GnomeDruid *druid; GtkWidget *child; GList *children; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GNOME_IS_DRUID (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); if (GTK_WIDGET_DRAWABLE (widget)) { druid = GNOME_DRUID (widget); children = druid->_priv->children; while (children) { child = GTK_WIDGET (children->data); children = children->next; gtk_container_propagate_expose (GTK_CONTAINER (widget), child, event); } gtk_container_propagate_expose (GTK_CONTAINER (widget), druid->_priv->bbox, event); #if 0 gtk_container_propagate_expose (GTK_CONTAINER (widget), druid->back, event); gtk_container_propagate_expose (GTK_CONTAINER (widget), druid->next, event); gtk_container_propagate_expose (GTK_CONTAINER (widget), druid->cancel, event); gtk_container_propagate_expose (GTK_CONTAINER (widget), druid->finish, event); gtk_container_propagate_expose (GTK_CONTAINER (widget), druid->help, event); #endif } return FALSE; }
/** * gnome_druid_insert_page: * @druid: A #GnomeDruid widget. * @back_page: The page prior to the page to be inserted. * @page: The page to insert. * * Description: This will insert @page after @back_page into the list of * internal pages that the @druid has. If @back_page is not present in the * list or %NULL, @page will be prepended to the list. Since #GnomeDruid is * just a container, you will need to also call gtk_widget_show() on the page, * otherwise the page will not be shown. **/ void gnome_druid_insert_page (GnomeDruid *druid, GnomeDruidPage *back_page, GnomeDruidPage *page) { GList *list; g_return_if_fail (druid != NULL); g_return_if_fail (GNOME_IS_DRUID (druid)); g_return_if_fail (page != NULL); g_return_if_fail (GNOME_IS_DRUID_PAGE (page)); list = g_list_find (druid->_priv->children, back_page); if (list == NULL) { druid->_priv->children = g_list_prepend (druid->_priv->children, page); } else { GList *new_el = g_list_alloc (); new_el->next = list->next; new_el->prev = list; if (new_el->next) new_el->next->prev = new_el; new_el->prev->next = new_el; new_el->data = (gpointer) page; } gtk_widget_set_parent (GTK_WIDGET (page), GTK_WIDGET (druid)); if (GTK_WIDGET_REALIZED (GTK_WIDGET (druid))) gtk_widget_realize (GTK_WIDGET (page)); if (GTK_WIDGET_VISIBLE (GTK_WIDGET (druid)) && GTK_WIDGET_VISIBLE (GTK_WIDGET (page))) { if (GTK_WIDGET_MAPPED (GTK_WIDGET (page))) gtk_widget_unmap (GTK_WIDGET (page)); gtk_widget_queue_resize (GTK_WIDGET (druid)); } /* if it's the first and only page, we want to bring it to the foreground. */ if (druid->_priv->children->next == NULL) gnome_druid_set_page (druid, page); }
static void gnome_druid_size_request (GtkWidget *widget, GtkRequisition *requisition) { guint16 temp_width, temp_height; GList *list; GnomeDruid *druid; GtkRequisition child_requisition; GnomeDruidPage *child; int border; g_return_if_fail (widget != NULL); g_return_if_fail (GNOME_IS_DRUID (widget)); druid = GNOME_DRUID (widget); temp_height = temp_width = 0; border = GTK_CONTAINER(widget)->border_width; /* We find the maximum size of all children widgets */ for (list = druid->_priv->children; list; list = list->next) { child = GNOME_DRUID_PAGE (list->data); if (GTK_WIDGET_VISIBLE (child)) { gtk_widget_size_request (GTK_WIDGET (child), &child_requisition); temp_width = MAX (temp_width, child_requisition.width); temp_height = MAX (temp_height, child_requisition.height); if (GTK_WIDGET_MAPPED (child) && child != druid->_priv->current) gtk_widget_unmap (GTK_WIDGET(child)); } } requisition->width = temp_width + 2 * border; requisition->height = temp_height + 2 * border; #if 0 /* In an Attempt to show how the widgets are packed, * here's a little diagram. * * [ Help ] ------------- [ Back ] [ Next ] [ Cancel ] * / * This part needs to be at least 1 button width. * In addition, there is 1/4 X Button width between Cancel and Next, * and a GNOME_PAD_SMALL between Next and Back. */ /* our_button width is temp_width and temp_height */ temp_height = 0; temp_width = 0; gtk_widget_size_request (druid->back, &child_requisition); temp_width = MAX (temp_width, child_requisition.width); temp_height = MAX (temp_height, child_requisition.height); gtk_widget_size_request (druid->next, &child_requisition); temp_width = MAX (temp_width, child_requisition.width); temp_height = MAX (temp_height, child_requisition.height); gtk_widget_size_request (druid->cancel, &child_requisition); temp_width = MAX (temp_width, child_requisition.width); temp_height = MAX (temp_height, child_requisition.height); gtk_widget_size_request (druid->finish, &child_requisition); temp_width = MAX (temp_width, child_requisition.width); temp_height = MAX (temp_height, child_requisition.height); gtk_widget_size_request (druid->help, &child_requisition); temp_width = MAX (temp_width, child_requisition.width); temp_height = MAX (temp_height, child_requisition.height); temp_width += border * 2; temp_height += GNOME_PAD_SMALL; temp_width = temp_width * 21/4 + GNOME_PAD_SMALL * 3; #endif gtk_widget_size_request (druid->_priv->bbox, &child_requisition); /* pick which is bigger, the buttons, or the GnomeDruidPages */ requisition->width = MAX (child_requisition.width, requisition->width); requisition->height += child_requisition.height + GNOME_PAD_SMALL * 2; }
/* * Adds menu items to a context menu which is just about to appear! * Add commands to aid in editing a GnomeDruid, with signals pointing to * other functions in this file. */ static void gb_gnome_druid_create_popup_menu (GtkWidget * widget, GbWidgetCreateMenuData * data) { GtkWidget *menuitem; GnomeDruid *druid; GList *children, *elem; if (data->child == NULL) return; g_return_if_fail (GNOME_IS_DRUID (data->child->parent)); druid = GNOME_DRUID (data->child->parent); children = gtk_container_get_children (GTK_CONTAINER (widget)); /* 'Add Start Page' is added if the druid has no pages or the first one is not a start page. */ if (!children || !(GNOME_IS_DRUID_PAGE_EDGE (children->data) && GNOME_DRUID_PAGE_EDGE (children->data)->position == GNOME_EDGE_START)) { menuitem = gtk_menu_item_new_with_label (_("Add Start Page")); gtk_widget_show (menuitem); gtk_menu_append (GTK_MENU (data->menu), menuitem); gtk_signal_connect (GTK_OBJECT (menuitem), "activate", GTK_SIGNAL_FUNC (gb_gnome_druid_add_start_page), druid); } /* 'Add Finish Page' is added if the druid has no pages or the last one is not a finish page. */ elem = g_list_last (children); if (!elem || !(GNOME_IS_DRUID_PAGE_EDGE (elem->data) && GNOME_DRUID_PAGE_EDGE (elem->data)->position == GNOME_EDGE_FINISH)) { menuitem = gtk_menu_item_new_with_label (_("Add Finish Page")); gtk_widget_show (menuitem); gtk_menu_append (GTK_MENU (data->menu), menuitem); gtk_signal_connect (GTK_OBJECT (menuitem), "activate", GTK_SIGNAL_FUNC (gb_gnome_druid_add_finish_page), druid); } g_list_free (children); /* 'Insert Page Before' is added if the current page is not the start page. */ if (!(GNOME_IS_DRUID_PAGE_EDGE (data->child) && GNOME_DRUID_PAGE_EDGE (data->child)->position == GNOME_EDGE_START)) { menuitem = gtk_menu_item_new_with_label (_("Insert Page Before")); gtk_widget_show (menuitem); gtk_menu_append (GTK_MENU (data->menu), menuitem); gtk_signal_connect (GTK_OBJECT (menuitem), "activate", GTK_SIGNAL_FUNC (gb_gnome_druid_insert_page_before), data->child); } /* 'Insert Page After' is added if the current page is not the finish page. */ if (!(GNOME_IS_DRUID_PAGE_EDGE (data->child) && GNOME_DRUID_PAGE_EDGE (data->child)->position == GNOME_EDGE_FINISH)) { menuitem = gtk_menu_item_new_with_label (_("Insert Page After")); gtk_widget_show (menuitem); gtk_menu_append (GTK_MENU (data->menu), menuitem); gtk_signal_connect (GTK_OBJECT (menuitem), "activate", GTK_SIGNAL_FUNC (gb_gnome_druid_insert_page_after), data->child); } }
static void gnome_druid_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { GnomeDruid *druid; GtkAllocation child_allocation; gint button_height; GList *list; int border; g_return_if_fail (widget != NULL); g_return_if_fail (GNOME_IS_DRUID (widget)); druid = GNOME_DRUID (widget); widget->allocation = *allocation; border = GTK_CONTAINER(widget)->border_width; #if 0 /* deal with the buttons */ child_allocation.width = child_allocation.height = 0; child_allocation.width = druid->back->requisition.width; child_allocation.height = druid->back->requisition.height; child_allocation.width = MAX (child_allocation.width, druid->next->requisition.width); child_allocation.height = MAX (child_allocation.height, druid->next->requisition.height); child_allocation.width = MAX (child_allocation.width, druid->cancel->requisition.width); child_allocation.height = MAX (child_allocation.height, druid->cancel->requisition.height); child_allocation.width = MAX (child_allocation.width, druid->help->requisition.width); child_allocation.height = MAX (child_allocation.height, druid->help->requisition.height); child_allocation.height += GNOME_PAD_SMALL; button_height = child_allocation.height; child_allocation.width += 2 * GNOME_PAD_SMALL; child_allocation.x = allocation->x + allocation->width - GNOME_PAD_SMALL - child_allocation.width; child_allocation.y = allocation->y + allocation->height - GNOME_PAD_SMALL - child_allocation.height; gtk_widget_size_allocate (druid->cancel, &child_allocation); child_allocation.x -= (child_allocation.width * 5 / 4); gtk_widget_size_allocate (druid->next, &child_allocation); gtk_widget_size_allocate (druid->finish, &child_allocation); child_allocation.x -= (GNOME_PAD_SMALL + child_allocation.width); gtk_widget_size_allocate (druid->back, &child_allocation); child_allocation.x = allocation->x + border; gtk_widget_size_allocate (druid->help, &child_allocation); #endif button_height = druid->_priv->bbox->requisition.height; child_allocation.x = allocation->x; child_allocation.y = allocation->y + allocation->height - button_height; child_allocation.height = button_height; child_allocation.width = allocation->width; gtk_widget_size_allocate (druid->_priv->bbox, &child_allocation); /* Put up the GnomeDruidPage */ child_allocation.x = allocation->x + border; child_allocation.y = allocation->y + border; child_allocation.width = ((allocation->width - 2 * border) > 0) ? (allocation->width - 2 * border):0; child_allocation.height = ((allocation->height - 2 * border - GNOME_PAD_SMALL - button_height) > 0) ? (allocation->height - 2 * border - GNOME_PAD_SMALL - button_height):0; for (list = druid->_priv->children; list; list=list->next) { GtkWidget *widget = GTK_WIDGET (list->data); if (GTK_WIDGET_VISIBLE (widget)) { gtk_widget_size_allocate (widget, &child_allocation); } } }