enum { GTK_POS_LEFT, GTK_POS_RIGHT, GTK_POS_TOP, GTK_POS_BOTTOM, DRAG_OPERATION_NONE, DRAG_OPERATION_REORDER, DRAG_OPERATION_DETACH }; typedef struct { int x; int y; int width; int height; } GdkRectangle; typedef struct { struct { void *parent; } *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_extra_space; int x; int y; int anchor; 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 (x) { case GTK_POS_TOP: case GTK_POS_BOTTOM: child_allocation.width = page->requisition.width + x+ tab_extra_space; if (x && y) { if (allocate_at_bottom && notebook->cur_page->pack && 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 && x >= anchor && x <= anchor + child_allocation.width / 2) anchor = notebook->cur_page-> allocation.width - x; child_allocation.x = anchor; } case GTK_POS_LEFT: case GTK_POS_RIGHT: child_allocation.height = page->requisition.height + x+ tab_extra_space; if (y) priv->x = child_allocation.x; if (priv->operation == DRAG_OPERATION_REORDER && page->pack == notebook->cur_page->pack) if (allocate_at_bottom && y >= anchor && y <= anchor + child_allocation.height / 2) anchor = notebook->cur_page->allocation. height - x; } 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 (x) { case GTK_POS_TOP: page->allocation.y = 0; case GTK_POS_BOTTOM: case GTK_POS_RIGHT: case GTK_POS_LEFT: page->allocation.x = 0; } switch (x) { 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 ; 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 && y >= anchor + child_allocation.height / 2 && y <= anchor + child_allocation.height) anchor = notebook->cur_page-> allocation.height ; } if (page->tab_label) IA__gtk_widget_set_child_visible(page->tab_label, 1); } }