[gtk+] GtkNotebook: Use GtkStyleContext.



commit 3306305fe193628f5b00579d76e4227076e8ed58
Author: Carlos Garnacho <carlosg gnome org>
Date:   Mon Dec 13 13:39:53 2010 +0100

    GtkNotebook: Use GtkStyleContext.

 gtk/gtknotebook.c     |  539 ++++++++++++++++++++++++++++++++++---------------
 gtk/gtkstylecontext.h |    8 +
 2 files changed, 385 insertions(+), 162 deletions(-)
---
diff --git a/gtk/gtknotebook.c b/gtk/gtknotebook.c
index f5a4db5..b66f421 100644
--- a/gtk/gtknotebook.c
+++ b/gtk/gtknotebook.c
@@ -358,12 +358,11 @@ static gint gtk_notebook_focus_out           (GtkWidget        *widget,
 					      GdkEventFocus    *event);
 static void gtk_notebook_grab_notify         (GtkWidget          *widget,
 					      gboolean            was_grabbed);
-static void gtk_notebook_state_changed       (GtkWidget          *widget,
-					      GtkStateType        previous_state);
+static void gtk_notebook_state_flags_changed (GtkWidget          *widget,
+					      GtkStateFlags       previous_state);
 static gint gtk_notebook_focus               (GtkWidget        *widget,
 					      GtkDirectionType  direction);
