Re: GtkTreeView focus drawing patch



Jonathan Blandford wrote:
> 
> Bill Haneman <bill haneman sun com> writes:
> 
> > Hi:
> >
> > Here is what I hope is the last of the focus drawing patches for
> > awhile...
> >
> > What it does:
> >
> > (1) increases size requests for tree/table cells to account for thicker
> > focus lines;
> >
> > OK to commit?
> 
> No.  Something is going wrong with cell sizing, leading to
> incrementally larger cells everytime they change.  This needs fixing
> before the patch can be applied.

Ah, oops... sorry about that.  A misunderstanding about 
gtk_tree_view_column_cell_get_size dealt with requested_width.

Revised patch, without this bug, is attached.  

Please note that since the previous behavior of GtkTreeView 
(which isn't compatible with high-contrast themes) used, 
in effect,  GTK_STATE_NORMAL for all cell focus drawing, the 
color of selected focus rectangles in treeviews is changed by 
this patch.  If the previous focus color is desired 
for the default case, an entry in an rc file (defining 
fg[GTK_STATE_SELECTED] to equal fg[GTK_STATE_NORMAL] for 
GtkTreeView widgets) is sufficient.


Please have a look and let me know if I may commit... it would
be nice to have this feature prior to G2 Beta.

Thanks,

Bill

> Thanks,
> -Jonathan
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gtk+/ChangeLog,v
retrieving revision 1.2872
diff -u -r1.2872 ChangeLog
--- ChangeLog	2002/01/28 07:43:25	1.2872
+++ ChangeLog	2002/01/28 14:24:39
@@ -1,3 +1,27 @@
+2002-01-28 Bill Haneman <bill haneman sun com>
+
+	* gtk/gtkstyle.c:
+	Make sure that the default expanders are drawn with
+	an outline thickness appropriate to the size of the
+	expanders (RINT expander_size/7).
+	Added static gtk_style_draw_polygon_with_gc(), to
+	reduce code duplication.
+
+	* gtk/gtktreeview.c: (gtk_tree_view_bin_expose):
+	Use focus_line_thickness when drawing focus lines.
+
+	* gtk/gtktreeviewcolumn.c:(gtk_tree_view_column_cell_get_size):
+	Adjust requested width to include focus line thickness.
+	(gtk_tree_view_column_cell_render_or_focus):
+	Calculate a focus line rectangle which gets larger as the focus
+	line thickness increases, to avoid overwriting cell content.
+	Render left-aligned content at x+focus_line_width.
+	(gtk_tree_view_column_cell_draw_focus):
+	Don't draw a focus line around an editable text cell, since the
+	text caret already indicates keyboard focus.
+	Pass a GtkStateType appropriate to the focussed cell's state
+	to gtk_paint_focus.
+
 2002-01-28  Anders Carlsson  <andersca gnu org>
 
 	* gtk/gtkaccelgroup.c (gtk_accel_groups_activate): & with the
Index: gtk/gtktreeview.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktreeview.c,v
retrieving revision 1.204
diff -u -r1.204 gtktreeview.c
--- gtk/gtktreeview.c	2002/01/27 21:11:29	1.204
+++ gtk/gtktreeview.c	2002/01/28 14:24:46
@@ -2847,6 +2847,7 @@
 	  GtkRBTree *tree = NULL;
 	  GtkRBNode *node = NULL;
 	  gint width;
+	  gint focus_line_width;
 
           switch (tree_view->priv->drag_dest_pos)
             {
@@ -2866,15 +2867,18 @@
 		break;
 	      gdk_drawable_get_size (tree_view->priv->bin_window,
 				     &width, NULL);
+	      gtk_widget_style_get (widget, "focus-line-width", &focus_line_width, NULL);
 	      gtk_paint_focus (widget->style,
 			       tree_view->priv->bin_window,
 			       GTK_WIDGET_STATE (widget),
 			       NULL,
 			       widget,
 			       "treeview-drop-indicator",
-			       0, BACKGROUND_FIRST_PIXEL (tree_view, tree, node),
-			       width, MAX (BACKGROUND_HEIGHT (node), tree_view->priv->expander_size));
-
+			       0, BACKGROUND_FIRST_PIXEL (tree_view, tree, node)
+			       - focus_line_width / 2,
+			       width, MAX(BACKGROUND_HEIGHT (node),
+					  tree_view->priv->expander_size)
+			       - focus_line_width + 1);
               break;
             }
 
