void clearlooks_get_notebook_tab_position (GtkWidget *widget, gboolean *start, gboolean *end) { /* default value */ *start = TRUE; *end = FALSE; if (GE_IS_NOTEBOOK (widget)) { gboolean found_tabs = FALSE; gint i, n_pages; GtkNotebook *notebook = GTK_NOTEBOOK (widget); /* got a notebook, so walk over all the tabs and decide based * on that ... * It works like this: * - If there is any visible tab that is expanded, set both. * - Set start/end if there is any visible tab that is at * the start/end. * - If one has the child_visibility set to false, arrows * are present; so none * The heuristic falls over if there is a notebook that just * happens to fill up all the available space. ie. All tabs * are left aligned, but it does not require scrolling. * (a more complex heuristic could calculate the tabs width * and add them all up) */ n_pages = gtk_notebook_get_n_pages (notebook); for (i = 0; i < n_pages; i++) { GtkWidget *tab_child; GtkWidget *tab_label; gboolean expand; GtkPackType pack_type; tab_child = gtk_notebook_get_nth_page (notebook, i); /* Skip invisible tabs */ tab_label = gtk_notebook_get_tab_label (notebook, tab_child); if (!tab_label || !GTK_WIDGET_VISIBLE (tab_label)) continue; /* This is the same what the notebook does internally. */ if (tab_label && !gtk_widget_get_child_visible (tab_label)) { /* One child is hidden because scroll arrows are present. * So both corners are rounded. */ *start = FALSE; *end = FALSE; return; } gtk_notebook_query_tab_label_packing (notebook, tab_child, &expand, NULL, /* don't need fill */ &pack_type); if (!found_tabs) { found_tabs = TRUE; *start = FALSE; *end = FALSE; } if (expand) { *start = TRUE; *end = TRUE; } else if (pack_type == GTK_PACK_START) { *start = TRUE; } else { *end = TRUE; } } } }
/* Border Function For Notebooks Tabs */ void hc_draw_extension (GtkStyle *style, cairo_t *cr, GtkStateType state_type, GtkShadowType shadow_type, GtkWidget *widget, const gchar *detail, gint x, gint y, gint width, gint height, GtkPositionType gap_side) { /* Fill Uses Background Color */ CairoColor *background = &HC_STYLE(style)->color_cube.bg[state_type]; /* Border Uses Foreground Color */ CairoColor *foreground = &HC_STYLE(style)->color_cube.fg[state_type]; gint line_width; gint widget_x = 0, widget_y = 0, widget_width = 0, widget_height = 0; gint clip_x = x, clip_y = y, clip_width = width, clip_height = height; /***********************************************/ /* GTK Sanity Checks */ /***********************************************/ CHECK_ARGS /***********************************************/ /* GTK Special Cases - adjust Size/Offset */ /***********************************************/ line_width = HC_STYLE(style)->edge_thickness; /* What all this is for - GTK doesn't overlap Extensions and Notebooks, but rather a tab is drawn with a "gap" side. Instead of long draw cases per gap side, perform a standard draw, but clipped to size, and overdraw edge thickness + one on gap side. To fake the apearance of overlap on edge aligned tabs increase clip by edge thickness on gap side. */ if (widget && (GE_IS_NOTEBOOK (widget))) { GtkAllocation allocation; gtk_widget_get_allocation (widget, &allocation); widget_x = (allocation.x + gtk_container_get_border_width (GTK_CONTAINER (widget))); widget_y = (allocation.y + gtk_container_get_border_width (GTK_CONTAINER (widget))); widget_width = (allocation.width - 2*gtk_container_get_border_width (GTK_CONTAINER (widget))); widget_height = (allocation.height - 2*gtk_container_get_border_width (GTK_CONTAINER (widget))); } switch (gap_side) { case GTK_POS_TOP: if (GTK_CHECK_VERSION(2,10,0) || ((widget && GE_IS_NOTEBOOK (widget)) && ((x==widget_x) || ((x + width) == (widget_x + widget_width))))) { clip_height += line_width; if (!GTK_CHECK_VERSION(2,10,0)) { height -= floor(line_width/2.0); } } y -= (line_width + 1); height += (line_width + 1); break; case GTK_POS_LEFT: if (GTK_CHECK_VERSION(2,10,0) || ((widget && GE_IS_NOTEBOOK (widget)) && ((y==widget_y) || ((y + height) == (widget_y + widget_height))))) { clip_width += line_width; if (!GTK_CHECK_VERSION(2,10,0)) { x -= floor(line_width/2.0); } } x -= (line_width + 1); width += (line_width + 1); break; default: case GTK_POS_BOTTOM: height += (line_width + 1); break; case GTK_POS_RIGHT: width += (line_width + 1); break; } /***********************************************/ /* Draw Border */ /***********************************************/ /* Clip Too Size */ cairo_rectangle(cr, clip_x, clip_y, clip_width, clip_height); cairo_clip(cr); /* Set Fill Style */ ge_cairo_set_color(cr, background); /* Fill Rectangle */ cairo_rectangle (cr, x, y, width, height); cairo_fill(cr); /* Set Line Style */ ge_cairo_set_color(cr, foreground); cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT); cairo_set_line_width (cr, line_width); ge_cairo_inner_rectangle (cr, x, y, width, height); cairo_stroke(cr); }