-static void gtk_notebook_style_set           (GtkWidget        *widget,
-					      GtkStyle         *previous);
+static void gtk_notebook_style_updated       (GtkWidget        *widget);
 
 /*** Drag and drop Methods ***/
 static void gtk_notebook_drag_begin          (GtkWidget        *widget,
@@ -422,6 +421,8 @@ static void gtk_notebook_forall              (GtkContainer     *container,
 					      gboolean		include_internals,
 					      GtkCallback       callback,
 					      gpointer          callback_data);
+static GtkWidgetPath * gtk_notebook_get_path_for_child (GtkContainer *container,
+                                                        GtkWidget    *widget);
 
 /*** GtkNotebook Methods ***/
 static gint gtk_notebook_real_insert_page    (GtkNotebook      *notebook,
@@ -463,8 +464,7 @@ static void gtk_notebook_paint               (GtkWidget        *widget,
 static void gtk_notebook_draw_tab            (GtkNotebook      *notebook,
 					      GtkNotebookPage  *page,
 					      cairo_t          *cr,
-                                              guint             position,
-                                              gboolean          is_last);
+                                              GtkRegionFlags    flags);
 static void gtk_notebook_draw_arrow          (GtkNotebook      *notebook,
                                               cairo_t          *cr,
 					      GtkNotebookArrow  arrow);
@@ -653,11 +653,11 @@ gtk_notebook_class_init (GtkNotebookClass *class)
   widget_class->leave_notify_event = gtk_notebook_leave_notify;
   widget_class->motion_notify_event = gtk_notebook_motion_notify;
   widget_class->grab_notify = gtk_notebook_grab_notify;
-  widget_class->state_changed = gtk_notebook_state_changed;
+  widget_class->state_flags_changed = gtk_notebook_state_flags_changed;
   widget_class->focus_in_event = gtk_notebook_focus_in;
   widget_class->focus_out_event = gtk_notebook_focus_out;
   widget_class->focus = gtk_notebook_focus;
-  widget_class->style_set = gtk_notebook_style_set;
+  widget_class->style_updated = gtk_notebook_style_updated;
   widget_class->drag_begin = gtk_notebook_drag_begin;
   widget_class->drag_end = gtk_notebook_drag_end;
   widget_class->drag_motion = gtk_notebook_drag_motion;
@@ -674,6 +674,7 @@ gtk_notebook_class_init (GtkNotebookClass *class)
   container_class->get_child_property = gtk_notebook_get_child_property;
   container_class->set_child_property = gtk_notebook_set_child_property;
   container_class->child_type = gtk_notebook_child_type;
+  container_class->get_path_for_child = gtk_notebook_get_path_for_child;
 
   class->switch_page = gtk_notebook_real_switch_page;
   class->insert_page = gtk_notebook_real_insert_page;
@@ -1149,6 +1150,7 @@ static void
 gtk_notebook_init (GtkNotebook *notebook)
 {
   GtkNotebookPrivate *priv;
+  GtkStyleContext *context;
 
   gtk_widget_set_can_focus (GTK_WIDGET (notebook), TRUE);
   gtk_widget_set_has_window (GTK_WIDGET (notebook), FALSE);
@@ -1204,6 +1206,9 @@ gtk_notebook_init (GtkNotebook *notebook)
 		    G_CALLBACK (gtk_notebook_drag_failed), NULL);
 
   gtk_drag_dest_set_track_motion (GTK_WIDGET (notebook), TRUE);
+
+  context = gtk_widget_get_style_context (GTK_WIDGET (notebook));
+  gtk_style_context_add_class (context, GTK_STYLE_CLASS_NOTEBOOK);
 }
 
 static void
@@ -1668,7 +1673,7 @@ gtk_notebook_get_property (GObject         *object,
  * gtk_notebook_motion_notify
  * gtk_notebook_focus_in
  * gtk_notebook_focus_out
- * gtk_notebook_style_set
+ * gtk_notebook_style_updated
  * gtk_notebook_drag_begin
  * gtk_notebook_drag_end
  * gtk_notebook_drag_failed
@@ -1915,6 +1920,89 @@ gtk_notebook_unrealize (GtkWidget *widget)
   GTK_WIDGET_CLASS (gtk_notebook_parent_class)->unrealize (widget);
 }
 
+static GtkRegionFlags
+_gtk_notebook_get_tab_flags (GtkNotebook     *notebook,
+                             GtkNotebookPage *page)
+{
+  GtkNotebookPrivate *priv = notebook->priv;
+  gint i = 0, page_num = -1;
+  GtkRegionFlags flags = 0;
+  gboolean is_last = FALSE;
+  GList *pages;
+
+  if (page->pack == GTK_PACK_START)
+    {
+      gint last = -1;
+
+      for (pages = priv->children; pages; pages = pages->next)
+        {
+          GtkNotebookPage *p = pages->data;
+
+          if (!gtk_widget_get_visible (p->tab_label))
+            continue;
+
+          if (p->pack == GTK_PACK_END)
+            last = i;
+
+          if (page->pack == p->pack)
+            i++;
+
+          /* No need to keep counting tabs after it */
+          if (page == p)
+            {
+              page_num = i;
+              is_last = (last == -1 && pages->next == NULL);
+              break;
+            }
+        }
+    }
+  else
+    {
+      gboolean found = FALSE;
+
+      is_last = TRUE;
+
+      /* Count all pack_start tabs from the beginning
+       * of the list until we find the page, then all
+       * items until the end, that should give us the
+       * tab position
+       */
+      for (pages = priv->children; pages; pages = pages->next)
+        {
+          GtkNotebookPage *p = pages->data;
+
+          if (!gtk_widget_get_visible (p->tab_label))
+            continue;
+
+          if (p->pack == GTK_PACK_START || p == page || found)
+            i++;
+
+          if (page == p)
+            found = TRUE;
+          else if (p->pack == GTK_PACK_END && !found)
+            is_last = FALSE;
+        }
+
+      page_num = i;
+    }
+
+  if (page_num < 0)
+    return 0;
+
+  if ((page_num) % 2 == 0)
+    flags |= GTK_REGION_EVEN;
+  else
+    flags |= GTK_REGION_ODD;
+
+  if (page_num == 1)
+    flags |= GTK_REGION_FIRST;
+
+  if (is_last)
+    flags |= GTK_REGION_LAST;
+
+  return flags;
+}
+
 static void
 gtk_notebook_size_request (GtkWidget      *widget,
 			   GtkRequisition *requisition)
@@ -1987,12 +2075,14 @@ gtk_notebook_size_request (GtkWidget      *widget,
 
   if (priv->show_border || priv->show_tabs)
     {
-      GtkStyle *style;
+      GtkStyleContext *context;
+      GtkBorder notebook_padding;
 
-      style = gtk_widget_get_style (widget);
+      context = gtk_widget_get_style_context (widget);
+      gtk_style_context_get_padding (context, 0, &notebook_padding);
 
-      requisition->width += style->xthickness * 2;
-      requisition->height += style->ythickness * 2;
+      requisition->width += notebook_padding.left + notebook_padding.right;
+      requisition->height += notebook_padding.top + notebook_padding.bottom;
 
       if (priv->show_tabs)
 	{
@@ -2011,14 +2101,26 @@ gtk_notebook_size_request (GtkWidget      *widget,
 	      
 	      if (gtk_widget_get_visible (page->child))
 		{
+                  GtkBorder tab_padding;
+
 		  if (!gtk_widget_get_visible (page->tab_label))
 		    gtk_widget_show (page->tab_label);
 
                   gtk_widget_get_preferred_size (page->tab_label,
                                                  &child_requisition, NULL);
 
-                  page->requisition.width = child_requisition.width + 2 * style->xthickness;
-		  page->requisition.height = child_requisition.height + 2 * style->ythickness;
+                  /* Get border/padding for tab */
+                  gtk_style_context_save (context);
+                  gtk_style_context_add_region (context, GTK_STYLE_REGION_TAB,
+                                                _gtk_notebook_get_tab_flags (notebook, page));
+                  gtk_style_context_get_padding (context, 0, &tab_padding);
+                  gtk_style_context_restore (context);
+
+                  page->requisition.width = child_requisition.width +
+                    tab_padding.left + tab_padding.right;
+
+		  page->requisition.height = child_requisition.height +
+                    tab_padding.top + tab_padding.bottom;
 
 		  switch (priv->tab_pos)
 		    {
@@ -2052,8 +2154,8 @@ gtk_notebook_size_request (GtkWidget      *widget,
                     {
                       gtk_widget_get_preferred_size (priv->action_widget[i],
                                                      &action_widget_requisition[i], NULL);
-                      action_widget_requisition[i].width += style->xthickness;
-                      action_widget_requisition[i].height += style->ythickness;
+                      action_widget_requisition[i].width += notebook_padding.left;
+                      action_widget_requisition[i].height += notebook_padding.top;
                     }
                 }
 
@@ -2249,12 +2351,12 @@ gtk_notebook_size_allocate (GtkWidget     *widget,
 {
   GtkNotebook *notebook = GTK_NOTEBOOK (widget);
   GtkNotebookPrivate *priv = notebook->priv;
-  GtkStyle *style;
+  GtkStyleContext *context;
   gint tab_pos = get_effective_tab_pos (notebook);
   gboolean is_rtl;
   gint focus_width;
 
-  style = gtk_widget_get_style (widget);
+  context = gtk_widget_get_style_context (widget);
 
   gtk_widget_style_get (widget, "focus-line-width", &focus_width, NULL);
 
@@ -2291,10 +2393,16 @@ gtk_notebook_size_allocate (GtkWidget     *widget,
 
       if (priv->show_tabs || priv->show_border)
 	{
-	  child_allocation.x += style->xthickness;
-	  child_allocation.y += style->ythickness;
-	  child_allocation.width = MAX (1, child_allocation.width - style->xthickness * 2);
-	  child_allocation.height = MAX (1, child_allocation.height - style->ythickness * 2);
+          GtkStyleContext *context;
+          GtkBorder padding;
+
+          context = gtk_widget_get_style_context (widget);
+          gtk_style_context_get_padding (context, 0, &padding);
+
+          child_allocation.x += padding.left;
+          child_allocation.y += padding.top;
+          child_allocation.width = MAX (1, child_allocation.width - padding.left - padding.right);
+          child_allocation.height = MAX (1, child_allocation.height - padding.top - padding.bottom);
 
 	  if (priv->show_tabs && priv->children && priv->cur_page)
 	    {
@@ -2338,7 +2446,7 @@ gtk_notebook_size_allocate (GtkWidget     *widget,
 		      /* fall through */
 		    case GTK_POS_TOP:
 		      widget_allocation.width = requisition.width;
-		      widget_allocation.height = priv->cur_page->requisition.height - style->ythickness;
+		      widget_allocation.height = priv->cur_page->requisition.height - padding.top;
 
 		      if ((i == ACTION_WIDGET_START && is_rtl) ||
                           (i == ACTION_WIDGET_END && !is_rtl))
@@ -2351,7 +2459,7 @@ gtk_notebook_size_allocate (GtkWidget     *widget,
 		      /* fall through */
 		    case GTK_POS_LEFT:
 		      widget_allocation.height = requisition.height;
-		      widget_allocation.width = priv->cur_page->requisition.width - style->xthickness;
+		      widget_allocation.width = priv->cur_page->requisition.width - padding.left;
 
                       if (i == ACTION_WIDGET_END)
                         widget_allocation.y += allocation->height - 2 * border_width - requisition.height;
@@ -2434,8 +2542,12 @@ gtk_notebook_draw (GtkWidget *widget,
   if (priv->operation == DRAG_OPERATION_REORDER &&
       gtk_cairo_should_draw_window (cr, priv->drag_window))
     {
+      GtkStyleContext *context;
+      GdkRGBA bg_color;
+
       cairo_save (cr);
       gtk_cairo_transform_to_window (cr, widget, priv->drag_window);
+      context = gtk_widget_get_style_context (widget);
 
       /* FIXME: This is a workaround to make tabs reordering work better
        * with engines with rounded tabs. If the drag window background
@@ -2444,12 +2556,13 @@ gtk_notebook_draw (GtkWidget *widget,
        * Ideally, these corners should be made transparent, Either by using
        * ARGB visuals or shape windows.
        */
-      gdk_cairo_set_source_color (cr, &gtk_widget_get_style (widget)->bg [GTK_STATE_NORMAL]);
+      gtk_style_context_get_background_color (context, 0, &bg_color);
+      gdk_cairo_set_source_rgba (cr, &bg_color);
       cairo_paint (cr);
 
       gtk_notebook_draw_tab (notebook,
 			     priv->cur_page,
-			     cr, 0, FALSE);
+			     cr, 0);
 
       cairo_restore (cr);
 
@@ -3322,8 +3435,8 @@ gtk_notebook_grab_notify (GtkWidget *widget,
 }
 
 static void
-gtk_notebook_state_changed (GtkWidget    *widget,
-			    GtkStateType  previous_state)
+gtk_notebook_state_flags_changed (GtkWidget     *widget,
+                                  GtkStateFlags  previous_state)
 {
   if (!gtk_widget_is_sensitive (widget))
     stop_scrolling (GTK_NOTEBOOK (widget));
@@ -3348,8 +3461,7 @@ gtk_notebook_focus_out (GtkWidget     *widget,
 }
 
 static void
-gtk_notebook_style_set  (GtkWidget *widget,
-			 GtkStyle  *previous)
+gtk_notebook_style_updated (GtkWidget *widget)
 {
   GtkNotebook *notebook = GTK_NOTEBOOK (widget);
   GtkNotebookPrivate *priv = notebook->priv;
@@ -3371,7 +3483,7 @@ gtk_notebook_style_set  (GtkWidget *widget,
   priv->has_after_previous = has_after_previous;
   priv->has_after_next = has_after_next;
 
-  GTK_WIDGET_CLASS (gtk_notebook_parent_class)->style_set (widget, previous);
+  GTK_WIDGET_CLASS (gtk_notebook_parent_class)->style_updated (widget);
 }
 
 static gboolean
@@ -3381,25 +3493,29 @@ on_drag_icon_draw (GtkWidget *widget,
 {
   GtkWidget *notebook, *child;
   GtkRequisition requisition;
+  GtkStyleContext *context;
   gint gap_pos;
 
   notebook = GTK_WIDGET (data);
   child = gtk_bin_get_child (GTK_BIN (widget));
+  context = gtk_widget_get_style_context (widget);
+
+  gtk_style_context_save (context);
+  gtk_style_context_add_region (context, GTK_STYLE_REGION_TAB, 0);
 
   gtk_widget_get_preferred_size (widget,
                                  &requisition, NULL);
   gap_pos = get_tab_gap_pos (GTK_NOTEBOOK (notebook));
 
-  gtk_paint_extension (gtk_widget_get_style (notebook),
-                       cr,
-		       GTK_STATE_NORMAL, GTK_SHADOW_OUT,
-		       widget, "tab",
-		       0, 0,
-		       requisition.width, requisition.height,
-		       gap_pos);
+  gtk_render_extension (context, cr, 0, 0,
+                        requisition.width, requisition.height,
+                        gap_pos);
+
   if (child)
     gtk_container_propagate_draw (GTK_CONTAINER (widget), child, cr);
 
+  gtk_style_context_restore (context);
+
   return TRUE;
 }
 
@@ -4320,6 +4436,40 @@ gtk_notebook_forall (GtkContainer *container,
   }
 }
 
+static GtkWidgetPath *
+gtk_notebook_get_path_for_child (GtkContainer *container,
+                                 GtkWidget    *widget)
+{
+  GtkNotebookPrivate *priv;
+  GtkNotebook *notebook;
+  GtkNotebookPage *page;
+  GtkWidgetPath *path;
+  GtkRegionFlags flags;
+  GList *c;
+
+  path = GTK_CONTAINER_CLASS (gtk_notebook_parent_class)->get_path_for_child (container, widget);
+
+  notebook = GTK_NOTEBOOK (container);
+  priv = notebook->priv;
+
+  for (c = priv->children; c; c = c->next)
+    {
+      page = c->data;
+
+      if (page->tab_label == widget)
+        break;
+    }
+
+  /* Widget is not a tab label */
+  if (!c)
+    return path;
+
+  flags = _gtk_notebook_get_tab_flags (notebook, page);
+  gtk_widget_path_iter_add_region (path, -1, GTK_STYLE_REGION_TAB, flags);
+
+  return path;
+}
+
 static GType
 gtk_notebook_child_type (GtkContainer     *container)
 {
@@ -4478,10 +4628,11 @@ gtk_notebook_redraw_tabs (GtkNotebook *notebook)
   GtkAllocation allocation;
   GtkWidget *widget;
   GtkNotebookPage *page;
-  GtkStyle *style;
+  GtkStyleContext *context;
   GdkRectangle redraw_rect;
   gint border;
   gint tab_pos = get_effective_tab_pos (notebook);
+  GtkBorder padding;
 
   widget = GTK_WIDGET (notebook);
   border = gtk_container_get_border_width (GTK_CONTAINER (notebook));
@@ -4494,38 +4645,40 @@ gtk_notebook_redraw_tabs (GtkNotebook *notebook)
   redraw_rect.x = border;
   redraw_rect.y = border;
 
-  style = gtk_widget_get_style (widget);
   gtk_widget_get_allocation (widget, &allocation);
 
+  context = gtk_widget_get_style_context (widget);
+  gtk_style_context_get_padding (context, 0, &padding);
+
   switch (tab_pos)
     {
     case GTK_POS_BOTTOM:
       redraw_rect.y = allocation.height - border -
-	page->allocation.height - style->ythickness;
+	page->allocation.height - padding.bottom;
 
       if (page != priv->cur_page)
-	redraw_rect.y -= style->ythickness;
+	redraw_rect.y -= padding.bottom;
       /* fall through */
     case GTK_POS_TOP:
       redraw_rect.width = allocation.width - 2 * border;
-      redraw_rect.height = page->allocation.height + style->ythickness;
+      redraw_rect.height = page->allocation.height + padding.top;
 
       if (page != priv->cur_page)
-	redraw_rect.height += style->ythickness;
+	redraw_rect.height += padding.top;
       break;
     case GTK_POS_RIGHT:
       redraw_rect.x = allocation.width - border -
-	page->allocation.width - style->xthickness;
+	page->allocation.width - padding.right;
 
       if (page != priv->cur_page)
-	redraw_rect.x -= style->xthickness;
+	redraw_rect.x -= padding.right;
       /* fall through */
     case GTK_POS_LEFT:
-      redraw_rect.width = page->allocation.width + style->xthickness;
+      redraw_rect.width = page->allocation.width + padding.left;
       redraw_rect.height = allocation.height - 2 * border;
 
       if (page != priv->cur_page)
-	redraw_rect.width += style->xthickness;
+	redraw_rect.width += padding.left;
       break;
     }
 
@@ -4785,7 +4938,7 @@ gtk_notebook_update_labels (GtkNotebook *notebook)
 	  else
 	    gtk_label_set_text (GTK_LABEL (page->menu_label), string);
 	}
-    }  
+    }
 }
 
 static gint
@@ -4897,13 +5050,18 @@ gtk_notebook_paint (GtkWidget    *widget,
   gint x, y;
   guint border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
   gint gap_x = 0, gap_width = 0, step = STEP_PREV;
-  gboolean is_rtl, cur_page_end;
-  gint tab_pos, i, cur_page_pos;
-   
+  gboolean is_rtl;
+  gint tab_pos;
+  GtkStyleContext *context;
+  GtkRegionFlags tab_flags;
+  gboolean has_pack_start, has_pack_end;
+
   notebook = GTK_NOTEBOOK (widget);
   priv = notebook->priv;
   is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
   tab_pos = get_effective_tab_pos (notebook);
+  context = gtk_widget_get_style_context (widget);
+  showarrow = has_pack_start = has_pack_end = FALSE;
 
   if ((!priv->show_tabs && !priv->show_border) ||
       !priv->cur_page || !gtk_widget_get_visible (priv->cur_page->child))
@@ -4918,10 +5076,10 @@ gtk_notebook_paint (GtkWidget    *widget,
 
   if (priv->show_border && (!priv->show_tabs || !priv->children))
     {
-      gtk_paint_box (gtk_widget_get_style (widget), cr,
-		     GTK_STATE_NORMAL, GTK_SHADOW_OUT,
-		     widget, "notebook",
-		     x, y, width, height);
+      gtk_render_background (context, cr,
+                             x, y, width, height);
+      gtk_render_frame (context, cr,
+                        x, y, width, height);
       return;
     }
 
@@ -4981,37 +5139,92 @@ gtk_notebook_paint (GtkWidget    *widget,
 	  break;
 	}
     }
-  gtk_paint_box_gap (gtk_widget_get_style (widget), cr,
-		     GTK_STATE_NORMAL, GTK_SHADOW_OUT,
-		     widget, "notebook",
-		     x, y, width, height,
-		     tab_pos, gap_x, gap_width);
 
-  showarrow = FALSE;
+  for (children = priv->children; children; children = children->next)
+    {
+      page = children->data;
+
+      if (!gtk_widget_get_visible (page->child))
+        continue;
+
+      if (page->pack == GTK_PACK_START)
+        has_pack_start = TRUE;
+      else
+        has_pack_end = TRUE;
+
+      if (!gtk_widget_get_mapped (page->tab_label))
+        showarrow = TRUE;
+
+      /* No point in keeping searching */
+      if (has_pack_start && has_pack_end && showarrow)
+        break;
+    }
+
+  gtk_style_context_save (context);
+
+  if (!showarrow || !priv->scrollable)
+    {
+      GtkJunctionSides junction = 0;
+
+      /* Apply junction sides, if no arrows are shown,
+       * then make corners with connecting tabs square.
+       */
+      switch (tab_pos)
+        {
+        case GTK_POS_TOP:
+          if (has_pack_start)
+            junction |= (is_rtl) ? GTK_JUNCTION_CORNER_TOPRIGHT : GTK_JUNCTION_CORNER_TOPLEFT;
+
+          if (has_pack_end)
+            junction |= (is_rtl) ? GTK_JUNCTION_CORNER_TOPLEFT : GTK_JUNCTION_CORNER_TOPRIGHT;
+          break;
+        case GTK_POS_BOTTOM:
+          if (has_pack_start)
+            junction |= (is_rtl) ? GTK_JUNCTION_CORNER_BOTTOMRIGHT : GTK_JUNCTION_CORNER_BOTTOMLEFT;
+
+          if (has_pack_end)
+            junction |= (is_rtl) ? GTK_JUNCTION_CORNER_BOTTOMLEFT : GTK_JUNCTION_CORNER_BOTTOMRIGHT;
+          break;
+        case GTK_POS_LEFT:
+          if (has_pack_start)
+            junction |= GTK_JUNCTION_CORNER_TOPLEFT;
+
+          if (has_pack_end)
+            junction |= GTK_JUNCTION_CORNER_BOTTOMLEFT;
+          break;
+        case GTK_POS_RIGHT:
+          if (has_pack_start)
+            junction |= GTK_JUNCTION_CORNER_TOPRIGHT;
+
+          if (has_pack_end)
+            junction |= GTK_JUNCTION_CORNER_BOTTOMRIGHT;
+          break;
+        }
+
+      gtk_style_context_set_junction_sides (context, junction);
+    }
+
+  gtk_render_background (context, cr,
+                         x, y, width, height);
+  gtk_render_frame_gap (context, cr,
+                        x, y, width, height,
+                        tab_pos, gap_x, gap_x + gap_width);
+
+  gtk_style_context_restore (context);
+
   children = gtk_notebook_search_page (notebook, NULL, step, TRUE);
-  i = 0;
 
   while (children)
     {
       page = children->data;
       children = gtk_notebook_search_page (notebook, children,
 					   step, TRUE);
-      if (!gtk_widget_get_visible (page->child))
+      if (!gtk_widget_get_visible (page->child) ||
+          !gtk_widget_get_mapped (page->tab_label))
 	continue;
-      if (!gtk_widget_get_mapped (page->tab_label))
-	showarrow = TRUE;
-      else
-        {
-          if (page != priv->cur_page)
-            gtk_notebook_draw_tab (notebook, page, cr, i, children != NULL);
-          else
-            {
-              cur_page_pos = i;
-              cur_page_end = (children != NULL);
-            }
 
-          i++;
-        }
+      tab_flags = _gtk_notebook_get_tab_flags (notebook, page);
+      gtk_notebook_draw_tab (notebook, page, cr, tab_flags);
     }
 
   if (showarrow && priv->scrollable)
@@ -5027,21 +5240,22 @@ gtk_notebook_paint (GtkWidget    *widget,
     }
 
   if (priv->operation != DRAG_OPERATION_REORDER)
-    gtk_notebook_draw_tab (notebook, priv->cur_page, cr, cur_page_pos, cur_page_end);
+    {
+      tab_flags = _gtk_notebook_get_tab_flags (notebook, priv->cur_page);
+      gtk_notebook_draw_tab (notebook, priv->cur_page, cr, tab_flags);
+    }
 }
 
 static void
 gtk_notebook_draw_tab (GtkNotebook     *notebook,
 		       GtkNotebookPage *page,
 		       cairo_t         *cr,
-                       guint            position,
-                       gboolean         is_last)
+                       GtkRegionFlags   flags)
 {
   GtkNotebookPrivate *priv;
-  GtkStateType state_type;
+  GtkStateFlags state = 0;
   GtkWidget *widget;
   GtkStyleContext *context;
-  GtkRegionFlags flags = 0;
 
   if (!NOTEBOOK_IS_TAB_LABEL_PARENT (notebook, page) ||
       !gtk_widget_get_mapped (page->tab_label) ||
@@ -5052,27 +5266,14 @@ gtk_notebook_draw_tab (GtkNotebook     *notebook,
   priv = notebook->priv;
 
   if (priv->cur_page == page)
-    state_type = GTK_STATE_NORMAL;
-  else 
-    state_type = GTK_STATE_ACTIVE;
-
-  if ((position + 1) % 2 == 0)
-    flags |= GTK_REGION_EVEN;
-  else
-    flags |= GTK_REGION_ODD;
-
-  if (position == 0)
-    flags |= GTK_REGION_FIRST;
-
-  if (is_last)
-    flags |= GTK_REGION_LAST;
+    state = GTK_STATE_FLAG_ACTIVE;
 
   context = gtk_widget_get_style_context (widget);
-  gtk_style_context_add_region (context, "tab", flags);
+  gtk_style_context_save (context);
+  gtk_style_context_add_region (context, GTK_STYLE_REGION_TAB, flags);
+  gtk_style_context_set_state (context, state);
 
-  gtk_paint_extension (gtk_widget_get_style (widget), cr,
-                       state_type, GTK_SHADOW_OUT,
-                       widget, "tab",
+  gtk_render_extension (context, cr,
                        page->allocation.x,
                        page->allocation.y,
                        page->allocation.width,
@@ -5088,15 +5289,14 @@ gtk_notebook_draw_tab (GtkNotebook     *notebook,
       gtk_widget_get_allocation (page->tab_label, &allocation);
       gtk_widget_style_get (widget, "focus-line-width", &focus_width, NULL);
 
-      gtk_paint_focus (gtk_widget_get_style (widget), cr,
-                       gtk_widget_get_state (widget), widget, "tab",
-                       allocation.x - focus_width,
-                       allocation.y - focus_width,
-                       allocation.width + 2 * focus_width,
-                       allocation.height + 2 * focus_width);
+      gtk_render_focus (context, cr,
+                        allocation.x - focus_width,
+                        allocation.y - focus_width,
+                        allocation.width + 2 * focus_width,
+                        allocation.height + 2 * focus_width);
     }
 
-  gtk_style_context_remove_region (context, "tab");
+  gtk_style_context_restore (context);
 }
 
 static void
@@ -5105,17 +5305,18 @@ gtk_notebook_draw_arrow (GtkNotebook      *notebook,
 			 GtkNotebookArrow  nbarrow)
 {
   GtkNotebookPrivate *priv = notebook->priv;
-  GtkStateType state_type;
-  GtkShadowType shadow_type;
+  GtkStyleContext *context;
+  GtkStateFlags state = 0;
   GtkWidget *widget;
   GdkRectangle arrow_rect;
-  GtkArrowType arrow;
   gboolean is_rtl, left;
   gint scroll_arrow_hlength;
   gint scroll_arrow_vlength;
   gint arrow_size;
+  gdouble angle;
 
   widget = GTK_WIDGET (notebook);
+  context = gtk_widget_get_style_context (widget);
 
   gtk_notebook_get_arrow_rect (notebook, &arrow_rect, nbarrow);
 
@@ -5130,44 +5331,39 @@ gtk_notebook_draw_arrow (GtkNotebook      *notebook,
 
   if (priv->in_child == nbarrow)
     {
+      state |= GTK_STATE_FLAG_PRELIGHT;
+
       if (priv->click_child == nbarrow)
-        state_type = GTK_STATE_ACTIVE;
-      else
-        state_type = GTK_STATE_PRELIGHT;
+        state |= GTK_STATE_FLAG_ACTIVE;
     }
   else
-    state_type = gtk_widget_get_state (widget);
-
-  if (priv->click_child == nbarrow)
-    shadow_type = GTK_SHADOW_IN;
-  else
-    shadow_type = GTK_SHADOW_OUT;
+    state = gtk_widget_get_state_flags (widget);
 
   if (priv->focus_tab &&
       !gtk_notebook_search_page (notebook, priv->focus_tab,
                                  left ? STEP_PREV : STEP_NEXT, TRUE))
-    {
-      shadow_type = GTK_SHADOW_ETCHED_IN;
-      state_type = GTK_STATE_INSENSITIVE;
-    }
-  
+    state = GTK_STATE_FLAG_INSENSITIVE;
+
   if (priv->tab_pos == GTK_POS_LEFT ||
       priv->tab_pos == GTK_POS_RIGHT)
     {
-      arrow = (ARROW_IS_LEFT (nbarrow) ? GTK_ARROW_UP : GTK_ARROW_DOWN);
+      angle = (ARROW_IS_LEFT (nbarrow)) ? 0 : G_PI;
       arrow_size = scroll_arrow_vlength;
     }
   else
     {
-      arrow = (ARROW_IS_LEFT (nbarrow) ? GTK_ARROW_LEFT : GTK_ARROW_RIGHT);
+      angle = (ARROW_IS_LEFT (nbarrow)) ? 3 * (G_PI / 2) : G_PI / 2;
       arrow_size = scroll_arrow_hlength;
     }
- 
-  gtk_paint_arrow (gtk_widget_get_style (widget),
-                   cr, state_type, 
-                   shadow_type, widget, "notebook",
-                   arrow, TRUE, arrow_rect.x, arrow_rect.y, 
-                   arrow_size, arrow_size);
+
+  gtk_style_context_save (context);
+  gtk_style_context_set_state (context, state);
+
+  gtk_render_arrow (context, cr, angle,
+                    arrow_rect.x, arrow_rect.y,
+                    arrow_size);
+
+  gtk_style_context_restore (context);
 }
 
 /* Private GtkNotebook Size Allocate Functions:
@@ -5189,7 +5385,7 @@ gtk_notebook_tab_space (GtkNotebook *notebook,
   GtkNotebookPrivate *priv = notebook->priv;
   GtkAllocation allocation, action_allocation;
   GtkWidget *widget;
-  GtkStyle *style;
+  GtkStyleContext *context;
   GList *children;
   gint tab_pos = get_effective_tab_pos (notebook);
   gint tab_overlap;
@@ -5199,12 +5395,13 @@ gtk_notebook_tab_space (GtkNotebook *notebook,
   gboolean is_rtl;
   gint i;
   guint border_width;
+  GtkBorder padding;
 
   widget = GTK_WIDGET (notebook);
   children = priv->children;
   is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
 
-  style = gtk_widget_get_style (widget);
+  context = gtk_widget_get_style_context (widget);
 
   gtk_widget_style_get (GTK_WIDGET (notebook),
                         "arrow-spacing", &arrow_spacing,
@@ -5213,6 +5410,7 @@ gtk_notebook_tab_space (GtkNotebook *notebook,
                         NULL);
 
   border_width = gtk_container_get_border_width (GTK_CONTAINER (notebook));
+  gtk_style_context_get_padding (context, 0, &padding);
 
   gtk_widget_get_allocation (widget, &allocation);
 
@@ -5231,9 +5429,9 @@ gtk_notebook_tab_space (GtkNotebook *notebook,
 
               if ((i == ACTION_WIDGET_START && !is_rtl) ||
                   (i == ACTION_WIDGET_END && is_rtl))
-                *min += action_allocation.width + style->xthickness;
+                *min += action_allocation.width + padding.left;
               else
-                *max -= action_allocation.width + style->xthickness;
+                *max -= action_allocation.width + padding.right;
             }
         }
 
@@ -5261,9 +5459,9 @@ gtk_notebook_tab_space (GtkNotebook *notebook,
               gtk_widget_get_allocation (priv->action_widget[i], &action_allocation);
 
               if (i == ACTION_WIDGET_START)
-                *min += action_allocation.height + style->ythickness;
+                *min += action_allocation.height + padding.top;
               else
-                *max -= action_allocation.height + style->ythickness;
+                *max -= action_allocation.height + padding.bottom;
             }
         }
 
@@ -5599,15 +5797,15 @@ gtk_notebook_calculate_tabs_allocation (GtkNotebook  *notebook,
   GtkWidget *widget;
   GtkContainer *container;
   GtkNotebookPage *page;
-  GtkStyle *style;
+  GtkStyleContext *context;
   gboolean allocate_at_bottom;
   gint tab_overlap, tab_pos, tab_extra_space;
   gint left_x, right_x, top_y, bottom_y, anchor;
-  gint xthickness, ythickness;
   guint border_width;
   gboolean gap_left, packing_changed;
   GtkAllocation child_allocation = { 0, };
   GtkOrientation tab_expand_orientation;
+  GtkBorder padding;
 
   widget = GTK_WIDGET (notebook);
   container = GTK_CONTAINER (notebook);
@@ -5622,9 +5820,7 @@ gtk_notebook_calculate_tabs_allocation (GtkNotebook  *notebook,
   child_allocation.x = allocation.x + border_width;
   child_allocation.y = allocation.y + border_width;
 
-  style = gtk_widget_get_style (widget);
-  xthickness = style->xthickness;
-  ythickness = style->ythickness;
+  context = gtk_widget_get_style_context (widget);
 
   switch (tab_pos)
     {
@@ -5662,10 +5858,16 @@ gtk_notebook_calculate_tabs_allocation (GtkNotebook  *notebook,
   else
     tab_expand_orientation = GTK_ORIENTATION_VERTICAL;
 
+  gtk_style_context_save (context);
+
   while (*children && *children != last_child)
     {
       page = (*children)->data;
 
+      gtk_style_context_add_region (context, GTK_STYLE_REGION_TAB,
+                                    _gtk_notebook_get_tab_flags (notebook, page));
+      gtk_style_context_get_padding (context, 0, &padding);
+
       if (direction == STEP_NEXT && page->pack != GTK_PACK_START)
 	{
 	  if (!showarrow)
@@ -5817,16 +6019,16 @@ gtk_notebook_calculate_tabs_allocation (GtkNotebook  *notebook,
 	  switch (tab_pos)
 	    {
 	    case GTK_POS_TOP:
-	      page->allocation.y += ythickness;
+	      page->allocation.y += padding.top;
 	      /* fall through */
 	    case GTK_POS_BOTTOM:
-	      page->allocation.height = MAX (1, page->allocation.height - ythickness);
+	      page->allocation.height = MAX (1, page->allocation.height - padding.top);
 	      break;
 	    case GTK_POS_LEFT:
-	      page->allocation.x += xthickness;
+	      page->allocation.x += padding.left;
 	      /* fall through */
 	    case GTK_POS_RIGHT:
-	      page->allocation.width = MAX (1, page->allocation.width - xthickness);
+	      page->allocation.width = MAX (1, page->allocation.width - padding.left);
 	      break;
 	    }
 	}
@@ -5893,6 +6095,8 @@ gtk_notebook_calculate_tabs_allocation (GtkNotebook  *notebook,
 	gtk_widget_set_child_visible (page->tab_label, TRUE);
     }
 
+  gtk_style_context_restore (context);
+
   /* Don't move the current tab past the last position during tabs reordering */
   if (children &&
       priv->operation == DRAG_OPERATION_REORDER &&
@@ -5983,15 +6187,14 @@ gtk_notebook_page_allocate (GtkNotebook     *notebook,
   GtkNotebookPrivate *priv = notebook->priv;
   GtkAllocation child_allocation, label_allocation;
   GtkRequisition tab_requisition;
-  GtkStyle *style;
-  gint xthickness;
-  gint ythickness;
+  GtkStyleContext *context;
   gint padding;
   gint focus_width;
   gint tab_curvature;
   gint tab_pos = get_effective_tab_pos (notebook);
   gboolean tab_allocation_changed;
   gboolean was_visible = page->tab_allocated_visible;
+  GtkBorder tab_padding;
 
   if (!page->tab_label ||
       !gtk_widget_get_visible (page->tab_label) ||
@@ -6001,9 +6204,13 @@ gtk_notebook_page_allocate (GtkNotebook     *notebook,
       return was_visible;
     }
 
-  style = gtk_widget_get_style (widget);
-  xthickness = style->xthickness;
-  ythickness = style->ythickness;
+  context = gtk_widget_get_style_context (widget);
+
+  gtk_style_context_save (context);
+  gtk_style_context_add_region (context, GTK_STYLE_REGION_TAB,
+                                _gtk_notebook_get_tab_flags (notebook, page));
+
+  gtk_style_context_get_padding (context, 0, &tab_padding);
 
   gtk_widget_get_preferred_size (page->tab_label, &tab_requisition, NULL);
   gtk_widget_style_get (widget,
@@ -6017,8 +6224,10 @@ gtk_notebook_page_allocate (GtkNotebook     *notebook,
       padding = tab_curvature + focus_width + priv->tab_hborder;
       if (page->fill)
 	{
-	  child_allocation.x = xthickness + focus_width + priv->tab_hborder;
-	  child_allocation.width = MAX (1, page->allocation.width - 2 * child_allocation.x);
+	  child_allocation.x = tab_padding.left + focus_width + priv->tab_hborder;
+	  child_allocation.width = MAX (1, (page->allocation.width -
+                                            tab_padding.left - tab_padding.right -
+                                            2 * (focus_width + priv->tab_hborder)));
 	  child_allocation.x += page->allocation.x;
 	}
       else
@@ -6032,9 +6241,10 @@ gtk_notebook_page_allocate (GtkNotebook     *notebook,
       child_allocation.y = priv->tab_vborder + focus_width + page->allocation.y;
 
       if (tab_pos == GTK_POS_TOP)
-	child_allocation.y += ythickness;
+	child_allocation.y += tab_padding.top;
 
-      child_allocation.height = MAX (1, (page->allocation.height - ythickness -
+      child_allocation.height = MAX (1, (page->allocation.height -
+                                         tab_padding.top - tab_padding.bottom -
 					 2 * (priv->tab_vborder + focus_width)));
       break;
     case GTK_POS_LEFT:
@@ -6042,9 +6252,10 @@ gtk_notebook_page_allocate (GtkNotebook     *notebook,
       padding = tab_curvature + focus_width + priv->tab_vborder;
       if (page->fill)
 	{
-	  child_allocation.y = ythickness + padding;
+	  child_allocation.y = tab_padding.top + padding;
 	  child_allocation.height = MAX (1, (page->allocation.height -
-					     2 * child_allocation.y));
+                                             tab_padding.bottom - tab_padding.top -
+                                             2 * padding));
 	  child_allocation.y += page->allocation.y;
 	}
       else
@@ -6058,9 +6269,9 @@ gtk_notebook_page_allocate (GtkNotebook     *notebook,
       child_allocation.x = priv->tab_hborder + focus_width + page->allocation.x;
 
       if (tab_pos == GTK_POS_LEFT)
-	child_allocation.x += xthickness;
+	child_allocation.x += tab_padding.left;
 
-      child_allocation.width = MAX (1, (page->allocation.width - xthickness -
+      child_allocation.width = MAX (1, (page->allocation.width - tab_padding.right -
 					2 * (priv->tab_hborder + focus_width)));
       break;
     }
@@ -6079,6 +6290,8 @@ gtk_notebook_page_allocate (GtkNotebook     *notebook,
       tab_allocation_changed = TRUE;
     }
 
+  gtk_style_context_restore (context);
+
   return tab_allocation_changed;
 }
 
@@ -6208,6 +6421,8 @@ gtk_notebook_update_tab_states (GtkNotebook *notebook)
             gtk_widget_set_state_flags (page->tab_label, GTK_STATE_FLAG_ACTIVE, TRUE);
           else
             gtk_widget_set_state_flags (page->tab_label, 0, TRUE);
+
+          gtk_widget_reset_style (page->tab_label);
 	}
     }
 }
diff --git a/gtk/gtkstylecontext.h b/gtk/gtkstylecontext.h
index 0d1f74b..74539c2 100644
--- a/gtk/gtkstylecontext.h
+++ b/gtk/gtkstylecontext.h
@@ -295,6 +295,14 @@ struct _GtkStyleContextClass
  */
 #define GTK_STYLE_CLASS_SPINNER "spinner"
 
+/**
+ * GTK_STYLE_CLASS_NOTEBOOK:
+ *
+ * A widget class defining a notebook
+ */
+#define GTK_STYLE_CLASS_NOTEBOOK "notebook"
+
+
 /* Predefined set of widget regions */
 
 /**



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]