Index: gtk/gtktreeviewcolumn.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktreeviewcolumn.c,v
retrieving revision 1.89
diff -u -r1.89 gtktreeviewcolumn.c
--- gtk/gtktreeviewcolumn.c	2002/01/24 20:42:48	1.89
+++ gtk/gtktreeviewcolumn.c	2002/01/28 14:24:48
@@ -2125,6 +2125,7 @@
 {
   GList *list;
   gboolean first_cell = TRUE;
+  gint focus_line_width;
 
   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
 
@@ -2133,6 +2134,8 @@
   if (width)
     * width = 0;
 
+  gtk_widget_style_get (tree_column->tree_view, "focus-line-width", &focus_line_width, NULL);
+  
   for (list = tree_column->cell_list; list; list = list->next)
     {
       GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
@@ -2156,8 +2159,8 @@
 				  &new_height);
 
       if (height)
-	* height = MAX (*height, new_height);
-      info->requested_width = MAX (info->requested_width, new_width);
+	* height = MAX (*height, new_height + focus_line_width * 2);
+      info->requested_width = MAX (info->requested_width, new_width + focus_line_width * 2);
       if (width)
 	* width += info->requested_width;
       first_cell = TRUE;
@@ -2184,6 +2187,7 @@
   gint full_requested_width = 0;
   gint extra_space;
   gint min_x, min_y, max_x, max_y;
+  gint focus_line_width;
 
   min_x = G_MAXINT;
   min_y = G_MAXINT;
@@ -2192,6 +2196,8 @@
 
   real_cell_area = *cell_area;
 
+  gtk_widget_style_get (GTK_WIDGET (tree_column->tree_view),
+			"focus-line-width", &focus_line_width, NULL);
   /* Find out how my extra space we have to allocate */
   for (list = tree_column->cell_list; list; list = list->next)
     {
@@ -2221,6 +2227,7 @@
 
       real_cell_area.width = info->requested_width +
 	(info->expand?extra_space:0);
+      real_cell_area.x += focus_line_width;
       if (render)
 	{
 	  gtk_cell_renderer_render (info->cell,
@@ -2278,17 +2285,17 @@
       if (min_x >= max_x || min_y >= max_y)
 	{
 	  *focus_rectangle = *cell_area;
-	  focus_rectangle->x -= 1;
-	  focus_rectangle->y -= 1;
-	  focus_rectangle->width += 2;
-	  focus_rectangle->height += 2;
+	  focus_rectangle->x -= focus_line_width;
+	  focus_rectangle->y -= focus_line_width;
+	  focus_rectangle->width += 2 * focus_line_width;
+	  focus_rectangle->height += 2 * focus_line_width;
 	}
       else
 	{
-	  focus_rectangle->x = min_x - 1;
-	  focus_rectangle->y = min_y - 1;
-	  focus_rectangle->width = (max_x - min_x) + 2;
-	  focus_rectangle->height = (max_y - min_y) + 2;
+	  focus_rectangle->x = min_x - focus_line_width;
+	  focus_rectangle->y = min_y - focus_line_width;
+	  focus_rectangle->width = (max_x - min_x) + 2 * focus_line_width;
+	  focus_rectangle->height = (max_y - min_y) + 2 * focus_line_width;
 	}
     }
 }
@@ -2394,23 +2401,28 @@
 				      GdkRectangle            *expose_area,
 				      guint                    flags)
 {
+  gint focus_line_width;
+  GtkStateType cell_state;
+  
   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
+  gtk_widget_style_get (GTK_WIDGET (tree_column->tree_view),
+			"focus-line-width", &focus_line_width, NULL);
   if (tree_column->editable_widget)
     {
       /* This function is only called on the editable row when editing.
        */
-
+#if 0
       gtk_paint_focus (tree_column->tree_view->style,
 		       window,
 		       GTK_WIDGET_STATE (tree_column->tree_view),
 		       NULL,
 		       tree_column->tree_view,
 		       "treeview",
-		       cell_area->x - 1,
-		       cell_area->y - 1,
-		       cell_area->width + 2,
-		       cell_area->height + 2);
-      
+		       cell_area->x - focus_line_width,
+		       cell_area->y - focus_line_width,
+		       cell_area->width + 2 * focus_line_width,
+		       cell_area->height + 2 * focus_line_width);
+#endif      
     }
   else
     {
@@ -2423,10 +2435,13 @@
 						 flags,
 						 FALSE,
 						 &focus_rectangle);
-      
+
+      cell_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));
       gtk_paint_focus (tree_column->tree_view->style,
 		       window,
-		       GTK_WIDGET_STATE (tree_column->tree_view),
+		       cell_state,
 		       NULL,
 		       tree_column->tree_view,
 		       "treeview",
Index: gtk/gtkstyle.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkstyle.c,v
retrieving revision 1.99
diff -u -r1.99 gtkstyle.c
--- gtk/gtkstyle.c	2002/01/27 16:39:29	1.99
+++ gtk/gtkstyle.c	2002/01/28 14:24:52
@@ -4346,6 +4346,18 @@
 }
 
 static void
