[gtk+/treeview-style: 2/8] Make GtkTreeView use GtkStyleContext



commit 5626711d7c2032a8b4027a9ca16fc32813645b37
Author: Carlos Garnacho <carlosg gnome org>
Date:   Wed Jan 12 21:18:07 2011 +0100

    Make GtkTreeView use GtkStyleContext
    
    Expander animation has been replaced by implicit animations
    from the style context.
    
    Column headers are also properly themed, GtkContainer::get_path_for_child()
    is implemented and the treeview resets column buttons style on columns
    being reordered.
    
    The default CSS has changed to theme treeviews sensibly.

 gtk/gtkcssprovider.c    |   27 ++-
 gtk/gtktreeprivate.h    |    2 +
 gtk/gtktreeview.c       |  666 ++++++++++++++++++++++------------------------
 gtk/gtktreeviewcolumn.c |    2 +
 4 files changed, 343 insertions(+), 354 deletions(-)
---
diff --git a/gtk/gtkcssprovider.c b/gtk/gtkcssprovider.c
index 7461fbf..fbd66d9 100644
--- a/gtk/gtkcssprovider.c
+++ b/gtk/gtkcssprovider.c
@@ -3603,8 +3603,7 @@ gtk_css_provider_get_default (void)
         "@define-color error_fg_color rgb (166, 38, 38);\n"
         "@define-color error_bg_color rgb (237, 54, 54);\n"
         "\n"
-        "*,\n"
-        "GtkTreeView > GtkButton {\n"
+        "* {\n"
         "  background-color: @bg_color;\n"
         "  color: @fg_color;\n"
         "  border-color: shade (@bg_color, 0.6);\n"
@@ -3640,12 +3639,9 @@ gtk_css_provider_get_default (void)
         "  color: shade (@bg_color, 0.7);\n"
         "}\n"
         "\n"
-        "GtkTreeView, GtkIconView {\n"
-        "  background-color: @base_color;\n"
-        "  color: @text_color;\n"
-        "}\n"
-        "\n"
         ".view {\n"
+        "  border-width: 0;\n"
+        "  border-radius: 0;\n"
         "  background-color: @base_color;\n"
         "  color: @text_color;\n"
         "}\n"
@@ -3668,6 +3664,22 @@ gtk_css_provider_get_default (void)
         "  background-color: shade (@base_color, 0.93); \n"
         "}\n"
         "\n"
+        "row:selected:focused {\n"
+        "  background-color: @selected_bg_color;\n"
+        "}\n"
+        "\n"
+        "row:selected {\n"
+        "  background-color: darker (@bg_color);\n"
+        "  color: @selected_fg_color;\n"
+        "}\n"
+        "\n"
+        ".rubberband {\n"
+        "  background-color: alpha (@fg_color, 0.25);\n"
+        "  border-color: @fg_color;\n"
+        "  border-style: solid;\n"
+        "  border-width: 1;\n"
+        "}\n"
+        "\n"
         ".tooltip {\n"
         "  background-color: @tooltip_bg_color; \n"
         "  color: @tooltip_fg_color; \n"
@@ -3747,6 +3759,7 @@ gtk_css_provider_get_default (void)
         ".check:selected, .radio:selected {\n"
         "  background-color: @selected_bg_color;\n"
         "  color: @selected_fg_color;\n"
+        "  border-color: @selected_fg_color;\n"
         "}\n"
         "\n"
         ".menu.check, .menu.radio {\n"
