1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
27 #include "gtknotebook.h"
28 #include "gtksignal.h"
31 #include "gtkmenuitem.h"
33 #include <gdk/gdkkeysyms.h>
39 #define TAB_CURVATURE 1
41 #define ARROW_SPACING 0
43 #define NOTEBOOK_INIT_SCROLL_DELAY (200)
44 #define NOTEBOOK_SCROLL_DELAY (100)
81 #define GTK_NOTEBOOK_PAGE(_glist_) ((GtkNotebookPage *)((GList *)(_glist_))->data)
83 struct _GtkNotebookPage
87 GtkWidget *menu_label;
89 guint default_menu : 1; /* If true, we create the menu label ourself */
90 guint default_tab : 1; /* If true, we create the tab label ourself */
95 GtkRequisition requisition;
96 GtkAllocation allocation;
99 #ifdef G_DISABLE_CHECKS
100 #define CHECK_FIND_CHILD(notebook, child) \
101 gtk_notebook_find_child(notebook, child, \
102 G_GNUC_PRETTY_FUNCTION)
104 #define CHECK_FIND_CHILD(notebook, child) \
105 gtk_notebook_find_child(notebook, child, NULL)
108 /*** GtkNotebook Methods ***/
109 static void gtk_notebook_class_init (GtkNotebookClass *klass);
110 static void gtk_notebook_init (GtkNotebook *notebook);
112 /*** GtkObject Methods ***/
113 static void gtk_notebook_destroy (GtkObject *object);
114 static void gtk_notebook_set_arg (GtkObject *object,
117 static void gtk_notebook_get_arg (GtkObject *object,
121 /*** GtkWidget Methods ***/
122 static void gtk_notebook_map (GtkWidget *widget);
123 static void gtk_notebook_unmap (GtkWidget *widget);
124 static void gtk_notebook_realize (GtkWidget *widget);
125 static void gtk_notebook_unrealize (GtkWidget *widget);
126 static void gtk_notebook_size_request (GtkWidget *widget,
127 GtkRequisition *requisition);
128 static void gtk_notebook_size_allocate (GtkWidget *widget,
129 GtkAllocation *allocation);
130 static gint gtk_notebook_expose (GtkWidget *widget,
131 GdkEventExpose *event);
132 static gint gtk_notebook_button_press (GtkWidget *widget,
133 GdkEventButton *event);
134 static gint gtk_notebook_button_release (GtkWidget *widget,
135 GdkEventButton *event);
136 static gint gtk_notebook_enter_notify (GtkWidget *widget,
137 GdkEventCrossing *event);
138 static gint gtk_notebook_leave_notify (GtkWidget *widget,
139 GdkEventCrossing *event);
140 static gint gtk_notebook_motion_notify (GtkWidget *widget,
141 GdkEventMotion *event);
142 static gint gtk_notebook_key_press (GtkWidget *widget,
144 static gint gtk_notebook_focus_in (GtkWidget *widget,
145 GdkEventFocus *event);
146 static gint gtk_notebook_focus_out (GtkWidget *widget,
147 GdkEventFocus *event);
148 static void gtk_notebook_draw_focus (GtkWidget *widget);
149 static void gtk_notebook_style_set (GtkWidget *widget,
150 GtkStyle *previous_style);
152 /*** GtkContainer Methods ***/
153 static void gtk_notebook_set_child_arg (GtkContainer *container,
157 static void gtk_notebook_get_child_arg (GtkContainer *container,
161 static void gtk_notebook_add (GtkContainer *container,
163 static void gtk_notebook_remove (GtkContainer *container,
165 static gint gtk_notebook_focus (GtkContainer *container,
166 GtkDirectionType direction);
167 static void gtk_notebook_set_focus_child (GtkContainer *container,
169 static GtkType gtk_notebook_child_type (GtkContainer *container);
170 static void gtk_notebook_forall (GtkContainer *container,
171 gboolean include_internals,
172 GtkCallback callback,
173 gpointer callback_data);
175 /*** GtkNotebook Private Functions ***/
176 static void gtk_notebook_panel_realize (GtkNotebook *notebook);
177 static void gtk_notebook_redraw_tabs (GtkNotebook *notebook);
178 static void gtk_notebook_redraw_arrows (GtkNotebook *notebook);
179 static void gtk_notebook_focus_changed (GtkNotebook *notebook,
180 GtkNotebookPage *old_page);
181 static void gtk_notebook_real_remove (GtkNotebook *notebook,
183 static void gtk_notebook_update_labels (GtkNotebook *notebook);
184 static gint gtk_notebook_timer (GtkNotebook *notebook);
185 static gint gtk_notebook_page_compare (gconstpointer a,
187 static GList *gtk_notebook_find_child (GtkNotebook *notebook,
189 const gchar *function);
190 static gint gtk_notebook_real_page_position (GtkNotebook *notebook,
192 static GList * gtk_notebook_search_page (GtkNotebook *notebook,
195 gboolean find_visible);
197 /*** GtkNotebook Drawing Functions ***/
198 static void gtk_notebook_paint (GtkWidget *widget,
200 static void gtk_notebook_draw_tab (GtkNotebook *notebook,
201 GtkNotebookPage *page,
203 static void gtk_notebook_draw_arrow (GtkNotebook *notebook,
205 static void gtk_notebook_set_shape (GtkNotebook *notebook);
207 /*** GtkNotebook Size Allocate Functions ***/
208 static void gtk_notebook_pages_allocate (GtkNotebook *notebook);
209 static void gtk_notebook_page_allocate (GtkNotebook *notebook,
210 GtkNotebookPage *page,
211 GtkAllocation *allocation);
212 static void gtk_notebook_calc_tabs (GtkNotebook *notebook,
218 /*** GtkNotebook Page Switch Methods ***/
219 static void gtk_notebook_real_switch_page (GtkNotebook *notebook,
220 GtkNotebookPage *page,
223 /*** GtkNotebook Page Switch Functions ***/
224 static void gtk_notebook_switch_page (GtkNotebook *notebook,
225 GtkNotebookPage *page,
227 static gint gtk_notebook_page_select (GtkNotebook *notebook,
228 gboolean move_focus);
229 static void gtk_notebook_switch_focus_tab (GtkNotebook *notebook,
231 static void gtk_notebook_menu_switch_page (GtkWidget *widget,
232 GtkNotebookPage *page);
234 /*** GtkNotebook Menu Functions ***/
235 static void gtk_notebook_menu_item_create (GtkNotebook *notebook,
237 static void gtk_notebook_menu_label_unparent (GtkWidget *widget,
239 static void gtk_notebook_menu_detacher (GtkWidget *widget,
243 static GtkContainerClass *parent_class = NULL;
244 static guint notebook_signals[LAST_SIGNAL] = { 0 };
247 gtk_notebook_get_type (void)
249 static GtkType notebook_type = 0;
253 static const GtkTypeInfo notebook_info =
256 sizeof (GtkNotebook),
257 sizeof (GtkNotebookClass),
258 (GtkClassInitFunc) gtk_notebook_class_init,
259 (GtkObjectInitFunc) gtk_notebook_init,
260 /* reserved_1 */ NULL,
261 /* reserved_2 */ NULL,
262 (GtkClassInitFunc) NULL,
265 notebook_type = gtk_type_unique (gtk_container_get_type (), ¬ebook_info);
268 return notebook_type;
272 gtk_notebook_class_init (GtkNotebookClass *class)
274 GtkObjectClass *object_class;
275 GtkWidgetClass *widget_class;
276 GtkContainerClass *container_class;
278 object_class = (GtkObjectClass*) class;
279 widget_class = (GtkWidgetClass*) class;
280 container_class = (GtkContainerClass*) class;
281 parent_class = gtk_type_class (gtk_container_get_type ());
284 object_class->set_arg = gtk_notebook_set_arg;
285 object_class->get_arg = gtk_notebook_get_arg;
286 object_class->destroy = gtk_notebook_destroy;
288 widget_class->map = gtk_notebook_map;
289 widget_class->unmap = gtk_notebook_unmap;
290 widget_class->realize = gtk_notebook_realize;
291 widget_class->unrealize = gtk_notebook_unrealize;
292 widget_class->size_request = gtk_notebook_size_request;
293 widget_class->size_allocate = gtk_notebook_size_allocate;
294 widget_class->expose_event = gtk_notebook_expose;
295 widget_class->button_press_event = gtk_notebook_button_press;
296 widget_class->button_release_event = gtk_notebook_button_release;
297 widget_class->enter_notify_event = gtk_notebook_enter_notify;
298 widget_class->leave_notify_event = gtk_notebook_leave_notify;
299 widget_class->motion_notify_event = gtk_notebook_motion_notify;
300 widget_class->key_press_event = gtk_notebook_key_press;
301 widget_class->focus_in_event = gtk_notebook_focus_in;
302 widget_class->focus_out_event = gtk_notebook_focus_out;
303 widget_class->draw_focus = gtk_notebook_draw_focus;
304 widget_class->style_set = gtk_notebook_style_set;
306 container_class->add = gtk_notebook_add;
307 container_class->remove = gtk_notebook_remove;
308 container_class->forall = gtk_notebook_forall;
309 container_class->focus = gtk_notebook_focus;
310 container_class->set_focus_child = gtk_notebook_set_focus_child;
311 container_class->get_child_arg = gtk_notebook_get_child_arg;
312 container_class->set_child_arg = gtk_notebook_set_child_arg;
313 container_class->child_type = gtk_notebook_child_type;
315 class->switch_page = gtk_notebook_real_switch_page;
317 gtk_object_add_arg_type ("GtkNotebook::page", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_PAGE);
318 gtk_object_add_arg_type ("GtkNotebook::tab_pos", GTK_TYPE_POSITION_TYPE, GTK_ARG_READWRITE, ARG_TAB_POS);
319 gtk_object_add_arg_type ("GtkNotebook::tab_border", GTK_TYPE_UINT, GTK_ARG_WRITABLE, ARG_TAB_BORDER);
320 gtk_object_add_arg_type ("GtkNotebook::tab_hborder", GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_TAB_HBORDER);
321 gtk_object_add_arg_type ("GtkNotebook::tab_vborder", GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_TAB_VBORDER);
322 gtk_object_add_arg_type ("GtkNotebook::show_tabs", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_SHOW_TABS);
323 gtk_object_add_arg_type ("GtkNotebook::show_border", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_SHOW_BORDER);
324 gtk_object_add_arg_type ("GtkNotebook::scrollable", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_SCROLLABLE);
325 gtk_object_add_arg_type ("GtkNotebook::enable_popup", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_ENABLE_POPUP);
326 gtk_object_add_arg_type ("GtkNotebook::homogeneous", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_HOMOGENEOUS);
328 gtk_container_add_child_arg_type ("GtkNotebook::tab_label", GTK_TYPE_STRING, GTK_ARG_READWRITE, CHILD_ARG_TAB_LABEL);
329 gtk_container_add_child_arg_type ("GtkNotebook::menu_label", GTK_TYPE_STRING, GTK_ARG_READWRITE, CHILD_ARG_MENU_LABEL);
330 gtk_container_add_child_arg_type ("GtkNotebook::position", GTK_TYPE_INT, GTK_ARG_READWRITE, CHILD_ARG_POSITION);
331 gtk_container_add_child_arg_type ("GtkNotebook::tab_fill", GTK_TYPE_BOOL, GTK_ARG_READWRITE, CHILD_ARG_TAB_FILL);
332 gtk_container_add_child_arg_type ("GtkNotebook::tab_pack", GTK_TYPE_BOOL, GTK_ARG_READWRITE, CHILD_ARG_TAB_PACK);
334 notebook_signals[SWITCH_PAGE] =
335 gtk_signal_new ("switch_page",
337 GTK_CLASS_TYPE (object_class),
338 GTK_SIGNAL_OFFSET (GtkNotebookClass, switch_page),
339 gtk_marshal_VOID__POINTER_UINT,
346 gtk_notebook_init (GtkNotebook *notebook)
348 GTK_WIDGET_SET_FLAGS (notebook, GTK_CAN_FOCUS | GTK_RECEIVES_DEFAULT);
349 GTK_WIDGET_UNSET_FLAGS (notebook, GTK_NO_WINDOW);
351 notebook->cur_page = NULL;
352 notebook->children = NULL;
353 notebook->first_tab = NULL;
354 notebook->focus_tab = NULL;
355 notebook->panel = NULL;
356 notebook->menu = NULL;
358 notebook->tab_hborder = 2;
359 notebook->tab_vborder = 2;
361 notebook->show_tabs = TRUE;
362 notebook->show_border = TRUE;
363 notebook->tab_pos = GTK_POS_TOP;
364 notebook->scrollable = FALSE;
365 notebook->in_child = 0;
366 notebook->click_child = 0;
367 notebook->button = 0;
368 notebook->need_timer = 0;
369 notebook->child_has_focus = FALSE;
370 notebook->have_visible_child = FALSE;
377 * Creates a new #GtkNotebook widget with no pages.
379 * Return value: the newly created #GtkNotebook
382 gtk_notebook_new (void)
384 return GTK_WIDGET (gtk_type_new (gtk_notebook_get_type ()));
387 /* Private GtkObject Methods :
389 * gtk_notebook_destroy
390 * gtk_notebook_set_arg
391 * gtk_notebook_get_arg
394 gtk_notebook_destroy (GtkObject *object)
396 GtkNotebook *notebook;
398 g_return_if_fail (object != NULL);
399 g_return_if_fail (GTK_IS_NOTEBOOK (object));
401 notebook = GTK_NOTEBOOK (object);
404 gtk_notebook_popup_disable (notebook);
406 GTK_OBJECT_CLASS (parent_class)->destroy (object);
410 gtk_notebook_set_arg (GtkObject *object,
414 GtkNotebook *notebook;
416 notebook = GTK_NOTEBOOK (object);
421 gtk_notebook_set_show_tabs (notebook, GTK_VALUE_BOOL (*arg));
423 case ARG_SHOW_BORDER:
424 gtk_notebook_set_show_border (notebook, GTK_VALUE_BOOL (*arg));
427 gtk_notebook_set_scrollable (notebook, GTK_VALUE_BOOL (*arg));
429 case ARG_ENABLE_POPUP:
430 if (GTK_VALUE_BOOL (*arg))
431 gtk_notebook_popup_enable (notebook);
433 gtk_notebook_popup_disable (notebook);
435 case ARG_HOMOGENEOUS:
436 gtk_notebook_set_homogeneous_tabs (notebook, GTK_VALUE_BOOL (*arg));
439 gtk_notebook_set_page (notebook, GTK_VALUE_INT (*arg));
442 gtk_notebook_set_tab_pos (notebook, GTK_VALUE_ENUM (*arg));
445 gtk_notebook_set_tab_border (notebook, GTK_VALUE_UINT (*arg));
447 case ARG_TAB_HBORDER:
448 gtk_notebook_set_tab_hborder (notebook, GTK_VALUE_UINT (*arg));
450 case ARG_TAB_VBORDER:
451 gtk_notebook_set_tab_vborder (notebook, GTK_VALUE_UINT (*arg));
459 gtk_notebook_get_arg (GtkObject *object,
463 GtkNotebook *notebook;
465 notebook = GTK_NOTEBOOK (object);
470 GTK_VALUE_BOOL (*arg) = notebook->show_tabs;
472 case ARG_SHOW_BORDER:
473 GTK_VALUE_BOOL (*arg) = notebook->show_border;
476 GTK_VALUE_BOOL (*arg) = notebook->scrollable;
478 case ARG_ENABLE_POPUP:
479 GTK_VALUE_BOOL (*arg) = notebook->menu != NULL;
481 case ARG_HOMOGENEOUS:
482 GTK_VALUE_BOOL (*arg) = notebook->homogeneous;
485 GTK_VALUE_INT (*arg) = gtk_notebook_get_current_page (notebook);
488 GTK_VALUE_ENUM (*arg) = notebook->tab_pos;
490 case ARG_TAB_HBORDER:
491 GTK_VALUE_UINT (*arg) = notebook->tab_hborder;
493 case ARG_TAB_VBORDER:
494 GTK_VALUE_UINT (*arg) = notebook->tab_vborder;
497 arg->type = GTK_TYPE_INVALID;
502 /* Private GtkWidget Methods :
506 * gtk_notebook_realize
507 * gtk_notebook_size_request
508 * gtk_notebook_size_allocate
509 * gtk_notebook_expose
510 * gtk_notebook_button_press
511 * gtk_notebook_button_release
512 * gtk_notebook_enter_notify
513 * gtk_notebook_leave_notify
514 * gtk_notebook_motion_notify
515 * gtk_notebook_key_press
516 * gtk_notebook_focus_in
517 * gtk_notebook_focus_out
518 * gtk_notebook_draw_focus
519 * gtk_notebook_style_set
522 gtk_notebook_map (GtkWidget *widget)
524 GtkNotebook *notebook;
525 GtkNotebookPage *page;
528 g_return_if_fail (widget != NULL);
529 g_return_if_fail (GTK_IS_NOTEBOOK (widget));
531 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
533 notebook = GTK_NOTEBOOK (widget);
535 if (notebook->cur_page &&
536 GTK_WIDGET_VISIBLE (notebook->cur_page->child) &&
537 !GTK_WIDGET_MAPPED (notebook->cur_page->child))
538 gtk_widget_map (notebook->cur_page->child);
540 if (notebook->scrollable)
541 gtk_notebook_pages_allocate (notebook);
544 children = notebook->children;
548 page = children->data;
549 children = children->next;
551 if (page->tab_label &&
552 GTK_WIDGET_VISIBLE (page->tab_label) &&
553 !GTK_WIDGET_MAPPED (page->tab_label))
554 gtk_widget_map (page->tab_label);
558 gdk_window_show (widget->window);
562 gtk_notebook_unmap (GtkWidget *widget)
564 g_return_if_fail (widget != NULL);
565 g_return_if_fail (GTK_IS_NOTEBOOK (widget));
567 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
568 gdk_window_hide (widget->window);
569 if (GTK_NOTEBOOK (widget)->panel)
570 gdk_window_hide (GTK_NOTEBOOK (widget)->panel);
574 gtk_notebook_realize (GtkWidget *widget)
576 GtkNotebook *notebook;
577 GdkWindowAttr attributes;
578 gint attributes_mask;
580 g_return_if_fail (widget != NULL);
581 g_return_if_fail (GTK_IS_NOTEBOOK (widget));
583 notebook = GTK_NOTEBOOK (widget);
584 GTK_WIDGET_SET_FLAGS (notebook, GTK_REALIZED);
586 attributes.window_type = GDK_WINDOW_CHILD;
587 attributes.x = widget->allocation.x;
588 attributes.y = widget->allocation.y;
589 attributes.width = widget->allocation.width;
590 attributes.height = widget->allocation.height;
591 attributes.wclass = GDK_INPUT_OUTPUT;
592 attributes.visual = gtk_widget_get_visual (widget);
593 attributes.colormap = gtk_widget_get_colormap (widget);
594 attributes.event_mask = gtk_widget_get_events (widget);
595 attributes.event_mask |= (GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK |
596 GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK);
598 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
600 widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
601 gdk_window_set_user_data (widget->window, notebook);
603 widget->style = gtk_style_attach (widget->style, widget->window);
604 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
606 gdk_window_set_back_pixmap (widget->window, NULL, TRUE);
607 if (notebook->scrollable)
608 gtk_notebook_panel_realize (notebook);
612 gtk_notebook_unrealize (GtkWidget *widget)
614 GtkNotebook *notebook;
616 g_return_if_fail (widget != NULL);
617 g_return_if_fail (GTK_IS_NOTEBOOK (widget));
619 notebook = GTK_NOTEBOOK (widget);
623 gdk_window_set_user_data (notebook->panel, NULL);
624 gdk_window_destroy (notebook->panel);
625 notebook->panel = NULL;
628 if (GTK_WIDGET_CLASS (parent_class)->unrealize)
629 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
633 gtk_notebook_size_request (GtkWidget *widget,
634 GtkRequisition *requisition)
636 GtkNotebook *notebook;
637 GtkNotebookPage *page;
639 GtkRequisition child_requisition;
640 gboolean switch_page = FALSE;
643 g_return_if_fail (widget != NULL);
644 g_return_if_fail (GTK_IS_NOTEBOOK (widget));
645 g_return_if_fail (requisition != NULL);
647 notebook = GTK_NOTEBOOK (widget);
648 widget->requisition.width = 0;
649 widget->requisition.height = 0;
651 for (children = notebook->children, vis_pages = 0; children;
652 children = children->next)
654 page = children->data;
656 if (GTK_WIDGET_VISIBLE (page->child))
659 gtk_widget_size_request (page->child, &child_requisition);
661 widget->requisition.width = MAX (widget->requisition.width,
662 child_requisition.width);
663 widget->requisition.height = MAX (widget->requisition.height,
664 child_requisition.height);
666 if (GTK_WIDGET_MAPPED (page->child) && page != notebook->cur_page)
667 gtk_widget_unmap (page->child);
668 if (notebook->menu && page->menu_label->parent &&
669 !GTK_WIDGET_VISIBLE (page->menu_label->parent))
670 gtk_widget_show (page->menu_label->parent);
674 if (page == notebook->cur_page)
676 if (notebook->menu && page->menu_label->parent &&
677 GTK_WIDGET_VISIBLE (page->menu_label->parent))
678 gtk_widget_hide (page->menu_label->parent);
682 if (notebook->show_border || notebook->show_tabs)
684 widget->requisition.width += widget->style->xthickness * 2;
685 widget->requisition.height += widget->style->ythickness * 2;
687 if (notebook->show_tabs)
694 for (children = notebook->children; children;
695 children = children->next)
697 page = children->data;
699 if (GTK_WIDGET_VISIBLE (page->child))
701 if (!GTK_WIDGET_VISIBLE (page->tab_label))
702 gtk_widget_show (page->tab_label);
704 gtk_widget_size_request (page->tab_label,
707 page->requisition.width =
708 child_requisition.width +
709 2 * widget->style->xthickness;
710 page->requisition.height =
711 child_requisition.height +
712 2 * widget->style->ythickness;
714 switch (notebook->tab_pos)
718 page->requisition.height += 2 * (notebook->tab_vborder +
720 tab_height = MAX (tab_height, page->requisition.height);
721 tab_max = MAX (tab_max, page->requisition.width);
725 page->requisition.width += 2 * (notebook->tab_hborder +
727 tab_width = MAX (tab_width, page->requisition.width);
728 tab_max = MAX (tab_max, page->requisition.height);
732 else if (GTK_WIDGET_VISIBLE (page->tab_label))
733 gtk_widget_hide (page->tab_label);
736 children = notebook->children;
740 switch (notebook->tab_pos)
747 if (notebook->scrollable && vis_pages > 1 &&
748 widget->requisition.width < tab_width)
749 tab_height = MAX (tab_height, ARROW_SIZE);
751 padding = 2 * (TAB_CURVATURE + FOCUS_WIDTH +
752 notebook->tab_hborder) - TAB_OVERLAP;
756 page = children->data;
757 children = children->next;
759 if (!GTK_WIDGET_VISIBLE (page->child))
762 if (notebook->homogeneous)
763 page->requisition.width = tab_max;
765 page->requisition.width += padding;
767 tab_width += page->requisition.width;
768 page->requisition.height = tab_height;
771 if (notebook->scrollable && vis_pages > 1 &&
772 widget->requisition.width < tab_width)
773 tab_width = tab_max + 2 * (ARROW_SIZE + ARROW_SPACING);
775 if (notebook->homogeneous && !notebook->scrollable)
776 widget->requisition.width = MAX (widget->requisition.width,
777 vis_pages * tab_max +
780 widget->requisition.width = MAX (widget->requisition.width,
781 tab_width + TAB_OVERLAP);
783 widget->requisition.height += tab_height;
790 if (notebook->scrollable && vis_pages > 1 &&
791 widget->requisition.height < tab_height)
792 tab_width = MAX (tab_width, ARROW_SPACING +2 * ARROW_SIZE);
794 padding = 2 * (TAB_CURVATURE + FOCUS_WIDTH +
795 notebook->tab_vborder) - TAB_OVERLAP;
800 page = children->data;
801 children = children->next;
803 if (!GTK_WIDGET_VISIBLE (page->child))
806 page->requisition.width = tab_width;
808 if (notebook->homogeneous)
809 page->requisition.height = tab_max;
811 page->requisition.height += padding;
813 tab_height += page->requisition.height;
816 if (notebook->scrollable && vis_pages > 1 &&
817 widget->requisition.height < tab_height)
818 tab_height = tab_max + ARROW_SIZE + ARROW_SPACING;
820 widget->requisition.width += tab_width;
822 if (notebook->homogeneous && !notebook->scrollable)
823 widget->requisition.height =
824 MAX (widget->requisition.height,
825 vis_pages * tab_max + TAB_OVERLAP);
827 widget->requisition.height =
828 MAX (widget->requisition.height,
829 tab_height + TAB_OVERLAP);
831 if (!notebook->homogeneous || notebook->scrollable)
833 widget->requisition.height = MAX (widget->requisition.height,
834 vis_pages * tab_max +
842 for (children = notebook->children; children;
843 children = children->next)
845 page = children->data;
847 if (page->tab_label && GTK_WIDGET_VISIBLE (page->tab_label))
848 gtk_widget_hide (page->tab_label);
853 widget->requisition.width += GTK_CONTAINER (widget)->border_width * 2;
854 widget->requisition.height += GTK_CONTAINER (widget)->border_width * 2;
860 for (children = notebook->children; children;
861 children = children->next)
863 page = children->data;
864 if (GTK_WIDGET_VISIBLE (page->child))
866 gtk_notebook_switch_page (notebook, page, -1);
871 else if (GTK_WIDGET_VISIBLE (widget))
873 widget->requisition.width = GTK_CONTAINER (widget)->border_width * 2;
874 widget->requisition.height= GTK_CONTAINER (widget)->border_width * 2;
877 if (vis_pages && !notebook->cur_page)
879 children = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, TRUE);
882 notebook->first_tab = children;
883 gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (children),-1);
889 gtk_notebook_size_allocate (GtkWidget *widget,
890 GtkAllocation *allocation)
892 GtkNotebook *notebook;
893 GtkNotebookPage *page;
894 GtkAllocation child_allocation;
897 g_return_if_fail (widget != NULL);
898 g_return_if_fail (GTK_IS_NOTEBOOK (widget));
899 g_return_if_fail (allocation != NULL);
901 widget->allocation = *allocation;
902 if (GTK_WIDGET_REALIZED (widget))
903 gdk_window_move_resize (widget->window,
904 allocation->x, allocation->y,
905 allocation->width, allocation->height);
907 notebook = GTK_NOTEBOOK (widget);
908 if (notebook->children)
910 child_allocation.x = GTK_CONTAINER (widget)->border_width;
911 child_allocation.y = GTK_CONTAINER (widget)->border_width;
912 child_allocation.width = MAX (1, (gint)allocation->width - child_allocation.x * 2);
913 child_allocation.height = MAX (1, (gint)allocation->height - child_allocation.y * 2);
915 if (notebook->show_tabs || notebook->show_border)
917 child_allocation.x += widget->style->xthickness;
918 child_allocation.y += widget->style->ythickness;
919 child_allocation.width = MAX (1, (gint)child_allocation.width -
920 (gint) widget->style->xthickness * 2);
921 child_allocation.height = MAX (1, (gint)child_allocation.height -
922 (gint) widget->style->ythickness * 2);
924 if (notebook->show_tabs && notebook->children && notebook->cur_page)
926 switch (notebook->tab_pos)
929 child_allocation.y += notebook->cur_page->requisition.height;
931 child_allocation.height =
932 MAX (1, (gint)child_allocation.height -
933 (gint)notebook->cur_page->requisition.height);
936 child_allocation.x += notebook->cur_page->requisition.width;
938 child_allocation.width =
939 MAX (1, (gint)child_allocation.width -
940 (gint)notebook->cur_page->requisition.width);
946 children = notebook->children;
949 page = children->data;
950 children = children->next;
952 if (GTK_WIDGET_VISIBLE (page->child))
953 gtk_widget_size_allocate (page->child, &child_allocation);
956 gtk_notebook_pages_allocate (notebook);
958 gtk_notebook_set_shape (notebook);
962 gtk_notebook_expose (GtkWidget *widget,
963 GdkEventExpose *event)
965 GtkNotebook *notebook;
966 GdkEventExpose child_event;
967 GdkRectangle child_area;
969 g_return_val_if_fail (widget != NULL, FALSE);
970 g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
971 g_return_val_if_fail (event != NULL, FALSE);
973 if (GTK_WIDGET_DRAWABLE (widget))
975 notebook = GTK_NOTEBOOK (widget);
977 gtk_notebook_paint (widget, &event->area);
978 if (notebook->show_tabs)
980 if (notebook->cur_page &&
981 gtk_widget_intersect (notebook->cur_page->tab_label,
982 &event->area, &child_area))
983 gtk_widget_draw_focus (widget);
986 child_event = *event;
987 if (notebook->cur_page &&
988 GTK_WIDGET_NO_WINDOW (notebook->cur_page->child) &&
989 gtk_widget_intersect (notebook->cur_page->child, &event->area,
991 gtk_widget_event (notebook->cur_page->child, (GdkEvent*) &child_event);
998 gtk_notebook_arrow_button_press (GtkNotebook *notebook,
999 GdkEventButton *event)
1001 GtkWidget *widget = GTK_WIDGET (notebook);
1003 GtkArrowType arrow = event->x <= ARROW_SIZE + ARROW_SPACING / 2 ? GTK_ARROW_LEFT : GTK_ARROW_RIGHT;
1005 if (!GTK_WIDGET_HAS_FOCUS (widget))
1006 gtk_widget_grab_focus (widget);
1008 notebook->button = event->button;
1009 notebook->click_child = arrow;
1011 if (event->button == 1)
1013 if (!notebook->focus_tab ||
1014 gtk_notebook_search_page (notebook, notebook->focus_tab,
1015 arrow == GTK_ARROW_LEFT ? STEP_PREV : STEP_NEXT,
1017 gtk_container_focus (GTK_CONTAINER (notebook),
1018 arrow == GTK_ARROW_LEFT ? GTK_DIR_LEFT : GTK_DIR_RIGHT);
1020 if (!notebook->timer)
1022 notebook->timer = gtk_timeout_add
1023 (NOTEBOOK_INIT_SCROLL_DELAY,
1024 (GtkFunction) gtk_notebook_timer, (gpointer) notebook);
1025 notebook->need_timer = TRUE;
1028 else if (event->button == 2)
1029 gtk_notebook_page_select (notebook, TRUE);
1030 else if (event->button == 3)
1031 gtk_notebook_switch_focus_tab (notebook,
1032 gtk_notebook_search_page (notebook,
1034 arrow == GTK_ARROW_LEFT ? STEP_NEXT : STEP_PREV,
1036 gtk_notebook_redraw_arrows (notebook);
1042 gtk_notebook_button_press (GtkWidget *widget,
1043 GdkEventButton *event)
1045 GtkNotebook *notebook;
1046 GtkNotebookPage *page;
1050 g_return_val_if_fail (widget != NULL, FALSE);
1051 g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
1052 g_return_val_if_fail (event != NULL, FALSE);
1054 notebook = GTK_NOTEBOOK (widget);
1056 if (event->type != GDK_BUTTON_PRESS || !notebook->children ||
1060 if (event->window == notebook->panel)
1062 return gtk_notebook_arrow_button_press (notebook, event);
1064 else if (event->window == widget->window)
1066 if (event->button == 3 && notebook->menu)
1068 gtk_menu_popup (GTK_MENU (notebook->menu), NULL, NULL,
1069 NULL, NULL, 3, event->time);
1074 children = notebook->children;
1077 page = children->data;
1079 if (GTK_WIDGET_VISIBLE (page->child) &&
1080 page->tab_label && GTK_WIDGET_MAPPED (page->tab_label) &&
1081 (event->x >= page->allocation.x) &&
1082 (event->y >= page->allocation.y) &&
1083 (event->x <= (page->allocation.x + page->allocation.width)) &&
1084 (event->y <= (page->allocation.y + page->allocation.height)))
1086 if (page == notebook->cur_page && notebook->focus_tab &&
1087 notebook->focus_tab != children &&
1088 GTK_WIDGET_HAS_FOCUS (notebook))
1090 GtkNotebookPage *old_page;
1092 notebook->child_has_focus = FALSE;
1093 old_page = (GtkNotebookPage *)
1094 (notebook->focus_tab->data);
1095 gtk_notebook_switch_focus_tab (notebook, children);
1096 gtk_notebook_focus_changed (notebook, old_page);
1100 gtk_notebook_switch_focus_tab (notebook, children);
1101 gtk_widget_grab_focus (widget);
1102 gtk_notebook_switch_page (notebook, page, num);
1106 children = children->next;
1109 if (!children && !GTK_WIDGET_HAS_FOCUS (widget))
1110 gtk_widget_grab_focus (widget);
1117 gtk_notebook_button_release (GtkWidget *widget,
1118 GdkEventButton *event)
1120 GtkNotebook *notebook;
1122 g_return_val_if_fail (widget != NULL, FALSE);
1123 g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
1124 g_return_val_if_fail (event != NULL, FALSE);
1126 if (event->type != GDK_BUTTON_RELEASE)
1129 notebook = GTK_NOTEBOOK (widget);
1131 if (event->button == notebook->button)
1135 if (notebook->timer)
1137 gtk_timeout_remove (notebook->timer);
1138 notebook->timer = 0;
1139 notebook->need_timer = FALSE;
1141 click_child = notebook->click_child;
1142 notebook->click_child = 0;
1143 notebook->button = 0;
1144 gtk_notebook_redraw_arrows (notebook);
1151 gtk_notebook_enter_notify (GtkWidget *widget,
1152 GdkEventCrossing *event)
1154 GtkNotebook *notebook;
1156 g_return_val_if_fail (widget != NULL, FALSE);
1157 g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
1158 g_return_val_if_fail (event != NULL, FALSE);
1160 notebook = GTK_NOTEBOOK (widget);
1162 if (event->window == notebook->panel)
1167 gdk_window_get_pointer (notebook->panel, &x, &y, NULL);
1169 if (x <= ARROW_SIZE + ARROW_SPACING / 2)
1170 notebook->in_child = GTK_ARROW_LEFT;
1172 notebook->in_child = GTK_ARROW_RIGHT;
1174 gtk_notebook_redraw_arrows (notebook);
1181 gtk_notebook_leave_notify (GtkWidget *widget,
1182 GdkEventCrossing *event)
1184 GtkNotebook *notebook;
1186 g_return_val_if_fail (widget != NULL, FALSE);
1187 g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
1188 g_return_val_if_fail (event != NULL, FALSE);
1190 notebook = GTK_NOTEBOOK (widget);
1192 if (event->window == notebook->panel)
1193 gtk_notebook_redraw_arrows (notebook);
1199 gtk_notebook_motion_notify (GtkWidget *widget,
1200 GdkEventMotion *event)
1202 GtkNotebook *notebook;
1204 g_return_val_if_fail (widget != NULL, FALSE);
1205 g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
1206 g_return_val_if_fail (event != NULL, FALSE);
1208 notebook = GTK_NOTEBOOK (widget);
1210 if (notebook->button)
1213 if (event->window == notebook->panel)
1216 GtkArrowType old_child = notebook->in_child;
1220 gdk_window_get_pointer (notebook->panel, &x, NULL, NULL);
1222 if (x <= ARROW_SIZE + ARROW_SPACING / 2)
1223 notebook->in_child = GTK_ARROW_LEFT;
1225 notebook->in_child = GTK_ARROW_RIGHT;
1227 if (old_child != notebook->in_child)
1228 gtk_notebook_redraw_arrows (notebook);
1235 gtk_notebook_key_press (GtkWidget *widget,
1238 GtkNotebook *notebook;
1241 g_return_val_if_fail (widget != NULL, FALSE);
1242 g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
1243 g_return_val_if_fail (event != NULL, FALSE);
1245 notebook = GTK_NOTEBOOK (widget);
1247 if (!notebook->children || !notebook->show_tabs)
1250 switch (event->keyval)
1253 list = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, TRUE);
1255 gtk_notebook_switch_focus_tab (notebook, list);
1258 list = gtk_notebook_search_page (notebook, NULL, STEP_PREV, TRUE);
1260 gtk_notebook_switch_focus_tab (notebook, list);
1263 gtk_notebook_page_select (GTK_NOTEBOOK (widget), TRUE);
1266 gtk_notebook_page_select (GTK_NOTEBOOK (widget), FALSE);
1274 gtk_notebook_focus_in (GtkWidget *widget,
1275 GdkEventFocus *event)
1277 g_return_val_if_fail (widget != NULL, FALSE);
1278 g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
1279 g_return_val_if_fail (event != NULL, FALSE);
1281 GTK_NOTEBOOK (widget)->child_has_focus = FALSE;
1282 GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
1283 gtk_widget_draw_focus (widget);
1289 gtk_notebook_focus_out (GtkWidget *widget,
1290 GdkEventFocus *event)
1292 g_return_val_if_fail (widget != NULL, FALSE);
1293 g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
1294 g_return_val_if_fail (event != NULL, FALSE);
1296 GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
1297 gtk_widget_draw_focus (widget);
1303 gtk_notebook_draw_focus (GtkWidget *widget)
1305 GtkNotebook *notebook;
1307 g_return_if_fail (widget != NULL);
1308 g_return_if_fail (GTK_IS_NOTEBOOK (widget));
1310 notebook = GTK_NOTEBOOK (widget);
1312 if (GTK_WIDGET_DRAWABLE (widget) && notebook->show_tabs &&
1313 notebook->focus_tab)
1315 GtkNotebookPage *page;
1318 page = notebook->focus_tab->data;
1320 area.x = page->tab_label->allocation.x - 1;
1321 area.y = page->tab_label->allocation.y - 1;
1322 area.width = page->tab_label->allocation.width + 2;
1323 area.height = page->tab_label->allocation.height + 2;
1325 gtk_notebook_draw_tab (GTK_NOTEBOOK (widget), page, &area);
1330 gtk_notebook_style_set (GtkWidget *widget,
1331 GtkStyle *previous_style)
1333 if (GTK_WIDGET_REALIZED (widget) &&
1334 !GTK_WIDGET_NO_WINDOW (widget))
1336 gtk_style_set_background (widget->style, widget->window, widget->state);
1337 if (GTK_WIDGET_DRAWABLE (widget))
1338 gdk_window_clear (widget->window);
1341 gtk_notebook_set_shape (GTK_NOTEBOOK(widget));
1344 /* Private GtkContainer Methods :
1346 * gtk_notebook_set_child_arg
1347 * gtk_notebook_get_child_arg
1349 * gtk_notebook_remove
1350 * gtk_notebook_focus
1351 * gtk_notebook_set_focus_child
1352 * gtk_notebook_child_type
1353 * gtk_notebook_forall
1356 gtk_notebook_set_child_arg (GtkContainer *container,
1363 GtkPackType pack_type;
1367 case CHILD_ARG_TAB_LABEL:
1368 /* a NULL pointer indicates a default_tab setting, otherwise
1369 * we need to set the associated label
1371 gtk_notebook_set_tab_label_text (GTK_NOTEBOOK (container), child,
1372 GTK_VALUE_STRING(*arg));
1374 case CHILD_ARG_MENU_LABEL:
1375 gtk_notebook_set_menu_label_text (GTK_NOTEBOOK (container), child,
1376 GTK_VALUE_STRING (*arg));
1378 case CHILD_ARG_POSITION:
1379 gtk_notebook_reorder_child (GTK_NOTEBOOK (container), child,
1380 GTK_VALUE_INT (*arg));
1382 case CHILD_ARG_TAB_EXPAND:
1383 gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (container), child,
1384 &expand, &fill, &pack_type);
1385 gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (container), child,
1386 GTK_VALUE_BOOL (*arg),
1389 case CHILD_ARG_TAB_FILL:
1390 gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (container), child,
1391 &expand, &fill, &pack_type);
1392 gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (container), child,
1394 GTK_VALUE_BOOL (*arg),
1397 case CHILD_ARG_TAB_PACK:
1398 gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (container), child,
1399 &expand, &fill, &pack_type);
1400 gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (container), child,
1402 GTK_VALUE_BOOL (*arg));
1410 gtk_notebook_get_child_arg (GtkContainer *container,
1416 GtkNotebook *notebook;
1420 GtkPackType pack_type;
1422 notebook = GTK_NOTEBOOK (container);
1424 arg->type = GTK_TYPE_INVALID;
1426 list = CHECK_FIND_CHILD (notebook, child);
1429 arg->type = GTK_TYPE_INVALID;
1435 case CHILD_ARG_TAB_LABEL:
1436 label = gtk_notebook_get_tab_label (notebook, child);
1438 if (label && GTK_IS_LABEL (label))
1439 GTK_VALUE_STRING (*arg) = g_strdup (GTK_LABEL (label)->label);
1441 GTK_VALUE_STRING (*arg) = NULL;
1443 case CHILD_ARG_MENU_LABEL:
1444 label = gtk_notebook_get_menu_label (notebook, child);
1446 if (label && GTK_IS_LABEL (label))
1447 GTK_VALUE_STRING (*arg) = g_strdup (GTK_LABEL (label)->label);
1449 GTK_VALUE_STRING (*arg) = NULL;
1451 case CHILD_ARG_POSITION:
1452 GTK_VALUE_INT (*arg) = g_list_position (notebook->children, list);
1454 case CHILD_ARG_TAB_EXPAND:
1455 gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (container), child,
1456 &expand, NULL, NULL);
1457 GTK_VALUE_BOOL (*arg) = expand;
1459 case CHILD_ARG_TAB_FILL:
1460 gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (container), child,
1462 GTK_VALUE_BOOL (*arg) = fill;
1464 case CHILD_ARG_TAB_PACK:
1465 gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (container), child,
1466 NULL, NULL, &pack_type);
1467 GTK_VALUE_BOOL (*arg) = pack_type;
1470 arg->type = GTK_TYPE_INVALID;
1476 gtk_notebook_add (GtkContainer *container,
1479 g_return_if_fail (container != NULL);
1480 g_return_if_fail (GTK_IS_NOTEBOOK (container));
1482 gtk_notebook_insert_page_menu (GTK_NOTEBOOK (container), widget,
1487 gtk_notebook_remove (GtkContainer *container,
1490 GtkNotebook *notebook;
1491 GtkNotebookPage *page;
1495 g_return_if_fail (container != NULL);
1496 g_return_if_fail (GTK_IS_NOTEBOOK (container));
1497 g_return_if_fail (widget != NULL);
1499 notebook = GTK_NOTEBOOK (container);
1501 children = notebook->children;
1505 page = children->data;
1506 if (page->child == widget)
1508 gtk_notebook_real_remove (notebook, children);
1512 children = children->next;
1517 focus_tabs_in (GtkNotebook *notebook)
1519 if (notebook->cur_page)
1521 gtk_widget_grab_focus (GTK_WIDGET (notebook));
1523 gtk_notebook_switch_focus_tab (notebook,
1524 g_list_find (notebook->children,
1525 notebook->cur_page));
1534 focus_tabs_move (GtkNotebook *notebook,
1535 GtkDirectionType direction,
1536 gint search_direction)
1540 new_page = gtk_notebook_search_page (notebook, notebook->focus_tab,
1541 search_direction, TRUE);
1543 new_page = (search_direction == STEP_NEXT) ?
1544 notebook->children :
1545 g_list_last (notebook->children);
1547 gtk_notebook_switch_focus_tab (notebook, new_page);
1553 focus_child_in (GtkNotebook *notebook,
1554 GtkDirectionType direction)
1556 if (GTK_WIDGET_DRAWABLE (notebook->cur_page->child) &&
1557 GTK_WIDGET_IS_SENSITIVE (notebook->cur_page->child))
1559 if (GTK_IS_CONTAINER (notebook->cur_page->child))
1561 if (gtk_container_focus (GTK_CONTAINER (notebook->cur_page->child), direction))
1564 else if (GTK_WIDGET_CAN_FOCUS (notebook->cur_page->child))
1566 gtk_widget_grab_focus (notebook->cur_page->child);
1573 /* Focus in the notebook can either be on the pages, or on
1577 gtk_notebook_focus (GtkContainer *container,
1578 GtkDirectionType direction)
1580 GtkWidget *old_focus_child;
1581 GtkNotebook *notebook;
1582 GtkDirectionType effective_direction;
1584 /* Remap the directions into the effective direction it would be for a
1585 * GTK_POS_TOP notebook
1587 #define D(rest) GTK_DIR_##rest
1589 static const GtkDirectionType translate_direction[4][6] = {
1590 /* LEFT */ { D(TAB_FORWARD), D(TAB_BACKWARD), D(LEFT), D(RIGHT), D(UP), D(DOWN) },
1591 /* RIGHT */ { D(TAB_BACKWARD), D(TAB_FORWARD), D(LEFT), D(RIGHT), D(DOWN), D(UP) },
1592 /* TOP */ { D(TAB_FORWARD), D(TAB_BACKWARD), D(UP), D(DOWN), D(LEFT), D(RIGHT) },
1593 /* BOTTOM */ { D(TAB_BACKWARD), D(TAB_FORWARD), D(DOWN), D(UP), D(LEFT), D(RIGHT) },
1598 gboolean widget_is_focus;
1600 g_return_val_if_fail (container != NULL, FALSE);
1601 g_return_val_if_fail (GTK_IS_NOTEBOOK (container), FALSE);
1603 notebook = GTK_NOTEBOOK (container);
1605 widget_is_focus = gtk_widget_is_focus (GTK_WIDGET (container));
1606 old_focus_child = container->focus_child;
1608 effective_direction = translate_direction[notebook->tab_pos][direction];
1610 if (old_focus_child &&
1611 GTK_IS_CONTAINER (old_focus_child) &&
1612 GTK_WIDGET_DRAWABLE (old_focus_child) &&
1613 GTK_WIDGET_IS_SENSITIVE (old_focus_child) &&
1614 gtk_container_focus (GTK_CONTAINER (old_focus_child), direction))
1617 if (old_focus_child) /* Focus on page child */
1619 switch (effective_direction)
1621 case GTK_DIR_TAB_BACKWARD:
1623 /* Focus onto the tabs */
1624 if (notebook->show_tabs)
1625 return focus_tabs_in (notebook);
1629 case GTK_DIR_TAB_FORWARD:
1635 else if (widget_is_focus) /* Focus was on tabs */
1637 switch (effective_direction)
1639 case GTK_DIR_TAB_BACKWARD:
1642 case GTK_DIR_TAB_FORWARD:
1644 return focus_child_in (notebook, direction);
1646 return focus_tabs_move (notebook, direction, STEP_PREV);
1648 return focus_tabs_move (notebook, direction, STEP_NEXT);
1651 else /* Focus was not on widget */
1653 switch (effective_direction)
1655 case GTK_DIR_TAB_FORWARD:
1657 if (focus_tabs_in (notebook))
1659 if (focus_child_in (notebook, direction))
1662 case GTK_DIR_TAB_BACKWARD:
1664 if (focus_child_in (notebook, direction))
1666 if (focus_tabs_in (notebook))
1671 return focus_child_in (notebook, direction);
1675 g_assert_not_reached ();
1680 gtk_notebook_set_focus_child (GtkContainer *container,
1683 GtkNotebook *notebook;
1685 g_return_if_fail (container != NULL);
1686 g_return_if_fail (GTK_IS_NOTEBOOK (container));
1690 g_return_if_fail (GTK_IS_WIDGET (child));
1692 notebook = GTK_NOTEBOOK (container);
1694 notebook->child_has_focus = TRUE;
1695 if (!notebook->focus_tab)
1698 GtkNotebookPage *page;
1700 children = notebook->children;
1703 page = children->data;
1704 if (page->child == child || page->tab_label == child)
1705 gtk_notebook_switch_focus_tab (notebook, children);
1706 children = children->next;
1710 parent_class->set_focus_child (container, child);
1714 gtk_notebook_forall (GtkContainer *container,
1715 gboolean include_internals,
1716 GtkCallback callback,
1717 gpointer callback_data)
1719 GtkNotebook *notebook;
1722 g_return_if_fail (container != NULL);
1723 g_return_if_fail (GTK_IS_NOTEBOOK (container));
1724 g_return_if_fail (callback != NULL);
1726 notebook = GTK_NOTEBOOK (container);
1728 children = notebook->children;
1731 GtkNotebookPage *page;
1733 page = children->data;
1734 children = children->next;
1735 (* callback) (page->child, callback_data);
1736 if (include_internals)
1738 if (page->tab_label)
1739 (* callback) (page->tab_label, callback_data);
1740 if (page->menu_label)
1741 (* callback) (page->menu_label, callback_data);
1747 gtk_notebook_child_type (GtkContainer *container)
1749 return GTK_TYPE_WIDGET;
1752 /* Private GtkNotebook Functions:
1754 * gtk_notebook_panel_realize
1755 * gtk_notebook_redraw_tabs
1756 * gtk_notebook_focus_changed
1757 * gtk_notebook_real_remove
1758 * gtk_notebook_update_labels
1759 * gtk_notebook_timer
1760 * gtk_notebook_page_compare
1761 * gtk_notebook_real_page_position
1762 * gtk_notebook_search_page
1765 gtk_notebook_panel_realize (GtkNotebook *notebook)
1768 GdkWindowAttr attributes;
1769 gint attributes_mask;
1771 g_return_if_fail (notebook != NULL);
1772 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
1774 widget = GTK_WIDGET (notebook);
1776 attributes.window_type = GDK_WINDOW_CHILD;
1777 attributes.wclass = GDK_INPUT_OUTPUT;
1778 attributes.visual = gtk_widget_get_visual (widget);
1779 attributes.colormap = gtk_widget_get_colormap (widget);
1780 attributes.event_mask = gtk_widget_get_events (widget);
1781 attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK
1782 | GDK_BUTTON_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_ENTER_NOTIFY_MASK
1783 | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK;
1785 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
1787 attributes.width = 2 * ARROW_SIZE + ARROW_SPACING;
1788 attributes.height = ARROW_SIZE;
1790 attributes.x = (widget->allocation.width - attributes.width -
1791 GTK_CONTAINER (notebook)->border_width);
1792 attributes.y = (widget->allocation.height - ARROW_SIZE -
1793 GTK_CONTAINER (notebook)->border_width);
1794 if (notebook->tab_pos == GTK_POS_TOP)
1795 attributes.y = GTK_CONTAINER (notebook)->border_width;
1796 else if (notebook->tab_pos == GTK_POS_LEFT)
1797 attributes.x = (widget->allocation.x +
1798 GTK_CONTAINER (notebook)->border_width);
1800 notebook->panel = gdk_window_new (widget->window, &attributes,
1802 gtk_style_set_background (widget->style, notebook->panel,
1804 gdk_window_set_back_pixmap (widget->window, NULL, TRUE);
1805 gdk_window_set_user_data (notebook->panel, widget);
1809 gtk_notebook_redraw_tabs (GtkNotebook *notebook)
1812 GtkNotebookPage *page;
1813 GdkRectangle redraw_rect;
1816 widget = GTK_WIDGET (notebook);
1817 border = GTK_CONTAINER (notebook)->border_width;
1819 if (!GTK_WIDGET_MAPPED (notebook) || !notebook->first_tab)
1822 page = notebook->first_tab->data;
1824 redraw_rect.x = border;
1825 redraw_rect.y = border;
1827 switch (notebook->tab_pos)
1829 case GTK_POS_BOTTOM:
1830 redraw_rect.y = (widget->allocation.height - border -
1831 page->allocation.height -
1832 widget->style->ythickness);
1833 if (page != notebook->cur_page)
1834 redraw_rect.y -= widget->style->ythickness;
1837 redraw_rect.width = widget->allocation.width - 2 * border;
1838 redraw_rect.height = (page->allocation.height +
1839 widget->style->ythickness);
1840 if (page != notebook->cur_page)
1841 redraw_rect.height += widget->style->ythickness;
1844 redraw_rect.x = (widget->allocation.width - border -
1845 page->allocation.width -
1846 widget->style->xthickness);
1847 if (page != notebook->cur_page)
1848 redraw_rect.x -= widget->style->xthickness;
1851 redraw_rect.width = (page->allocation.width +
1852 widget->style->xthickness);
1853 redraw_rect.height = widget->allocation.height - 2 * border;
1854 if (page != notebook->cur_page)
1855 redraw_rect.width += widget->style->xthickness;
1859 gdk_window_invalidate_rect (widget->window, &redraw_rect, TRUE);
1863 gtk_notebook_redraw_arrows (GtkNotebook *notebook)
1865 if (GTK_WIDGET_MAPPED (notebook) && notebook->panel)
1866 gdk_window_invalidate_rect (notebook->panel, NULL, FALSE);
1870 gtk_notebook_focus_changed (GtkNotebook *notebook,
1871 GtkNotebookPage *old_page)
1873 g_return_if_fail (notebook != NULL);
1874 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
1876 if (GTK_WIDGET_DRAWABLE (notebook) && notebook->show_tabs)
1880 if (notebook->focus_tab)
1882 GtkNotebookPage *page;
1884 page = notebook->focus_tab->data;
1886 area.x = page->tab_label->allocation.x - 1;
1887 area.y = page->tab_label->allocation.y - 1;
1888 area.width = page->tab_label->allocation.width + 2;
1889 area.height = page->tab_label->allocation.height + 2;
1891 gtk_notebook_draw_tab (notebook, page, &area);
1896 area.x = old_page->tab_label->allocation.x - 1;
1897 area.y = old_page->tab_label->allocation.y - 1;
1898 area.width = old_page->tab_label->allocation.width + 2;
1899 area.height = old_page->tab_label->allocation.height + 2;
1901 gtk_notebook_draw_tab (notebook, old_page, &area);
1907 gtk_notebook_timer (GtkNotebook *notebook)
1909 gboolean retval = FALSE;
1911 GDK_THREADS_ENTER ();
1913 if (notebook->timer)
1915 if (notebook->click_child == GTK_ARROW_LEFT)
1917 if (!notebook->focus_tab ||
1918 gtk_notebook_search_page (notebook, notebook->focus_tab,
1920 gtk_container_focus (GTK_CONTAINER (notebook), GTK_DIR_LEFT);
1922 else if (notebook->click_child == GTK_ARROW_RIGHT)
1924 if (!notebook->focus_tab ||
1925 gtk_notebook_search_page (notebook, notebook->focus_tab,
1927 gtk_container_focus (GTK_CONTAINER (notebook), GTK_DIR_RIGHT);
1929 if (notebook->need_timer)
1931 notebook->need_timer = FALSE;
1932 notebook->timer = gtk_timeout_add (NOTEBOOK_SCROLL_DELAY,
1933 (GtkFunction) gtk_notebook_timer,
1934 (gpointer) notebook);
1940 GDK_THREADS_LEAVE ();
1946 gtk_notebook_page_compare (gconstpointer a,
1949 return (((GtkNotebookPage *) a)->child != b);
1953 gtk_notebook_find_child (GtkNotebook *notebook,
1955 const gchar *function)
1957 GList *list = g_list_find_custom (notebook->children, child,
1958 gtk_notebook_page_compare);
1960 #ifndef G_DISABLE_CHECKS
1962 g_warning ("child argument to '%s' does not refer to the contents of a notebook page",
1970 gtk_notebook_real_remove (GtkNotebook *notebook,
1973 GtkNotebookPage *page;
1975 gint need_resize = FALSE;
1977 next_list = gtk_notebook_search_page (notebook, list, STEP_PREV, TRUE);
1979 next_list = gtk_notebook_search_page (notebook, list, STEP_NEXT, TRUE);
1981 if (notebook->cur_page == list->data)
1983 notebook->cur_page = NULL;
1985 gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (next_list), -1);
1988 if (list == notebook->first_tab)
1989 notebook->first_tab = next_list;
1990 if (list == notebook->focus_tab)
1991 gtk_notebook_switch_focus_tab (notebook, next_list);
1995 if (GTK_WIDGET_VISIBLE (page->child) && GTK_WIDGET_VISIBLE (notebook))
1998 gtk_widget_unparent (page->child);
2000 if (page->tab_label)
2001 gtk_widget_unparent (page->tab_label);
2005 gtk_container_remove (GTK_CONTAINER (notebook->menu),
2006 page->menu_label->parent);
2007 gtk_widget_queue_resize (notebook->menu);
2009 if (!page->default_menu)
2010 gtk_widget_unref (page->menu_label);
2012 notebook->children = g_list_remove_link (notebook->children, list);
2016 gtk_notebook_update_labels (notebook);
2018 gtk_widget_queue_resize (GTK_WIDGET (notebook));
2022 gtk_notebook_update_labels (GtkNotebook *notebook)
2024 GtkNotebookPage *page;
2029 for (list = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, FALSE);
2031 list = gtk_notebook_search_page (notebook, list, STEP_NEXT, FALSE))
2034 g_snprintf (string, sizeof(string), _("Page %u"), page_num++);
2035 if (notebook->show_tabs)
2037 if (page->default_tab)
2039 if (!page->tab_label)
2041 page->tab_label = gtk_label_new (string);
2042 gtk_widget_set_parent (page->tab_label,
2043 GTK_WIDGET (notebook));
2046 gtk_label_set_text (GTK_LABEL (page->tab_label), string);
2049 if (GTK_WIDGET_VISIBLE (page->child) &&
2050 !GTK_WIDGET_VISIBLE (page->tab_label))
2051 gtk_widget_show (page->tab_label);
2052 else if (!GTK_WIDGET_VISIBLE (page->child) &&
2053 GTK_WIDGET_VISIBLE (page->tab_label))
2054 gtk_widget_hide (page->tab_label);
2056 if (notebook->menu && page->default_menu)
2058 if (page->tab_label && GTK_IS_LABEL (page->tab_label))
2059 gtk_label_set_text (GTK_LABEL (page->menu_label),
2060 GTK_LABEL (page->tab_label)->label);
2062 gtk_label_set_text (GTK_LABEL (page->menu_label), string);
2068 gtk_notebook_real_page_position (GtkNotebook *notebook,
2074 g_return_val_if_fail (notebook != NULL, -1);
2075 g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1);
2076 g_return_val_if_fail (list != NULL, -1);
2078 for (work = notebook->children, count_start = 0;
2079 work && work != list; work = work->next)
2080 if (GTK_NOTEBOOK_PAGE (work)->pack == GTK_PACK_START)
2086 if (GTK_NOTEBOOK_PAGE (list)->pack == GTK_PACK_START)
2089 return (count_start + g_list_length (list) - 1);
2093 gtk_notebook_search_page (GtkNotebook *notebook,
2096 gboolean find_visible)
2098 GtkNotebookPage *page = NULL;
2099 GList *old_list = NULL;
2102 g_return_val_if_fail (notebook != NULL, NULL);
2103 g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL);
2108 flag = GTK_PACK_END;
2112 flag = GTK_PACK_START;
2119 if (!page || page->pack == flag)
2127 list = notebook->children;
2132 if (page->pack == flag &&
2133 (!find_visible || GTK_WIDGET_VISIBLE (page->child)))
2148 if (page->pack != flag &&
2149 (!find_visible || GTK_WIDGET_VISIBLE (page->child)))
2157 /* Private GtkNotebook Drawing Functions:
2159 * gtk_notebook_paint
2160 * gtk_notebook_draw_tab
2161 * gtk_notebook_draw_arrow
2162 * gtk_notebook_set_shape
2165 gtk_notebook_paint (GtkWidget *widget,
2168 GtkNotebook *notebook;
2169 GtkNotebookPage *page;
2174 gint gap_x = 0, gap_width = 0;
2176 g_return_if_fail (widget != NULL);
2177 g_return_if_fail (GTK_IS_NOTEBOOK (widget));
2178 g_return_if_fail (area != NULL);
2180 if (!GTK_WIDGET_DRAWABLE (widget))
2183 notebook = GTK_NOTEBOOK (widget);
2185 if ((!notebook->show_tabs && !notebook->show_border) ||
2186 !notebook->cur_page || !GTK_WIDGET_VISIBLE (notebook->cur_page->child))
2188 gdk_window_clear_area (widget->window,
2190 area->width, area->height);
2194 x = GTK_CONTAINER (widget)->border_width;
2195 y = GTK_CONTAINER (widget)->border_width;
2196 width = widget->allocation.width - x * 2;
2197 height = widget->allocation.height - y * 2;
2199 if (notebook->show_border && (!notebook->show_tabs || !notebook->children))
2201 gtk_paint_box (widget->style, widget->window,
2202 GTK_STATE_NORMAL, GTK_SHADOW_OUT,
2203 area, widget, "notebook",
2204 x, y, width, height);
2209 if (!GTK_WIDGET_MAPPED (notebook->cur_page->tab_label))
2211 page = notebook->first_tab->data;
2213 switch (notebook->tab_pos)
2216 y += page->allocation.height + widget->style->ythickness;
2217 case GTK_POS_BOTTOM:
2218 height -= page->allocation.height + widget->style->ythickness;
2221 x += page->allocation.width + widget->style->xthickness;
2223 width -= page->allocation.width + widget->style->xthickness;
2226 gtk_paint_box (widget->style, widget->window,
2227 GTK_STATE_NORMAL, GTK_SHADOW_OUT,
2228 area, widget, "notebook",
2229 x, y, width, height);
2233 switch (notebook->tab_pos)
2236 y += notebook->cur_page->allocation.height;
2237 case GTK_POS_BOTTOM:
2238 height -= notebook->cur_page->allocation.height;
2241 x += notebook->cur_page->allocation.width;
2243 width -= notebook->cur_page->allocation.width;
2247 switch (notebook->tab_pos)
2250 gap_x = (notebook->cur_page->allocation.x -
2251 GTK_CONTAINER(notebook)->border_width);
2252 gap_width = notebook->cur_page->allocation.width;
2254 case GTK_POS_BOTTOM:
2255 gap_x = (notebook->cur_page->allocation.x -
2256 GTK_CONTAINER(notebook)->border_width);
2257 gap_width = notebook->cur_page->allocation.width;
2260 gap_x = (notebook->cur_page->allocation.y -
2261 GTK_CONTAINER(notebook)->border_width);
2262 gap_width = notebook->cur_page->allocation.height;
2265 gap_x = (notebook->cur_page->allocation.y -
2266 GTK_CONTAINER(notebook)->border_width);
2267 gap_width = notebook->cur_page->allocation.height;
2270 gtk_paint_box_gap(widget->style, widget->window,
2271 GTK_STATE_NORMAL, GTK_SHADOW_OUT,
2272 area, widget, "notebook",
2273 x, y, width, height,
2274 notebook->tab_pos, gap_x, gap_width);
2278 children = gtk_notebook_search_page (notebook, NULL, STEP_PREV, TRUE);
2281 page = children->data;
2282 children = gtk_notebook_search_page (notebook, children,
2284 if (!GTK_WIDGET_VISIBLE (page->child))
2286 if (!GTK_WIDGET_MAPPED (page->tab_label))
2288 else if (page != notebook->cur_page)
2289 gtk_notebook_draw_tab (notebook, page, area);
2292 if (showarrow && notebook->scrollable)
2294 gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT);
2295 gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT);
2297 gtk_notebook_draw_tab (notebook, notebook->cur_page, area);
2301 gtk_notebook_draw_tab (GtkNotebook *notebook,
2302 GtkNotebookPage *page,
2305 GdkRectangle child_area;
2306 GdkRectangle page_area;
2307 GtkStateType state_type;
2308 GtkPositionType gap_side;
2310 g_return_if_fail (notebook != NULL);
2311 g_return_if_fail (page != NULL);
2312 g_return_if_fail (area != NULL);
2314 if (!GTK_WIDGET_MAPPED (page->tab_label) ||
2315 (page->allocation.width == 0) || (page->allocation.height == 0))
2318 page_area.x = page->allocation.x;
2319 page_area.y = page->allocation.y;
2320 page_area.width = page->allocation.width;
2321 page_area.height = page->allocation.height;
2323 if (gdk_rectangle_intersect (&page_area, area, &child_area))
2327 widget = GTK_WIDGET (notebook);
2329 switch (notebook->tab_pos)
2332 gap_side = GTK_POS_BOTTOM;
2334 case GTK_POS_BOTTOM:
2335 gap_side = GTK_POS_TOP;
2338 gap_side = GTK_POS_RIGHT;
2341 gap_side = GTK_POS_LEFT;
2345 if (notebook->cur_page == page)
2346 state_type = GTK_STATE_NORMAL;
2348 state_type = GTK_STATE_ACTIVE;
2349 gtk_paint_extension(widget->style, widget->window,
2350 state_type, GTK_SHADOW_OUT,
2351 area, widget, "tab",
2352 page_area.x, page_area.y,
2353 page_area.width, page_area.height,
2355 if ((GTK_WIDGET_HAS_FOCUS (widget)) &&
2356 notebook->focus_tab && (notebook->focus_tab->data == page))
2358 gtk_paint_focus (widget->style, widget->window,
2359 area, widget, "tab",
2360 page->tab_label->allocation.x - 1,
2361 page->tab_label->allocation.y - 1,
2362 page->tab_label->allocation.width + 1,
2363 page->tab_label->allocation.height + 1);
2365 if (gtk_widget_intersect (page->tab_label, area, &child_area) &&
2366 GTK_WIDGET_DRAWABLE (page->tab_label))
2368 GdkEventExpose expose_event;
2370 /* This is a lame hack since all this code needs rewriting anyhow */
2372 expose_event.window = page->tab_label->window;
2373 expose_event.area = child_area;
2374 expose_event.send_event = TRUE;
2375 expose_event.type = GDK_EXPOSE;
2376 expose_event.count = 0;
2378 gtk_widget_event (page->tab_label,
2379 (GdkEvent*)&expose_event);
2385 gtk_notebook_draw_arrow (GtkNotebook *notebook,
2388 GtkStateType state_type;
2389 GtkShadowType shadow_type;
2392 g_return_if_fail (notebook != NULL);
2393 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
2395 widget = GTK_WIDGET(notebook);
2397 if (GTK_WIDGET_DRAWABLE (notebook))
2399 if (notebook->in_child == arrow)
2401 if (notebook->click_child == arrow)
2402 state_type = GTK_STATE_ACTIVE;
2404 state_type = GTK_STATE_PRELIGHT;
2407 state_type = GTK_STATE_NORMAL;
2409 if (notebook->click_child == arrow)
2410 shadow_type = GTK_SHADOW_IN;
2412 shadow_type = GTK_SHADOW_OUT;
2414 if (arrow == GTK_ARROW_LEFT)
2416 if (notebook->focus_tab &&
2417 !gtk_notebook_search_page (notebook, notebook->focus_tab,
2420 shadow_type = GTK_SHADOW_ETCHED_IN;
2421 state_type = GTK_STATE_NORMAL;
2424 if (notebook->tab_pos == GTK_POS_LEFT ||
2425 notebook->tab_pos == GTK_POS_RIGHT)
2426 arrow = GTK_ARROW_UP;
2428 gdk_window_clear_area (notebook->panel, 0, 0, ARROW_SIZE, ARROW_SIZE);
2429 gtk_paint_arrow (widget->style, notebook->panel, state_type,
2430 shadow_type, NULL, GTK_WIDGET(notebook), "notebook",
2432 0, 0, ARROW_SIZE, ARROW_SIZE);
2436 if (notebook->focus_tab &&
2437 !gtk_notebook_search_page (notebook, notebook->focus_tab,
2440 shadow_type = GTK_SHADOW_ETCHED_IN;
2441 state_type = GTK_STATE_NORMAL;
2444 if (notebook->tab_pos == GTK_POS_LEFT ||
2445 notebook->tab_pos == GTK_POS_RIGHT)
2446 arrow = GTK_ARROW_DOWN;
2448 gdk_window_clear_area(notebook->panel, ARROW_SIZE + ARROW_SPACING,
2449 0, ARROW_SIZE, ARROW_SIZE);
2450 gtk_paint_arrow (widget->style, notebook->panel, state_type,
2451 shadow_type, NULL, GTK_WIDGET(notebook), "notebook",
2452 arrow, TRUE, ARROW_SIZE + ARROW_SPACING,
2453 0, ARROW_SIZE, ARROW_SIZE);
2459 gtk_notebook_set_shape (GtkNotebook *notebook)
2461 GtkWidget *widget = NULL;
2462 GdkPixmap *pm = NULL;
2465 gint x, y, width, height, w, h, depth;
2466 GtkNotebookPage *page;
2469 if (!GTK_WIDGET(notebook)->window)
2472 widget = GTK_WIDGET(notebook);
2474 w = widget->allocation.width;
2475 h = widget->allocation.height;
2477 pm = gdk_pixmap_new (widget->window, w, h, 1);
2478 pmgc = gdk_gc_new (pm);
2480 /* clear the shape mask */
2482 gdk_gc_set_foreground(pmgc, &col);
2483 gdk_draw_rectangle(pm, pmgc, TRUE, 0, 0, w, h);
2486 gdk_gc_set_foreground(pmgc, &col);
2488 /* draw the shape for the notebook page itself */
2489 x = GTK_CONTAINER(notebook)->border_width;
2490 y = GTK_CONTAINER(notebook)->border_width;
2491 width = widget->allocation.width - x * 2;
2492 height = widget->allocation.height - y * 2;
2494 if (notebook->show_tabs && notebook->children)
2496 if (!(notebook->show_tabs))
2498 page = notebook->first_tab->data;
2499 switch (notebook->tab_pos)
2502 y += page->allocation.height +
2503 widget->style->ythickness;
2504 case GTK_POS_BOTTOM:
2505 height -= page->allocation.height +
2506 widget->style->ythickness;
2509 x += page->allocation.width +
2510 widget->style->xthickness;
2512 width -= page->allocation.width +
2513 widget->style->xthickness;
2519 if (notebook->cur_page)
2520 page = notebook->cur_page;
2522 page = notebook->children->data;
2524 if (!GTK_WIDGET_MAPPED (page->tab_label))
2526 if (notebook->tab_pos == GTK_POS_LEFT)
2528 x -= widget->style->xthickness * 2;
2529 width += widget->style->xthickness * 2;
2531 else if (notebook->tab_pos == GTK_POS_RIGHT)
2532 width += widget->style->xthickness * 2;
2534 switch (notebook->tab_pos)
2537 y += page->allocation.height;
2538 case GTK_POS_BOTTOM:
2539 height -= page->allocation.height;
2542 x += page->allocation.width;
2544 width -= page->allocation.width;
2549 gdk_draw_rectangle(pm, pmgc, TRUE, x, y, width, height);
2551 /* if theres an area for scrollign arrows draw the shape for them */
2552 if (notebook->panel)
2554 gdk_window_get_geometry(notebook->panel, &x, &y, &width, &height, &depth);
2555 gdk_draw_rectangle(pm, pmgc, TRUE, x, y, width, height);
2558 /* draw the shapes of all the children */
2559 if (notebook->show_tabs)
2561 children = notebook->children;
2564 page = children->data;
2565 if (GTK_WIDGET_MAPPED (page->tab_label))
2567 x = page->allocation.x;
2568 y = page->allocation.y;
2569 width = page->allocation.width;
2570 height = page->allocation.height;
2571 gdk_draw_rectangle(pm, pmgc, TRUE, x, y, width, height);
2573 children = children->next;
2578 gdk_window_shape_combine_mask(widget->window, pm, 0, 0);
2579 gdk_pixmap_unref(pm);
2580 gdk_gc_destroy(pmgc);
2583 /* Private GtkNotebook Size Allocate Functions:
2585 * gtk_notebook_pages_allocate
2586 * gtk_notebook_page_allocate
2587 * gtk_notebook_calc_tabs
2590 gtk_notebook_pages_allocate (GtkNotebook *notebook)
2592 GtkWidget *widget = GTK_WIDGET (notebook);
2593 GtkContainer *container = GTK_CONTAINER (notebook);
2594 GtkNotebookPage *page = NULL;
2595 GtkAllocation *allocation = &widget->allocation;
2596 GtkAllocation child_allocation;
2597 GList *children = NULL;
2598 GList *last_child = NULL;
2599 gboolean showarrow = FALSE;
2609 if (!notebook->show_tabs || !notebook->children || !notebook->cur_page)
2612 child_allocation.x = container->border_width;
2613 child_allocation.y = container->border_width;
2615 switch (notebook->tab_pos)
2617 case GTK_POS_BOTTOM:
2618 child_allocation.y = (allocation->height -
2619 notebook->cur_page->requisition.height -
2620 container->border_width);
2623 child_allocation.height = notebook->cur_page->requisition.height;
2627 child_allocation.x = (allocation->width -
2628 notebook->cur_page->requisition.width -
2629 container->border_width);
2632 child_allocation.width = notebook->cur_page->requisition.width;
2636 if (notebook->scrollable)
2640 children = notebook->children;
2642 if (notebook->focus_tab)
2643 focus_tab = notebook->focus_tab;
2644 else if (notebook->first_tab)
2645 focus_tab = notebook->first_tab;
2647 focus_tab = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, TRUE);
2649 switch (notebook->tab_pos)
2652 case GTK_POS_BOTTOM:
2655 page = children->data;
2656 children = children->next;
2658 if (GTK_WIDGET_VISIBLE (page->child))
2659 tab_space += page->requisition.width;
2662 allocation->width - 2 * container->border_width - TAB_OVERLAP)
2665 page = focus_tab->data;
2667 tab_space = (allocation->width - TAB_OVERLAP -
2668 page->requisition.width -
2669 2 * (container->border_width + ARROW_SPACING +
2671 x = (allocation->width - 2 * ARROW_SIZE - ARROW_SPACING -
2672 container->border_width);
2674 page = notebook->children->data;
2675 if (notebook->tab_pos == GTK_POS_TOP)
2676 y = (container->border_width +
2677 (page->requisition.height - ARROW_SIZE) / 2);
2679 y = (allocation->height - container->border_width -
2680 ARROW_SIZE - (page->requisition.height - ARROW_SIZE) / 2);
2687 page = children->data;
2688 children = children->next;
2690 if (GTK_WIDGET_VISIBLE (page->child))
2691 tab_space += page->requisition.height;
2694 (allocation->height - 2 * container->border_width - TAB_OVERLAP))
2697 page = focus_tab->data;
2698 tab_space = (allocation->height -
2699 ARROW_SIZE - ARROW_SPACING - TAB_OVERLAP -
2700 2 * container->border_width -
2701 page->requisition.height);
2702 y = allocation->height - container->border_width - ARROW_SIZE;
2704 page = notebook->children->data;
2705 if (notebook->tab_pos == GTK_POS_LEFT)
2706 x = (container->border_width +
2707 (page->requisition.width -
2708 (2 * ARROW_SIZE - ARROW_SPACING)) / 2);
2710 x = (allocation->width - container->border_width -
2711 (2 * ARROW_SIZE - ARROW_SPACING) -
2712 (page->requisition.width -
2713 (2 * ARROW_SIZE - ARROW_SPACING)) / 2);
2717 if (showarrow) /* first_tab <- focus_tab */
2721 notebook->first_tab = focus_tab;
2722 last_child = gtk_notebook_search_page (notebook, focus_tab,
2728 if (notebook->first_tab && notebook->first_tab != focus_tab)
2730 /* Is first_tab really predecessor of focus_tab ? */
2731 page = notebook->first_tab->data;
2732 if (GTK_WIDGET_VISIBLE (page->child))
2733 for (children = focus_tab;
2734 children && children != notebook->first_tab;
2735 children = gtk_notebook_search_page (notebook,
2741 notebook->first_tab = focus_tab;
2743 gtk_notebook_calc_tabs (notebook,
2744 gtk_notebook_search_page (notebook,
2748 &(notebook->first_tab), &tab_space,
2753 notebook->first_tab =
2754 gtk_notebook_search_page (notebook, notebook->first_tab,
2756 if (!notebook->first_tab)
2757 notebook->first_tab = focus_tab;
2758 last_child = gtk_notebook_search_page (notebook, focus_tab,
2761 else /* focus_tab -> end */
2763 if (!notebook->first_tab)
2764 notebook->first_tab = gtk_notebook_search_page (notebook,
2769 gtk_notebook_calc_tabs (notebook,
2770 gtk_notebook_search_page (notebook,
2774 &children, &tab_space, STEP_NEXT);
2777 last_child = children;
2778 else /* start <- first_tab */
2782 gtk_notebook_calc_tabs
2784 gtk_notebook_search_page (notebook,
2785 notebook->first_tab,
2788 &children, &tab_space, STEP_PREV);
2789 notebook->first_tab = gtk_notebook_search_page(notebook,
2797 if (GTK_WIDGET_REALIZED (notebook))
2799 gdk_window_move (notebook->panel, x, y);
2800 gdk_window_show (notebook->panel);
2805 tab_space = -tab_space;
2807 for (children = notebook->first_tab;
2808 children && children != last_child;
2809 children = gtk_notebook_search_page (notebook, children,
2816 /*unmap all non-visible tabs*/
2817 for (children = gtk_notebook_search_page (notebook, NULL,
2819 children && children != notebook->first_tab;
2820 children = gtk_notebook_search_page (notebook, children,
2823 page = children->data;
2824 if (page->tab_label && GTK_WIDGET_MAPPED (page->tab_label))
2825 gtk_widget_unmap (page->tab_label);
2827 for (children = last_child; children;
2828 children = gtk_notebook_search_page (notebook, children,
2831 page = children->data;
2832 if (page->tab_label && GTK_WIDGET_MAPPED (page->tab_label))
2833 gtk_widget_unmap (page->tab_label);
2836 else /* !showarrow */
2838 notebook->first_tab = gtk_notebook_search_page (notebook, NULL,
2841 if (GTK_WIDGET_REALIZED (notebook))
2842 gdk_window_hide (notebook->panel);
2851 children = notebook->children;
2852 switch (notebook->tab_pos)
2855 case GTK_POS_BOTTOM:
2858 page = children->data;
2859 children = children->next;
2861 if (GTK_WIDGET_VISIBLE (page->child))
2864 tab_space += page->requisition.width;
2869 tab_space -= allocation->width;
2875 page = children->data;
2876 children = children->next;
2878 if (GTK_WIDGET_VISIBLE (page->child))
2881 tab_space += page->requisition.height;
2886 tab_space -= allocation->height;
2888 tab_space += 2 * container->border_width + TAB_OVERLAP;
2890 notebook->first_tab = gtk_notebook_search_page (notebook, NULL,
2892 if (notebook->homogeneous && n)
2896 children = notebook->first_tab;
2900 if (children == last_child)
2902 /* FIXME double check */
2906 page = children->data;
2907 if (!showarrow && page->pack != GTK_PACK_START)
2909 children = gtk_notebook_search_page (notebook, children, STEP_NEXT,TRUE);
2912 if (n && (showarrow || page->expand || notebook->homogeneous))
2914 new_fill = (tab_space * i++) / n;
2915 delta = new_fill - old_fill;
2916 old_fill = new_fill;
2919 switch (notebook->tab_pos)
2922 case GTK_POS_BOTTOM:
2923 child_allocation.width = (page->requisition.width +
2924 TAB_OVERLAP + delta);
2928 child_allocation.height = (page->requisition.height +
2929 TAB_OVERLAP + delta);
2933 gtk_notebook_page_allocate (notebook, page, &child_allocation);
2935 switch (notebook->tab_pos)
2938 case GTK_POS_BOTTOM:
2939 child_allocation.x += child_allocation.width - TAB_OVERLAP;
2943 child_allocation.y += child_allocation.height - TAB_OVERLAP;
2947 if (GTK_WIDGET_REALIZED (notebook) &&
2948 page->tab_label && !GTK_WIDGET_MAPPED (page->tab_label))
2950 if (GTK_WIDGET_VISIBLE (page->tab_label))
2951 gtk_widget_map (page->tab_label);
2953 gtk_widget_show (page->tab_label);
2959 children = notebook->children;
2960 switch (notebook->tab_pos)
2963 case GTK_POS_BOTTOM:
2964 child_allocation.x = (allocation->x + allocation->width -
2965 container->border_width);
2969 child_allocation.y = (allocation->y + allocation->height -
2970 container->border_width);
2974 while (children != last_child)
2976 page = children->data;
2977 children = children->next;
2979 if (page->pack != GTK_PACK_END || !GTK_WIDGET_VISIBLE (page->child))
2983 if (n && (page->expand || notebook->homogeneous))
2985 new_fill = (tab_space * i++) / n;
2986 delta = new_fill - old_fill;
2987 old_fill = new_fill;
2990 switch (notebook->tab_pos)
2993 case GTK_POS_BOTTOM:
2994 child_allocation.width = (page->requisition.width +
2995 TAB_OVERLAP + delta);
2996 child_allocation.x -= child_allocation.width;
3000 child_allocation.height = (page->requisition.height +
3001 TAB_OVERLAP + delta);
3002 child_allocation.y -= child_allocation.height;
3006 gtk_notebook_page_allocate (notebook, page, &child_allocation);
3008 switch (notebook->tab_pos)
3011 case GTK_POS_BOTTOM:
3012 child_allocation.x += TAB_OVERLAP;
3016 child_allocation.y += TAB_OVERLAP;
3020 if (GTK_WIDGET_REALIZED (notebook) && page->tab_label &&
3021 !GTK_WIDGET_MAPPED (page->tab_label))
3023 if (GTK_WIDGET_VISIBLE (page->tab_label))
3024 gtk_widget_map (page->tab_label);
3026 gtk_widget_show (page->tab_label);
3032 gtk_notebook_set_shape (notebook);
3033 gtk_notebook_redraw_tabs (notebook);
3037 gtk_notebook_page_allocate (GtkNotebook *notebook,
3038 GtkNotebookPage *page,
3039 GtkAllocation *allocation)
3042 GtkAllocation child_allocation;
3043 GtkRequisition tab_requisition;
3048 g_return_if_fail (notebook != NULL);
3049 g_return_if_fail (page != NULL);
3050 g_return_if_fail (allocation != NULL);
3052 widget = GTK_WIDGET (notebook);
3054 xthickness = widget->style->xthickness;
3055 ythickness = widget->style->ythickness;
3057 /* If the size of the notebook tabs change, we need to queue
3058 * a redraw on the tab area
3060 if ((allocation->width != page->allocation.width) ||
3061 (allocation->height != page->allocation.height))
3063 gint x, y, width, height, border_width;
3065 border_width = GTK_CONTAINER (notebook)->border_width;
3067 switch (notebook->tab_pos)
3070 width = widget->allocation.width;
3071 height = MAX (page->allocation.height, allocation->height) + ythickness;
3076 case GTK_POS_BOTTOM:
3077 width = widget->allocation.width + xthickness;
3078 height = MAX (page->allocation.height, allocation->height) + ythickness;
3080 y = widget->allocation.height - height - border_width;
3084 width = MAX (page->allocation.width, allocation->width) + xthickness;
3085 height = widget->allocation.height;
3091 default: /* quiet gcc */
3092 width = MAX (page->allocation.width, allocation->width) + xthickness;
3093 height = widget->allocation.height;
3094 x = widget->allocation.width - width - border_width;
3099 gtk_widget_queue_clear_area (widget, x, y, width, height);
3102 page->allocation = *allocation;
3103 gtk_widget_get_child_requisition (page->tab_label, &tab_requisition);
3105 if (notebook->cur_page != page)
3107 switch (notebook->tab_pos)
3110 page->allocation.y += ythickness;
3111 case GTK_POS_BOTTOM:
3112 if (page->allocation.height > ythickness)
3113 page->allocation.height -= ythickness;
3116 page->allocation.x += xthickness;
3118 if (page->allocation.width > xthickness)
3119 page->allocation.width -= xthickness;
3124 switch (notebook->tab_pos)
3127 case GTK_POS_BOTTOM:
3128 padding = TAB_CURVATURE + FOCUS_WIDTH + notebook->tab_hborder;
3131 child_allocation.x = (xthickness + FOCUS_WIDTH +
3132 notebook->tab_hborder);
3133 child_allocation.width = MAX (1, (((gint) page->allocation.width) -
3134 2 * child_allocation.x));
3135 child_allocation.x += page->allocation.x;
3139 child_allocation.x = (page->allocation.x +
3140 (page->allocation.width -
3141 tab_requisition.width) / 2);
3142 child_allocation.width = tab_requisition.width;
3144 child_allocation.y = (notebook->tab_vborder + FOCUS_WIDTH +
3145 page->allocation.y);
3146 if (notebook->tab_pos == GTK_POS_TOP)
3147 child_allocation.y += ythickness;
3148 child_allocation.height = MAX (1, (((gint) page->allocation.height) - ythickness -
3149 2 * (notebook->tab_vborder + FOCUS_WIDTH)));
3153 padding = TAB_CURVATURE + FOCUS_WIDTH + notebook->tab_vborder;
3156 child_allocation.y = ythickness + padding;
3157 child_allocation.height = MAX (1, (((gint) page->allocation.height) -
3158 2 * child_allocation.y));
3159 child_allocation.y += page->allocation.y;
3163 child_allocation.y = (page->allocation.y + (page->allocation.height -
3164 tab_requisition.height) / 2);
3165 child_allocation.height = tab_requisition.height;
3167 child_allocation.x = page->allocation.x + notebook->tab_hborder + FOCUS_WIDTH;
3168 if (notebook->tab_pos == GTK_POS_LEFT)
3169 child_allocation.x += xthickness;
3170 child_allocation.width = MAX (1, (((gint) page->allocation.width) - xthickness -
3171 2 * (notebook->tab_hborder + FOCUS_WIDTH)));
3175 if (page->tab_label)
3176 gtk_widget_size_allocate (page->tab_label, &child_allocation);
3180 gtk_notebook_calc_tabs (GtkNotebook *notebook,
3186 GtkNotebookPage *page = NULL;
3188 GList *last_list = NULL;
3195 pack = GTK_NOTEBOOK_PAGE (start)->pack;
3196 if (pack == GTK_PACK_END)
3197 direction = (direction == STEP_PREV) ? STEP_NEXT : STEP_PREV;
3201 switch (notebook->tab_pos)
3204 case GTK_POS_BOTTOM:
3207 page = children->data;
3208 if (GTK_WIDGET_VISIBLE (page->child))
3210 if (page->pack == pack)
3212 *tab_space -= page->requisition.width;
3213 if (*tab_space < 0 || children == *end)
3217 *tab_space = - (*tab_space +
3218 page->requisition.width);
3224 last_list = children;
3226 if (direction == STEP_NEXT)
3227 children = children->next;
3229 children = children->prev;
3236 page = children->data;
3237 if (GTK_WIDGET_VISIBLE (page->child))
3239 if (page->pack == pack)
3241 *tab_space -= page->requisition.height;
3242 if (*tab_space < 0 || children == *end)
3246 *tab_space = - (*tab_space +
3247 page->requisition.height);
3253 last_list = children;
3255 if (direction == STEP_NEXT)
3256 children = children->next;
3258 children = children->prev;
3262 if (direction == STEP_PREV)
3264 pack = (pack == GTK_PACK_END) ? GTK_PACK_START : GTK_PACK_END;
3265 direction = STEP_PREV;
3266 children = last_list;
3270 /* Private GtkNotebook Page Switch Methods:
3272 * gtk_notebook_real_switch_page
3275 gtk_notebook_real_switch_page (GtkNotebook *notebook,
3276 GtkNotebookPage *page,
3279 g_return_if_fail (notebook != NULL);
3280 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3281 g_return_if_fail (page != NULL);
3283 if (notebook->cur_page == page || !GTK_WIDGET_VISIBLE (page->child))
3286 if (notebook->cur_page && GTK_WIDGET_MAPPED (notebook->cur_page->child))
3287 gtk_widget_unmap (notebook->cur_page->child);
3289 notebook->cur_page = page;
3291 if (!notebook->focus_tab ||
3292 notebook->focus_tab->data != (gpointer) notebook->cur_page)
3293 notebook->focus_tab =
3294 g_list_find (notebook->children, notebook->cur_page);
3296 if (GTK_WIDGET_MAPPED (notebook))
3297 gtk_widget_map (notebook->cur_page->child);
3299 gtk_widget_queue_resize (GTK_WIDGET (notebook));
3302 /* Private GtkNotebook Page Switch Functions:
3304 * gtk_notebook_switch_page
3305 * gtk_notebook_page_select
3306 * gtk_notebook_switch_focus_tab
3307 * gtk_notebook_menu_switch_page
3310 gtk_notebook_switch_page (GtkNotebook *notebook,
3311 GtkNotebookPage *page,
3314 g_return_if_fail (notebook != NULL);
3315 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3316 g_return_if_fail (page != NULL);
3318 if (notebook->cur_page == page)
3322 page_num = g_list_index (notebook->children, page);
3324 gtk_signal_emit (GTK_OBJECT (notebook),
3325 notebook_signals[SWITCH_PAGE],
3331 gtk_notebook_page_select (GtkNotebook *notebook,
3332 gboolean move_focus)
3334 GtkNotebookPage *page;
3335 GtkDirectionType dir = GTK_DIR_DOWN; /* Quiet GCC */
3337 g_return_val_if_fail (notebook != NULL, FALSE);
3338 g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), FALSE);
3340 if (!notebook->focus_tab)
3343 page = notebook->focus_tab->data;
3344 gtk_notebook_switch_page (notebook, page, -1);
3348 switch (notebook->tab_pos)
3353 case GTK_POS_BOTTOM:
3357 dir = GTK_DIR_RIGHT;
3364 if (GTK_WIDGET_VISIBLE (page->child))
3366 if (GTK_IS_CONTAINER (page->child))
3368 if (gtk_container_focus (GTK_CONTAINER (page->child),
3372 else if (GTK_WIDGET_CAN_FOCUS (page->child))
3374 gtk_widget_grab_focus (page->child);
3383 gtk_notebook_switch_focus_tab (GtkNotebook *notebook,
3387 GtkNotebookPage *old_page = NULL;
3388 GtkNotebookPage *page;
3390 g_return_if_fail (notebook != NULL);
3391 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3393 if (notebook->focus_tab == new_child)
3396 old_child = notebook->focus_tab;
3397 notebook->focus_tab = new_child;
3399 if (notebook->scrollable && GTK_WIDGET_DRAWABLE (notebook))
3400 gtk_notebook_redraw_arrows (notebook);
3402 if (!notebook->show_tabs || !notebook->focus_tab)
3406 old_page = old_child->data;
3408 page = notebook->focus_tab->data;
3409 if (GTK_WIDGET_MAPPED (page->tab_label))
3410 gtk_notebook_focus_changed (notebook, old_page);
3412 gtk_notebook_pages_allocate (notebook);
3414 gtk_notebook_set_shape (notebook);
3418 gtk_notebook_menu_switch_page (GtkWidget *widget,
3419 GtkNotebookPage *page)
3421 GtkNotebook *notebook;
3425 g_return_if_fail (widget != NULL);
3426 g_return_if_fail (page != NULL);
3428 notebook = GTK_NOTEBOOK (gtk_menu_get_attach_widget
3429 (GTK_MENU (widget->parent)));
3431 if (notebook->cur_page == page)
3435 children = notebook->children;
3436 while (children && children->data != page)
3438 children = children->next;
3442 gtk_signal_emit (GTK_OBJECT (notebook),
3443 notebook_signals[SWITCH_PAGE],
3448 /* Private GtkNotebook Menu Functions:
3450 * gtk_notebook_menu_item_create
3451 * gtk_notebook_menu_label_unparent
3452 * gtk_notebook_menu_detacher
3455 gtk_notebook_menu_item_create (GtkNotebook *notebook,
3458 GtkNotebookPage *page;
3459 GtkWidget *menu_item;
3462 if (page->default_menu)
3464 if (page->tab_label && GTK_IS_LABEL (page->tab_label))
3465 page->menu_label = gtk_label_new (GTK_LABEL (page->tab_label)->label);
3467 page->menu_label = gtk_label_new ("");
3468 gtk_misc_set_alignment (GTK_MISC (page->menu_label), 0.0, 0.5);
3471 gtk_widget_show (page->menu_label);
3472 menu_item = gtk_menu_item_new ();
3473 gtk_widget_lock_accelerators (menu_item);
3474 gtk_container_add (GTK_CONTAINER (menu_item), page->menu_label);
3475 gtk_menu_shell_insert (GTK_MENU_SHELL (notebook->menu), menu_item,
3476 gtk_notebook_real_page_position (notebook, list));
3477 gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
3478 GTK_SIGNAL_FUNC (gtk_notebook_menu_switch_page), page);
3479 if (GTK_WIDGET_VISIBLE (page->child))
3480 gtk_widget_show (menu_item);
3484 gtk_notebook_menu_label_unparent (GtkWidget *widget,
3487 gtk_widget_unparent (GTK_BIN(widget)->child);
3488 GTK_BIN(widget)->child = NULL;
3492 gtk_notebook_menu_detacher (GtkWidget *widget,
3495 GtkNotebook *notebook;
3497 g_return_if_fail (widget != NULL);
3498 g_return_if_fail (GTK_IS_NOTEBOOK (widget));
3500 notebook = GTK_NOTEBOOK (widget);
3501 g_return_if_fail (notebook->menu == (GtkWidget*) menu);
3503 notebook->menu = NULL;
3506 /* Public GtkNotebook Page Insert/Remove Methods :
3508 * gtk_notebook_append_page
3509 * gtk_notebook_append_page_menu
3510 * gtk_notebook_prepend_page
3511 * gtk_notebook_prepend_page_menu
3512 * gtk_notebook_insert_page
3513 * gtk_notebook_insert_page_menu
3514 * gtk_notebook_remove_page
3517 * gtk_notebook_append_page:
3518 * @notebook: a #GtkNotebook
3519 * @child: the #GtkWidget to use as the contents of the page.
3520 * @tab_label: the #GtkWidget to be used as the label for the page,
3521 * or %NULL to use the default label, 'page N'.
3523 * Appends a page to @notebook.
3526 gtk_notebook_append_page (GtkNotebook *notebook,
3528 GtkWidget *tab_label)
3530 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3531 g_return_if_fail (GTK_IS_WIDGET (child));
3532 g_return_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label));
3534 gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, -1);
3538 * gtk_notebook_append_page_menu:
3539 * @notebook: a #GtkNotebook
3540 * @child: the #GtkWidget to use as the contents of the page.
3541 * @tab_label: the #GtkWidget to be used as the label for the page,
3542 * or %NULL to use the default label, 'page N'.
3543 * @menu_label: the widget to use as a label for the page-switch
3544 * menu, if that is enabled. If %NULL, and @tab_label
3545 * is a #GtkLabel or %NULL, then the menu label will be
3546 * a newly created label with the same text as @tab_label;
3547 * If @tab_label is not a #GtkLabel, @menu_label must be
3548 * specified if the page-switch menu is to be used.
3550 * Appends a page to @notebook, specifying the widget to use as the
3551 * label in the popup menu.
3554 gtk_notebook_append_page_menu (GtkNotebook *notebook,
3556 GtkWidget *tab_label,
3557 GtkWidget *menu_label)
3559 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3560 g_return_if_fail (GTK_IS_WIDGET (child));
3561 g_return_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label));
3562 g_return_if_fail (menu_label == NULL || GTK_IS_WIDGET (menu_label));
3564 gtk_notebook_insert_page_menu (notebook, child, tab_label, menu_label, -1);
3568 * gtk_notebook_prepend_page:
3569 * @notebook: a #GtkNotebook
3570 * @child: the #GtkWidget to use as the contents of the page.
3571 * @tab_label: the #GtkWidget to be used as the label for the page,
3572 * or %NULL to use the default label, 'page N'.
3574 * Prepends a page to @noteobook.
3577 gtk_notebook_prepend_page (GtkNotebook *notebook,
3579 GtkWidget *tab_label)
3581 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3582 g_return_if_fail (GTK_IS_WIDGET (child));
3583 g_return_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label));
3585 gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, 0);
3589 * gtk_notebook_prepend_page_menu:
3590 * @notebook: a #GtkNotebook
3591 * @child: the #GtkWidget to use as the contents of the page.
3592 * @tab_label: the #GtkWidget to be used as the label for the page,
3593 * or %NULL to use the default label, 'page N'.
3594 * @menu_label: the widget to use as a label for the page-switch
3595 * menu, if that is enabled. If %NULL, and @tab_label
3596 * is a #GtkLabel or %NULL, then the menu label will be
3597 * a newly created label with the same text as @tab_label;
3598 * If @tab_label is not a #GtkLabel, @menu_label must be
3599 * specified if the page-switch menu is to be used.
3601 * Prepends a page to @notebook, specifying the widget to use as the
3602 * label in the popup menu.
3605 gtk_notebook_prepend_page_menu (GtkNotebook *notebook,
3607 GtkWidget *tab_label,
3608 GtkWidget *menu_label)
3610 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3611 g_return_if_fail (GTK_IS_WIDGET (child));
3612 g_return_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label));
3613 g_return_if_fail (menu_label == NULL || GTK_IS_WIDGET (menu_label));
3615 gtk_notebook_insert_page_menu (notebook, child, tab_label, menu_label, 0);
3619 * gtk_notebook_insert_page:
3620 * @notebook: a #GtkNotebook
3621 * @child: the #GtkWidget to use as the contents of the page.
3622 * @tab_label: the #GtkWidget to be used as the label for the page,
3623 * or %NULL to use the default label, 'page N'.
3624 * @position: the index (starting at 0) at which to insert the page,
3625 * or -1 to append the page after all other pages.
3627 * Insert a page into @notebook at the given position
3630 gtk_notebook_insert_page (GtkNotebook *notebook,
3632 GtkWidget *tab_label,
3635 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3636 g_return_if_fail (GTK_IS_WIDGET (child));
3637 g_return_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label));
3639 gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, position);
3643 * gtk_notebook_insert_page_menu:
3644 * @notebook: a #GtkNotebook
3645 * @child: the #GtkWidget to use as the contents of the page.
3646 * @tab_label: the #GtkWidget to be used as the label for the page,
3647 * or %NULL to use the default label, 'page N'.
3648 * @menu_label: the widget to use as a label for the page-switch
3649 * menu, if that is enabled. If %NULL, and @tab_label
3650 * is a #GtkLabel or %NULL, then the menu label will be
3651 * a newly created label with the same text as @tab_label;
3652 * If @tab_label is not a #GtkLabel, @menu_label must be
3653 * specified if the page-switch menu is to be used.
3654 * @position: the index (starting at 0) at which to insert the page,
3655 * or -1 to append the page after all other pages.
3657 * Insert a page into @notebook at the given position, specifying
3658 * the widget to use as the label in the popup menu.
3661 gtk_notebook_insert_page_menu (GtkNotebook *notebook,
3663 GtkWidget *tab_label,
3664 GtkWidget *menu_label,
3667 GtkNotebookPage *page;
3670 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3671 g_return_if_fail (GTK_IS_WIDGET (child));
3672 g_return_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label));
3673 g_return_if_fail (menu_label == NULL || GTK_IS_WIDGET (menu_label));
3675 page = g_new (GtkNotebookPage, 1);
3676 page->child = child;
3677 page->requisition.width = 0;
3678 page->requisition.height = 0;
3679 page->allocation.x = 0;
3680 page->allocation.y = 0;
3681 page->allocation.width = 0;
3682 page->allocation.height = 0;
3683 page->default_menu = FALSE;
3684 page->default_tab = FALSE;
3686 nchildren = g_list_length (notebook->children);
3687 if ((position < 0) || (position > nchildren))
3688 position = nchildren;
3690 notebook->children = g_list_insert (notebook->children, page, position);
3694 page->default_tab = TRUE;
3695 if (notebook->show_tabs)
3696 tab_label = gtk_label_new ("");
3698 page->tab_label = tab_label;
3699 page->menu_label = menu_label;
3700 page->expand = FALSE;
3702 page->pack = GTK_PACK_START;
3705 page->default_menu = TRUE;
3708 gtk_widget_ref (page->menu_label);
3709 gtk_object_sink (GTK_OBJECT (page->menu_label));
3713 gtk_notebook_menu_item_create (notebook,
3714 g_list_find (notebook->children, page));
3716 gtk_notebook_update_labels (notebook);
3718 if (!notebook->first_tab)
3719 notebook->first_tab = notebook->children;
3721 gtk_widget_set_parent (child, GTK_WIDGET (notebook));
3723 gtk_widget_set_parent (tab_label, GTK_WIDGET (notebook));
3725 if (!notebook->cur_page)
3727 gtk_notebook_switch_page (notebook, page, 0);
3728 gtk_notebook_switch_focus_tab (notebook, NULL);
3731 if (GTK_WIDGET_REALIZED (child->parent))
3732 gtk_widget_realize (child);
3734 if (GTK_WIDGET_VISIBLE (notebook))
3736 if (GTK_WIDGET_VISIBLE (child))
3738 if (GTK_WIDGET_MAPPED (notebook) &&
3739 !GTK_WIDGET_MAPPED (child) &&
3740 notebook->cur_page == page)
3741 gtk_widget_map (child);
3743 gtk_widget_queue_resize (child);
3748 if (notebook->show_tabs && GTK_WIDGET_VISIBLE (child))
3750 if (!GTK_WIDGET_VISIBLE (tab_label))
3751 gtk_widget_show (tab_label);
3753 if (GTK_WIDGET_REALIZED (notebook) &&
3754 !GTK_WIDGET_REALIZED (tab_label))
3755 gtk_widget_realize (tab_label);
3757 if (GTK_WIDGET_MAPPED (notebook) &&
3758 !GTK_WIDGET_MAPPED (tab_label))
3759 gtk_widget_map (tab_label);
3761 else if (GTK_WIDGET_VISIBLE (tab_label))
3762 gtk_widget_hide (tab_label);
3768 * gtk_notebook_remove_page:
3769 * @notebook: a #GtkNotebook.
3770 * @page_num: the index of a notebook page, starting
3771 * from 0. If -1, the last page will
3774 * Removes a page from the notebook given its index
3778 gtk_notebook_remove_page (GtkNotebook *notebook,
3783 g_return_if_fail (notebook != NULL);
3784 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3788 list = g_list_nth (notebook->children, page_num);
3790 gtk_notebook_real_remove (notebook, list);
3794 list = g_list_last (notebook->children);
3796 gtk_notebook_real_remove (notebook, list);
3800 /* Public GtkNotebook Page Switch Methods :
3801 * gtk_notebook_get_current_page
3802 * gtk_notebook_page_num
3803 * gtk_notebook_set_page
3804 * gtk_notebook_next_page
3805 * gtk_notebook_prev_page
3808 * gtk_notebook_get_current_page:
3809 * @notebook: a #GtkNotebook
3811 * Returns the page number of the current page.
3813 * Return value: the index (starting from 0) of the current
3814 * page in the notebook. If the notebook has no pages, then
3815 * -1 will be returned.
3818 gtk_notebook_get_current_page (GtkNotebook *notebook)
3820 g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1);
3822 if (!notebook->cur_page)
3825 return g_list_index (notebook->children, notebook->cur_page);
3829 * gtk_notebook_get_nth_page:
3830 * @notebook: a #GtkNotebook
3831 * @page_num: the index of a page in the noteobok
3833 * Returns the child widget contained in page number @page_num.
3835 * Return value: the child widget, or %NULL if @page_num is
3839 gtk_notebook_get_nth_page (GtkNotebook *notebook,
3842 GtkNotebookPage *page;
3844 g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL);
3846 page = g_list_nth_data (notebook->children, page_num);
3855 * gtk_notebook_page_num:
3856 * @notebook: a #GtkNotebook
3857 * @child: a #GtkWidget
3859 * Finds the index of the page which contains the given child
3862 * Return value: the index of the page containing @child, or
3863 * -1 if @child is not in the notebook.
3866 gtk_notebook_page_num (GtkNotebook *notebook,
3872 g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1);
3875 children = notebook->children;
3878 GtkNotebookPage *page = children->data;
3880 if (page->child == child)
3883 children = children->next;
3891 * gtk_notebook_set_page:
3892 * @notebook: a #GtkNotebook
3893 * @page_num: index of the page to switch to, starting from 0.
3894 * If negative, or greater than the number of pages
3895 * in the notebook the last page will be used.
3897 * Switches to the page number @page_num.
3900 gtk_notebook_set_page (GtkNotebook *notebook,
3905 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3908 list = g_list_nth (notebook->children, page_num);
3910 list = g_list_last (notebook->children);
3912 page_num = g_list_index (notebook->children, list);
3915 gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (list), page_num);
3919 * gtk_notebook_next_page:
3920 * @notebook: a #GtkNotebook
3922 * Switches to the next page. Nothing happens if the current page is
3926 gtk_notebook_next_page (GtkNotebook *notebook)
3930 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3932 list = g_list_find (notebook->children, notebook->cur_page);
3936 list = gtk_notebook_search_page (notebook, list, STEP_NEXT, TRUE);
3940 gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (list), -1);
3944 * gtk_notebook_prev_page:
3945 * @notebook: a #GtkNotebook
3947 * Switches to the previous page. Nothing happens if the current page
3948 * is the first page.
3951 gtk_notebook_prev_page (GtkNotebook *notebook)
3955 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3957 list = g_list_find (notebook->children, notebook->cur_page);
3961 list = gtk_notebook_search_page (notebook, list, STEP_PREV, TRUE);
3965 gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (list), -1);
3968 /* Public GtkNotebook/Tab Style Functions
3970 * gtk_notebook_set_show_border
3971 * gtk_notebook_set_show_tabs
3972 * gtk_notebook_set_tab_pos
3973 * gtk_notebook_set_homogeneous_tabs
3974 * gtk_notebook_set_tab_border
3975 * gtk_notebook_set_tab_hborder
3976 * gtk_notebook_set_tab_vborder
3977 * gtk_notebook_set_scrollable
3980 * gtk_notebook_set_show_border:
3981 * @notebook: a #GtkNotebook
3982 * @show_border: %TRUE if a bevel should be drawn around the notebook.
3984 * Sets whether a bevel will be drawn around the notebook pages.
3985 * this is only has an effect when the tabs are not shown.
3986 * See gtk_notebook_set_show_tabs().
3989 gtk_notebook_set_show_border (GtkNotebook *notebook,
3990 gboolean show_border)
3992 g_return_if_fail (notebook != NULL);
3993 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3995 if (notebook->show_border != show_border)
3997 notebook->show_border = show_border;
3999 if (GTK_WIDGET_VISIBLE (notebook))
4000 gtk_widget_queue_resize (GTK_WIDGET (notebook));
4005 * gtk_notebook_set_show_tabs:
4006 * @notebook: a #GtkNotebook
4007 * @show_tabs: %TRUE if the tabs should be shown.
4009 * Sets whether to show the tabs for the notebook or not.
4012 gtk_notebook_set_show_tabs (GtkNotebook *notebook,
4015 GtkNotebookPage *page;
4018 g_return_if_fail (notebook != NULL);
4019 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
4021 show_tabs = show_tabs != FALSE;
4023 if (notebook->show_tabs == show_tabs)
4026 notebook->show_tabs = show_tabs;
4027 children = notebook->children;
4031 GTK_WIDGET_UNSET_FLAGS (notebook, GTK_CAN_FOCUS);
4035 page = children->data;
4036 children = children->next;
4037 if (page->default_tab)
4039 gtk_widget_destroy (page->tab_label);
4040 page->tab_label = NULL;
4043 gtk_widget_hide (page->tab_label);
4046 if (notebook->panel)
4047 gdk_window_hide (notebook->panel);
4051 GTK_WIDGET_SET_FLAGS (notebook, GTK_CAN_FOCUS);
4052 gtk_notebook_update_labels (notebook);
4054 gtk_widget_queue_resize (GTK_WIDGET (notebook));
4058 * gtk_notebook_set_tab_pos:
4062 * Sets the edge at which the tabs for switching pages in the
4063 * notebook are drawn.
4066 gtk_notebook_set_tab_pos (GtkNotebook *notebook,
4067 GtkPositionType pos)
4069 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
4071 if (notebook->tab_pos != pos)
4073 notebook->tab_pos = pos;
4074 if (GTK_WIDGET_VISIBLE (notebook))
4075 gtk_widget_queue_resize (GTK_WIDGET (notebook));
4080 * gtk_notebook_set_homogeneous_tabs:
4081 * @notebook: a #GtkNotebook
4082 * @homogeneous: %TRUE if all tabs should be the same size.
4084 * Sets whether the tabs must have all the same size or not.
4087 gtk_notebook_set_homogeneous_tabs (GtkNotebook *notebook,
4088 gboolean homogeneous)
4090 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
4092 if (homogeneous == notebook->homogeneous)
4095 notebook->homogeneous = homogeneous;
4096 gtk_widget_queue_resize (GTK_WIDGET (notebook));
4100 * gtk_notebook_set_tab_border:
4101 * @notebook: a #GtkNotebook
4102 * @tab_border: %TRUE if there should be a border around the
4105 * Sets whether there should be a border around the tab labels
4106 * in a notebook. This is equivalent to calling
4107 * gtk_notebook_set_tab_hborder (@notebook, @tab_border) followed
4108 * by gtk_noteobok_set_tab_vborder (@notebook, @tab_border).
4111 gtk_notebook_set_tab_border (GtkNotebook *notebook,
4114 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
4116 notebook->tab_hborder = tab_border;
4117 notebook->tab_vborder = tab_border;
4119 if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs)
4120 gtk_widget_queue_resize (GTK_WIDGET (notebook));
4124 * gtk_notebook_set_tab_hborder:
4125 * @notebook: a #GtkNotebook
4126 * @tab_vborder: %TRUE if the notebook tabs should have
4127 * a vertical border.
4129 * Sets whether the tabs should have a vertical border.
4132 gtk_notebook_set_tab_hborder (GtkNotebook *notebook,
4135 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
4137 if (notebook->tab_hborder == tab_hborder)
4140 notebook->tab_hborder = tab_hborder;
4142 if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs)
4143 gtk_widget_queue_resize (GTK_WIDGET (notebook));
4147 * gtk_notebook_set_tab_vborder:
4148 * @notebook: a #GtkNotebook
4149 * @tab_vborder: %TRUE if the notebook tabs should have
4150 * a vertical border.
4152 * Sets whether the tabs should have a vertical border.
4155 gtk_notebook_set_tab_vborder (GtkNotebook *notebook,
4158 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
4160 if (notebook->tab_vborder == tab_vborder)
4163 notebook->tab_vborder = tab_vborder;
4165 if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs)
4166 gtk_widget_queue_resize (GTK_WIDGET (notebook));
4170 * gtk_notebook_set_scrollable:
4171 * @notebook: a #GtkNotebook
4172 * @scrollable: %TRUE if scroll arrows should be added
4174 * Sets whether the tab label area will have arrows for scrolling if
4175 * there are too many tabs to fit in the area.
4179 gtk_notebook_set_scrollable (GtkNotebook *notebook,
4180 gboolean scrollable)
4182 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
4184 scrollable = (scrollable != FALSE);
4186 if (scrollable != notebook->scrollable)
4188 notebook->scrollable = scrollable;
4190 if (GTK_WIDGET_REALIZED (notebook))
4194 gtk_notebook_panel_realize (notebook);
4196 else if (notebook->panel)
4198 gdk_window_set_user_data (notebook->panel, NULL);
4199 gdk_window_destroy (notebook->panel);
4200 notebook->panel = NULL;
4204 if (GTK_WIDGET_VISIBLE (notebook))
4205 gtk_widget_queue_resize (GTK_WIDGET (notebook));
4209 /* Public GtkNotebook Popup Menu Methods:
4211 * gtk_notebook_popup_enable
4212 * gtk_notebook_popup_disable
4217 * gtk_notebook_popup_enable:
4218 * @notebook: a #GtkNotebook
4220 * Enables the popup menu: if the user clicks with the right mouse button on
4221 * the bookmarks, a menu with all the pages will be popped up.
4224 gtk_notebook_popup_enable (GtkNotebook *notebook)
4228 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
4233 notebook->menu = gtk_menu_new ();
4234 for (list = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, FALSE);
4236 list = gtk_notebook_search_page (notebook, list, STEP_NEXT, FALSE))
4237 gtk_notebook_menu_item_create (notebook, list);
4239 gtk_notebook_update_labels (notebook);
4240 gtk_menu_attach_to_widget (GTK_MENU (notebook->menu),
4241 GTK_WIDGET (notebook),
4242 gtk_notebook_menu_detacher);
4246 * gtk_notebook_popup_disable:
4247 * @notebook: a #GtkNotebook
4249 * Disables the popup menu.
4252 gtk_notebook_popup_disable (GtkNotebook *notebook)
4254 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
4256 if (!notebook->menu)
4259 gtk_container_foreach (GTK_CONTAINER (notebook->menu),
4260 (GtkCallback) gtk_notebook_menu_label_unparent, NULL);
4261 gtk_widget_destroy (notebook->menu);
4264 /* Public GtkNotebook Page Properties Functions:
4266 * gtk_notebook_get_tab_label
4267 * gtk_notebook_set_tab_label
4268 * gtk_notebook_set_tab_label_text
4269 * gtk_notebook_get_menu_label
4270 * gtk_notebook_set_menu_label
4271 * gtk_notebook_set_menu_label_text
4272 * gtk_notebook_set_tab_label_packing
4273 * gtk_notebook_query_tab_label_packing
4277 * gtk_notebook_get_tab_label:
4278 * @notebook: a #GtkNotebook
4281 * Returns the tab label widget for the page @child. %NULL is returned
4282 * if @child is not in @notebook or if no tab label has specifically
4283 * been set for @child.
4285 * Return value: the tab label
4288 gtk_notebook_get_tab_label (GtkNotebook *notebook,
4293 g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL);
4294 g_return_val_if_fail (child != NULL, NULL);
4296 list = CHECK_FIND_CHILD (notebook, child);
4300 if (GTK_NOTEBOOK_PAGE (list)->default_tab)
4303 return GTK_NOTEBOOK_PAGE (list)->tab_label;
4307 * gtk_notebook_set_tab_label:
4308 * @notebook: a #GtkNotebook
4310 * @tab_label: the tab label widget to use, or %NULL for default tab
4313 * Changes the tab label for @child. If %NULL is specified
4314 * for @tab_label, then the page will have the label 'page N'.
4317 gtk_notebook_set_tab_label (GtkNotebook *notebook,
4319 GtkWidget *tab_label)
4321 GtkNotebookPage *page;
4324 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
4325 g_return_if_fail (child != NULL);
4327 list = CHECK_FIND_CHILD (notebook, child);
4331 /* a NULL pointer indicates a default_tab setting, otherwise
4332 * we need to set the associated label
4335 if (page->tab_label)
4336 gtk_widget_unparent (page->tab_label);
4340 page->default_tab = FALSE;
4341 page->tab_label = tab_label;
4342 gtk_widget_set_parent (page->tab_label, GTK_WIDGET (notebook));
4346 page->default_tab = TRUE;
4347 page->tab_label = NULL;
4349 if (notebook->show_tabs)
4353 g_snprintf (string, sizeof(string), _("Page %u"),
4354 gtk_notebook_real_page_position (notebook, list));
4355 page->tab_label = gtk_label_new (string);
4356 gtk_widget_set_parent (page->tab_label, GTK_WIDGET (notebook));
4360 if (notebook->show_tabs && GTK_WIDGET_VISIBLE (child))
4362 gtk_widget_show (page->tab_label);
4363 gtk_widget_queue_resize (GTK_WIDGET (notebook));
4368 * gtk_notebook_set_tab_label_text:
4369 * @notebook: a #GtkNotebook
4371 * @tab_label: the label text
4373 * Creates a new label and sets it as the tab label for the page
4374 * containing @child.
4377 gtk_notebook_set_tab_label_text (GtkNotebook *notebook,
4379 const gchar *tab_text)
4381 GtkWidget *tab_label = NULL;
4383 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
4386 tab_label = gtk_label_new (tab_text);
4387 gtk_notebook_set_tab_label (notebook, child, tab_label);
4391 * gtk_notebook_get_menu_label:
4392 * @notebook: a #GtkNotebook
4395 * Returns the menu label of the page containing @child. NULL is
4396 * returned if @child is not in @notebook or NULL if it has the
4397 * default menu label.
4399 * Return value: the menu label
4402 gtk_notebook_get_menu_label (GtkNotebook *notebook,
4407 g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL);
4408 g_return_val_if_fail (child != NULL, NULL);
4410 list = CHECK_FIND_CHILD (notebook, child);
4414 if (GTK_NOTEBOOK_PAGE (list)->default_menu)
4417 return GTK_NOTEBOOK_PAGE (list)->menu_label;
4421 * gtk_notebook_set_menu_label:
4422 * @notebook: a #GtkNotebook
4423 * @child: the child widget
4424 * @menu_label: the menu label, or NULL for default
4426 * Changes the menu label for the page containing @child.
4429 gtk_notebook_set_menu_label (GtkNotebook *notebook,
4431 GtkWidget *menu_label)
4433 GtkNotebookPage *page;
4436 g_return_if_fail (notebook != NULL);
4437 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
4438 g_return_if_fail (child != NULL);
4440 list = CHECK_FIND_CHILD (notebook, child);
4445 if (page->menu_label)
4448 gtk_container_remove (GTK_CONTAINER (notebook->menu),
4449 page->menu_label->parent);
4451 if (!page->default_menu)
4452 gtk_widget_unref (page->menu_label);
4457 page->menu_label = menu_label;
4458 gtk_widget_ref (page->menu_label);
4459 gtk_object_sink (GTK_OBJECT(page->menu_label));
4460 page->default_menu = FALSE;
4463 page->default_menu = TRUE;
4466 gtk_notebook_menu_item_create (notebook, list);
4470 * gtk_notebook_set_menu_label_text:
4471 * @notebook: a #GtkNotebook
4472 * @child: the child widget
4473 * @menu_text: the label text
4475 * Creates a new label and sets it as the menu label of @child.
4478 gtk_notebook_set_menu_label_text (GtkNotebook *notebook,
4480 const gchar *menu_text)
4482 GtkWidget *menu_label = NULL;
4484 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
4487 menu_label = gtk_label_new (menu_text);
4488 gtk_notebook_set_menu_label (notebook, child, menu_label);
4491 /* Helper function called when pages are reordered
4494 gtk_notebook_child_reordered (GtkNotebook *notebook,
4495 GtkNotebookPage *page)
4499 GtkWidget *menu_item;
4501 menu_item = page->menu_label->parent;
4502 gtk_container_remove (GTK_CONTAINER (menu_item), page->menu_label);
4503 gtk_container_remove (GTK_CONTAINER (notebook->menu), menu_item);
4504 gtk_notebook_menu_item_create (notebook, g_list_find (notebook->children, page));
4507 gtk_notebook_update_labels (notebook);
4511 * gtk_notebook_set_tab_label_packing:
4512 * @notebook: a #GtkNotebook
4513 * @child: the child widget
4514 * @expand: whether to expand the bookmark or not
4515 * @fill: whether the bookmark should fill the allocated area or not
4516 * @pack_type: the position of the bookmark
4518 * Sets the packing parameters for the tab label of the page
4519 * containing @child. See gtk_box_pack_start() for the exact meaning
4520 * of the parameters.
4523 gtk_notebook_set_tab_label_packing (GtkNotebook *notebook,
4527 GtkPackType pack_type)
4529 GtkNotebookPage *page;
4532 g_return_if_fail (notebook != NULL);
4533 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
4534 g_return_if_fail (child != NULL);
4536 list = CHECK_FIND_CHILD (notebook, child);
4541 if (page->pack == pack_type && page->expand == expand && page->fill == fill)
4544 page->expand = expand;
4547 if (page->pack != pack_type)
4549 page->pack = pack_type;
4550 gtk_notebook_child_reordered (notebook, page);
4553 if (!notebook->show_tabs)
4556 gtk_notebook_pages_allocate (notebook);
4560 * gtk_notebook_query_tab_label_packing:
4561 * @notebook: a #GtkNotebook
4563 * @expand: location to store the expand value (or NULL)
4564 * @fill: location to store the fill value (or NULL)
4565 * @pack_type: location to store the pack_type (or NULL)
4567 * Query the packing attributes for the tab label of the page
4568 * containing @child.
4571 gtk_notebook_query_tab_label_packing (GtkNotebook *notebook,
4575 GtkPackType *pack_type)
4579 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
4580 g_return_if_fail (child != NULL);
4582 list = CHECK_FIND_CHILD (notebook, child);
4587 *expand = GTK_NOTEBOOK_PAGE (list)->expand;
4589 *fill = GTK_NOTEBOOK_PAGE (list)->fill;
4591 *pack_type = GTK_NOTEBOOK_PAGE (list)->pack;
4595 * gtk_notebook_reorder_child:
4596 * @notebook: a #GtkNotebook
4597 * @child: the child to move
4598 * @position: the new position
4600 * Reorders the page containing @child, so that it appears in position
4601 * @position. Out of bounds @position will be clamped.
4604 gtk_notebook_reorder_child (GtkNotebook *notebook,
4608 GList *list, *new_list;
4609 GtkNotebookPage *page;
4612 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
4613 g_return_if_fail (GTK_IS_WIDGET (child));
4615 list = CHECK_FIND_CHILD (notebook, child);
4619 old_pos = g_list_position (notebook->children, list);
4621 if (old_pos == position)
4625 notebook->children = g_list_delete_link (notebook->children, list);
4627 position = CLAMP (position, 0, g_list_length (notebook->children));
4629 notebook->children = g_list_insert (notebook->children, page, position);
4630 new_list = g_list_nth (notebook->children, position);
4632 /* Fix up GList references in GtkNotebook structure */
4633 if (notebook->first_tab == list)
4634 notebook->first_tab = new_list;
4635 if (notebook->focus_tab == list)
4636 notebook->focus_tab = new_list;
4638 /* Move around the menu items if necesary */
4639 gtk_notebook_child_reordered (notebook, page);
4641 if (notebook->show_tabs)
4642 gtk_notebook_pages_allocate (notebook);