+gtk_style_draw_polygon_with_gc (GdkWindow *window, GdkGC *gc, gint line_width,
+				gboolean do_fill, GdkPoint *points, gint n_points)
+{
+  gdk_gc_set_line_attributes (gc, line_width,
+			      GDK_LINE_SOLID,
+			      GDK_CAP_BUTT, GDK_JOIN_MITER);
+
+  gdk_draw_polygon (window, gc, do_fill, points, n_points);
+  gdk_gc_set_line_attributes (gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
+}
+
+static void
 gtk_default_draw_expander (GtkStyle        *style,
                            GdkWindow       *window,
                            GtkStateType     state_type,
@@ -4359,12 +4371,14 @@
   gint expander_size;
   GdkPoint points[3];
   gint i;
+  gint line_width;
   gdouble affine[6];
   gint degrees = 0;
   
   gtk_widget_style_get (widget,
 			"expander_size", &expander_size,
 			NULL);
+  line_width = MAX (1, expander_size/7);
 
   if (area)
     {
@@ -4372,12 +4386,13 @@
       gdk_gc_set_clip_rectangle (style->base_gc[GTK_STATE_NORMAL], area);
     }
 
-  points[0].x = 0;
-  points[0].y = 0;
-  points[1].x = expander_size / 2;
-  points[1].y =  expander_size / 2;
-  points[2].x = 0;
-  points[2].y = expander_size;
+  expander_size -= (line_width * 2 - 2);
+  points[0].x = line_width / 2;
+  points[0].y = line_width / 2;
+  points[1].x = expander_size / 2 + line_width / 2;
+  points[1].y = expander_size / 2 + line_width / 2;
+  points[2].x = line_width / 2;
+  points[2].y = expander_size + line_width / 2;
 
   switch (expander_style)
     {
@@ -4404,22 +4419,22 @@
 
   if (state_type == GTK_STATE_PRELIGHT)
     {
-      gdk_draw_polygon (window, style->fg_gc[GTK_STATE_NORMAL],
-			TRUE, points, 3);
+      gtk_style_draw_polygon_with_gc (window, style->fg_gc[GTK_STATE_NORMAL],
+				      1, TRUE, points, 3);
     }
   else if (state_type == GTK_STATE_ACTIVE)
     {
-      gdk_draw_polygon (window, style->light_gc[GTK_STATE_ACTIVE],
-			TRUE, points, 3);
-      gdk_draw_polygon (window, style->fg_gc[GTK_STATE_NORMAL],
-			FALSE, points, 3);
+      gtk_style_draw_polygon_with_gc (window, style->light_gc[GTK_STATE_ACTIVE],
+				      1, TRUE, points, 3);
+      gtk_style_draw_polygon_with_gc (window, style->fg_gc[GTK_STATE_NORMAL],
+				      line_width, FALSE, points, 3);
     }
   else
     {
-      gdk_draw_polygon (window, style->base_gc[GTK_STATE_NORMAL],
-			TRUE, points, 3);
-      gdk_draw_polygon (window, style->fg_gc[GTK_STATE_NORMAL],
-			FALSE, points, 3);
+      gtk_style_draw_polygon_with_gc (window, style->base_gc[GTK_STATE_NORMAL],
+				      1, TRUE, points, 3);
+      gtk_style_draw_polygon_with_gc (window, style->fg_gc[GTK_STATE_NORMAL],
+				      line_width, FALSE, points, 3);
     }
   if (area)
     {


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