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 Library 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 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library 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.
19 #include "gtknotebook.h"
20 #include "gtksignal.h"
23 #include "gtkmenuitem.h"
25 #include <gdk/gdkkeysyms.h>
30 #define TAB_CURVATURE 1
32 #define ARROW_SPACING 0
34 #define NOTEBOOK_INIT_SCROLL_DELAY (200)
35 #define NOTEBOOK_SCROLL_DELAY (100)
71 /** GtkNotebook Methods **/
72 static void gtk_notebook_class_init (GtkNotebookClass *klass);
73 static void gtk_notebook_init (GtkNotebook *notebook);
75 /** GtkObject Methods **/
76 static void gtk_notebook_destroy (GtkObject *object);
77 static void gtk_notebook_set_arg (GtkObject *object,
80 static void gtk_notebook_get_arg (GtkObject *object,
84 /** GtkWidget Methods **/
85 static void gtk_notebook_map (GtkWidget *widget);
86 static void gtk_notebook_unmap (GtkWidget *widget);
87 static void gtk_notebook_realize (GtkWidget *widget);
88 static void gtk_notebook_size_request (GtkWidget *widget,
89 GtkRequisition *requisition);
90 static void gtk_notebook_size_allocate (GtkWidget *widget,
91 GtkAllocation *allocation);
92 static void gtk_notebook_draw (GtkWidget *widget,
94 static gint gtk_notebook_expose (GtkWidget *widget,
95 GdkEventExpose *event);
96 static gint gtk_notebook_button_press (GtkWidget *widget,
97 GdkEventButton *event);
98 static gint gtk_notebook_button_release (GtkWidget *widget,
99 GdkEventButton *event);
100 static gint gtk_notebook_enter_notify (GtkWidget *widget,
101 GdkEventCrossing *event);
102 static gint gtk_notebook_leave_notify (GtkWidget *widget,
103 GdkEventCrossing *event);
104 static gint gtk_notebook_motion_notify (GtkWidget *widget,
105 GdkEventMotion *event);
106 static gint gtk_notebook_key_press (GtkWidget *widget,
108 static gint gtk_notebook_focus_in (GtkWidget *widget,
109 GdkEventFocus *event);
110 static gint gtk_notebook_focus_out (GtkWidget *widget,
111 GdkEventFocus *event);
112 static void gtk_notebook_draw_focus (GtkWidget *widget);
113 static void gtk_notebook_style_set (GtkWidget *widget,
114 GtkStyle *previous_style);
116 /** GtkContainer Methods **/
117 static void gtk_notebook_set_child_arg (GtkContainer *container,
121 static void gtk_notebook_get_child_arg (GtkContainer *container,
125 static void gtk_notebook_add (GtkContainer *container,
127 static void gtk_notebook_remove (GtkContainer *container,
129 static gint gtk_notebook_focus (GtkContainer *container,
130 GtkDirectionType direction);
131 static void gtk_notebook_set_focus_child (GtkContainer *container,
133 static GtkType gtk_notebook_child_type (GtkContainer *container);
134 static void gtk_notebook_forall (GtkContainer *container,
135 gboolean include_internals,
136 GtkCallback callback,
137 gpointer callback_data);
139 /** GtkNotebook Private Functions **/
140 static void gtk_notebook_panel_realize (GtkNotebook *notebook);
141 static void gtk_notebook_expose_tabs (GtkNotebook *notebook);
142 static void gtk_notebook_focus_changed (GtkNotebook *notebook,
143 GtkNotebookPage *old_page);
144 static void gtk_notebook_real_remove (GtkNotebook *notebook,
146 static void gtk_notebook_update_labels (GtkNotebook *notebook);
147 static gint gtk_notebook_timer (GtkNotebook *notebook);
148 static gint gtk_notebook_page_compare (gconstpointer a,
150 static gint gtk_notebook_real_page_position (GtkNotebook *notebook,
152 static GList * gtk_notebook_search_page (GtkNotebook *notebook,
155 gboolean find_visible);
157 /** GtkNotebook Drawing Functions **/
158 static void gtk_notebook_paint (GtkWidget *widget,
160 static void gtk_notebook_draw_tab (GtkNotebook *notebook,
161 GtkNotebookPage *page,
163 static void gtk_notebook_draw_arrow (GtkNotebook *notebook,
165 static void gtk_notebook_set_shape (GtkNotebook *notebook);
167 /** GtkNotebook Size Allocate Functions **/
168 static void gtk_notebook_pages_allocate (GtkNotebook *notebook,
169 GtkAllocation *allocation);
170 static void gtk_notebook_page_allocate (GtkNotebook *notebook,
171 GtkNotebookPage *page,
172 GtkAllocation *allocation);
173 static void gtk_notebook_calc_tabs (GtkNotebook *notebook,
179 /** GtkNotebook Page Switch Methods **/
180 static void gtk_notebook_real_switch_page (GtkNotebook *notebook,
181 GtkNotebookPage *page,
184 /** GtkNotebook Page Switch Functions **/
185 static void gtk_notebook_switch_page (GtkNotebook *notebook,
186 GtkNotebookPage *page,
188 static gint gtk_notebook_page_select (GtkNotebook *notebook);
189 static void gtk_notebook_switch_focus_tab (GtkNotebook *notebook,
191 static void gtk_notebook_menu_switch_page (GtkWidget *widget,
192 GtkNotebookPage *page);
194 /** GtkNotebook Menu Functions **/
195 static void gtk_notebook_menu_item_create (GtkNotebook *notebook,
197 static void gtk_notebook_menu_label_unparent (GtkWidget *widget,
199 static void gtk_notebook_menu_detacher (GtkWidget *widget,
203 static GtkContainerClass *parent_class = NULL;
204 static guint notebook_signals[LAST_SIGNAL] = { 0 };
207 gtk_notebook_get_type (void)
209 static GtkType notebook_type = 0;
213 GtkTypeInfo notebook_info =
216 sizeof (GtkNotebook),
217 sizeof (GtkNotebookClass),
218 (GtkClassInitFunc) gtk_notebook_class_init,
219 (GtkObjectInitFunc) gtk_notebook_init,
220 /* reserved_1 */ NULL,
221 /* reserved_2 */ NULL,
222 (GtkClassInitFunc) NULL,
225 notebook_type = gtk_type_unique (gtk_container_get_type (), ¬ebook_info);
228 return notebook_type;
232 gtk_notebook_class_init (GtkNotebookClass *class)
234 GtkObjectClass *object_class;
235 GtkWidgetClass *widget_class;
236 GtkContainerClass *container_class;
238 object_class = (GtkObjectClass*) class;
239 widget_class = (GtkWidgetClass*) class;
240 container_class = (GtkContainerClass*) class;
241 parent_class = gtk_type_class (gtk_container_get_type ());
243 gtk_object_add_arg_type ("GtkNotebook::page", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_PAGE);
244 gtk_object_add_arg_type ("GtkNotebook::tab_pos", GTK_TYPE_POSITION_TYPE, GTK_ARG_READWRITE, ARG_TAB_POS);
245 gtk_object_add_arg_type ("GtkNotebook::tab_border", GTK_TYPE_UINT, GTK_ARG_WRITABLE, ARG_TAB_BORDER);
246 gtk_object_add_arg_type ("GtkNotebook::tab_hborder", GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_TAB_HBORDER);
247 gtk_object_add_arg_type ("GtkNotebook::tab_vborder", GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_TAB_VBORDER);
248 gtk_object_add_arg_type ("GtkNotebook::show_tabs", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_SHOW_TABS);
249 gtk_object_add_arg_type ("GtkNotebook::show_border", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_SHOW_BORDER);
250 gtk_object_add_arg_type ("GtkNotebook::scrollable", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_SCROLLABLE);
251 gtk_object_add_arg_type ("GtkNotebook::enable_popup", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_ENABLE_POPUP);
253 gtk_container_add_child_arg_type ("GtkNotebook::tab_label", GTK_TYPE_STRING, GTK_ARG_READWRITE, CHILD_ARG_TAB_LABEL);
254 gtk_container_add_child_arg_type ("GtkNotebook::menu_label", GTK_TYPE_STRING, GTK_ARG_READWRITE, CHILD_ARG_MENU_LABEL);
255 gtk_container_add_child_arg_type ("GtkNotebook::position", GTK_TYPE_INT, GTK_ARG_READWRITE, CHILD_ARG_POSITION);
256 gtk_container_add_child_arg_type ("GtkNotebook::tab_fill", GTK_TYPE_BOOL, GTK_ARG_READWRITE, CHILD_ARG_TAB_FILL);
257 gtk_container_add_child_arg_type ("GtkNotebook::tab_pack", GTK_TYPE_BOOL, GTK_ARG_READWRITE, CHILD_ARG_TAB_PACK);
259 notebook_signals[SWITCH_PAGE] =
260 gtk_signal_new ("switch_page",
263 GTK_SIGNAL_OFFSET (GtkNotebookClass, switch_page),
264 gtk_marshal_NONE__POINTER_UINT,
269 gtk_object_class_add_signals (object_class, notebook_signals, LAST_SIGNAL);
271 object_class->set_arg = gtk_notebook_set_arg;
272 object_class->get_arg = gtk_notebook_get_arg;
273 object_class->destroy = gtk_notebook_destroy;
275 widget_class->map = gtk_notebook_map;
276 widget_class->unmap = gtk_notebook_unmap;
277 widget_class->realize = gtk_notebook_realize;
278 widget_class->size_request = gtk_notebook_size_request;
279 widget_class->size_allocate = gtk_notebook_size_allocate;
280 widget_class->draw = gtk_notebook_draw;
281 widget_class->expose_event = gtk_notebook_expose;
282 widget_class->button_press_event = gtk_notebook_button_press;
283 widget_class->button_release_event = gtk_notebook_button_release;
284 widget_class->enter_notify_event = gtk_notebook_enter_notify;
285 widget_class->leave_notify_event = gtk_notebook_leave_notify;
286 widget_class->motion_notify_event = gtk_notebook_motion_notify;
287 widget_class->key_press_event = gtk_notebook_key_press;
288 widget_class->focus_in_event = gtk_notebook_focus_in;
289 widget_class->focus_out_event = gtk_notebook_focus_out;
290 widget_class->draw_focus = gtk_notebook_draw_focus;
291 widget_class->style_set = gtk_notebook_style_set;
293 container_class->add = gtk_notebook_add;
294 container_class->remove = gtk_notebook_remove;
295 container_class->forall = gtk_notebook_forall;
296 container_class->focus = gtk_notebook_focus;
297 container_class->set_focus_child = gtk_notebook_set_focus_child;
298 container_class->get_child_arg = gtk_notebook_get_child_arg;
299 container_class->set_child_arg = gtk_notebook_set_child_arg;
300 container_class->child_type = gtk_notebook_child_type;
302 class->switch_page = gtk_notebook_real_switch_page;
306 gtk_notebook_init (GtkNotebook *notebook)
308 GTK_WIDGET_SET_FLAGS (notebook, GTK_CAN_FOCUS);
309 GTK_WIDGET_UNSET_FLAGS (notebook, GTK_NO_WINDOW);
311 notebook->cur_page = NULL;
312 notebook->children = NULL;
313 notebook->first_tab = NULL;
314 notebook->focus_tab = NULL;
315 notebook->panel = NULL;
316 notebook->menu = NULL;
318 notebook->tab_hborder = 2;
319 notebook->tab_vborder = 2;
321 notebook->show_tabs = TRUE;
322 notebook->show_border = TRUE;
323 notebook->tab_pos = GTK_POS_TOP;
324 notebook->scrollable = FALSE;
325 notebook->in_child = 0;
326 notebook->click_child = 0;
327 notebook->button = 0;
328 notebook->need_timer = 0;
329 notebook->child_has_focus = FALSE;
333 gtk_notebook_new (void)
335 return GTK_WIDGET (gtk_type_new (gtk_notebook_get_type ()));
338 /* Private GtkObject Methods :
340 * gtk_notebook_destroy
341 * gtk_notebook_set_arg
342 * gtk_notebook_get_arg
345 gtk_notebook_destroy (GtkObject *object)
347 GtkNotebook *notebook;
349 g_return_if_fail (object != NULL);
350 g_return_if_fail (GTK_IS_NOTEBOOK (object));
352 notebook = GTK_NOTEBOOK (object);
355 gtk_notebook_popup_disable (notebook);
357 GTK_OBJECT_CLASS (parent_class)->destroy (object);
361 gtk_notebook_set_arg (GtkObject *object,
365 GtkNotebook *notebook;
367 notebook = GTK_NOTEBOOK (object);
372 gtk_notebook_set_show_tabs (notebook, GTK_VALUE_BOOL (*arg));
374 case ARG_SHOW_BORDER:
375 gtk_notebook_set_show_border (notebook, GTK_VALUE_BOOL (*arg));
378 gtk_notebook_set_scrollable (notebook, GTK_VALUE_BOOL (*arg));
380 case ARG_ENABLE_POPUP:
381 if (GTK_VALUE_BOOL (*arg))
382 gtk_notebook_popup_enable (notebook);
384 gtk_notebook_popup_disable (notebook);
387 gtk_notebook_set_page (notebook, GTK_VALUE_INT (*arg));
390 gtk_notebook_set_tab_pos (notebook, GTK_VALUE_ENUM (*arg));
393 gtk_notebook_set_tab_border (notebook, GTK_VALUE_UINT (*arg));
395 case ARG_TAB_HBORDER:
396 gtk_notebook_set_tab_hborder (notebook, GTK_VALUE_UINT (*arg));
398 case ARG_TAB_VBORDER:
399 gtk_notebook_set_tab_vborder (notebook, GTK_VALUE_UINT (*arg));
407 gtk_notebook_get_arg (GtkObject *object,
411 GtkNotebook *notebook;
413 notebook = GTK_NOTEBOOK (object);
418 GTK_VALUE_BOOL (*arg) = notebook->show_tabs;
420 case ARG_SHOW_BORDER:
421 GTK_VALUE_BOOL (*arg) = notebook->show_border;
424 GTK_VALUE_BOOL (*arg) = notebook->scrollable;
426 case ARG_ENABLE_POPUP:
427 GTK_VALUE_BOOL (*arg) = notebook->menu != NULL;
430 GTK_VALUE_INT (*arg) = gtk_notebook_current_page (notebook);
433 GTK_VALUE_ENUM (*arg) = notebook->tab_pos;
435 case ARG_TAB_HBORDER:
436 GTK_VALUE_UINT (*arg) = notebook->tab_hborder;
438 case ARG_TAB_VBORDER:
439 GTK_VALUE_UINT (*arg) = notebook->tab_vborder;
442 arg->type = GTK_TYPE_INVALID;
447 /* Private GtkWidget Methods :
451 * gtk_notebook_realize
452 * gtk_notebook_size_request
453 * gtk_notebook_size_allocate
455 * gtk_notebook_expose
456 * gtk_notebook_button_press
457 * gtk_notebook_button_release
458 * gtk_notebook_enter_notify
459 * gtk_notebook_leave_notify
460 * gtk_notebook_motion_notify
461 * gtk_notebook_key_press
462 * gtk_notebook_focus_in
463 * gtk_notebook_focus_out
464 * gtk_notebook_draw_focus
465 * gtk_notebook_style_set
468 gtk_notebook_map (GtkWidget *widget)
470 GtkNotebook *notebook;
471 GtkNotebookPage *page;
474 g_return_if_fail (widget != NULL);
475 g_return_if_fail (GTK_IS_NOTEBOOK (widget));
477 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
478 gdk_window_show (widget->window);
480 notebook = GTK_NOTEBOOK (widget);
482 if (notebook->cur_page &&
483 GTK_WIDGET_VISIBLE (notebook->cur_page->child) &&
484 !GTK_WIDGET_MAPPED (notebook->cur_page->child))
485 gtk_widget_map (notebook->cur_page->child);
487 if (notebook->scrollable)
488 gtk_notebook_pages_allocate (notebook, &(widget->allocation));
491 children = notebook->children;
495 page = children->data;
496 children = children->next;
498 if (page->tab_label &&
499 GTK_WIDGET_VISIBLE (page->child) &&
500 !GTK_WIDGET_MAPPED (page->tab_label))
501 gtk_widget_map (page->tab_label);
507 gtk_notebook_unmap (GtkWidget *widget)
509 g_return_if_fail (widget != NULL);
510 g_return_if_fail (GTK_IS_NOTEBOOK (widget));
512 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
513 gdk_window_hide (widget->window);
514 if (GTK_NOTEBOOK (widget)->panel)
515 gdk_window_hide (GTK_NOTEBOOK (widget)->panel);
519 gtk_notebook_realize (GtkWidget *widget)
521 GtkNotebook *notebook;
522 GdkWindowAttr attributes;
523 gint attributes_mask;
525 g_return_if_fail (widget != NULL);
526 g_return_if_fail (GTK_IS_NOTEBOOK (widget));
528 notebook = GTK_NOTEBOOK (widget);
529 GTK_WIDGET_SET_FLAGS (notebook, GTK_REALIZED);
531 attributes.window_type = GDK_WINDOW_CHILD;
532 attributes.x = widget->allocation.x;
533 attributes.y = widget->allocation.y;
534 attributes.width = widget->allocation.width;
535 attributes.height = widget->allocation.height;
536 attributes.wclass = GDK_INPUT_OUTPUT;
537 attributes.visual = gtk_widget_get_visual (widget);
538 attributes.colormap = gtk_widget_get_colormap (widget);
539 attributes.event_mask = gtk_widget_get_events (widget);
540 attributes.event_mask |= (GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK |
541 GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK);
543 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
545 widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
546 gdk_window_set_user_data (widget->window, notebook);
548 widget->style = gtk_style_attach (widget->style, widget->window);
549 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
551 gdk_window_set_back_pixmap (widget->window, NULL, TRUE);
552 if (notebook->scrollable)
553 gtk_notebook_panel_realize (notebook);
557 gtk_notebook_size_request (GtkWidget *widget,
558 GtkRequisition *requisition)
560 GtkNotebook *notebook;
561 GtkNotebookPage *page;
563 gboolean switch_page = FALSE;
566 g_return_if_fail (widget != NULL);
567 g_return_if_fail (GTK_IS_NOTEBOOK (widget));
568 g_return_if_fail (requisition != NULL);
570 notebook = GTK_NOTEBOOK (widget);
571 widget->requisition.width = 0;
572 widget->requisition.height = 0;
574 for (children = notebook->children, vis_pages = 0; children;
575 children = children->next)
577 page = children->data;
579 if (GTK_WIDGET_VISIBLE (page->child))
582 gtk_widget_size_request (page->child, &page->child->requisition);
584 widget->requisition.width = MAX (widget->requisition.width,
585 page->child->requisition.width);
586 widget->requisition.height = MAX (widget->requisition.height,
587 page->child->requisition.height);
589 if (GTK_WIDGET_MAPPED (page->child) && page != notebook->cur_page)
590 gtk_widget_unmap (page->child);
591 if (notebook->menu && page->menu_label->parent &&
592 !GTK_WIDGET_VISIBLE (page->menu_label->parent))
593 gtk_widget_show (page->menu_label->parent);
597 if (page == notebook->cur_page)
599 if (notebook->menu && page->menu_label->parent &&
600 GTK_WIDGET_VISIBLE (page->menu_label->parent))
601 gtk_widget_hide (page->menu_label->parent);
605 if (notebook->show_border || notebook->show_tabs)
607 widget->requisition.width += widget->style->klass->xthickness * 2;
608 widget->requisition.height += widget->style->klass->ythickness * 2;
610 if (notebook->show_tabs)
617 for (children = notebook->children; children;
618 children = children->next)
620 page = children->data;
622 if (GTK_WIDGET_VISIBLE (page->child))
624 if (!GTK_WIDGET_VISIBLE (page->tab_label))
625 gtk_widget_show (page->tab_label);
627 gtk_widget_size_request (page->tab_label,
628 &page->tab_label->requisition);
630 page->requisition.width =
631 page->tab_label->requisition.width +
632 2 * widget->style->klass->xthickness;
633 page->requisition.height =
634 page->tab_label->requisition.height +
635 2 * widget->style->klass->ythickness;
637 switch (notebook->tab_pos)
641 page->requisition.height += 2 * (notebook->tab_vborder +
643 tab_height = MAX (tab_height, page->requisition.height);
644 tab_max = MAX (tab_max, page->requisition.width);
648 page->requisition.width += 2 * (notebook->tab_hborder +
650 tab_width = MAX (tab_width, page->requisition.width);
651 tab_max = MAX (tab_max, page->requisition.height);
655 else if (GTK_WIDGET_VISIBLE (page->tab_label))
656 gtk_widget_hide (page->tab_label);
659 children = notebook->children;
663 switch (notebook->tab_pos)
670 if (notebook->scrollable && vis_pages > 1 &&
671 widget->requisition.width < tab_width)
672 tab_height = MAX (tab_height, ARROW_SIZE);
674 padding = 2 * (TAB_CURVATURE + FOCUS_WIDTH +
675 notebook->tab_hborder) - TAB_OVERLAP;
679 page = children->data;
680 children = children->next;
682 if (!GTK_WIDGET_VISIBLE (page->child))
685 if (notebook->homogeneous)
686 page->requisition.width = tab_max;
688 page->requisition.width += padding;
690 tab_width += page->requisition.width;
691 page->requisition.height = tab_height;
694 if (notebook->scrollable && vis_pages > 1 &&
695 widget->requisition.width < tab_width)
696 tab_width = tab_max + 2 * (ARROW_SIZE + ARROW_SPACING);
698 if (notebook->homogeneous && !notebook->scrollable)
699 widget->requisition.width = MAX (widget->requisition.width,
700 vis_pages * tab_max +
703 widget->requisition.width = MAX (widget->requisition.width,
704 tab_width + TAB_OVERLAP);
706 widget->requisition.height += tab_height;
713 if (notebook->scrollable && vis_pages > 1 &&
714 widget->requisition.height < tab_height)
715 tab_width = MAX (tab_width, ARROW_SPACING +2 * ARROW_SIZE);
717 padding = 2 * (TAB_CURVATURE + FOCUS_WIDTH +
718 notebook->tab_vborder) - TAB_OVERLAP;
723 page = children->data;
724 children = children->next;
726 if (!GTK_WIDGET_VISIBLE (page->child))
729 page->requisition.width = tab_width;
731 if (notebook->homogeneous)
732 page->requisition.height = tab_max;
734 page->requisition.height += padding;
736 tab_height += page->requisition.height;
739 if (notebook->scrollable && vis_pages > 1 &&
740 widget->requisition.height < tab_height)
741 tab_height = tab_max + ARROW_SIZE + ARROW_SPACING;
743 widget->requisition.width += tab_width;
745 if (notebook->homogeneous && !notebook->scrollable)
746 widget->requisition.height =
747 MAX (widget->requisition.height,
748 vis_pages * tab_max + TAB_OVERLAP);
750 widget->requisition.height =
751 MAX (widget->requisition.height,
752 tab_height + TAB_OVERLAP);
754 if (!notebook->homogeneous || notebook->scrollable)
756 widget->requisition.height = MAX (widget->requisition.height,
757 vis_pages * tab_max +
765 widget->requisition.width += GTK_CONTAINER (widget)->border_width * 2;
766 widget->requisition.height += GTK_CONTAINER (widget)->border_width * 2;
772 for (children = notebook->children; children;
773 children = children->next)
775 page = children->data;
776 if (GTK_WIDGET_VISIBLE (page->child))
778 gtk_notebook_switch_page (notebook, page, -1);
783 else if (GTK_WIDGET_VISIBLE (widget))
785 widget->requisition.width = GTK_CONTAINER (widget)->border_width * 2;
786 widget->requisition.height= GTK_CONTAINER (widget)->border_width * 2;
789 if (vis_pages && !notebook->cur_page)
791 children = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, TRUE);
794 notebook->first_tab = children;
795 gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (children),-1);
801 gtk_notebook_size_allocate (GtkWidget *widget,
802 GtkAllocation *allocation)
804 GtkNotebook *notebook;
805 GtkNotebookPage *page;
806 GtkAllocation child_allocation;
809 g_return_if_fail (widget != NULL);
810 g_return_if_fail (GTK_IS_NOTEBOOK (widget));
811 g_return_if_fail (allocation != NULL);
813 widget->allocation = *allocation;
814 if (GTK_WIDGET_REALIZED (widget))
815 gdk_window_move_resize (widget->window,
816 allocation->x, allocation->y,
817 allocation->width, allocation->height);
819 notebook = GTK_NOTEBOOK (widget);
820 if (notebook->children)
822 child_allocation.x = GTK_CONTAINER (widget)->border_width;
823 child_allocation.y = GTK_CONTAINER (widget)->border_width;
824 child_allocation.width = MAX (1, allocation->width - child_allocation.x * 2);
825 child_allocation.height = MAX (1, allocation->height - child_allocation.y * 2);
827 if (notebook->show_tabs || notebook->show_border)
829 child_allocation.x += widget->style->klass->xthickness;
830 child_allocation.y += widget->style->klass->ythickness;
831 child_allocation.width = MAX (1, child_allocation.width -
832 widget->style->klass->xthickness * 2);
833 child_allocation.height = MAX (1, child_allocation.height -
834 widget->style->klass->ythickness * 2);
836 if (notebook->show_tabs && notebook->children && notebook->cur_page)
838 switch (notebook->tab_pos)
841 child_allocation.y += notebook->cur_page->requisition.height;
843 child_allocation.height =
844 MAX (1, child_allocation.height -
845 notebook->cur_page->requisition.height);
848 child_allocation.x += notebook->cur_page->requisition.width;
850 child_allocation.width =
851 MAX (1, child_allocation.width -
852 notebook->cur_page->requisition.width);
858 children = notebook->children;
861 page = children->data;
862 children = children->next;
864 if (GTK_WIDGET_VISIBLE (page->child))
865 gtk_widget_size_allocate (page->child, &child_allocation);
868 gtk_notebook_pages_allocate (notebook, allocation);
870 gtk_notebook_set_shape (notebook);
874 gtk_notebook_draw (GtkWidget *widget,
877 GtkNotebook *notebook;
878 GdkRectangle child_area;
880 g_return_if_fail (widget != NULL);
881 g_return_if_fail (GTK_IS_NOTEBOOK (widget));
882 g_return_if_fail (area != NULL);
884 if (GTK_WIDGET_DRAWABLE (widget))
886 notebook = GTK_NOTEBOOK (widget);
888 gtk_notebook_paint (widget, area);
889 gtk_widget_draw_focus (widget);
891 if (notebook->cur_page &&
892 gtk_widget_intersect (notebook->cur_page->child, area, &child_area))
893 gtk_widget_draw (notebook->cur_page->child, &child_area);
898 gtk_notebook_expose (GtkWidget *widget,
899 GdkEventExpose *event)
901 GtkNotebook *notebook;
902 GdkEventExpose child_event;
903 GdkRectangle child_area;
905 g_return_val_if_fail (widget != NULL, FALSE);
906 g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
907 g_return_val_if_fail (event != NULL, FALSE);
909 if (GTK_WIDGET_DRAWABLE (widget))
911 notebook = GTK_NOTEBOOK (widget);
913 gtk_notebook_paint (widget, &event->area);
914 if (notebook->show_tabs)
916 if (notebook->cur_page &&
917 gtk_widget_intersect (notebook->cur_page->tab_label,
918 &event->area, &child_area))
919 gtk_widget_draw_focus (widget);
922 child_event = *event;
923 if (notebook->cur_page &&
924 GTK_WIDGET_NO_WINDOW (notebook->cur_page->child) &&
925 gtk_widget_intersect (notebook->cur_page->child, &event->area,
927 gtk_widget_event (notebook->cur_page->child, (GdkEvent*) &child_event);
934 gtk_notebook_button_press (GtkWidget *widget,
935 GdkEventButton *event)
937 GtkNotebook *notebook;
938 GtkNotebookPage *page;
942 g_return_val_if_fail (widget != NULL, FALSE);
943 g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
944 g_return_val_if_fail (event != NULL, FALSE);
946 notebook = GTK_NOTEBOOK (widget);
948 if (event->type != GDK_BUTTON_PRESS || !notebook->children ||
952 if (event->window == notebook->panel)
954 if (!GTK_WIDGET_HAS_FOCUS (widget))
955 gtk_widget_grab_focus (widget);
957 gtk_grab_add (widget);
958 notebook->button = event->button;
960 if (event->x <= ARROW_SIZE + ARROW_SPACING / 2)
962 notebook->click_child = GTK_ARROW_LEFT;
963 if (event->button == 1)
965 if (!notebook->focus_tab ||
966 gtk_notebook_search_page (notebook, notebook->focus_tab,
968 gtk_container_focus (GTK_CONTAINER (notebook), GTK_DIR_LEFT);
970 if (!notebook->timer)
972 notebook->timer = gtk_timeout_add
973 (NOTEBOOK_INIT_SCROLL_DELAY,
974 (GtkFunction) gtk_notebook_timer, (gpointer) notebook);
975 notebook->need_timer = TRUE;
978 else if (event->button == 2)
979 gtk_notebook_page_select (GTK_NOTEBOOK (widget));
980 else if (event->button == 3)
981 gtk_notebook_switch_focus_tab (notebook,
982 gtk_notebook_search_page (notebook,
986 gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT);
990 notebook->click_child = GTK_ARROW_RIGHT;
991 if (event->button == 1)
993 if (!notebook->focus_tab ||
994 gtk_notebook_search_page (notebook, notebook->focus_tab,
996 gtk_container_focus (GTK_CONTAINER (notebook), GTK_DIR_RIGHT);
998 if (!notebook->timer)
1000 notebook->timer = gtk_timeout_add
1001 (NOTEBOOK_INIT_SCROLL_DELAY,
1002 (GtkFunction) gtk_notebook_timer, (gpointer) notebook);
1003 notebook->need_timer = TRUE;
1006 else if (event->button == 2)
1007 gtk_notebook_page_select (GTK_NOTEBOOK (widget));
1008 else if (event->button == 3)
1009 gtk_notebook_switch_focus_tab
1010 (notebook, gtk_notebook_search_page (notebook, NULL,
1012 gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT);
1015 else if (event->window == widget->window)
1017 if (event->button == 3 && notebook->menu)
1019 gtk_menu_popup (GTK_MENU (notebook->menu), NULL, NULL,
1020 NULL, NULL, 3, event->time);
1025 children = notebook->children;
1028 page = children->data;
1030 if (GTK_WIDGET_VISIBLE (page->child) &&
1031 page->tab_label && GTK_WIDGET_MAPPED (page->tab_label) &&
1032 (event->x >= page->allocation.x) &&
1033 (event->y >= page->allocation.y) &&
1034 (event->x <= (page->allocation.x + page->allocation.width)) &&
1035 (event->y <= (page->allocation.y + page->allocation.height)))
1037 if (page == notebook->cur_page && notebook->focus_tab &&
1038 notebook->focus_tab != children &&
1039 GTK_WIDGET_HAS_FOCUS (notebook))
1041 GtkNotebookPage *old_page;
1043 notebook->child_has_focus = FALSE;
1044 old_page = (GtkNotebookPage *)
1045 (notebook->focus_tab->data);
1046 gtk_notebook_switch_focus_tab (notebook, children);
1047 gtk_notebook_focus_changed (notebook, old_page);
1051 gtk_notebook_switch_focus_tab (notebook, children);
1052 gtk_notebook_switch_page (notebook, page, num);
1053 gtk_widget_grab_focus (widget);
1057 children = children->next;
1060 if (!children && !GTK_WIDGET_HAS_FOCUS (widget))
1061 gtk_widget_grab_focus (widget);
1063 gtk_notebook_set_shape (notebook);
1068 gtk_notebook_button_release (GtkWidget *widget,
1069 GdkEventButton *event)
1071 GtkNotebook *notebook;
1073 g_return_val_if_fail (widget != NULL, FALSE);
1074 g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
1075 g_return_val_if_fail (event != NULL, FALSE);
1077 if (event->type != GDK_BUTTON_RELEASE)
1080 notebook = GTK_NOTEBOOK (widget);
1082 if (event->button == notebook->button)
1086 if (notebook->timer)
1088 gtk_timeout_remove (notebook->timer);
1089 notebook->timer = 0;
1090 notebook->need_timer = FALSE;
1092 gtk_grab_remove (widget);
1093 click_child = notebook->click_child;
1094 notebook->click_child = 0;
1095 notebook->button = 0;
1096 gtk_notebook_draw_arrow (notebook, click_child);
1103 gtk_notebook_enter_notify (GtkWidget *widget,
1104 GdkEventCrossing *event)
1106 GtkNotebook *notebook;
1108 g_return_val_if_fail (widget != NULL, FALSE);
1109 g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
1110 g_return_val_if_fail (event != NULL, FALSE);
1112 notebook = GTK_NOTEBOOK (widget);
1114 if (event->window == notebook->panel)
1119 gdk_window_get_pointer (notebook->panel, &x, &y, NULL);
1121 if (x <= ARROW_SIZE + ARROW_SPACING / 2)
1123 notebook->in_child = GTK_ARROW_LEFT;
1125 if (notebook->click_child == 0)
1126 gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT);
1130 notebook->in_child = GTK_ARROW_RIGHT;
1132 if (notebook->click_child == 0)
1133 gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT);
1141 gtk_notebook_leave_notify (GtkWidget *widget,
1142 GdkEventCrossing *event)
1144 GtkNotebook *notebook;
1146 g_return_val_if_fail (widget != NULL, FALSE);
1147 g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
1148 g_return_val_if_fail (event != NULL, FALSE);
1150 notebook = GTK_NOTEBOOK (widget);
1152 if (event->window == notebook->panel && !notebook->click_child)
1154 if (notebook->in_child == GTK_ARROW_LEFT)
1156 notebook->in_child = 0;
1157 gtk_notebook_draw_arrow (notebook,GTK_ARROW_LEFT);
1161 notebook->in_child = 0;
1162 gtk_notebook_draw_arrow (notebook,GTK_ARROW_RIGHT);
1169 gtk_notebook_motion_notify (GtkWidget *widget,
1170 GdkEventMotion *event)
1172 GtkNotebook *notebook;
1174 g_return_val_if_fail (widget != NULL, FALSE);
1175 g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
1176 g_return_val_if_fail (event != NULL, FALSE);
1178 notebook = GTK_NOTEBOOK (widget);
1180 if (notebook->button)
1183 if (event->window == notebook->panel)
1189 gdk_window_get_pointer (notebook->panel, &x, NULL, NULL);
1191 if (x <= ARROW_SIZE + ARROW_SPACING / 2 &&
1192 notebook->in_child == GTK_ARROW_RIGHT)
1194 notebook->in_child = GTK_ARROW_LEFT;
1195 gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT);
1196 gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT);
1198 else if (x > ARROW_SIZE + ARROW_SPACING / 2 &&
1199 notebook->in_child == GTK_ARROW_LEFT)
1201 notebook->in_child = GTK_ARROW_RIGHT;
1202 gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT);
1203 gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT);
1211 gtk_notebook_key_press (GtkWidget *widget,
1214 GtkNotebook *notebook;
1215 GtkDirectionType direction = 0;
1218 g_return_val_if_fail (widget != NULL, FALSE);
1219 g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
1220 g_return_val_if_fail (event != NULL, FALSE);
1222 notebook = GTK_NOTEBOOK (widget);
1224 if (!notebook->children || !notebook->show_tabs)
1227 switch (event->keyval)
1230 direction = GTK_DIR_UP;
1233 direction = GTK_DIR_LEFT;
1236 direction = GTK_DIR_DOWN;
1239 direction = GTK_DIR_RIGHT;
1242 case GDK_ISO_Left_Tab:
1243 if (event->state & GDK_SHIFT_MASK)
1244 direction = GTK_DIR_TAB_BACKWARD;
1246 direction = GTK_DIR_TAB_FORWARD;
1249 list = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, TRUE);
1251 gtk_notebook_switch_focus_tab (notebook, list);
1254 list = gtk_notebook_search_page (notebook, NULL, STEP_PREV, TRUE);
1256 gtk_notebook_switch_focus_tab (notebook, list);
1260 gtk_notebook_page_select (GTK_NOTEBOOK (widget));
1265 return gtk_container_focus (GTK_CONTAINER (widget), direction);
1269 gtk_notebook_focus_in (GtkWidget *widget,
1270 GdkEventFocus *event)
1272 g_return_val_if_fail (widget != NULL, FALSE);
1273 g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
1274 g_return_val_if_fail (event != NULL, FALSE);
1276 GTK_NOTEBOOK (widget)->child_has_focus = FALSE;
1277 GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
1278 gtk_widget_draw_focus (widget);
1284 gtk_notebook_focus_out (GtkWidget *widget,
1285 GdkEventFocus *event)
1287 g_return_val_if_fail (widget != NULL, FALSE);
1288 g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
1289 g_return_val_if_fail (event != NULL, FALSE);
1291 GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
1292 gtk_widget_draw_focus (widget);
1298 gtk_notebook_draw_focus (GtkWidget *widget)
1300 GtkNotebook *notebook;
1302 g_return_if_fail (widget != NULL);
1303 g_return_if_fail (GTK_IS_NOTEBOOK (widget));
1305 notebook = GTK_NOTEBOOK (widget);
1307 if (GTK_WIDGET_DRAWABLE (widget) && notebook->show_tabs &&
1308 notebook->focus_tab)
1310 GtkNotebookPage *page;
1313 page = notebook->focus_tab->data;
1315 area.x = page->tab_label->allocation.x - 1;
1316 area.y = page->tab_label->allocation.y - 1;
1317 area.width = page->tab_label->allocation.width + 2;
1318 area.height = page->tab_label->allocation.height + 2;
1320 gtk_notebook_draw_tab (GTK_NOTEBOOK (widget), page, &area);
1325 gtk_notebook_style_set (GtkWidget *widget,
1326 GtkStyle *previous_style)
1328 if (GTK_WIDGET_REALIZED (widget) &&
1329 !GTK_WIDGET_NO_WINDOW (widget))
1331 gtk_style_set_background (widget->style, widget->window, widget->state);
1332 if (GTK_WIDGET_DRAWABLE (widget))
1333 gdk_window_clear (widget->window);
1336 gtk_widget_queue_draw (widget);
1337 gtk_notebook_set_shape (GTK_NOTEBOOK(widget));
1340 /* Private GtkContainer Methods :
1342 * gtk_notebook_set_child_arg
1343 * gtk_notebook_get_child_arg
1345 * gtk_notebook_remove
1346 * gtk_notebook_focus
1347 * gtk_notebook_set_focus_child
1348 * gtk_notebook_child_type
1349 * gtk_notebook_forall
1352 gtk_notebook_set_child_arg (GtkContainer *container,
1359 GtkPackType pack_type;
1363 case CHILD_ARG_TAB_LABEL:
1364 /* a NULL pointer indicates a default_tab setting, otherwise
1365 * we need to set the associated label
1367 gtk_notebook_set_tab_label_text (GTK_NOTEBOOK (container), child,
1368 GTK_VALUE_STRING(*arg));
1370 case CHILD_ARG_MENU_LABEL:
1371 gtk_notebook_set_menu_label_text (GTK_NOTEBOOK (container), child,
1372 GTK_VALUE_STRING (*arg));
1374 case CHILD_ARG_POSITION:
1375 gtk_notebook_reorder_child (GTK_NOTEBOOK (container), child,
1376 GTK_VALUE_INT (*arg));
1378 case CHILD_ARG_TAB_EXPAND:
1379 gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (container), child,
1380 &expand, &fill, &pack_type);
1381 gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (container), child,
1382 GTK_VALUE_BOOL (*arg),
1385 case CHILD_ARG_TAB_FILL:
1386 gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (container), child,
1387 &expand, &fill, &pack_type);
1388 gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (container), child,
1390 GTK_VALUE_BOOL (*arg),
1393 case CHILD_ARG_TAB_PACK:
1394 gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (container), child,
1395 &expand, &fill, &pack_type);
1396 gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (container), child,
1398 GTK_VALUE_BOOL (*arg));
1406 gtk_notebook_get_child_arg (GtkContainer *container,
1412 GtkNotebook *notebook;
1416 GtkPackType pack_type;
1418 notebook = GTK_NOTEBOOK (container);
1420 if (!(list = g_list_find_custom (notebook->children, child,
1421 gtk_notebook_page_compare)))
1423 arg->type = GTK_TYPE_INVALID;
1429 case CHILD_ARG_TAB_LABEL:
1430 label = gtk_notebook_query_tab_label (notebook, child);
1432 if (label && GTK_IS_LABEL (label))
1433 GTK_VALUE_STRING (*arg) = g_strdup (GTK_LABEL (label)->label);
1435 GTK_VALUE_STRING (*arg) = NULL;
1437 case CHILD_ARG_MENU_LABEL:
1438 label = gtk_notebook_query_menu_label (notebook, child);
1440 if (label && GTK_IS_LABEL (label))
1441 GTK_VALUE_STRING (*arg) = g_strdup (GTK_LABEL (label)->label);
1443 GTK_VALUE_STRING (*arg) = NULL;
1445 case CHILD_ARG_POSITION:
1446 GTK_VALUE_INT (*arg) = g_list_position (notebook->children, list);
1448 case CHILD_ARG_TAB_EXPAND:
1449 gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (container), child,
1450 &expand, NULL, NULL);
1451 GTK_VALUE_BOOL (*arg) = expand;
1453 case CHILD_ARG_TAB_FILL:
1454 gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (container), child,
1456 GTK_VALUE_BOOL (*arg) = fill;
1458 case CHILD_ARG_TAB_PACK:
1459 gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (container), child,
1460 NULL, NULL, &pack_type);
1461 GTK_VALUE_BOOL (*arg) = pack_type;
1464 arg->type = GTK_TYPE_INVALID;
1470 gtk_notebook_add (GtkContainer *container,
1473 g_return_if_fail (container != NULL);
1474 g_return_if_fail (GTK_IS_NOTEBOOK (container));
1476 gtk_notebook_insert_page_menu (GTK_NOTEBOOK (container), widget,
1481 gtk_notebook_remove (GtkContainer *container,
1484 GtkNotebook *notebook;
1485 GtkNotebookPage *page;
1489 g_return_if_fail (container != NULL);
1490 g_return_if_fail (GTK_IS_NOTEBOOK (container));
1491 g_return_if_fail (widget != NULL);
1493 notebook = GTK_NOTEBOOK (container);
1495 children = notebook->children;
1499 page = children->data;
1500 if (page->child == widget)
1502 gtk_notebook_real_remove (notebook, children);
1506 children = children->next;
1511 gtk_notebook_focus (GtkContainer *container,
1512 GtkDirectionType direction)
1514 GtkNotebook *notebook;
1515 GtkWidget *focus_child;
1516 GtkNotebookPage *page = NULL;
1517 GtkNotebookPage *old_page = NULL;
1519 g_return_val_if_fail (container != NULL, FALSE);
1520 g_return_val_if_fail (GTK_IS_NOTEBOOK (container), FALSE);
1522 notebook = GTK_NOTEBOOK (container);
1524 if (!GTK_WIDGET_DRAWABLE (notebook) || !GTK_WIDGET_SENSITIVE (container) ||
1525 !notebook->children || !notebook->cur_page)
1528 focus_child = container->focus_child;
1529 gtk_container_set_focus_child (container, NULL);
1531 if (!notebook->show_tabs)
1533 if (GTK_WIDGET_DRAWABLE (notebook->cur_page->child) &&
1534 GTK_WIDGET_SENSITIVE (notebook->cur_page->child))
1536 if (GTK_IS_CONTAINER (notebook->cur_page->child))
1538 if (gtk_container_focus
1539 (GTK_CONTAINER (notebook->cur_page->child), direction))
1542 else if (GTK_WIDGET_CAN_FOCUS (notebook->cur_page->child))
1546 gtk_widget_grab_focus (notebook->cur_page->child);
1554 if (notebook->focus_tab)
1555 old_page = notebook->focus_tab->data;
1557 if (focus_child && old_page && focus_child == old_page->child &&
1558 notebook->child_has_focus)
1560 if (GTK_WIDGET_DRAWABLE (old_page->child))
1562 if (GTK_IS_CONTAINER (old_page->child) &&
1563 !GTK_WIDGET_HAS_FOCUS (old_page->child))
1565 if (gtk_container_focus (GTK_CONTAINER (old_page->child),
1569 gtk_widget_grab_focus (GTK_WIDGET(notebook));
1577 case GTK_DIR_TAB_FORWARD:
1580 gtk_notebook_switch_focus_tab
1581 (notebook, gtk_notebook_search_page (notebook, notebook->focus_tab,
1584 case GTK_DIR_TAB_BACKWARD:
1587 gtk_notebook_switch_focus_tab
1588 (notebook, gtk_notebook_search_page (notebook, notebook->focus_tab,
1593 if (notebook->focus_tab)
1595 if (!GTK_WIDGET_HAS_FOCUS (container))
1596 gtk_widget_grab_focus (GTK_WIDGET (container));
1598 page = notebook->focus_tab->data;
1599 if (GTK_WIDGET_MAPPED (page->tab_label))
1600 gtk_notebook_focus_changed (notebook, old_page);
1603 gtk_notebook_pages_allocate (notebook,
1604 &(GTK_WIDGET (notebook)->allocation));
1605 gtk_notebook_expose_tabs (notebook);
1610 gtk_notebook_focus_changed (notebook, old_page);
1615 gtk_notebook_set_focus_child (GtkContainer *container,
1618 GtkNotebook *notebook;
1620 g_return_if_fail (container != NULL);
1621 g_return_if_fail (GTK_IS_NOTEBOOK (container));
1625 g_return_if_fail (GTK_IS_WIDGET (child));
1627 notebook = GTK_NOTEBOOK (container);
1629 notebook->child_has_focus = TRUE;
1630 if (!notebook->focus_tab)
1633 GtkNotebookPage *page;
1635 children = notebook->children;
1638 page = children->data;
1639 if (page->child == child || page->tab_label == child)
1640 gtk_notebook_switch_focus_tab (notebook, children);
1641 children = children->next;
1645 parent_class->set_focus_child (container, child);
1649 gtk_notebook_forall (GtkContainer *container,
1650 gboolean include_internals,
1651 GtkCallback callback,
1652 gpointer callback_data)
1654 GtkNotebook *notebook;
1657 g_return_if_fail (container != NULL);
1658 g_return_if_fail (GTK_IS_NOTEBOOK (container));
1659 g_return_if_fail (callback != NULL);
1661 notebook = GTK_NOTEBOOK (container);
1663 children = notebook->children;
1666 GtkNotebookPage *page;
1668 page = children->data;
1669 children = children->next;
1670 (* callback) (page->child, callback_data);
1671 if (include_internals)
1673 if (page->tab_label)
1674 (* callback) (page->tab_label, callback_data);
1675 if (page->menu_label)
1676 (* callback) (page->menu_label, callback_data);
1682 gtk_notebook_child_type (GtkContainer *container)
1684 return GTK_TYPE_WIDGET;
1687 /* Private GtkNotebook Functions:
1689 * gtk_notebook_panel_realize
1690 * gtk_notebook_expose_tabs
1691 * gtk_notebook_focus_changed
1692 * gtk_notebook_real_remove
1693 * gtk_notebook_update_labels
1694 * gtk_notebook_timer
1695 * gtk_notebook_page_compare
1696 * gtk_notebook_real_page_position
1697 * gtk_notebook_search_page
1700 gtk_notebook_panel_realize (GtkNotebook *notebook)
1703 GdkWindowAttr attributes;
1704 gint attributes_mask;
1706 g_return_if_fail (notebook != NULL);
1707 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
1709 widget = GTK_WIDGET (notebook);
1711 attributes.window_type = GDK_WINDOW_CHILD;
1712 attributes.wclass = GDK_INPUT_OUTPUT;
1713 attributes.visual = gtk_widget_get_visual (widget);
1714 attributes.colormap = gtk_widget_get_colormap (widget);
1715 attributes.event_mask = gtk_widget_get_events (widget);
1716 attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK
1717 | GDK_BUTTON_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_ENTER_NOTIFY_MASK
1718 | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK;
1720 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
1722 attributes.width = 2 * ARROW_SIZE + ARROW_SPACING;
1723 attributes.height = ARROW_SIZE;
1725 attributes.x = (widget->allocation.width - attributes.width -
1726 GTK_CONTAINER (notebook)->border_width);
1727 attributes.y = (widget->allocation.height - ARROW_SIZE -
1728 GTK_CONTAINER (notebook)->border_width);
1729 if (notebook->tab_pos == GTK_POS_TOP)
1730 attributes.y = GTK_CONTAINER (notebook)->border_width;
1731 else if (notebook->tab_pos == GTK_POS_LEFT)
1732 attributes.x = (widget->allocation.x +
1733 GTK_CONTAINER (notebook)->border_width);
1735 notebook->panel = gdk_window_new (widget->window, &attributes,
1737 gtk_style_set_background (widget->style, notebook->panel,
1739 gdk_window_set_back_pixmap (widget->window, NULL, TRUE);
1740 gdk_window_set_user_data (notebook->panel, widget);
1744 gtk_notebook_expose_tabs (GtkNotebook *notebook)
1747 GtkNotebookPage *page;
1748 GdkEventExpose event;
1751 widget = GTK_WIDGET (notebook);
1752 border = GTK_CONTAINER (notebook)->border_width;
1754 if (!GTK_WIDGET_MAPPED (notebook) || !notebook->first_tab)
1757 page = notebook->first_tab->data;
1759 event.type = GDK_EXPOSE;
1760 event.window = widget->window;
1762 event.area.x = border;
1763 event.area.y = border;
1765 switch (notebook->tab_pos)
1767 case GTK_POS_BOTTOM:
1768 event.area.y = (widget->allocation.height - border -
1769 page->allocation.height -
1770 widget->style->klass->ythickness);
1771 if (page != notebook->cur_page)
1772 event.area.y -= widget->style->klass->ythickness;
1774 event.area.width = widget->allocation.width - 2 * border;
1775 event.area.height = (page->allocation.height +
1776 widget->style->klass->ythickness);
1777 if (page != notebook->cur_page)
1778 event.area.height += widget->style->klass->ythickness;
1781 event.area.x = (widget->allocation.width - border -
1782 page->allocation.width -
1783 widget->style->klass->xthickness);
1784 if (page != notebook->cur_page)
1785 event.area.x -= widget->style->klass->xthickness;
1787 event.area.width = (page->allocation.width +
1788 widget->style->klass->xthickness);
1789 event.area.height = widget->allocation.height - 2 * border;
1790 if (page != notebook->cur_page)
1791 event.area.width += widget->style->klass->xthickness;
1794 gtk_widget_event (widget, (GdkEvent *) &event);
1798 gtk_notebook_focus_changed (GtkNotebook *notebook,
1799 GtkNotebookPage *old_page)
1801 g_return_if_fail (notebook != NULL);
1802 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
1804 if (GTK_WIDGET_DRAWABLE (notebook) && notebook->show_tabs)
1808 if (notebook->focus_tab)
1810 GtkNotebookPage *page;
1812 page = notebook->focus_tab->data;
1814 area.x = page->tab_label->allocation.x - 1;
1815 area.y = page->tab_label->allocation.y - 1;
1816 area.width = page->tab_label->allocation.width + 2;
1817 area.height = page->tab_label->allocation.height + 2;
1819 gtk_notebook_draw_tab (notebook, page, &area);
1824 area.x = old_page->tab_label->allocation.x - 1;
1825 area.y = old_page->tab_label->allocation.y - 1;
1826 area.width = old_page->tab_label->allocation.width + 2;
1827 area.height = old_page->tab_label->allocation.height + 2;
1829 gtk_notebook_draw_tab (notebook, old_page, &area);
1835 gtk_notebook_timer (GtkNotebook *notebook)
1837 g_return_val_if_fail (notebook != NULL, FALSE);
1838 g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), FALSE);
1840 if (notebook->timer)
1842 if (notebook->click_child == GTK_ARROW_LEFT)
1844 if (!notebook->focus_tab ||
1845 gtk_notebook_search_page (notebook, notebook->focus_tab,
1847 gtk_container_focus (GTK_CONTAINER (notebook), GTK_DIR_LEFT);
1849 else if (notebook->click_child == GTK_ARROW_RIGHT)
1851 if (!notebook->focus_tab ||
1852 gtk_notebook_search_page (notebook, notebook->focus_tab,
1854 gtk_container_focus (GTK_CONTAINER (notebook), GTK_DIR_RIGHT);
1856 if (notebook->need_timer)
1858 notebook->need_timer = FALSE;
1859 notebook->timer = gtk_timeout_add (NOTEBOOK_SCROLL_DELAY,
1860 (GtkFunction) gtk_notebook_timer,
1861 (gpointer) notebook);
1870 gtk_notebook_page_compare (gconstpointer a,
1873 return (((GtkNotebookPage *) a)->child != b);
1877 gtk_notebook_real_remove (GtkNotebook *notebook,
1880 GtkNotebookPage *page;
1882 gint need_resize = FALSE;
1884 next_list = gtk_notebook_search_page (notebook, list, STEP_PREV, TRUE);
1886 next_list = gtk_notebook_search_page (notebook, list, STEP_NEXT, TRUE);
1888 if (notebook->cur_page == list->data)
1890 notebook->cur_page = NULL;
1892 gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (next_list), -1);
1895 if (list == notebook->first_tab)
1896 notebook->first_tab = next_list;
1897 if (list == notebook->focus_tab)
1898 gtk_notebook_switch_focus_tab (notebook, next_list);
1902 if (GTK_WIDGET_VISIBLE (page->child) && GTK_WIDGET_VISIBLE (notebook))
1905 gtk_widget_unparent (page->child);
1907 if (page->tab_label)
1908 gtk_widget_unparent (page->tab_label);
1912 gtk_container_remove (GTK_CONTAINER (notebook->menu),
1913 page->menu_label->parent);
1914 gtk_widget_queue_resize (notebook->menu);
1916 if (!page->default_menu)
1917 gtk_widget_unref (page->menu_label);
1919 notebook->children = g_list_remove_link (notebook->children, list);
1923 gtk_notebook_update_labels (notebook);
1925 gtk_widget_queue_resize (GTK_WIDGET (notebook));
1929 gtk_notebook_update_labels (GtkNotebook *notebook)
1931 GtkNotebookPage *page;
1936 for (list = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, FALSE);
1938 list = gtk_notebook_search_page (notebook, list, STEP_NEXT, FALSE))
1941 sprintf (string, "Page %u", page_num++);
1942 if (notebook->show_tabs)
1944 if (page->default_tab)
1946 if (!page->tab_label)
1948 page->tab_label = gtk_label_new (string);
1949 gtk_widget_set_parent (page->tab_label,
1950 GTK_WIDGET (notebook));
1953 gtk_label_set (GTK_LABEL (page->tab_label), string);
1956 if (GTK_WIDGET_VISIBLE (page->child) &&
1957 !GTK_WIDGET_VISIBLE (page->tab_label))
1958 gtk_widget_show (page->tab_label);
1959 else if (!GTK_WIDGET_VISIBLE (page->child) &&
1960 GTK_WIDGET_VISIBLE (page->tab_label))
1961 gtk_widget_hide (page->tab_label);
1963 if (notebook->menu && page->default_menu)
1965 if (page->tab_label && GTK_IS_LABEL (page->tab_label))
1966 gtk_label_set (GTK_LABEL (page->menu_label),
1967 GTK_LABEL (page->tab_label)->label);
1969 gtk_label_set (GTK_LABEL (page->menu_label), string);
1975 gtk_notebook_real_page_position (GtkNotebook *notebook,
1981 g_return_val_if_fail (notebook != NULL, -1);
1982 g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1);
1983 g_return_val_if_fail (list != NULL, -1);
1985 for (work = notebook->children, count_start = 0;
1986 work && work != list; work = work->next)
1987 if (GTK_NOTEBOOK_PAGE (work)->pack == GTK_PACK_START)
1993 if (GTK_NOTEBOOK_PAGE (list)->pack == GTK_PACK_START)
1996 return (count_start + g_list_length (list) - 1);
2000 gtk_notebook_search_page (GtkNotebook *notebook,
2003 gboolean find_visible)
2005 GtkNotebookPage *page = NULL;
2006 GList *old_list = NULL;
2009 g_return_val_if_fail (notebook != NULL, NULL);
2010 g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL);
2015 flag = GTK_PACK_END;
2019 flag = GTK_PACK_START;
2026 if (!page || page->pack == flag)
2034 list = notebook->children;
2039 if (page->pack == flag &&
2040 (!find_visible || GTK_WIDGET_VISIBLE (page->child)))
2055 if (page->pack != flag &&
2056 (!find_visible || GTK_WIDGET_VISIBLE (page->child)))
2064 /* Private GtkNotebook Drawing Functions:
2066 * gtk_notebook_paint
2067 * gtk_notebook_draw_tab
2068 * gtk_notebook_draw_arrow
2069 * gtk_notebook_set_shape
2072 gtk_notebook_paint (GtkWidget *widget,
2075 GtkNotebook *notebook;
2076 GtkNotebookPage *page;
2081 gint gap_x = 0, gap_width = 0;
2083 g_return_if_fail (widget != NULL);
2084 g_return_if_fail (GTK_IS_NOTEBOOK (widget));
2085 g_return_if_fail (area != NULL);
2087 if (!GTK_WIDGET_DRAWABLE (widget))
2090 notebook = GTK_NOTEBOOK (widget);
2092 if ((!notebook->show_tabs && !notebook->show_border) ||
2093 !notebook->cur_page || !GTK_WIDGET_VISIBLE (notebook->cur_page->child))
2095 gdk_window_clear_area (widget->window,
2097 area->width, area->height);
2101 x = GTK_CONTAINER (widget)->border_width;
2102 y = GTK_CONTAINER (widget)->border_width;
2103 width = widget->allocation.width - x * 2;
2104 height = widget->allocation.height - y * 2;
2106 if (notebook->show_border && (!notebook->show_tabs || !notebook->children))
2109 gtk_paint_box(widget->style, widget->window,
2110 GTK_STATE_NORMAL, GTK_SHADOW_OUT,
2111 area, widget, "notebook",
2112 x, y, width, height);
2117 if (!GTK_WIDGET_MAPPED (notebook->cur_page->tab_label))
2119 page = notebook->first_tab->data;
2121 switch (notebook->tab_pos)
2124 y += page->allocation.height + widget->style->klass->ythickness;
2125 case GTK_POS_BOTTOM:
2126 height -= page->allocation.height + widget->style->klass->ythickness;
2129 x += page->allocation.width + widget->style->klass->xthickness;
2131 width -= page->allocation.width + widget->style->klass->xthickness;
2134 gtk_paint_box (widget->style, widget->window,
2135 GTK_STATE_NORMAL, GTK_SHADOW_OUT,
2136 area, widget, "notebook",
2137 x, y, width, height);
2141 switch (notebook->tab_pos)
2144 y += notebook->cur_page->allocation.height;
2145 case GTK_POS_BOTTOM:
2146 height -= notebook->cur_page->allocation.height;
2149 x += notebook->cur_page->allocation.width;
2151 width -= notebook->cur_page->allocation.width;
2155 switch (notebook->tab_pos)
2158 gap_x = (notebook->cur_page->allocation.x -
2159 GTK_CONTAINER(notebook)->border_width);
2160 gap_width = notebook->cur_page->allocation.width;
2162 case GTK_POS_BOTTOM:
2163 gap_x = (notebook->cur_page->allocation.x -
2164 GTK_CONTAINER(notebook)->border_width);
2165 gap_width = notebook->cur_page->allocation.width;
2168 gap_x = (notebook->cur_page->allocation.y -
2169 GTK_CONTAINER(notebook)->border_width);
2170 gap_width = notebook->cur_page->allocation.height;
2173 gap_x = (notebook->cur_page->allocation.y -
2174 GTK_CONTAINER(notebook)->border_width);
2175 gap_width = notebook->cur_page->allocation.height;
2178 gtk_paint_box_gap(widget->style, widget->window,
2179 GTK_STATE_NORMAL, GTK_SHADOW_OUT,
2180 area, widget, "notebook",
2181 x, y, width, height,
2182 notebook->tab_pos, gap_x, gap_width);
2186 children = gtk_notebook_search_page (notebook, NULL, STEP_PREV, TRUE);
2189 page = children->data;
2190 children = gtk_notebook_search_page (notebook, children,
2192 if (!GTK_WIDGET_VISIBLE (page->child))
2194 if (!GTK_WIDGET_MAPPED (page->tab_label))
2196 else if (page != notebook->cur_page)
2197 gtk_notebook_draw_tab (notebook, page, area);
2200 if (showarrow && notebook->scrollable)
2202 gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT);
2203 gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT);
2205 gtk_notebook_draw_tab (notebook, notebook->cur_page, area);
2209 gtk_notebook_draw_tab (GtkNotebook *notebook,
2210 GtkNotebookPage *page,
2213 GdkRectangle child_area;
2214 GdkRectangle page_area;
2215 GtkStateType state_type;
2216 GtkPositionType gap_side;
2218 g_return_if_fail (notebook != NULL);
2219 g_return_if_fail (page != NULL);
2220 g_return_if_fail (area != NULL);
2222 if (!GTK_WIDGET_MAPPED (page->tab_label) ||
2223 (page->allocation.width == 0) || (page->allocation.height == 0))
2226 page_area.x = page->allocation.x;
2227 page_area.y = page->allocation.y;
2228 page_area.width = page->allocation.width;
2229 page_area.height = page->allocation.height;
2231 if (gdk_rectangle_intersect (&page_area, area, &child_area))
2235 widget = GTK_WIDGET (notebook);
2237 switch (notebook->tab_pos)
2240 gap_side = GTK_POS_BOTTOM;
2242 case GTK_POS_BOTTOM:
2243 gap_side = GTK_POS_TOP;
2246 gap_side = GTK_POS_RIGHT;
2249 gap_side = GTK_POS_LEFT;
2253 if (notebook->cur_page == page)
2254 state_type = GTK_STATE_NORMAL;
2256 state_type = GTK_STATE_ACTIVE;
2257 gtk_paint_extension(widget->style, widget->window,
2258 state_type, GTK_SHADOW_OUT,
2259 area, widget, "tab",
2260 page_area.x, page_area.y,
2261 page_area.width, page_area.height,
2263 if ((GTK_WIDGET_HAS_FOCUS (widget)) &&
2264 notebook->focus_tab && (notebook->focus_tab->data == page))
2266 gtk_paint_focus (widget->style, widget->window,
2267 area, widget, "tab",
2268 page->tab_label->allocation.x - 1,
2269 page->tab_label->allocation.y - 1,
2270 page->tab_label->allocation.width + 1,
2271 page->tab_label->allocation.height + 1);
2273 if (gtk_widget_intersect (page->tab_label, area, &child_area))
2274 gtk_widget_draw (page->tab_label, &child_area);
2279 gtk_notebook_draw_arrow (GtkNotebook *notebook,
2282 GtkStateType state_type;
2283 GtkShadowType shadow_type;
2286 g_return_if_fail (notebook != NULL);
2287 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
2289 widget = GTK_WIDGET(notebook);
2291 if (GTK_WIDGET_DRAWABLE (notebook))
2293 if (notebook->in_child == arrow)
2295 if (notebook->click_child == arrow)
2296 state_type = GTK_STATE_ACTIVE;
2298 state_type = GTK_STATE_PRELIGHT;
2301 state_type = GTK_STATE_NORMAL;
2303 if (notebook->click_child == arrow)
2304 shadow_type = GTK_SHADOW_IN;
2306 shadow_type = GTK_SHADOW_OUT;
2308 if (arrow == GTK_ARROW_LEFT)
2310 if (notebook->focus_tab &&
2311 !gtk_notebook_search_page (notebook, notebook->focus_tab,
2314 shadow_type = GTK_SHADOW_ETCHED_IN;
2315 state_type = GTK_STATE_NORMAL;
2318 if (notebook->tab_pos == GTK_POS_LEFT ||
2319 notebook->tab_pos == GTK_POS_RIGHT)
2320 arrow = GTK_ARROW_UP;
2322 gdk_window_clear_area (notebook->panel, 0, 0, ARROW_SIZE, ARROW_SIZE);
2323 gtk_paint_arrow (widget->style, notebook->panel, state_type,
2324 shadow_type, NULL, GTK_WIDGET(notebook), "notebook",
2326 0, 0, ARROW_SIZE, ARROW_SIZE);
2330 if (notebook->focus_tab &&
2331 !gtk_notebook_search_page (notebook, notebook->focus_tab,
2334 shadow_type = GTK_SHADOW_ETCHED_IN;
2335 state_type = GTK_STATE_NORMAL;
2338 if (notebook->tab_pos == GTK_POS_LEFT ||
2339 notebook->tab_pos == GTK_POS_RIGHT)
2340 arrow = GTK_ARROW_DOWN;
2342 gdk_window_clear_area(notebook->panel, ARROW_SIZE + ARROW_SPACING,
2343 0, ARROW_SIZE, ARROW_SIZE);
2344 gtk_paint_arrow (widget->style, notebook->panel, state_type,
2345 shadow_type, NULL, GTK_WIDGET(notebook), "notebook",
2346 arrow, TRUE, ARROW_SIZE + ARROW_SPACING,
2347 0, ARROW_SIZE, ARROW_SIZE);
2353 gtk_notebook_set_shape (GtkNotebook *notebook)
2355 GtkWidget *widget = NULL;
2356 GdkPixmap *pm = NULL;
2359 gint x, y, width, height, w, h, depth;
2360 GtkNotebookPage *page;
2363 if (!GTK_WIDGET(notebook)->window)
2366 widget = GTK_WIDGET(notebook);
2368 w = widget->allocation.width;
2369 h = widget->allocation.height;
2371 pm = gdk_pixmap_new (widget->window, w, h, 1);
2372 pmgc = gdk_gc_new (pm);
2374 /* clear the shape mask */
2376 gdk_gc_set_foreground(pmgc, &col);
2377 gdk_draw_rectangle(pm, pmgc, TRUE, 0, 0, w, h);
2380 gdk_gc_set_foreground(pmgc, &col);
2382 /* draw the shape for the notebook page itself */
2383 x = GTK_CONTAINER(notebook)->border_width;
2384 y = GTK_CONTAINER(notebook)->border_width;
2385 width = widget->allocation.width - x * 2;
2386 height = widget->allocation.height - y * 2;
2388 if (notebook->show_tabs && notebook->children)
2390 if (!(notebook->show_tabs))
2392 page = notebook->first_tab->data;
2393 switch (notebook->tab_pos)
2396 y += page->allocation.height +
2397 widget->style->klass->ythickness;
2398 case GTK_POS_BOTTOM:
2399 height -= page->allocation.height +
2400 widget->style->klass->ythickness;
2403 x += page->allocation.width +
2404 widget->style->klass->xthickness;
2406 width -= page->allocation.width +
2407 widget->style->klass->xthickness;
2413 page = notebook->cur_page;
2414 if (!GTK_WIDGET_MAPPED (page->tab_label))
2416 if (notebook->tab_pos == GTK_POS_LEFT)
2418 x -= widget->style->klass->xthickness * 2;
2419 width += widget->style->klass->xthickness * 2;
2421 else if (notebook->tab_pos == GTK_POS_RIGHT)
2422 width += widget->style->klass->xthickness * 2;
2424 switch (notebook->tab_pos)
2427 y += page->allocation.height;
2428 case GTK_POS_BOTTOM:
2429 height -= page->allocation.height;
2432 x += page->allocation.width;
2434 width -= page->allocation.width;
2439 gdk_draw_rectangle(pm, pmgc, TRUE, x, y, width, height);
2441 /* if theres an area for scrollign arrows draw the shape for them */
2442 if (notebook->panel)
2444 gdk_window_get_geometry(notebook->panel, &x, &y, &width, &height, &depth);
2445 gdk_draw_rectangle(pm, pmgc, TRUE, x, y, width, height);
2448 /* draw the shapes of all the children */
2449 if (notebook->show_tabs)
2451 children = notebook->children;
2454 page = children->data;
2455 if (GTK_WIDGET_MAPPED (page->tab_label))
2457 x = page->allocation.x;
2458 y = page->allocation.y;
2459 width = page->allocation.width;
2460 height = page->allocation.height;
2461 gdk_draw_rectangle(pm, pmgc, TRUE, x, y, width, height);
2463 children = children->next;
2468 gdk_window_shape_combine_mask(widget->window, pm, 0, 0);
2469 gdk_pixmap_unref(pm);
2470 gdk_gc_destroy(pmgc);
2473 /* Private GtkNotebook Size Allocate Functions:
2475 * gtk_notebook_pages_allocate
2476 * gtk_notebook_page_allocate
2477 * gtk_notebook_calc_tabs
2480 gtk_notebook_pages_allocate (GtkNotebook *notebook,
2481 GtkAllocation *allocation)
2484 GtkContainer *container;
2485 GtkNotebookPage *page = NULL;
2486 GtkAllocation child_allocation;
2487 GList *children = NULL;
2488 GList *last_child = NULL;
2489 gboolean showarrow = FALSE;
2499 if (!notebook->show_tabs || !notebook->children || !notebook->cur_page)
2502 widget = GTK_WIDGET (notebook);
2503 container = GTK_CONTAINER (notebook);
2505 child_allocation.x = container->border_width;
2506 child_allocation.y = container->border_width;
2508 switch (notebook->tab_pos)
2510 case GTK_POS_BOTTOM:
2511 child_allocation.y = (allocation->height -
2512 notebook->cur_page->requisition.height -
2513 container->border_width);
2515 child_allocation.height = notebook->cur_page->requisition.height;
2518 child_allocation.x = (allocation->width -
2519 notebook->cur_page->requisition.width -
2520 container->border_width);
2522 child_allocation.width = notebook->cur_page->requisition.width;
2526 if (notebook->scrollable)
2530 children = notebook->children;
2532 if (notebook->focus_tab)
2533 focus_tab = notebook->focus_tab;
2534 else if (notebook->first_tab)
2535 focus_tab = notebook->first_tab;
2537 focus_tab = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, TRUE);
2539 switch (notebook->tab_pos)
2542 case GTK_POS_BOTTOM:
2545 page = children->data;
2546 children = children->next;
2548 if (GTK_WIDGET_VISIBLE (page->child))
2549 tab_space += page->requisition.width;
2552 allocation->width - 2 * container->border_width - TAB_OVERLAP)
2555 page = focus_tab->data;
2557 tab_space = (allocation->width - TAB_OVERLAP -
2558 page->requisition.width -
2559 2 * (container->border_width + ARROW_SPACING +
2561 x = (allocation->width - 2 * ARROW_SIZE - ARROW_SPACING -
2562 container->border_width);
2564 page = notebook->children->data;
2565 if (notebook->tab_pos == GTK_POS_TOP)
2566 y = (container->border_width +
2567 (page->requisition.height - ARROW_SIZE) / 2);
2569 y = (allocation->height - container->border_width -
2570 ARROW_SIZE - (page->requisition.height - ARROW_SIZE) / 2);
2577 page = children->data;
2578 children = children->next;
2580 if (GTK_WIDGET_VISIBLE (page->child))
2581 tab_space += page->requisition.height;
2584 (allocation->height - 2 * container->border_width - TAB_OVERLAP))
2587 page = focus_tab->data;
2588 tab_space = (allocation->height -
2589 ARROW_SIZE - ARROW_SPACING - TAB_OVERLAP -
2590 2 * container->border_width -
2591 page->requisition.height);
2592 y = allocation->height - container->border_width - ARROW_SIZE;
2594 page = notebook->children->data;
2595 if (notebook->tab_pos == GTK_POS_LEFT)
2596 x = (container->border_width +
2597 (page->requisition.width -
2598 (2 * ARROW_SIZE - ARROW_SPACING)) / 2);
2600 x = (allocation->width - container->border_width -
2601 (2 * ARROW_SIZE - ARROW_SPACING) -
2602 (page->requisition.width -
2603 (2 * ARROW_SIZE - ARROW_SPACING)) / 2);
2607 if (showarrow) /* first_tab <- focus_tab */
2611 notebook->first_tab = focus_tab;
2612 last_child = gtk_notebook_search_page (notebook, focus_tab,
2618 if (notebook->first_tab && notebook->first_tab != focus_tab)
2620 /* Is first_tab really predecessor of focus_tab ? */
2621 page = notebook->first_tab->data;
2622 if (GTK_WIDGET_VISIBLE (page->child))
2623 for (children = focus_tab;
2624 children && children != notebook->first_tab;
2625 children = gtk_notebook_search_page (notebook,
2631 notebook->first_tab = focus_tab;
2633 gtk_notebook_calc_tabs (notebook,
2634 gtk_notebook_search_page (notebook,
2638 &(notebook->first_tab), &tab_space,
2643 notebook->first_tab =
2644 gtk_notebook_search_page (notebook, notebook->first_tab,
2646 if (!notebook->first_tab)
2647 notebook->first_tab = focus_tab;
2648 last_child = gtk_notebook_search_page (notebook, focus_tab,
2651 else /* focus_tab -> end */
2653 if (!notebook->first_tab)
2654 notebook->first_tab = gtk_notebook_search_page (notebook,
2659 gtk_notebook_calc_tabs (notebook,
2660 gtk_notebook_search_page (notebook,
2664 &children, &tab_space, STEP_NEXT);
2667 last_child = children;
2668 else /* start <- first_tab */
2672 gtk_notebook_calc_tabs
2674 gtk_notebook_search_page (notebook,
2675 notebook->first_tab,
2678 &children, &tab_space, STEP_PREV);
2679 notebook->first_tab = gtk_notebook_search_page(notebook,
2687 if (GTK_WIDGET_REALIZED (notebook))
2689 gdk_window_move (notebook->panel, x, y);
2690 gdk_window_show (notebook->panel);
2695 tab_space = -tab_space;
2697 for (children = notebook->first_tab;
2698 children && children != last_child;
2699 children = gtk_notebook_search_page (notebook, children,
2706 /*unmap all non-visible tabs*/
2707 for (children = gtk_notebook_search_page (notebook, NULL,
2709 children && children != notebook->first_tab;
2710 children = gtk_notebook_search_page (notebook, children,
2713 page = children->data;
2714 if (page->tab_label && GTK_WIDGET_MAPPED (page->tab_label))
2715 gtk_widget_unmap (page->tab_label);
2717 for (children = last_child; children;
2718 children = gtk_notebook_search_page (notebook, children,
2721 page = children->data;
2722 if (page->tab_label && GTK_WIDGET_MAPPED (page->tab_label))
2723 gtk_widget_unmap (page->tab_label);
2726 else /* !showarrow */
2728 notebook->first_tab = gtk_notebook_search_page (notebook, NULL,
2731 if (GTK_WIDGET_REALIZED (notebook))
2732 gdk_window_hide (notebook->panel);
2741 children = notebook->children;
2742 switch (notebook->tab_pos)
2745 case GTK_POS_BOTTOM:
2748 page = children->data;
2749 children = children->next;
2751 if (GTK_WIDGET_VISIBLE (page->child))
2754 tab_space += page->requisition.width;
2759 tab_space -= allocation->width;
2765 page = children->data;
2766 children = children->next;
2768 if (GTK_WIDGET_VISIBLE (page->child))
2771 tab_space += page->requisition.height;
2776 tab_space -= allocation->height;
2778 tab_space += 2 * container->border_width + TAB_OVERLAP;
2780 notebook->first_tab = gtk_notebook_search_page (notebook, NULL,
2782 if (notebook->homogeneous && n)
2786 children = notebook->first_tab;
2790 if (children == last_child)
2792 gtk_notebook_set_shape (notebook);
2798 page = children->data;
2799 if (!showarrow && page->pack != GTK_PACK_START)
2801 children = gtk_notebook_search_page (notebook, children, STEP_NEXT,TRUE);
2804 if (n && (showarrow || page->expand || notebook->homogeneous))
2806 new_fill = (tab_space * i++) / n;
2807 delta = new_fill - old_fill;
2808 old_fill = new_fill;
2811 switch (notebook->tab_pos)
2814 case GTK_POS_BOTTOM:
2815 child_allocation.width = (page->requisition.width +
2816 TAB_OVERLAP + delta);
2820 child_allocation.height = (page->requisition.height +
2821 TAB_OVERLAP + delta);
2825 gtk_notebook_page_allocate (notebook, page, &child_allocation);
2827 switch (notebook->tab_pos)
2830 case GTK_POS_BOTTOM:
2831 child_allocation.x += child_allocation.width - TAB_OVERLAP;
2835 child_allocation.y += child_allocation.height - TAB_OVERLAP;
2839 if (GTK_WIDGET_REALIZED (notebook) &&
2840 page->tab_label && !GTK_WIDGET_MAPPED (page->tab_label))
2841 gtk_widget_map (page->tab_label);
2846 children = notebook->children;
2847 switch (notebook->tab_pos)
2850 case GTK_POS_BOTTOM:
2851 child_allocation.x = (allocation->x + allocation->width -
2852 container->border_width);
2856 child_allocation.y = (allocation->y + allocation->height -
2857 container->border_width);
2861 while (children != last_child)
2863 page = children->data;
2864 children = children->next;
2866 if (page->pack != GTK_PACK_END || !GTK_WIDGET_VISIBLE (page->child))
2870 if (n && (page->expand || notebook->homogeneous))
2872 new_fill = (tab_space * i++) / n;
2873 delta = new_fill - old_fill;
2874 old_fill = new_fill;
2877 switch (notebook->tab_pos)
2880 case GTK_POS_BOTTOM:
2881 child_allocation.width = (page->requisition.width +
2882 TAB_OVERLAP + delta);
2883 child_allocation.x -= child_allocation.width;
2887 child_allocation.height = (page->requisition.height +
2888 TAB_OVERLAP + delta);
2889 child_allocation.y -= child_allocation.height;
2893 gtk_notebook_page_allocate (notebook, page, &child_allocation);
2895 switch (notebook->tab_pos)
2898 case GTK_POS_BOTTOM:
2899 child_allocation.x += TAB_OVERLAP;
2903 child_allocation.y += TAB_OVERLAP;
2907 if (GTK_WIDGET_REALIZED (notebook) && page->tab_label &&
2908 !GTK_WIDGET_MAPPED (page->tab_label))
2909 gtk_widget_map (page->tab_label);
2912 gtk_notebook_set_shape (notebook);
2916 gtk_notebook_page_allocate (GtkNotebook *notebook,
2917 GtkNotebookPage *page,
2918 GtkAllocation *allocation)
2920 GtkAllocation child_allocation;
2925 g_return_if_fail (notebook != NULL);
2926 g_return_if_fail (page != NULL);
2927 g_return_if_fail (allocation != NULL);
2929 page->allocation = *allocation;
2931 xthickness = GTK_WIDGET (notebook)->style->klass->xthickness;
2932 ythickness = GTK_WIDGET (notebook)->style->klass->ythickness;
2934 if (notebook->cur_page != page)
2936 switch (notebook->tab_pos)
2939 page->allocation.y += ythickness;
2940 case GTK_POS_BOTTOM:
2941 page->allocation.height -= ythickness;
2944 page->allocation.x += xthickness;
2946 page->allocation.width -= xthickness;
2951 switch (notebook->tab_pos)
2954 case GTK_POS_BOTTOM:
2955 padding = TAB_CURVATURE + FOCUS_WIDTH + notebook->tab_hborder;
2958 child_allocation.x = (xthickness + FOCUS_WIDTH +
2959 notebook->tab_hborder);
2960 child_allocation.width = (page->allocation.width -
2961 2 * child_allocation.x);
2962 child_allocation.x += page->allocation.x;
2966 child_allocation.x = (page->allocation.x +
2967 (page->allocation.width -
2968 page->tab_label->requisition.width) / 2);
2969 child_allocation.width = page->tab_label->requisition.width;
2971 child_allocation.y = (notebook->tab_vborder + FOCUS_WIDTH +
2972 page->allocation.y);
2973 if (notebook->tab_pos == GTK_POS_TOP)
2974 child_allocation.y += ythickness;
2975 child_allocation.height = (page->allocation.height - ythickness -
2976 2 * (notebook->tab_vborder + FOCUS_WIDTH));
2980 padding = TAB_CURVATURE + FOCUS_WIDTH + notebook->tab_vborder;
2983 child_allocation.y = ythickness + padding;
2984 child_allocation.height = (page->allocation.height -
2985 2 * child_allocation.y);
2986 child_allocation.y += page->allocation.y;
2990 child_allocation.y = (page->allocation.y +
2991 (page->allocation.height -
2992 page->tab_label->requisition.height) / 2);
2993 child_allocation.height = page->tab_label->requisition.height;
2995 child_allocation.x = (page->allocation.x + notebook->tab_hborder +
2997 if (notebook->tab_pos == GTK_POS_LEFT)
2998 child_allocation.x += xthickness;
2999 child_allocation.width = (page->allocation.width - xthickness -
3000 2 * (notebook->tab_hborder + FOCUS_WIDTH));
3004 if (page->tab_label)
3005 gtk_widget_size_allocate (page->tab_label, &child_allocation);
3009 gtk_notebook_calc_tabs (GtkNotebook *notebook,
3015 GtkNotebookPage *page = NULL;
3017 GList *last_list = NULL;
3024 pack = GTK_NOTEBOOK_PAGE (start)->pack;
3025 if (pack == GTK_PACK_END)
3026 direction = (direction == STEP_PREV) ? STEP_NEXT : STEP_PREV;
3030 switch (notebook->tab_pos)
3033 case GTK_POS_BOTTOM:
3036 page = children->data;
3037 if (GTK_WIDGET_VISIBLE (page->child))
3039 if (page->pack == pack)
3041 *tab_space -= page->requisition.width;
3042 if (*tab_space < 0 || children == *end)
3046 *tab_space = - (*tab_space +
3047 page->requisition.width);
3053 last_list = children;
3055 if (direction == STEP_NEXT)
3056 children = children->next;
3058 children = children->prev;
3065 page = children->data;
3066 if (GTK_WIDGET_VISIBLE (page->child))
3068 if (page->pack == pack)
3070 *tab_space -= page->requisition.height;
3071 if (*tab_space < 0 || children == *end)
3075 *tab_space = - (*tab_space +
3076 page->requisition.height);
3082 last_list = children;
3084 if (direction == STEP_NEXT)
3085 children = children->next;
3087 children = children->prev;
3091 if (direction == STEP_PREV)
3093 pack = (pack == GTK_PACK_END) ? GTK_PACK_START : GTK_PACK_END;
3094 direction = STEP_PREV;
3095 children = last_list;
3099 /* Private GtkNotebook Page Switch Methods:
3101 * gtk_notebook_real_switch_page
3104 gtk_notebook_real_switch_page (GtkNotebook *notebook,
3105 GtkNotebookPage *page,
3108 g_return_if_fail (notebook != NULL);
3109 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3110 g_return_if_fail (page != NULL);
3112 if (notebook->cur_page == page || !GTK_WIDGET_VISIBLE (page->child))
3115 if (notebook->cur_page && GTK_WIDGET_MAPPED (notebook->cur_page->child))
3116 gtk_widget_unmap (notebook->cur_page->child);
3118 notebook->cur_page = page;
3120 if (!notebook->focus_tab ||
3121 notebook->focus_tab->data != (gpointer) notebook->cur_page)
3122 notebook->focus_tab =
3123 g_list_find (notebook->children, notebook->cur_page);
3125 gtk_notebook_pages_allocate (notebook, >K_WIDGET (notebook)->allocation);
3126 gtk_notebook_expose_tabs (notebook);
3128 if (GTK_WIDGET_MAPPED (notebook))
3130 if (GTK_WIDGET_REALIZED (notebook->cur_page->child))
3131 gtk_widget_map (notebook->cur_page->child);
3134 gtk_widget_map (notebook->cur_page->child);
3135 gtk_widget_size_allocate (GTK_WIDGET (notebook),
3136 >K_WIDGET (notebook)->allocation);
3140 if (GTK_WIDGET_DRAWABLE (notebook))
3141 gtk_widget_queue_draw (GTK_WIDGET (notebook));
3142 gtk_notebook_set_shape (notebook);
3145 /* Private GtkNotebook Page Switch Functions:
3147 * gtk_notebook_switch_page
3148 * gtk_notebook_page_select
3149 * gtk_notebook_switch_focus_tab
3150 * gtk_notebook_menu_switch_page
3153 gtk_notebook_switch_page (GtkNotebook *notebook,
3154 GtkNotebookPage *page,
3157 g_return_if_fail (notebook != NULL);
3158 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3159 g_return_if_fail (page != NULL);
3161 if (notebook->cur_page == page)
3165 page_num = g_list_index (notebook->children, page);
3167 gtk_signal_emit (GTK_OBJECT (notebook),
3168 notebook_signals[SWITCH_PAGE],
3174 gtk_notebook_page_select (GtkNotebook *notebook)
3176 GtkNotebookPage *page;
3178 g_return_val_if_fail (notebook != NULL, FALSE);
3179 g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), FALSE);
3181 if (!notebook->focus_tab)
3184 page = notebook->focus_tab->data;
3185 gtk_notebook_switch_page (notebook, page, -1);
3187 if (GTK_WIDGET_VISIBLE (page->child))
3189 if (GTK_IS_CONTAINER (page->child))
3191 if (gtk_container_focus (GTK_CONTAINER (page->child),
3192 GTK_DIR_TAB_FORWARD))
3195 else if (GTK_WIDGET_CAN_FOCUS (page->child))
3197 gtk_widget_grab_focus (page->child);
3205 gtk_notebook_switch_focus_tab (GtkNotebook *notebook,
3209 GtkNotebookPage *old_page = NULL;
3210 GtkNotebookPage *page;
3212 g_return_if_fail (notebook != NULL);
3213 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3215 if (notebook->focus_tab == new_child)
3218 old_child = notebook->focus_tab;
3219 notebook->focus_tab = new_child;
3221 if (notebook->scrollable && GTK_WIDGET_DRAWABLE (notebook))
3223 if ((new_child == NULL) != (old_child == NULL))
3225 gdk_window_clear (notebook->panel);
3226 gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT);
3227 gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT);
3234 olist = gtk_notebook_search_page (notebook, old_child,
3236 nlist = gtk_notebook_search_page (notebook, new_child,
3239 if ((olist == NULL) != (nlist == NULL))
3241 gdk_window_clear_area (notebook->panel, 0, 0,
3242 ARROW_SIZE, ARROW_SIZE);
3243 gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT);
3246 olist = gtk_notebook_search_page (notebook, old_child,
3248 nlist = gtk_notebook_search_page (notebook, new_child,
3251 if ((olist == NULL) != (nlist == NULL))
3253 gdk_window_clear_area (notebook->panel,
3254 ARROW_SIZE + ARROW_SPACING, 0,
3255 ARROW_SIZE, ARROW_SIZE);
3256 gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT);
3261 if (!notebook->show_tabs || !notebook->focus_tab)
3265 old_page = old_child->data;
3267 page = notebook->focus_tab->data;
3268 if (GTK_WIDGET_MAPPED (page->tab_label))
3269 gtk_notebook_focus_changed (notebook, old_page);
3272 gtk_notebook_pages_allocate (notebook,
3273 &(GTK_WIDGET (notebook)->allocation));
3274 gtk_notebook_expose_tabs (notebook);
3277 gtk_notebook_set_shape (notebook);
3281 gtk_notebook_menu_switch_page (GtkWidget *widget,
3282 GtkNotebookPage *page)
3284 GtkNotebook *notebook;
3288 g_return_if_fail (widget != NULL);
3289 g_return_if_fail (page != NULL);
3291 notebook = GTK_NOTEBOOK (gtk_menu_get_attach_widget
3292 (GTK_MENU (widget->parent)));
3294 if (notebook->cur_page == page)
3298 children = notebook->children;
3299 while (children && children->data != page)
3301 children = children->next;
3305 gtk_signal_emit (GTK_OBJECT (notebook),
3306 notebook_signals[SWITCH_PAGE],
3311 /* Private GtkNotebook Menu Functions:
3313 * gtk_notebook_menu_item_create
3314 * gtk_notebook_menu_label_unparent
3315 * gtk_notebook_menu_detacher
3318 gtk_notebook_menu_item_create (GtkNotebook *notebook,
3321 GtkNotebookPage *page;
3322 GtkWidget *menu_item;
3325 if (page->default_menu)
3327 if (page->tab_label && GTK_IS_LABEL (page->tab_label))
3328 page->menu_label = gtk_label_new (GTK_LABEL (page->tab_label)->label);
3330 page->menu_label = gtk_label_new ("");
3331 gtk_misc_set_alignment (GTK_MISC (page->menu_label), 0.0, 0.5);
3334 gtk_widget_show (page->menu_label);
3335 menu_item = gtk_menu_item_new ();
3336 gtk_widget_freeze_accelerators (menu_item);
3337 gtk_container_add (GTK_CONTAINER (menu_item), page->menu_label);
3338 gtk_menu_insert (GTK_MENU (notebook->menu), menu_item,
3339 gtk_notebook_real_page_position (notebook, list));
3340 gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
3341 GTK_SIGNAL_FUNC (gtk_notebook_menu_switch_page), page);
3342 if (GTK_WIDGET_VISIBLE (page->child))
3343 gtk_widget_show (menu_item);
3347 gtk_notebook_menu_label_unparent (GtkWidget *widget,
3350 gtk_widget_unparent (GTK_BIN(widget)->child);
3351 GTK_BIN(widget)->child = NULL;
3355 gtk_notebook_menu_detacher (GtkWidget *widget,
3358 GtkNotebook *notebook;
3360 g_return_if_fail (widget != NULL);
3361 g_return_if_fail (GTK_IS_NOTEBOOK (widget));
3363 notebook = GTK_NOTEBOOK (widget);
3364 g_return_if_fail (notebook->menu == (GtkWidget*) menu);
3366 notebook->menu = NULL;
3369 /* Public GtkNotebook Page Insert/Remove Methods :
3371 * gtk_notebook_append_page
3372 * gtk_notebook_append_page_menu
3373 * gtk_notebook_prepend_page
3374 * gtk_notebook_prepend_page_menu
3375 * gtk_notebook_insert_page
3376 * gtk_notebook_insert_page_menu
3377 * gtk_notebook_remove_page
3380 gtk_notebook_append_page (GtkNotebook *notebook,
3382 GtkWidget *tab_label)
3384 gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, -1);
3388 gtk_notebook_append_page_menu (GtkNotebook *notebook,
3390 GtkWidget *tab_label,
3391 GtkWidget *menu_label)
3393 gtk_notebook_insert_page_menu (notebook, child, tab_label, menu_label, -1);
3397 gtk_notebook_prepend_page (GtkNotebook *notebook,
3399 GtkWidget *tab_label)
3401 gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, 0);
3405 gtk_notebook_prepend_page_menu (GtkNotebook *notebook,
3407 GtkWidget *tab_label,
3408 GtkWidget *menu_label)
3410 gtk_notebook_insert_page_menu (notebook, child, tab_label, menu_label, 0);
3414 gtk_notebook_insert_page (GtkNotebook *notebook,
3416 GtkWidget *tab_label,
3419 gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, position);
3423 gtk_notebook_insert_page_menu (GtkNotebook *notebook,
3425 GtkWidget *tab_label,
3426 GtkWidget *menu_label,
3429 GtkNotebookPage *page;
3432 g_return_if_fail (notebook != NULL);
3433 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3434 g_return_if_fail (child != NULL);
3436 page = g_new (GtkNotebookPage, 1);
3437 page->child = child;
3438 page->requisition.width = 0;
3439 page->requisition.height = 0;
3440 page->allocation.x = 0;
3441 page->allocation.y = 0;
3442 page->allocation.width = 0;
3443 page->allocation.height = 0;
3444 page->default_menu = FALSE;
3445 page->default_tab = FALSE;
3447 nchildren = g_list_length (notebook->children);
3448 if ((position < 0) || (position > nchildren))
3449 position = nchildren;
3451 notebook->children = g_list_insert (notebook->children, page, position);
3455 page->default_tab = TRUE;
3456 if (notebook->show_tabs)
3457 tab_label = gtk_label_new ("");
3459 page->tab_label = tab_label;
3460 page->menu_label = menu_label;
3461 page->expand = FALSE;
3463 page->pack = GTK_PACK_START;
3466 page->default_menu = TRUE;
3469 gtk_widget_ref (page->menu_label);
3470 gtk_object_sink (GTK_OBJECT(page->menu_label));
3474 gtk_notebook_menu_item_create (notebook,
3475 g_list_find (notebook->children, page));
3477 gtk_notebook_update_labels (notebook);
3479 if (!notebook->first_tab)
3480 notebook->first_tab = notebook->children;
3482 gtk_widget_set_parent (child, GTK_WIDGET (notebook));
3484 gtk_widget_set_parent (tab_label, GTK_WIDGET (notebook));
3486 if (!notebook->cur_page)
3488 gtk_notebook_switch_page (notebook, page, 0);
3489 gtk_notebook_switch_focus_tab (notebook, NULL);
3492 if (GTK_WIDGET_VISIBLE (notebook))
3494 if (GTK_WIDGET_REALIZED (notebook) &&
3495 !GTK_WIDGET_REALIZED (child))
3496 gtk_widget_realize (child);
3498 if (GTK_WIDGET_MAPPED (notebook) &&
3499 !GTK_WIDGET_MAPPED (child) && notebook->cur_page == page)
3500 gtk_widget_map (child);
3504 if (notebook->show_tabs && GTK_WIDGET_VISIBLE (child))
3506 if (!GTK_WIDGET_VISIBLE (tab_label))
3507 gtk_widget_show (tab_label);
3509 if (GTK_WIDGET_REALIZED (notebook) &&
3510 !GTK_WIDGET_REALIZED (tab_label))
3511 gtk_widget_realize (tab_label);
3513 if (GTK_WIDGET_MAPPED (notebook) &&
3514 !GTK_WIDGET_MAPPED (tab_label))
3515 gtk_widget_map (tab_label);
3517 else if (GTK_WIDGET_VISIBLE (tab_label))
3518 gtk_widget_hide (tab_label);
3522 if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (notebook))
3523 gtk_widget_queue_resize (child);
3527 gtk_notebook_remove_page (GtkNotebook *notebook,
3532 g_return_if_fail (notebook != NULL);
3533 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3537 list = g_list_nth (notebook->children, page_num);
3539 gtk_notebook_real_remove (notebook, list);
3543 list = g_list_last (notebook->children);
3545 gtk_notebook_real_remove (notebook, list);
3549 /* Public GtkNotebook Page Switch Methods :
3550 * gtk_notebook_current_page
3551 * gtk_notebook_page_num
3552 * gtk_notebook_set_page
3553 * gtk_notebook_next_page
3554 * gtk_notebook_prev_page
3557 gtk_notebook_current_page (GtkNotebook *notebook)
3559 g_return_val_if_fail (notebook != NULL, -1);
3560 g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1);
3562 if (!notebook->cur_page)
3565 return g_list_index (notebook->children, notebook->cur_page);
3569 gtk_notebook_page_num (GtkNotebook *notebook,
3575 g_return_val_if_fail (notebook != NULL, -1);
3576 g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1);
3579 children = notebook->children;
3582 GtkNotebookPage *page;
3584 page = children->data;
3585 if (page->child == child)
3588 children = children->next;
3596 gtk_notebook_set_page (GtkNotebook *notebook,
3601 g_return_if_fail (notebook != NULL);
3602 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3605 list = g_list_nth (notebook->children, page_num);
3608 list = g_list_last (notebook->children);
3609 page_num = g_list_length (notebook->children) - 1;
3612 gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (list), page_num);
3616 gtk_notebook_next_page (GtkNotebook *notebook)
3620 g_return_if_fail (notebook != NULL);
3621 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3623 list = g_list_find (notebook->children, notebook->cur_page);
3627 list = gtk_notebook_search_page (notebook, list, STEP_NEXT, TRUE);
3631 gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (list), -1);
3635 gtk_notebook_prev_page (GtkNotebook *notebook)
3639 g_return_if_fail (notebook != NULL);
3640 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3642 list = g_list_find (notebook->children, notebook->cur_page);
3646 list = gtk_notebook_search_page (notebook, list, STEP_PREV, TRUE);
3650 gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (list), -1);
3653 /* Public GtkNotebook/Tab Style Functions
3655 * gtk_notebook_set_show_border
3656 * gtk_notebook_set_show_tabs
3657 * gtk_notebook_set_tab_pos
3658 * gtk_notebook_set_homogeneous_tabs
3659 * gtk_notebook_set_tab_border
3660 * gtk_notebook_set_tab_hborder
3661 * gtk_notebook_set_tab_vborder
3662 * gtk_notebook_set_scrollable
3665 gtk_notebook_set_show_border (GtkNotebook *notebook,
3668 g_return_if_fail (notebook != NULL);
3669 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3671 if (notebook->show_border != show_border)
3673 notebook->show_border = show_border;
3675 if (GTK_WIDGET_VISIBLE (notebook))
3676 gtk_widget_queue_resize (GTK_WIDGET (notebook));
3681 gtk_notebook_set_show_tabs (GtkNotebook *notebook,
3684 GtkNotebookPage *page;
3687 g_return_if_fail (notebook != NULL);
3688 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3690 show_tabs = show_tabs != FALSE;
3692 if (notebook->show_tabs == show_tabs)
3695 notebook->show_tabs = show_tabs;
3696 children = notebook->children;
3700 GTK_WIDGET_UNSET_FLAGS (notebook, GTK_CAN_FOCUS);
3704 page = children->data;
3705 children = children->next;
3706 if (page->default_tab)
3708 gtk_widget_destroy (page->tab_label);
3709 page->tab_label = NULL;
3712 gtk_widget_hide (page->tab_label);
3715 if (notebook->panel)
3716 gdk_window_hide (notebook->panel);
3720 GTK_WIDGET_SET_FLAGS (notebook, GTK_CAN_FOCUS);
3721 gtk_notebook_update_labels (notebook);
3723 gtk_widget_queue_resize (GTK_WIDGET (notebook));
3727 gtk_notebook_set_tab_pos (GtkNotebook *notebook,
3728 GtkPositionType pos)
3730 g_return_if_fail (notebook != NULL);
3731 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3733 if (notebook->tab_pos != pos)
3735 notebook->tab_pos = pos;
3736 if (GTK_WIDGET_VISIBLE (notebook))
3737 gtk_widget_queue_resize (GTK_WIDGET (notebook));
3742 gtk_notebook_set_homogeneous_tabs (GtkNotebook *notebook,
3743 gboolean homogeneous)
3745 g_return_if_fail (notebook != NULL);
3746 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3748 if (homogeneous == notebook->homogeneous)
3751 notebook->homogeneous = homogeneous;
3752 gtk_widget_queue_resize (GTK_WIDGET (notebook));
3756 gtk_notebook_set_tab_border (GtkNotebook *notebook,
3759 g_return_if_fail (notebook != NULL);
3760 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3762 notebook->tab_hborder = tab_border;
3763 notebook->tab_vborder = tab_border;
3765 if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs)
3766 gtk_widget_queue_resize (GTK_WIDGET (notebook));
3770 gtk_notebook_set_tab_hborder (GtkNotebook *notebook,
3773 g_return_if_fail (notebook != NULL);
3774 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3776 if (notebook->tab_hborder == tab_hborder)
3779 notebook->tab_hborder = tab_hborder;
3781 if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs)
3782 gtk_widget_queue_resize (GTK_WIDGET (notebook));
3786 gtk_notebook_set_tab_vborder (GtkNotebook *notebook,
3789 g_return_if_fail (notebook != NULL);
3790 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3792 if (notebook->tab_vborder == tab_vborder)
3795 notebook->tab_vborder = tab_vborder;
3797 if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs)
3798 gtk_widget_queue_resize (GTK_WIDGET (notebook));
3802 gtk_notebook_set_scrollable (GtkNotebook *notebook,
3805 g_return_if_fail (notebook != NULL);
3806 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3808 scrollable = (scrollable != FALSE);
3810 if (scrollable != notebook->scrollable)
3812 notebook->scrollable = scrollable;
3814 if (GTK_WIDGET_REALIZED (notebook))
3818 gtk_notebook_panel_realize (notebook);
3820 else if (notebook->panel)
3822 gdk_window_destroy (notebook->panel);
3823 notebook->panel = NULL;
3827 if (GTK_WIDGET_VISIBLE (notebook))
3828 gtk_widget_queue_resize (GTK_WIDGET(notebook));
3832 /* Public GtkNotebook Popup Menu Methods:
3834 * gtk_notebook_popup_enable
3835 * gtk_notebook_popup_disable
3838 gtk_notebook_popup_enable (GtkNotebook *notebook)
3842 g_return_if_fail (notebook != NULL);
3843 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3848 notebook->menu = gtk_menu_new ();
3849 for (list = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, FALSE);
3851 list = gtk_notebook_search_page (notebook, list, STEP_NEXT, FALSE))
3852 gtk_notebook_menu_item_create (notebook, list);
3854 gtk_notebook_update_labels (notebook);
3855 gtk_menu_attach_to_widget (GTK_MENU (notebook->menu),
3856 GTK_WIDGET (notebook),
3857 gtk_notebook_menu_detacher);
3861 gtk_notebook_popup_disable (GtkNotebook *notebook)
3863 g_return_if_fail (notebook != NULL);
3864 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3866 if (!notebook->menu)
3869 gtk_container_foreach (GTK_CONTAINER (notebook->menu),
3870 (GtkCallback) gtk_notebook_menu_label_unparent, NULL);
3871 gtk_widget_destroy (notebook->menu);
3874 /* Public GtkNotebook Page Properties Functions:
3876 * gtk_notebook_query_tab_label
3877 * gtk_notebook_set_tab_label
3878 * gtk_notebook_set_tab_label_text
3879 * gtk_notebook_query_menu_label
3880 * gtk_notebook_set_menu_label
3881 * gtk_notebook_set_menu_label_text
3882 * gtk_notebook_set_tab_label_packing
3883 * gtk_notebook_query_tab_label_packing
3886 gtk_notebook_query_tab_label (GtkNotebook *notebook,
3891 g_return_val_if_fail (notebook != NULL, NULL);
3892 g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL);
3893 g_return_val_if_fail (child != NULL, NULL);
3895 if (!(list = g_list_find_custom (notebook->children, child,
3896 gtk_notebook_page_compare)))
3899 if (GTK_NOTEBOOK_PAGE (list)->default_tab)
3902 return GTK_NOTEBOOK_PAGE (list)->tab_label;
3906 gtk_notebook_set_tab_label (GtkNotebook *notebook,
3908 GtkWidget *tab_label)
3910 GtkNotebookPage *page;
3913 g_return_if_fail (notebook != NULL);
3914 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
3915 g_return_if_fail (child != NULL);
3917 if (!(list = g_list_find_custom (notebook->children, child,
3918 gtk_notebook_page_compare)))
3921 /* a NULL pointer indicates a default_tab setting, otherwise
3922 * we need to set the associated label
3926 if (page->tab_label)
3927 gtk_widget_unparent (page->tab_label);
3931 page->default_tab = FALSE;
3932 page->tab_label = tab_label;
3933 gtk_widget_set_parent (page->tab_label, GTK_WIDGET (notebook));
3937 page->default_tab = TRUE;
3938 page->tab_label = NULL;
3940 if (notebook->show_tabs)
3944 sprintf (string, "Page %u",
3945 gtk_notebook_real_page_position (notebook, list));
3946 page->tab_label = gtk_label_new (string);
3947 gtk_widget_set_parent (page->tab_label, GTK_WIDGET (notebook));
3951 if (notebook->show_tabs && GTK_WIDGET_VISIBLE (child))
3953 gtk_widget_show (page->tab_label);
3954 gtk_widget_queue_resize (GTK_WIDGET (notebook));
3959 gtk_notebook_set_tab_label_text (GtkNotebook *notebook,
3961 const gchar *tab_text)
3963 GtkWidget *tab_label = NULL;
3966 tab_label = gtk_label_new (tab_text);
3967 gtk_notebook_set_tab_label (notebook, child, tab_label);
3971 gtk_notebook_query_menu_label (GtkNotebook *notebook,
3976 g_return_val_if_fail (notebook != NULL, NULL);
3977 g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL);
3978 g_return_val_if_fail (child != NULL, NULL);
3980 if (!(list = g_list_find_custom (notebook->children, child,
3981 gtk_notebook_page_compare)))
3984 if (GTK_NOTEBOOK_PAGE (list)->default_menu)
3987 return GTK_NOTEBOOK_PAGE (list)->menu_label;
3991 gtk_notebook_set_menu_label (GtkNotebook *notebook,
3993 GtkWidget *menu_label)
3995 GtkNotebookPage *page;
3998 g_return_if_fail (notebook != NULL);
3999 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
4000 g_return_if_fail (child != NULL);
4002 if (!(list = g_list_find_custom (notebook->children, child,
4003 gtk_notebook_page_compare)))
4007 if (page->menu_label)
4011 gtk_container_remove (GTK_CONTAINER (notebook->menu),
4012 page->menu_label->parent);
4013 gtk_widget_queue_resize (notebook->menu);
4015 if (!page->default_menu)
4016 gtk_widget_unref (page->menu_label);
4021 page->menu_label = menu_label;
4022 gtk_widget_ref (page->menu_label);
4023 gtk_object_sink (GTK_OBJECT(page->menu_label));
4024 page->default_menu = FALSE;
4027 page->default_menu = TRUE;
4030 gtk_notebook_menu_item_create (notebook, list);
4034 gtk_notebook_set_menu_label_text (GtkNotebook *notebook,
4036 const gchar *menu_text)
4038 GtkWidget *menu_label = NULL;
4041 menu_label = gtk_label_new (menu_text);
4042 gtk_notebook_set_menu_label (notebook, child, menu_label);
4046 gtk_notebook_set_tab_label_packing (GtkNotebook *notebook,
4050 GtkPackType pack_type)
4052 GtkNotebookPage *page;
4055 g_return_if_fail (notebook != NULL);
4056 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
4057 g_return_if_fail (child != NULL);
4059 if (!(list = g_list_find_custom (notebook->children, child,
4060 gtk_notebook_page_compare)))
4064 if (page->pack == pack_type && page->expand == expand && page->fill == fill)
4067 page->expand = expand;
4070 if (page->pack != pack_type)
4072 page->pack = pack_type;
4075 GtkWidget *menu_item;
4077 menu_item = page->menu_label->parent;
4078 gtk_container_remove (GTK_CONTAINER (menu_item), page->menu_label);
4079 gtk_container_remove (GTK_CONTAINER (notebook->menu), menu_item);
4080 gtk_notebook_menu_item_create (notebook, list);
4081 gtk_widget_queue_resize (notebook->menu);
4083 gtk_notebook_update_labels (notebook);
4086 if (!notebook->show_tabs)
4089 gtk_notebook_pages_allocate (notebook, &(GTK_WIDGET (notebook)->allocation));
4090 gtk_notebook_expose_tabs (notebook);
4094 gtk_notebook_query_tab_label_packing (GtkNotebook *notebook,
4098 GtkPackType *pack_type)
4102 g_return_if_fail (notebook != NULL);
4103 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
4104 g_return_if_fail (child != NULL);
4106 if (!(list = g_list_find_custom (notebook->children, child,
4107 gtk_notebook_page_compare)))
4111 *expand = GTK_NOTEBOOK_PAGE (list)->expand;
4113 *fill = GTK_NOTEBOOK_PAGE (list)->fill;
4115 *pack_type = GTK_NOTEBOOK_PAGE (list)->pack;
4119 gtk_notebook_reorder_child (GtkNotebook *notebook,
4125 GtkNotebookPage *page;
4128 g_return_if_fail (notebook != NULL);
4129 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
4130 g_return_if_fail (child != NULL);
4131 g_return_if_fail (GTK_IS_WIDGET (child));
4133 for (old_pos = 0, list = notebook->children; list;
4134 list = list->next, old_pos++)
4137 if (page->child == child)
4141 if (!list || old_pos == position)
4144 notebook->children = g_list_remove_link (notebook->children, list);
4146 if (position <= 0 || !notebook->children)
4148 list->next = notebook->children;
4150 list->next->prev = list;
4151 notebook->children = list;
4153 else if (position > 0 && (work = g_list_nth (notebook->children, position)))
4155 list->prev = work->prev;
4157 list->prev->next = list;
4163 work = g_list_last (notebook->children);
4170 GtkWidget *menu_item;
4172 menu_item = page->menu_label->parent;
4173 gtk_container_remove (GTK_CONTAINER (menu_item), page->menu_label);
4174 gtk_container_remove (GTK_CONTAINER (notebook->menu), menu_item);
4175 gtk_notebook_menu_item_create (notebook, list);
4176 gtk_widget_queue_resize (notebook->menu);
4179 gtk_notebook_update_labels (notebook);
4181 if (notebook->show_tabs)
4183 gtk_notebook_pages_allocate (notebook,
4184 &(GTK_WIDGET (notebook)->allocation));
4185 gtk_notebook_expose_tabs (notebook);