[gtk/wip/baedert/for-master: 1/11] treeview: Redo grid line drawing using textures
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/baedert/for-master: 1/11] treeview: Redo grid line drawing using textures
- Date: Sun, 11 Aug 2019 06:35:53 +0000 (UTC)
commit 3ba207dbe2838d6f2d2552c1fe48c2fed7fa3552
Author: Timm Bäder <mail baedert org>
Date: Sat Aug 10 08:49:45 2019 +0200
treeview: Redo grid line drawing using textures
The cairo pattern in use was simple enough, so just use a 2×1 or 1×2
texture to draw horizontal and vertical grid lines. This avoids a bunch
of cairo nodes (that can't be cached by the renderers).
gtk/gtktreeview.c | 156 ++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 116 insertions(+), 40 deletions(-)
---
diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c
index e7629baf09..534876f9f0 100644
--- a/gtk/gtktreeview.c
+++ b/gtk/gtktreeview.c
@@ -67,6 +67,7 @@
#include "a11y/gtktreeviewaccessibleprivate.h"
#include "gdk/gdkeventsprivate.h"
+#include "gdk/gdktextureprivate.h"
#include <math.h>
#include <string.h>
@@ -509,6 +510,10 @@ struct _GtkTreeViewPrivate
int expander_size;
+ GdkRGBA grid_line_color; /* Color used in the textures */
+ GdkTexture *horizontal_grid_line_texture;
+ GdkTexture *vertical_grid_line_texture;
+
/* Here comes the bitfield */
guint scroll_to_use_align : 1;
@@ -2213,6 +2218,8 @@ gtk_tree_view_destroy (GtkWidget *widget)
g_clear_object (&priv->hadjustment);
g_clear_object (&priv->vadjustment);
+ g_clear_object (&priv->horizontal_grid_line_texture);
+ g_clear_object (&priv->vertical_grid_line_texture);
GTK_WIDGET_CLASS (gtk_tree_view_parent_class)->destroy (widget);
}
@@ -4209,7 +4216,6 @@ invalidate_empty_focus (GtkTreeView *tree_view)
}
typedef enum {
- GTK_TREE_VIEW_GRID_LINE,
GTK_TREE_VIEW_TREE_LINE,
} GtkTreeViewLineType;
@@ -4249,18 +4255,6 @@ gtk_tree_view_snapshot_line (GtkTreeView *tree_view,
}
break;
- case GTK_TREE_VIEW_GRID_LINE:
- {
- const GdkRGBA *color;
-
- color = _gtk_css_rgba_value_get_rgba (_gtk_style_context_peek_property (context,
GTK_CSS_PROPERTY_BORDER_TOP_COLOR));
-
- gdk_cairo_set_source_rgba (cr, color);
- cairo_set_line_width (cr, _TREE_VIEW_GRID_LINE_WIDTH);
- cairo_set_dash (cr, (double[]){ 1, 1 }, 2, 0.5);
- }
- break;
-
default:
g_assert_not_reached ();
break;
@@ -4272,23 +4266,100 @@ gtk_tree_view_snapshot_line (GtkTreeView *tree_view,
cairo_destroy (cr);
}
-
+
+static void
+gtk_tree_view_snapshot_grid_line (GtkTreeView *tree_view,
+ GtkSnapshot *snapshot,
+ GtkOrientation orientation,
+ const graphene_point_t *start,
+ float size)
+{
+ GtkTreeViewPrivate *priv = gtk_tree_view_get_instance_private (tree_view);
+ GtkStyleContext *context;
+ const GdkRGBA *grid_line_color;
+
+ context = gtk_widget_get_style_context (GTK_WIDGET (tree_view));
+ grid_line_color = _gtk_css_rgba_value_get_rgba (_gtk_style_context_peek_property (context,
+
GTK_CSS_PROPERTY_BORDER_TOP_COLOR));
+
+ if (!gdk_rgba_equal (grid_line_color, &priv->grid_line_color) ||
+ (orientation == GTK_ORIENTATION_HORIZONTAL && !priv->horizontal_grid_line_texture) ||
+ (orientation == GTK_ORIENTATION_VERTICAL && !priv->vertical_grid_line_texture))
+ {
+ cairo_surface_t *surface;
+ unsigned char *data;
+
+ g_clear_object (&priv->horizontal_grid_line_texture);
+ g_clear_object (&priv->vertical_grid_line_texture);
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 2, 1);
+ data = cairo_image_surface_get_data (surface);
+ /* just color the first pixel... */
+ data[0] = round (grid_line_color->blue * 255);
+ data[1] = round (grid_line_color->green * 255);
+ data[2] = round (grid_line_color->red * 255);
+ data[3] = round (grid_line_color->alpha * 255);
+
+ priv->horizontal_grid_line_texture = gdk_texture_new_for_surface (surface);
+ cairo_surface_destroy (surface);
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 2);
+ data = cairo_image_surface_get_data (surface);
+ data[0] = round (grid_line_color->blue * 255);
+ data[1] = round (grid_line_color->green * 255);
+ data[2] = round (grid_line_color->red * 255);
+ data[3] = round (grid_line_color->alpha * 255);
+
+ priv->vertical_grid_line_texture = gdk_texture_new_for_surface (surface);
+ cairo_surface_destroy (surface);
+ }
+
+ g_assert (priv->horizontal_grid_line_texture);
+ g_assert (priv->vertical_grid_line_texture);
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ gtk_snapshot_push_repeat (snapshot,
+ &GRAPHENE_RECT_INIT (
+ start->x, start->y,
+ size, 1),
+ NULL);
+ gtk_snapshot_append_texture (snapshot, priv->horizontal_grid_line_texture,
+ &GRAPHENE_RECT_INIT (0, 0, 2, 1));
+ gtk_snapshot_pop (snapshot);
+ }
+ else /* VERTICAL */
+ {
+ gtk_snapshot_push_repeat (snapshot,
+ &GRAPHENE_RECT_INIT (
+ start->x, start->y,
+ 1, size),
+ NULL);
+ gtk_snapshot_append_texture (snapshot, priv->vertical_grid_line_texture,
+ &GRAPHENE_RECT_INIT (0, 0, 1, 2));
+ gtk_snapshot_pop (snapshot);
+ }
+}
+
static void
gtk_tree_view_snapshot_grid_lines (GtkTreeView *tree_view,
- GtkSnapshot *snapshot)
+ GtkSnapshot *snapshot)
{
+ GtkTreeViewPrivate *priv = gtk_tree_view_get_instance_private (tree_view);
GList *list, *first, *last;
gboolean rtl;
- gint current_x = 0;
+ int current_x = 0;
+ int tree_view_height;
- if (tree_view->priv->grid_lines != GTK_TREE_VIEW_GRID_LINES_VERTICAL
- && tree_view->priv->grid_lines != GTK_TREE_VIEW_GRID_LINES_BOTH)
+ if (priv->grid_lines != GTK_TREE_VIEW_GRID_LINES_VERTICAL &&
+ priv->grid_lines != GTK_TREE_VIEW_GRID_LINES_BOTH)
return;
rtl = (_gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_RTL);
- first = g_list_first (tree_view->priv->columns);
- last = g_list_last (tree_view->priv->columns);
+ first = g_list_first (priv->columns);
+ last = g_list_last (priv->columns);
+ tree_view_height = gtk_tree_view_get_height (tree_view);
for (list = (rtl ? last : first);
list;
@@ -4305,10 +4376,11 @@ gtk_tree_view_snapshot_grid_lines (GtkTreeView *tree_view,
current_x += gtk_tree_view_column_get_width (column);
- gtk_tree_view_snapshot_line (tree_view, snapshot,
- GTK_TREE_VIEW_GRID_LINE,
- current_x - 1, 0,
- current_x - 1, gtk_tree_view_get_height (tree_view));
+ gtk_tree_view_snapshot_grid_line (tree_view,
+ snapshot,
+ GTK_ORIENTATION_VERTICAL,
+ &(graphene_point_t) { current_x - 1, 0 },
+ tree_view_height);
}
}
@@ -4675,22 +4747,26 @@ gtk_tree_view_bin_snapshot (GtkWidget *widget,
draw_focus);
}
- if (draw_hgrid_lines)
- {
- if (background_area.y >= clip.y)
- gtk_tree_view_snapshot_line (tree_view, snapshot,
- GTK_TREE_VIEW_GRID_LINE,
- background_area.x, background_area.y,
- background_area.x + background_area.width,
- background_area.y);
-
- if (background_area.y + max_height < clip.y + clip.height)
- gtk_tree_view_snapshot_line (tree_view, snapshot,
- GTK_TREE_VIEW_GRID_LINE,
- background_area.x, background_area.y + max_height,
- background_area.x + background_area.width,
- background_area.y + max_height);
- }
+ if (draw_hgrid_lines)
+ {
+ if (background_area.y >= clip.y)
+ gtk_tree_view_snapshot_grid_line (tree_view,
+ snapshot,
+ GTK_ORIENTATION_HORIZONTAL,
+ &(graphene_point_t) {
+ background_area.x, background_area.y
+ },
+ background_area.width);
+
+ if (background_area.y + max_height < clip.y + clip.height)
+ gtk_tree_view_snapshot_grid_line (tree_view,
+ snapshot,
+ GTK_ORIENTATION_HORIZONTAL,
+ &(graphene_point_t) {
+ background_area.x, background_area.y + max_height
+ },
+ background_area.width);
+ }
if (gtk_tree_view_is_expander_column (tree_view, column) &&
tree_view->priv->tree_lines_enabled)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]