typedef struct { int x; int y; int width; int height; } GdkRectangle; enum { GTK_POS_LEFT, GTK_POS_RIGHT, GTK_POS_TOP, GTK_POS_BOTTOM, DRAG_OPERATION_NONE, DRAG_OPERATION_REORDER, DRAG_OPERATION_DETACH }; typedef struct { void *parent; } GtkWidget; typedef struct { GtkWidget *tab_label; int pack; GdkRectangle requisition, allocation; } GtkNotebookPage; typedef struct { GtkNotebookPage *cur_page; int homogeneous:1; } GtkNotebook; typedef struct { int operation; int x; GtkNotebookPage *detached_tab; } GtkNotebookPrivate; gtk_notebook_calculate_tabs_allocation() { GtkNotebook *notebook; void **children; void *last_child; int *remaining_space; int *expanded_tabs; GtkNotebookPrivate *priv; GtkNotebookPage *page; int allocate_at_bottom; int tab_overlap; int tab_pos; int tab_extra_space; int left_x; int right_x; int top_y; int anchor; int xthickness; int ythickness; int gap_left; int packing_changed; GdkRectangle child_allocation; while (*children && *children != last_child) { if (page->tab_label->parent != notebook) continue; if (*expanded_tabs && notebook->homogeneous) tab_extra_space = *remaining_space / *expanded_tabs; switch (tab_pos) { case GTK_POS_TOP: case GTK_POS_BOTTOM: child_allocation.width = page->requisition.width + tab_overlap + tab_extra_space; if (gap_left && packing_changed) { if (allocate_at_bottom && notebook->cur_page->pack && right_x > anchor) anchor -= notebook->cur_page-> allocation.width; } else { if (allocate_at_bottom) anchor -= child_allocation.width; if (priv->operation == DRAG_OPERATION_REORDER && page->pack == notebook->cur_page->pack) if (!allocate_at_bottom && left_x >= anchor && left_x <= anchor + child_allocation.width / 2) anchor += notebook->cur_page-> allocation.width - tab_overlap; child_allocation.x = anchor; } case GTK_POS_LEFT: case GTK_POS_RIGHT: child_allocation.height = page->requisition.height + tab_overlap + tab_extra_space; if (packing_changed) priv->x = child_allocation.x; if (priv->operation == DRAG_OPERATION_REORDER && page->pack == notebook->cur_page->pack) if (!allocate_at_bottom && top_y >= anchor && top_y <= anchor + child_allocation.height / 2) anchor += notebook->cur_page-> allocation.height - tab_overlap; } if ((page == priv->detached_tab && priv->operation == DRAG_OPERATION_DETACH) || (page == notebook->cur_page && priv->operation == DRAG_OPERATION_REORDER)) page->allocation.x = 0; if (page != notebook->cur_page) switch (tab_pos) { case GTK_POS_TOP: page->allocation.y = ythickness; case GTK_POS_BOTTOM: page->allocation.height = page->allocation.height ; case GTK_POS_LEFT: page->allocation.x = xthickness; case GTK_POS_RIGHT: page->allocation.width = page->allocation.width ; } switch (tab_pos) { case GTK_POS_TOP: case GTK_POS_BOTTOM: if (priv->operation != DRAG_OPERATION_REORDER || priv->operation == DRAG_OPERATION_REORDER && page != notebook->cur_page) if (!allocate_at_bottom) anchor += child_allocation.width - tab_overlap; case GTK_POS_LEFT: case GTK_POS_RIGHT: if (priv->operation != DRAG_OPERATION_REORDER || priv->operation == DRAG_OPERATION_REORDER && page != notebook->cur_page) if (priv->operation == DRAG_OPERATION_REORDER) if (page->pack == notebook->cur_page->pack && !allocate_at_bottom && top_y >= anchor + child_allocation.height / 2 && top_y <= anchor + child_allocation.height) anchor += notebook->cur_page-> allocation.height - tab_overlap; } if (page->tab_label) IA__gtk_widget_set_child_visible(page->tab_label, 1); } }