diff --git a/gtk/gtktreeprivate.h b/gtk/gtktreeprivate.h
index a47a17b..2c54a04 100644
--- a/gtk/gtktreeprivate.h
+++ b/gtk/gtktreeprivate.h
@@ -154,6 +154,8 @@ void              _gtk_tree_view_column_set_use_resized_width (GtkTreeViewColumn
 gboolean          _gtk_tree_view_column_get_use_resized_width (GtkTreeViewColumn  *column);
 gint              _gtk_tree_view_column_get_drag_x            (GtkTreeViewColumn  *column);
 GtkCellAreaContext *_gtk_tree_view_column_get_context         (GtkTreeViewColumn  *column);
+void              _gtk_tree_view_reset_header_styles       (GtkTreeView        *tree_view);
+
 
 G_END_DECLS
 
diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c
index 76b748f..10ee768 100644
--- a/gtk/gtktreeview.c
+++ b/gtk/gtktreeview.c
@@ -603,6 +603,9 @@ static gboolean gtk_tree_view_configure            (GtkWidget         *widget,
 						    GdkEventConfigure *event);
 #endif
 
+static GtkWidgetPath * gtk_tree_view_get_path_for_child (GtkContainer *container,
+                                                         GtkWidget    *child);
+
 static void     gtk_tree_view_set_focus_child      (GtkContainer     *container,
 						    GtkWidget        *child);
 static gint     gtk_tree_view_focus_out            (GtkWidget        *widget,
@@ -610,12 +613,11 @@ static gint     gtk_tree_view_focus_out            (GtkWidget        *widget,
 static gint     gtk_tree_view_focus                (GtkWidget        *widget,
 						    GtkDirectionType  direction);
 static void     gtk_tree_view_grab_focus           (GtkWidget        *widget);
-static void     gtk_tree_view_style_set            (GtkWidget        *widget,
-						    GtkStyle         *previous_style);
+static void     gtk_tree_view_style_updated        (GtkWidget        *widget);
 static void     gtk_tree_view_grab_notify          (GtkWidget        *widget,
 						    gboolean          was_grabbed);
-static void     gtk_tree_view_state_changed        (GtkWidget        *widget,
-						    GtkStateType      previous_state);
+static void     gtk_tree_view_state_flags_changed  (GtkWidget        *widget,
+						    GtkStateFlags     previous_state);
 
 /* container signals */
 static void     gtk_tree_view_remove               (GtkContainer     *container,
@@ -794,14 +796,6 @@ static gboolean gtk_tree_view_has_can_focus_cell             (GtkTreeView
 static void     column_sizing_notify                         (GObject            *object,
                                                               GParamSpec         *pspec,
                                                               gpointer            data);
-static gboolean expand_collapse_timeout                      (gpointer            data);
-static void     add_expand_collapse_timeout                  (GtkTreeView        *tree_view,
-                                                              GtkRBTree          *tree,
-                                                              GtkRBNode          *node,
-                                                              gboolean            expand);
-static void     remove_expand_collapse_timeout               (GtkTreeView        *tree_view);
-static void     cancel_arrow_animation                       (GtkTreeView        *tree_view);
-static gboolean do_expand_collapse                           (GtkTreeView        *tree_view);
 static void     gtk_tree_view_stop_rubber_band               (GtkTreeView        *tree_view);
 static void     update_prelight                              (GtkTreeView        *tree_view,
                                                               int                 x,
@@ -963,14 +957,15 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
   widget_class->drag_data_received = gtk_tree_view_drag_data_received;
   widget_class->focus = gtk_tree_view_focus;
   widget_class->grab_focus = gtk_tree_view_grab_focus;
-  widget_class->style_set = gtk_tree_view_style_set;
+  widget_class->style_updated = gtk_tree_view_style_updated;
   widget_class->grab_notify = gtk_tree_view_grab_notify;
-  widget_class->state_changed = gtk_tree_view_state_changed;
+  widget_class->state_flags_changed = gtk_tree_view_state_flags_changed;
 
   /* GtkContainer signals */
   container_class->remove = gtk_tree_view_remove;
   container_class->forall = gtk_tree_view_forall;
   container_class->set_focus_child = gtk_tree_view_set_focus_child;
+  container_class->get_path_for_child = gtk_tree_view_get_path_for_child;
 
   class->move_cursor = gtk_tree_view_real_move_cursor;
   class->select_all = gtk_tree_view_real_select_all;
@@ -2186,7 +2181,7 @@ static void
 gtk_tree_view_realize (GtkWidget *widget)
 {
   GtkAllocation allocation;
-  GtkStyle *style;
+  GtkStyleContext *context;
   GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
   GdkWindow *window;
   GdkWindowAttr attributes;
@@ -2255,12 +2250,14 @@ gtk_tree_view_realize (GtkWidget *widget)
 						   &attributes, attributes_mask);
   gdk_window_set_user_data (tree_view->priv->header_window, widget);
 
-  /* Add them all up. */
-  gtk_widget_style_attach (widget);
-  style = gtk_widget_get_style (widget);
-  gdk_window_set_background (tree_view->priv->bin_window,
-                             &style->base[gtk_widget_get_state (widget)]);
-  gtk_style_set_background (style, tree_view->priv->header_window, GTK_STATE_NORMAL);
+  context = gtk_widget_get_style_context (widget);
+
+  gtk_style_context_set_background (context, tree_view->priv->bin_window);
+
+  gtk_style_context_save (context);
+  gtk_style_context_remove_class (context, GTK_STYLE_CLASS_VIEW);
+  gtk_style_context_set_background (context, tree_view->priv->header_window);
+  gtk_style_context_restore (context);
 
   tmp_list = tree_view->priv->children;
   while (tmp_list)
@@ -2306,8 +2303,6 @@ gtk_tree_view_unrealize (GtkWidget *widget)
       priv->open_dest_timeout = 0;
     }
 
-  remove_expand_collapse_timeout (tree_view);
-  
   if (priv->presize_handler_timer != 0)
     {
       g_source_remove (priv->presize_handler_timer);
@@ -4481,30 +4476,31 @@ gtk_tree_view_paint_rubber_band (GtkTreeView  *tree_view,
                                  cairo_t      *cr)
 {
   GdkRectangle rect;
-  GtkStyle *style;
+  GtkStyleContext *context;
 
   cairo_save (cr);
 
+  context = gtk_widget_get_style_context (GTK_WIDGET (tree_view));
+
+  gtk_style_context_save (context);
+  gtk_style_context_add_class (context, GTK_STYLE_CLASS_RUBBERBAND);
+
   rect.x = MIN (tree_view->priv->press_start_x, tree_view->priv->rubber_band_x);
   rect.y = MIN (tree_view->priv->press_start_y, tree_view->priv->rubber_band_y) - tree_view->priv->dy;
   rect.width = ABS (tree_view->priv->press_start_x - tree_view->priv->rubber_band_x) + 1;
   rect.height = ABS (tree_view->priv->press_start_y - tree_view->priv->rubber_band_y) + 1;
 
-  cairo_set_line_width (cr, 1.0);
-
-  style = gtk_widget_get_style (GTK_WIDGET (tree_view));
-
-  gdk_cairo_set_source_color (cr, &style->fg[GTK_STATE_NORMAL]);
-
   gdk_cairo_rectangle (cr, &rect);
   cairo_clip (cr);
-  cairo_paint_with_alpha (cr, 0.25);
 
-  cairo_rectangle (cr,
-		   rect.x + 0.5, rect.y + 0.5,
-		   rect.width - 1, rect.height - 1);
-  cairo_stroke (cr);
+  gtk_render_background (context, cr,
+                         rect.x, rect.y,
+                         rect.width, rect.height);
+  gtk_render_frame (context, cr,
+                    rect.x, rect.y,
+                    rect.width, rect.height);
 
+  gtk_style_context_restore (context);
   cairo_restore (cr);
 }
 
@@ -4617,12 +4613,20 @@ draw_empty_focus (GtkTreeView *tree_view, cairo_t *cr)
   h = gdk_window_get_height (tree_view->priv->bin_window) - 2;
 
   if (w > 0 && h > 0)
-    gtk_paint_focus (gtk_widget_get_style (widget),
-                     cr,
-		     gtk_widget_get_state (widget),
-		     widget,
-		     NULL,
-		     1, 1, w, h);
+    {
+      GtkStyleContext *context;
+      GtkStateFlags state;
+
+      context = gtk_widget_get_style_context (widget);
+      state = gtk_widget_get_state_flags (widget);
+
+      gtk_style_context_save (context);
+      gtk_style_context_set_state (context, state);
+
+      gtk_render_focus (context, cr, 1, 1, w, h);
+
+      gtk_style_context_restore (context);
+    }
 }
 
 typedef enum {
@@ -4664,9 +4668,19 @@ gtk_tree_view_draw_line (GtkTreeView         *tree_view,
       g_assert_not_reached ();
       /* fall through */
     case GTK_TREE_VIEW_FOREGROUND_LINE:
-      cairo_set_line_width (cr, 1.0);
-      gdk_cairo_set_source_color (cr,
-                                  &gtk_widget_get_style (GTK_WIDGET (tree_view))->fg[gtk_widget_get_state (GTK_WIDGET (tree_view))]);
+      {
+        GtkStyleContext *context;
+        GtkStateFlags state;
+        GdkRGBA color;
+
+        context = gtk_widget_get_style_context (GTK_WIDGET (tree_view));
+        state = gtk_widget_get_state_flags (GTK_WIDGET (tree_view));
+
+        cairo_set_line_width (cr, 1.0);
+        gtk_style_context_get_color (context, state, &color);
+        gdk_cairo_set_source_rgba (cr, &color);
+      }
+
       break;
     }
 
@@ -4723,7 +4737,6 @@ gtk_tree_view_bin_draw (GtkWidget      *widget,
 {
   GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
   GtkTreePath *path;
-  GtkStyle *style;
   GtkRBTree *tree;
   GList *list;
   GtkRBNode *node;
@@ -4758,8 +4771,12 @@ gtk_tree_view_bin_draw (GtkWidget      *widget,
   gint grid_line_width;
   gboolean got_pointer = FALSE;
   gboolean draw_vgrid_lines, draw_hgrid_lines;
+  GtkStyleContext *context;
+  GtkStateFlags state;
 
   rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
+  context = gtk_widget_get_style_context (widget);
+  state = gtk_widget_get_state_flags (widget);
 
   gtk_widget_style_get (widget,
 			"horizontal-separator", &horizontal_separator,
@@ -4774,8 +4791,6 @@ gtk_tree_view_bin_draw (GtkWidget      *widget,
       return TRUE;
     }
 
-  style = gtk_widget_get_style (widget);
-
   bin_window_width = gdk_window_get_width (tree_view->priv->bin_window);
   bin_window_height = gdk_window_get_height (tree_view->priv->bin_window);
   cairo_rectangle (cr, 0, 0, bin_window_width, bin_window_height);
@@ -4791,15 +4806,16 @@ gtk_tree_view_bin_draw (GtkWidget      *widget,
 
   if (tree_view->priv->height < bin_window_height)
     {
-      gtk_paint_flat_box (style,
-                          cr,
-                          gtk_widget_get_state (widget),
-                          GTK_SHADOW_NONE,
-                          widget,
-                          "cell_even",
-                          0, tree_view->priv->height,
-                          bin_window_width,
-                          bin_window_height - tree_view->priv->height);
+      gtk_style_context_save (context);
+      gtk_style_context_set_state (context, state);
+      gtk_style_context_add_class (context, GTK_STYLE_CLASS_CELL);
+
+      gtk_render_background (context, cr,
+                             0, tree_view->priv->height,
+                             bin_window_width,
+                             bin_window_height - tree_view->priv->height);
+
+      gtk_style_context_restore (context);
     }
 
   if (node == NULL)
@@ -4875,7 +4891,8 @@ gtk_tree_view_bin_draw (GtkWidget      *widget,
       gboolean is_separator = FALSE;
       gboolean is_first = FALSE;
       gboolean is_last = FALSE;
-      
+      gint n_col = 0;
+
       is_separator = row_is_separator (tree_view, &iter, NULL);
 
       max_height = gtk_tree_view_get_row_height (tree_view, node);
@@ -4920,15 +4937,15 @@ gtk_tree_view_bin_draw (GtkWidget      *widget,
 	   list = (rtl ? list->prev : list->next))
 	{
 	  GtkTreeViewColumn *column = list->data;
-	  const gchar *detail = NULL;
-	  gchar new_detail[128];
+          GtkRegionFlags row_flags = 0, column_flags = 0;
+	  GtkStateFlags state = 0;
           gint width;
-	  GtkStateType state;
           gboolean draw_focus;
 
 	  if (!gtk_tree_view_column_get_visible (column))
             continue;
 
+          n_col++;
           width = gtk_tree_view_column_get_width (column);
 
 	  if (cell_offset > clip.x + clip.width ||
@@ -4999,49 +5016,47 @@ gtk_tree_view_bin_draw (GtkWidget      *widget,
            */
           if (allow_rules && tree_view->priv->has_rules)
             {
-              if ((flags & GTK_CELL_RENDERER_SORTED) &&
-		  n_visible_columns >= 3)
-                {
-                  if (parity)
-                    detail = "cell_odd_ruled_sorted";
-                  else
-                    detail = "cell_even_ruled_sorted";
-                }
+              if (parity)
+                row_flags |= GTK_REGION_ODD;
               else
-                {
-                  if (parity)
-                    detail = "cell_odd_ruled";
-                  else
-                    detail = "cell_even_ruled";
-                }
+                row_flags |= GTK_REGION_EVEN;
             }
+
+          if ((flags & GTK_CELL_RENDERER_SORTED) &&
+              n_visible_columns >= 3)
+            column_flags |= GTK_REGION_SORTED;
+
+	  is_first = (rtl ? !list->next : !list->prev);
+	  is_last = (rtl ? !list->prev : !list->next);
+
+          if (is_first)
+            column_flags |= GTK_REGION_FIRST;
+
+          if (is_last)
+            column_flags |= GTK_REGION_LAST;
+
+          if ((n_col % 2) == 0)
+            column_flags |= GTK_REGION_EVEN;
           else
+            column_flags |= GTK_REGION_ODD;
+
+	  if (!gtk_widget_get_sensitive (widget))
+	    state |= GTK_STATE_FLAG_INSENSITIVE;
+	  else
             {
-              if ((flags & GTK_CELL_RENDERER_SORTED) &&
-		  n_visible_columns >= 3)
-                {
-                  if (parity)
-                    detail = "cell_odd_sorted";
-                  else
-                    detail = "cell_even_sorted";
-                }
-              else
-                {
-                  if (parity)
-                    detail = "cell_odd";
-                  else
-                    detail = "cell_even";
-                }
+              if (flags & GTK_CELL_RENDERER_SELECTED)
+                state |= GTK_STATE_FLAG_SELECTED;
+
+              if (gtk_widget_has_focus (widget))
+                state |= GTK_STATE_FLAG_FOCUSED;
             }
 
-          g_assert (detail);
+          gtk_style_context_save (context);
 
-	  if (gtk_widget_get_state (widget) == GTK_STATE_INSENSITIVE)
-	    state = GTK_STATE_INSENSITIVE;	    
-	  else if (flags & GTK_CELL_RENDERER_SELECTED)
-	    state = GTK_STATE_SELECTED;
-	  else
-	    state = GTK_STATE_NORMAL;
+          gtk_style_context_add_class (context, GTK_STYLE_CLASS_CELL);
+          gtk_style_context_add_region (context, GTK_STYLE_REGION_ROW, row_flags);
+          gtk_style_context_add_region (context, GTK_STYLE_REGION_COLUMN, column_flags);
+          gtk_style_context_set_state (context, state);
 
 	  if (node == cursor && has_can_focus_cell
               && ((column == tree_view->priv->focus_column
@@ -5053,31 +5068,13 @@ gtk_tree_view_bin_draw (GtkWidget      *widget,
             draw_focus = FALSE;
 
 	  /* Draw background */
-	  is_first = (rtl ? !list->next : !list->prev);
-	  is_last = (rtl ? !list->prev : !list->next);
+          gtk_render_background (context, cr,
+                                 background_area.x,
+                                 background_area.y,
+                                 background_area.width,
+                                 background_area.height);
 
-	  /* (I don't like the snprintfs either, but couldn't find a
-	   * less messy way).
-	   */
-	  if (is_first && is_last)
-	    g_snprintf (new_detail, 127, "%s", detail);
-	  else if (is_first)
-	    g_snprintf (new_detail, 127, "%s_start", detail);
-	  else if (is_last)
-	    g_snprintf (new_detail, 127, "%s_end", detail);
-	  else
-	    g_snprintf (new_detail, 127, "%s_middle", detail);
-
-	  gtk_paint_flat_box (style,
-			      cr,
-			      state,
-			      GTK_SHADOW_NONE,
-			      widget,
-			      new_detail,
-			      background_area.x,
-			      background_area.y,
-			      background_area.width,
-			      background_area.height);
+          gtk_style_context_restore (context);
 
 	  if (gtk_tree_view_is_expander_column (tree_view, column))
 	    {
@@ -5100,12 +5097,9 @@ gtk_tree_view_bin_draw (GtkWidget      *widget,
 	      expander_cell_width = cell_area.width;
 
 	      if (is_separator)
-		gtk_paint_hline (style,
-				 cr,
-				 state,
-				 widget,
-				 NULL,
-				 cell_area.x,
+                gtk_render_line (context, cr,
+                                 cell_area.x,
+                                 cell_area.y + cell_area.height / 2,
 				 cell_area.x + cell_area.width,
 				 cell_area.y + cell_area.height / 2);
 	      else
@@ -5135,12 +5129,9 @@ gtk_tree_view_bin_draw (GtkWidget      *widget,
 	  else
 	    {
 	      if (is_separator)
-		gtk_paint_hline (style,
-				 cr,
-				 state,
-				 widget,
-				 NULL,
+                gtk_render_line (context, cr,
 				 cell_area.x,
+                                 cell_area.y + cell_area.height / 2,
 				 cell_area.x + cell_area.width,
 				 cell_area.y + cell_area.height / 2);
 	      else
@@ -5271,13 +5262,7 @@ gtk_tree_view_bin_draw (GtkWidget      *widget,
 	      if (tree == NULL)
 		break;
 
-	      gtk_paint_focus (style,
-			       cr,
-			       gtk_widget_get_state (widget),
-			       widget,
-			       (is_first
-			        ? (is_last ? "treeview-drop-indicator" : "treeview-drop-indicator-left" )
-			        : (is_last ? "treeview-drop-indicator-right" : "tree-view-drop-indicator-middle" )),
+              gtk_render_focus (context, cr,
 			        0, gtk_tree_view_get_row_y_offset (tree_view, tree, node)
 			           - focus_line_width / 2,
 			        gdk_window_get_width (tree_view->priv->bin_window),
@@ -5303,13 +5288,16 @@ gtk_tree_view_bin_draw (GtkWidget      *widget,
 	  gtk_widget_has_focus (widget))
         {
 	  gint tmp_y, tmp_height;
-	  GtkStateType focus_rect_state;
+	  GtkStateFlags focus_rect_state = 0;
 
-	  focus_rect_state =
-	    flags & GTK_CELL_RENDERER_SELECTED ? GTK_STATE_SELECTED :
-	    (flags & GTK_CELL_RENDERER_PRELIT ? GTK_STATE_PRELIGHT :
-	     (flags & GTK_CELL_RENDERER_INSENSITIVE ? GTK_STATE_INSENSITIVE :
-	      GTK_STATE_NORMAL));
+          if (flags & GTK_CELL_RENDERER_SELECTED)
+            focus_rect_state |= GTK_STATE_FLAG_SELECTED;
+
+          if (flags & GTK_CELL_RENDERER_PRELIT)
+            focus_rect_state |= GTK_STATE_FLAG_PRELIGHT;
+
+          if (flags & GTK_CELL_RENDERER_INSENSITIVE)
+            focus_rect_state |= GTK_STATE_FLAG_INSENSITIVE;
 
 	  if (draw_hgrid_lines)
 	    {
@@ -5322,16 +5310,15 @@ gtk_tree_view_bin_draw (GtkWidget      *widget,
               tmp_height = gtk_tree_view_get_row_height (tree_view, node);
 	    }
 
-	  gtk_paint_focus (style,
-			   cr,
-			   focus_rect_state,
-			   widget,
-			   (is_first
-			    ? (is_last ? "treeview" : "treeview-left" )
-			    : (is_last ? "treeview-right" : "treeview-middle" )),
-			   0, tmp_y,
-			   gdk_window_get_width (tree_view->priv->bin_window),
-                           tmp_height);
+          gtk_style_context_save (context);
+          gtk_style_context_set_state (context, focus_rect_state);
+
+          gtk_render_focus (context, cr,
+                            0, tmp_y,
+                            gdk_window_get_width (tree_view->priv->bin_window),
+                            tmp_height);
+
+          gtk_style_context_restore (context);
         }
 
       y_offset += max_height;
@@ -5418,14 +5405,21 @@ gtk_tree_view_draw (GtkWidget *widget,
 
   if (gtk_cairo_should_draw_window (cr, tree_view->priv->bin_window))
     {
+      GtkStyleContext *context;
       GList *tmp_list;
 
+      context = gtk_widget_get_style_context (widget);
+
       cairo_save (cr);
 
+      gtk_style_context_save (context);
+      gtk_style_context_add_class (context, GTK_STYLE_CLASS_VIEW);
+
       gtk_cairo_transform_to_window (cr, widget, tree_view->priv->bin_window);
 
       gtk_tree_view_bin_draw (widget, cr);
 
+      gtk_style_context_restore (context);
       cairo_restore (cr);
 
       /* We can't just chain up to Container::draw as it will try to send the
@@ -8505,20 +8499,24 @@ gtk_tree_view_grab_focus (GtkWidget *widget)
 }
 
 static void
-gtk_tree_view_style_set (GtkWidget *widget,
-			 GtkStyle *previous_style)
+gtk_tree_view_style_updated (GtkWidget *widget)
 {
   GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
-  GtkStyle *style;
   GList *list;
   GtkTreeViewColumn *column;
 
   if (gtk_widget_get_realized (widget))
     {
-      style = gtk_widget_get_style (widget);
-      gdk_window_set_background (tree_view->priv->bin_window,
-                                 &style->base[gtk_widget_get_state (widget)]);
-      gtk_style_set_background (style, tree_view->priv->header_window, GTK_STATE_NORMAL);
+      GtkStyleContext *context;
+
+      context = gtk_widget_get_style_context (widget);
+
+      gtk_style_context_save (context);
+      gtk_style_context_add_class (context, GTK_STYLE_CLASS_VIEW);
+      gtk_style_context_set_background (context, tree_view->priv->bin_window);
+      gtk_style_context_restore (context);
+
+      gtk_style_context_set_background (context, tree_view->priv->header_window);
 
       gtk_tree_view_set_grid_lines (tree_view, tree_view->priv->grid_lines);
       gtk_tree_view_set_enable_tree_lines (tree_view, tree_view->priv->tree_lines_enabled);
@@ -8561,6 +8559,54 @@ gtk_tree_view_set_focus_child (GtkContainer *container,
   GTK_CONTAINER_CLASS (gtk_tree_view_parent_class)->set_focus_child (container, child);
 }
 
+static GtkWidgetPath *
+gtk_tree_view_get_path_for_child (GtkContainer *container,
+                                  GtkWidget    *child)
+{
+  GtkTreeView *tree_view = GTK_TREE_VIEW (container);
+  GtkWidgetPath *path;
+  gboolean rtl;
+  GList *list;
+  gint i = 0;
+
+  path = GTK_CONTAINER_CLASS (gtk_tree_view_parent_class)->get_path_for_child (container, child);
+  rtl = (gtk_widget_get_direction (GTK_WIDGET (container)) == GTK_TEXT_DIR_RTL);
+
+  for (list = (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns));
+       list;
+       list = (rtl ? list->prev : list->next))
+    {
+      GtkTreeViewColumn *column = list->data;
+      GtkRegionFlags flags = 0;
+
+      if (!gtk_tree_view_column_get_visible (column))
+        continue;
+
+      i++;
+
+      if (gtk_tree_view_column_get_widget (column) != child &&
+          gtk_tree_view_column_get_button (column) != child)
+        continue;
+
+      if ((i % 2) == 0)
+        flags |= GTK_REGION_EVEN;
+      else
+        flags |= GTK_REGION_ODD;
+
+      if (i == 1)
+        flags |= GTK_REGION_FIRST;
+
+      if ((rtl && !list->prev) ||
+          (!rtl && !list->next))
+        flags |= GTK_REGION_LAST;
+
+      gtk_widget_path_iter_add_region (path, -1, GTK_STYLE_REGION_COLUMN_HEADER, flags);
+      break;
+    }
+
+  return path;
+}
+
 static gboolean
 gtk_tree_view_real_move_cursor (GtkTreeView       *tree_view,
 				GtkMovementStep    step,
@@ -8988,6 +9034,7 @@ gtk_tree_view_row_deleted (GtkTreeModel *model,
   GtkRBNode *node;
   GList *list;
   gint selection_changed = FALSE;
+  GtkStyleContext *context;
 
   g_return_if_fail (path != NULL);
 
@@ -9014,9 +9061,6 @@ gtk_tree_view_row_deleted (GtkTreeModel *model,
   /* Cancel editting if we've started */
   gtk_tree_view_stop_editing (tree_view, TRUE);
 
-  /* If we have a node expanded/collapsed timeout, remove it */
-  remove_expand_collapse_timeout (tree_view);
-
   if (tree_view->priv->destroy_count_func)
     {
       gint child_count = 0;
@@ -9043,6 +9087,10 @@ gtk_tree_view_row_deleted (GtkTreeModel *model,
       tree_view->priv->top_row = NULL;
     }
 
+  /* Cancel any ongoing animation happening within the row */
+  context = gtk_widget_get_style_context (GTK_WIDGET (tree_view));
+  gtk_style_context_cancel_animations (context, node);
+
   install_scroll_sync_handler (tree_view);
 
   gtk_widget_queue_resize (GTK_WIDGET (tree_view));
@@ -9094,9 +9142,6 @@ gtk_tree_view_rows_reordered (GtkTreeModel *model,
   /* we need to be unprelighted */
   ensure_unprelighted (tree_view);
 
-  /* clear the timeout */
-  cancel_arrow_animation (tree_view);
-  
   _gtk_rbtree_reorder (tree, new_order, len);
 
   gtk_widget_queue_draw (GTK_WIDGET (tree_view));
@@ -9985,15 +10030,16 @@ gtk_tree_view_draw_arrow (GtkTreeView *tree_view,
 			  gint         y)
 {
   GdkRectangle area;
-  GtkStateType state;
+  GtkStateFlags state = 0;
+  GtkStyleContext *context;
   GtkWidget *widget;
   gint x_offset = 0;
   gint x2;
   gint vertical_separator;
   gint expander_size;
-  GtkExpanderStyle expander_style;
 
   widget = GTK_WIDGET (tree_view);
+  context = gtk_widget_get_style_context (widget);
 
   gtk_widget_style_get (widget,
 			"vertical-separator", &vertical_separator,
@@ -10012,44 +10058,36 @@ gtk_tree_view_draw_arrow (GtkTreeView *tree_view,
   area.height = gtk_tree_view_get_cell_area_height (tree_view, node,
                                                     vertical_separator);
 
-  if (gtk_widget_get_state (widget) == GTK_STATE_INSENSITIVE)
-    {
-      state = GTK_STATE_INSENSITIVE;
-    }
-  else if (node == tree_view->priv->button_pressed_node)
-    {
-      if (x >= area.x && x <= (area.x + area.width) &&
-	  y >= area.y && y <= (area.y + area.height))
-        state = GTK_STATE_ACTIVE;
-      else
-        state = GTK_STATE_NORMAL;
-    }
+  if (!gtk_widget_get_sensitive (widget))
+    state |= GTK_STATE_FLAG_INSENSITIVE;
   else
     {
+      if (node == tree_view->priv->button_pressed_node &&
+          x >= area.x && x <= (area.x + area.width) &&
+          y >= area.y && y <= (area.y + area.height))
+        state = GTK_STATE_FLAG_SELECTED;
+
       if (node == tree_view->priv->prelight_node &&
           tree_view->priv->arrow_prelit)
-	state = GTK_STATE_PRELIGHT;
-      else
-	state = GTK_STATE_NORMAL;
+	state = GTK_STATE_FLAG_PRELIGHT;
     }
 
-  if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SEMI_EXPANDED))
-    expander_style = GTK_EXPANDER_SEMI_EXPANDED;
-  else if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SEMI_COLLAPSED))
-    expander_style = GTK_EXPANDER_SEMI_COLLAPSED;
-  else if (node->children != NULL)
-    expander_style = GTK_EXPANDER_EXPANDED;
-  else
-    expander_style = GTK_EXPANDER_COLLAPSED;
+  if (node->children != NULL)
+    state |= GTK_STATE_FLAG_ACTIVE;
 
-  gtk_paint_expander (gtk_widget_get_style (widget),
-                      cr,
-                      state,
-                      widget,
-                      "treeview",
-		      area.x + area.width / 2,
-		      area.y + area.height / 2,
-		      expander_style);
+  gtk_style_context_save (context);
+
+  gtk_style_context_set_state (context, state);
+  gtk_style_context_add_class (context, GTK_STYLE_CLASS_EXPANDER);
+
+  gtk_style_context_push_animatable_region (context, node);
+
+  gtk_render_expander (context, cr,
+                       area.x, area.y,
+                       area.width, area.height);
+
+  gtk_style_context_pop_animatable_region (context);
+  gtk_style_context_restore (context);
 }
 
 static void
@@ -11194,6 +11232,7 @@ gtk_tree_view_adjustment_changed (GtkAdjustment *adjustment,
 {
   if (gtk_widget_get_realized (GTK_WIDGET (tree_view)))
     {
+      GtkStyleContext *context;
       gint dy;
 	
       gdk_window_move (tree_view->priv->bin_window,
@@ -11236,6 +11275,9 @@ gtk_tree_view_adjustment_changed (GtkAdjustment *adjustment,
 	}
       gdk_window_scroll (tree_view->priv->bin_window, 0, dy);
 
+      context = gtk_widget_get_style_context (GTK_WIDGET (tree_view));
+      gtk_style_context_scroll_animations (context, tree_view->priv->bin_window, 0, dy);
+
       if (tree_view->priv->dy != (int) gtk_adjustment_get_value (tree_view->priv->vadjustment))
         {
           /* update our dy and top_row */
@@ -11334,8 +11376,6 @@ gtk_tree_view_set_model (GtkTreeView  *tree_view,
       gtk_tree_view_unref_and_check_selection_tree (tree_view, tree_view->priv->tree);
       gtk_tree_view_stop_editing (tree_view, TRUE);
 
-      remove_expand_collapse_timeout (tree_view);
-
       g_signal_handlers_disconnect_by_func (tree_view->priv->model,
 					    gtk_tree_view_row_changed,
 					    tree_view);
@@ -11834,6 +11874,28 @@ gtk_tree_view_append_column (GtkTreeView       *tree_view,
   return gtk_tree_view_insert_column (tree_view, column, -1);
 }
 
+void
+_gtk_tree_view_reset_header_styles (GtkTreeView *tree_view)
+{
+  GList *columns;
+
+  for (columns = tree_view->priv->columns; columns; columns = columns->next)
+    {
+      GtkTreeViewColumn *column = columns->data;
+      GtkWidget *header_widget;
+
+      if (gtk_tree_view_column_get_visible (column))
+        continue;
+
+      header_widget = gtk_tree_view_column_get_widget (column);
+
+      if (!header_widget)
+        header_widget = gtk_tree_view_column_get_button (column);
+
+      gtk_widget_reset_style (header_widget);
+    }
+}
+
 
 /**
  * gtk_tree_view_remove_column:
@@ -11886,7 +11948,7 @@ gtk_tree_view_remove_column (GtkTreeView       *tree_view,
 
 	  tmp_column = GTK_TREE_VIEW_COLUMN (list->data);
 	  if (gtk_tree_view_column_get_visible (tmp_column))
-	    _gtk_tree_view_column_cell_set_dirty (tmp_column, TRUE);
+            _gtk_tree_view_column_cell_set_dirty (tmp_column, TRUE);
 	}
 
       if (tree_view->priv->n_columns == 0 &&
@@ -11896,6 +11958,8 @@ gtk_tree_view_remove_column (GtkTreeView       *tree_view,
       gtk_widget_queue_resize (GTK_WIDGET (tree_view));
     }
 
+  _gtk_tree_view_reset_header_styles (tree_view);
+
   g_object_unref (column);
   g_signal_emit (tree_view, tree_view_signals[COLUMNS_CHANGED], 0);
 
@@ -11956,11 +12020,12 @@ gtk_tree_view_insert_column (GtkTreeView       *tree_view,
 	{
 	  column = GTK_TREE_VIEW_COLUMN (list->data);
 	  if (gtk_tree_view_column_get_visible (column))
-	    _gtk_tree_view_column_cell_set_dirty (column, TRUE);
+            _gtk_tree_view_column_cell_set_dirty (column, TRUE);
 	}
       gtk_widget_queue_resize (GTK_WIDGET (tree_view));
     }
 
+  _gtk_tree_view_reset_header_styles (tree_view);
   g_signal_emit (tree_view, tree_view_signals[COLUMNS_CHANGED], 0);
 
   return tree_view->priv->n_columns;
@@ -12162,6 +12227,7 @@ gtk_tree_view_move_column_after (GtkTreeView       *tree_view,
       gtk_tree_view_size_allocate_columns (GTK_WIDGET (tree_view), NULL);
     }
 
+  _gtk_tree_view_reset_header_styles (tree_view);
   g_signal_emit (tree_view, tree_view_signals[COLUMNS_CHANGED], 0);
 }
 
@@ -12494,124 +12560,6 @@ gtk_tree_view_expand_all (GtkTreeView *tree_view)
   gtk_tree_path_free (path);
 }
 
-/* Timeout to animate the expander during expands and collapses */
-static gboolean
-expand_collapse_timeout (gpointer data)
-{
-  return do_expand_collapse (data);
-}
-
-static void
-add_expand_collapse_timeout (GtkTreeView *tree_view,
-                             GtkRBTree   *tree,
-                             GtkRBNode   *node,
-                             gboolean     expand)
-{
-  if (tree_view->priv->expand_collapse_timeout != 0)
-    return;
-
-  tree_view->priv->expand_collapse_timeout =
-      gdk_threads_add_timeout (50, expand_collapse_timeout, tree_view);
-  tree_view->priv->expanded_collapsed_tree = tree;
-  tree_view->priv->expanded_collapsed_node = node;
-
-  if (expand)
-    GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_IS_SEMI_COLLAPSED);
-  else
-    GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_IS_SEMI_EXPANDED);
-}
-
-static void
-remove_expand_collapse_timeout (GtkTreeView *tree_view)
-{
-  if (tree_view->priv->expand_collapse_timeout)
-    {
-      g_source_remove (tree_view->priv->expand_collapse_timeout);
-      tree_view->priv->expand_collapse_timeout = 0;
-    }
-
-  if (tree_view->priv->expanded_collapsed_node != NULL)
-    {
-      GTK_RBNODE_UNSET_FLAG (tree_view->priv->expanded_collapsed_node, GTK_RBNODE_IS_SEMI_EXPANDED);
-      GTK_RBNODE_UNSET_FLAG (tree_view->priv->expanded_collapsed_node, GTK_RBNODE_IS_SEMI_COLLAPSED);
-
-      tree_view->priv->expanded_collapsed_node = NULL;
-    }
-}
-
-static void
-cancel_arrow_animation (GtkTreeView *tree_view)
-{
-  if (tree_view->priv->expand_collapse_timeout)
-    {
-      while (do_expand_collapse (tree_view));
-
-      remove_expand_collapse_timeout (tree_view);
-    }
-}
-
-static gboolean
-do_expand_collapse (GtkTreeView *tree_view)
-{
-  GtkRBNode *node;
-  GtkRBTree *tree;
-  gboolean expanding;
-  gboolean redraw;
-
-  redraw = FALSE;
-  expanding = TRUE;
-
-  node = tree_view->priv->expanded_collapsed_node;
-  tree = tree_view->priv->expanded_collapsed_tree;
-
-  if (node->children == NULL)
-    expanding = FALSE;
-
-  if (expanding)
-    {
-      if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SEMI_COLLAPSED))
-	{
-	  GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_IS_SEMI_COLLAPSED);
-	  GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_IS_SEMI_EXPANDED);
-
-	  redraw = TRUE;
-
-	}
-      else if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SEMI_EXPANDED))
-	{
-	  GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_IS_SEMI_EXPANDED);
-
-	  redraw = TRUE;
-	}
-    }
-  else
-    {
-      if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SEMI_EXPANDED))
-	{
-	  GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_IS_SEMI_EXPANDED);
-	  GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_IS_SEMI_COLLAPSED);
-
-	  redraw = TRUE;
-	}
-      else if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SEMI_COLLAPSED))
-	{
-	  GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_IS_SEMI_COLLAPSED);
-
-	  redraw = TRUE;
-
-	}
-    }
-
-  if (redraw)
-    {
-      gtk_tree_view_queue_draw_arrow (tree_view, tree, node);
-
-      return TRUE;
-    }
-
-  return FALSE;
-}
-
 /**
  * gtk_tree_view_collapse_all:
  * @tree_view: A #GtkTreeView.
@@ -12772,10 +12720,21 @@ gtk_tree_view_real_expand_row (GtkTreeView *tree_view,
 			    gtk_tree_path_get_depth (path) + 1,
 			    open_all);
 
-  remove_expand_collapse_timeout (tree_view);
-
   if (animate)
-    add_expand_collapse_timeout (tree_view, tree, node, TRUE);
+    {
+      GtkStyleContext *context;
+
+      context = gtk_widget_get_style_context (GTK_WIDGET (tree_view));
+
+      gtk_style_context_save (context);
+      gtk_style_context_add_class (context, GTK_STYLE_CLASS_EXPANDER);
+
+      gtk_style_context_notify_state_change (context, tree_view->priv->bin_window,
+                                             node, GTK_STATE_ACTIVE, TRUE);
+
+      _gtk_style_context_invalidate_animation_areas (context);
+      gtk_style_context_restore (context);
+    }
 
   install_presize_handler (tree_view);
 
@@ -12932,8 +12891,6 @@ gtk_tree_view_real_collapse_row (GtkTreeView *tree_view,
   tree_view->priv->last_button_x = -1;
   tree_view->priv->last_button_y = -1;
 
-  remove_expand_collapse_timeout (tree_view);
-
   if (gtk_tree_view_unref_and_check_selection_tree (tree_view, node->children))
     {
       _gtk_rbtree_remove (node->children);
@@ -12941,10 +12898,23 @@ gtk_tree_view_real_collapse_row (GtkTreeView *tree_view,
     }
   else
     _gtk_rbtree_remove (node->children);
-  
+
   if (animate)
-    add_expand_collapse_timeout (tree_view, tree, node, FALSE);
-  
+    {
+      GtkStyleContext *context;
+
+      context = gtk_widget_get_style_context (GTK_WIDGET (tree_view));
+
+      gtk_style_context_save (context);
+      gtk_style_context_add_class (context, GTK_STYLE_CLASS_EXPANDER);
+
+      gtk_style_context_notify_state_change (context, tree_view->priv->bin_window,
+                                             node, GTK_STATE_ACTIVE, FALSE);
+
+      _gtk_style_context_invalidate_animation_areas (context);
+      gtk_style_context_restore (context);
+    }
+
   if (gtk_widget_get_mapped (GTK_WIDGET (tree_view)))
     {
       gtk_widget_queue_resize (GTK_WIDGET (tree_view));
@@ -14518,7 +14488,8 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView  *tree_view,
   GtkTreeIter   iter;
   GtkRBTree    *tree;
   GtkRBNode    *node;
-  GtkStyle *style;
+  GtkStyleContext *context;
+  GtkStateFlags state;
   gint cell_offset;
   GList *list;
   GdkRectangle background_area;
@@ -14530,6 +14501,7 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView  *tree_view,
   gint bin_window_width;
   gboolean is_separator = FALSE;
   gboolean rtl;
+  GdkRGBA color;
   cairo_t *cr;
 
   g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), NULL);
@@ -14555,7 +14527,7 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView  *tree_view,
                                 path))
     return NULL;
 
-  style = gtk_widget_get_style (widget);
+  context = gtk_widget_get_style_context (widget);
 
   is_separator = row_is_separator (tree_view, &iter, NULL);
 
@@ -14572,7 +14544,9 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView  *tree_view,
                                                background_area.height + 2);
 
   cr = cairo_create (surface);
-  gdk_cairo_set_source_color (cr, &style->base [gtk_widget_get_state (widget)]);
+  state = gtk_widget_get_state_flags (widget);
+  gtk_style_context_get_background_color (context, state, &color);
+  gdk_cairo_set_source_rgba (cr, &color);
   cairo_paint (cr);
 
   rtl = gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_RTL;
@@ -14621,14 +14595,11 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView  *tree_view,
       if (gtk_tree_view_column_cell_is_visible (column))
 	{
 	  if (is_separator)
-	    gtk_paint_hline (style,
-                                   cr,
-                                   GTK_STATE_NORMAL,
-                                   widget,
-                                   NULL,
-                                   cell_area.x,
-                                   cell_area.x + cell_area.width,
-                                   cell_area.y + cell_area.height / 2);
+            gtk_render_line (context, cr,
+                             cell_area.x,
+                             cell_area.y + cell_area.height / 2,
+                             cell_area.x + cell_area.width,
+                             cell_area.y + cell_area.height / 2);
 	  else
 	    _gtk_tree_view_column_cell_render (column,
                                                cr,
@@ -15863,15 +15834,16 @@ gtk_tree_view_grab_notify (GtkWidget *widget,
 }
 
 static void
-gtk_tree_view_state_changed (GtkWidget      *widget,
-		 	     GtkStateType    previous_state)
+gtk_tree_view_state_flags_changed (GtkWidget     *widget,
+                                   GtkStateFlags  previous_state)
 {
-  GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
-
   if (gtk_widget_get_realized (widget))
     {
-      gdk_window_set_background (tree_view->priv->bin_window,
-                                 &gtk_widget_get_style (widget)->base[gtk_widget_get_state (widget)]);
+      GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
+      GtkStyleContext *context;
+
+      context = gtk_widget_get_style_context (widget);
+      gtk_style_context_set_background (context, tree_view->priv->bin_window);
     }
 
   gtk_widget_queue_draw (widget);
diff --git a/gtk/gtktreeviewcolumn.c b/gtk/gtktreeviewcolumn.c
index 98a7746..9b82ad3 100644
--- a/gtk/gtktreeviewcolumn.c
+++ b/gtk/gtktreeviewcolumn.c
@@ -1881,6 +1881,8 @@ gtk_tree_view_column_set_visible (GtkTreeViewColumn *tree_column,
   if (priv->visible)
     _gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
 
+  _gtk_tree_view_reset_header_styles (GTK_TREE_VIEW (priv->tree_view));
+
   gtk_tree_view_column_update_button (tree_column);
   g_object_notify (G_OBJECT (tree_column), "visible");
 }



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