[gitg] Use GtkSourceGutter API to render diff line numbers
- From: Jesse van den Kieboom <jessevdk src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gitg] Use GtkSourceGutter API to render diff line numbers
- Date: Mon, 11 Jan 2010 20:57:24 +0000 (UTC)
commit 19396f8fb0335fffb3f842f83c4ea2b0159de699
Author: Jesse van den Kieboom <jessevdk gnome org>
Date: Mon Jan 11 21:56:53 2010 +0100
Use GtkSourceGutter API to render diff line numbers
gitg/Makefile.am | 2 +
gitg/gitg-diff-line-renderer.c | 255 ++++++++++++++++++++++++++++++
gitg/gitg-diff-line-renderer.h | 36 +++++
gitg/gitg-diff-view.c | 342 +++++++++++++++++-----------------------
gitg/gitg-window.ui | 4 +-
5 files changed, 441 insertions(+), 198 deletions(-)
---
diff --git a/gitg/Makefile.am b/gitg/Makefile.am
index a7961fb..5a5fe54 100644
--- a/gitg/Makefile.am
+++ b/gitg/Makefile.am
@@ -24,6 +24,7 @@ NOINST_H_FILES = \
gitg-commit-view.h \
gitg-data-binding.h \
gitg-debug.h \
+ gitg-diff-line-renderer.h \
gitg-diff-view.h \
gitg-dirs.h \
gitg-dnd.h \
@@ -58,6 +59,7 @@ gitg_SOURCES = \
gitg-commit-view.c \
gitg-data-binding.c \
gitg-debug.c \
+ gitg-diff-line-renderer.c \
gitg-diff-view.c \
gitg-dirs.c \
gitg-dnd.c \
diff --git a/gitg/gitg-diff-line-renderer.c b/gitg/gitg-diff-line-renderer.c
new file mode 100644
index 0000000..37e9a1e
--- /dev/null
+++ b/gitg/gitg-diff-line-renderer.c
@@ -0,0 +1,255 @@
+#include "gitg-diff-line-renderer.h"
+
+#define GITG_DIFF_LINE_RENDERER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_DIFF_LINE_RENDERER, GitgDiffLineRendererPrivate))
+
+#ifndef MAX
+#define MAX(a, b) (a > b ? a : b)
+#endif
+
+#ifndef MIN
+#define MIN(a, b) (a < b ? a : b)
+#endif
+
+/* Properties */
+enum
+{
+ PROP_0,
+ PROP_LINE_OLD,
+ PROP_LINE_NEW
+};
+
+struct _GitgDiffLineRendererPrivate
+{
+ gint line_old;
+ gint line_new;
+};
+
+G_DEFINE_TYPE (GitgDiffLineRenderer, gitg_diff_line_renderer, GTK_TYPE_CELL_RENDERER)
+
+static void
+gitg_diff_line_renderer_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (gitg_diff_line_renderer_parent_class)->finalize (object);
+}
+
+static void
+gitg_diff_line_renderer_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GitgDiffLineRenderer *self = GITG_DIFF_LINE_RENDERER (object);
+
+ switch (prop_id)
+ {
+ case PROP_LINE_OLD:
+ self->priv->line_old = g_value_get_int (value);
+ break;
+ case PROP_LINE_NEW:
+ self->priv->line_new = g_value_get_int (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gitg_diff_line_renderer_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GitgDiffLineRenderer *self = GITG_DIFF_LINE_RENDERER (object);
+
+ switch (prop_id)
+ {
+ case PROP_LINE_OLD:
+ g_value_set_int (value, self->priv->line_old);
+ break;
+ case PROP_LINE_NEW:
+ g_value_set_int (value, self->priv->line_new);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gitg_diff_line_renderer_render_impl (GtkCellRenderer *cell,
+ GdkDrawable *window,
+ GtkWidget *widget,
+ GdkRectangle *background_area,
+ GdkRectangle *cell_area,
+ GdkRectangle *expose_area,
+ GtkCellRendererState flags)
+{
+ GitgDiffLineRenderer *lr = GITG_DIFF_LINE_RENDERER (cell);
+
+ /* Render new/old in the cell area */
+ gchar old_str[16];
+ gchar new_str[16];
+ guint xpad;
+ guint ypad;
+
+ PangoLayout *layout = gtk_widget_create_pango_layout (widget, "");
+ pango_layout_set_width (layout, cell_area->width / 2);
+
+ pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT);
+
+ if (lr->priv->line_old >= 0)
+ {
+ g_snprintf (old_str, sizeof (old_str), "%d", lr->priv->line_old);
+ }
+ else
+ {
+ *old_str = '\0';
+ }
+
+ if (lr->priv->line_new >= 0)
+ {
+ g_snprintf (new_str, sizeof (old_str), "%d", lr->priv->line_new);
+ }
+ else
+ {
+ *new_str = '\0';
+ }
+
+ g_object_get (cell, "xpad", &xpad, "ypad", &ypad, NULL);
+
+ pango_layout_set_text (layout, old_str, -1);
+ gtk_paint_layout (widget->style,
+ window,
+ GTK_WIDGET_STATE (widget),
+ FALSE,
+ NULL,
+ widget,
+ NULL,
+ cell_area->x + cell_area->width / 2 - 1 - xpad,
+ cell_area->y,
+ layout);
+
+ pango_layout_set_text (layout, new_str, -1);
+ gtk_paint_layout (widget->style,
+ window,
+ GTK_WIDGET_STATE (widget),
+ FALSE,
+ NULL,
+ widget,
+ NULL,
+ cell_area->x + cell_area->width - xpad,
+ cell_area->y,
+ layout);
+
+ g_object_unref (layout);
+
+ gtk_paint_vline (widget->style,
+ window,
+ GTK_WIDGET_STATE (widget),
+ NULL,
+ widget,
+ NULL,
+ background_area->y,
+ background_area->y + background_area->height,
+ background_area->x + background_area->width / 2);
+}
+
+static void
+gitg_diff_line_renderer_get_size_impl (GtkCellRenderer *cell,
+ GtkWidget *widget,
+ GdkRectangle *cell_area,
+ gint *x_offset,
+ gint *y_offset,
+ gint *width,
+ gint *height)
+{
+ GitgDiffLineRenderer *lr = GITG_DIFF_LINE_RENDERER (cell);
+
+ /* Get size of this rendering */
+ PangoLayout *layout;
+ gchar str[16];
+ gint pixel_width;
+ gint pixel_height;
+ guint xpad;
+ guint ypad;
+
+ g_snprintf(str, sizeof(str), "%d", MAX(MAX(99, lr->priv->line_old), lr->priv->line_new));
+ layout = gtk_widget_create_pango_layout (widget, str);
+ pango_layout_get_pixel_size(layout, &pixel_width, &pixel_height);
+
+ g_object_get (cell, "xpad", &xpad, "ypad", &ypad, NULL);
+
+ pixel_width = pixel_width * 2 + xpad * 4 + 3;
+ pixel_height += ypad * 2;
+
+ if (width)
+ {
+ *width = pixel_width;
+ }
+
+ if (height)
+ {
+ *height = pixel_height;
+ }
+
+ if (x_offset)
+ {
+ *x_offset = 0;
+ }
+
+ if (y_offset)
+ {
+ *y_offset = 0;
+ }
+
+ g_object_unref (G_OBJECT (layout));
+}
+
+static void
+gitg_diff_line_renderer_class_init (GitgDiffLineRendererClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkCellRendererClass *cell_renderer_class = GTK_CELL_RENDERER_CLASS (klass);
+
+ cell_renderer_class->render = gitg_diff_line_renderer_render_impl;
+ cell_renderer_class->get_size = gitg_diff_line_renderer_get_size_impl;
+
+ object_class->finalize = gitg_diff_line_renderer_finalize;
+ object_class->set_property = gitg_diff_line_renderer_set_property;
+ object_class->get_property = gitg_diff_line_renderer_get_property;
+
+ g_object_class_install_property (object_class,
+ PROP_LINE_OLD,
+ g_param_spec_int ("line-old",
+ "Line Old",
+ "Line Old",
+ -1,
+ G_MAXINT,
+ -1,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (object_class,
+ PROP_LINE_NEW,
+ g_param_spec_int ("line-new",
+ "Line New",
+ "Line New",
+ -1,
+ G_MAXINT,
+ -1,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ g_type_class_add_private (object_class, sizeof(GitgDiffLineRendererPrivate));
+}
+
+static void
+gitg_diff_line_renderer_init (GitgDiffLineRenderer *self)
+{
+ self->priv = GITG_DIFF_LINE_RENDERER_GET_PRIVATE (self);
+}
+
+GitgDiffLineRenderer *
+gitg_diff_line_renderer_new ()
+{
+ return g_object_new (GITG_TYPE_DIFF_LINE_RENDERER, NULL);
+}
diff --git a/gitg/gitg-diff-line-renderer.h b/gitg/gitg-diff-line-renderer.h
new file mode 100644
index 0000000..006cb25
--- /dev/null
+++ b/gitg/gitg-diff-line-renderer.h
@@ -0,0 +1,36 @@
+#ifndef __GITG_DIFF_LINE_RENDERER_H__
+#define __GITG_DIFF_LINE_RENDERER_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GITG_TYPE_DIFF_LINE_RENDERER (gitg_diff_line_renderer_get_type ())
+#define GITG_DIFF_LINE_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_DIFF_LINE_RENDERER, GitgDiffLineRenderer))
+#define GITG_DIFF_LINE_RENDERER_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_DIFF_LINE_RENDERER, GitgDiffLineRenderer const))
+#define GITG_DIFF_LINE_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_DIFF_LINE_RENDERER, GitgDiffLineRendererClass))
+#define GITG_IS_DIFF_LINE_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_DIFF_LINE_RENDERER))
+#define GITG_IS_DIFF_LINE_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_DIFF_LINE_RENDERER))
+#define GITG_DIFF_LINE_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_DIFF_LINE_RENDERER, GitgDiffLineRendererClass))
+
+typedef struct _GitgDiffLineRenderer GitgDiffLineRenderer;
+typedef struct _GitgDiffLineRendererClass GitgDiffLineRendererClass;
+typedef struct _GitgDiffLineRendererPrivate GitgDiffLineRendererPrivate;
+
+struct _GitgDiffLineRenderer {
+ GtkCellRenderer parent;
+
+ GitgDiffLineRendererPrivate *priv;
+};
+
+struct _GitgDiffLineRendererClass {
+ GtkCellRendererClass parent_class;
+};
+
+GType gitg_diff_line_renderer_get_type (void) G_GNUC_CONST;
+GitgDiffLineRenderer *gitg_diff_line_renderer_new (void);
+
+
+G_END_DECLS
+
+#endif /* __GITG_DIFF_LINE_RENDERER_H__ */
diff --git a/gitg/gitg-diff-view.c b/gitg/gitg-diff-view.c
index e0befdd..b02410c 100644
--- a/gitg/gitg-diff-view.c
+++ b/gitg/gitg-diff-view.c
@@ -22,6 +22,8 @@
#include "gitg-diff-view.h"
#include "gitg-types.h"
+#include "gitg-diff-line-renderer.h"
+
#include <string.h>
#include <stdlib.h>
@@ -40,6 +42,17 @@
static void on_buffer_insert_text(GtkTextBuffer *buffer, GtkTextIter *iter, gchar const *text, gint len, GitgDiffView *view);
static void on_buffer_delete_range(GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, GitgDiffView *view);
+static void
+line_renderer_size_func (GtkSourceGutter *gutter,
+ GtkCellRenderer *cell,
+ GitgDiffView *view);
+static void
+line_renderer_data_func (GtkSourceGutter *gutter,
+ GtkCellRenderer *cell,
+ gint line_number,
+ gboolean current_line,
+ GitgDiffView *view);
+
static gboolean on_idle_scan(GitgDiffView *view);
/* Signals */
@@ -98,6 +111,12 @@ struct _GitgDiffViewPrivate
gboolean diff_enabled;
GtkTextBuffer *current_buffer;
GtkTextTag *invisible_tag;
+
+ GitgDiffLineRenderer *line_renderer;
+
+ Region *lines_current_region;
+ gint lines_previous_line;
+ guint lines_counters[2];
};
G_DEFINE_TYPE(GitgDiffView, gitg_diff_view, GTK_TYPE_SOURCE_VIEW)
@@ -151,14 +170,14 @@ regions_free(GitgDiffView *view, gboolean remove_signals)
}
static void
-gitg_diff_view_finalize(GObject *object)
+gitg_diff_view_finalize (GObject *object)
{
- GitgDiffView *view = GITG_DIFF_VIEW(object);
+ GitgDiffView *view = GITG_DIFF_VIEW (object);
- regions_free(view, TRUE);
- g_sequence_free(view->priv->regions_index);
+ regions_free (view, TRUE);
+ g_sequence_free (view->priv->regions_index);
- G_OBJECT_CLASS(gitg_diff_view_parent_class)->finalize(object);
+ G_OBJECT_CLASS (gitg_diff_view_parent_class)->finalize (object);
}
static void
@@ -201,6 +220,12 @@ gitg_diff_view_get_property(GObject *object, guint prop_id, GValue *value, GPara
}
static void
+gitg_diff_view_constructed (GObject *object)
+{
+ g_object_set (object, "show-line-numbers", FALSE, NULL);
+}
+
+static void
gitg_diff_view_class_init(GitgDiffViewClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS(klass);
@@ -210,6 +235,8 @@ gitg_diff_view_class_init(GitgDiffViewClass *klass)
object_class->set_property = gitg_diff_view_set_property;
object_class->get_property = gitg_diff_view_get_property;
+ object_class->constructed = gitg_diff_view_constructed;
+
widget_class->expose_event = gitg_diff_view_expose;
diff_view_signals[HEADER_ADDED] =
@@ -259,88 +286,42 @@ on_buffer_set(GitgDiffView *self, GParamSpec *spec, gpointer userdata)
}
static void
-gitg_diff_view_init(GitgDiffView *self)
-{
- self->priv = GITG_DIFF_VIEW_GET_PRIVATE(self);
-
- self->priv->regions_index = g_sequence_new(NULL);
-
- g_signal_connect(self, "notify::buffer", G_CALLBACK(on_buffer_set), NULL);
-}
-
-GitgDiffView*
-gitg_diff_view_new()
-{
- return g_object_new(GITG_TYPE_DIFF_VIEW, NULL);
-}
-
-/* This function is taken from gtk+/tests/testtext.c */
-static void
-get_lines (GtkTextView *text_view, gint first_y, gint last_y, GArray *buffer_coords, GArray *line_heights, GArray *numbers, gint *countp)
+gitg_diff_view_init (GitgDiffView *self)
{
- GtkTextIter iter;
- gint count;
- gint size;
- gint last_line_num = -1;
-
- g_array_set_size(buffer_coords, 0);
- g_array_set_size(numbers, 0);
-
- if (line_heights != NULL)
- g_array_set_size(line_heights, 0);
-
- /* Get iter at first y */
- gtk_text_view_get_line_at_y(text_view, &iter, first_y, NULL);
+ GtkSourceGutter *gutter;
- /* For each iter, get its location and add it to the arrays.
- * Stop when we pass last_y */
- count = 0;
- size = 0;
+ self->priv = GITG_DIFF_VIEW_GET_PRIVATE (self);
- while (!gtk_text_iter_is_end(&iter))
- {
- gint y, height;
+ self->priv->regions_index = g_sequence_new (NULL);
+ self->priv->line_renderer = gitg_diff_line_renderer_new ();
- gtk_text_view_get_line_yrange(text_view, &iter, &y, &height);
+ g_object_set (self->priv->line_renderer, "xpad", 2, NULL);
- g_array_append_val(buffer_coords, y);
+ gutter = gtk_source_view_get_gutter (GTK_SOURCE_VIEW (self), GTK_TEXT_WINDOW_LEFT);
- if (line_heights)
- g_array_append_val(line_heights, height);
+ gtk_source_gutter_insert (gutter,
+ GTK_CELL_RENDERER (self->priv->line_renderer),
+ 0);
- last_line_num = gtk_text_iter_get_line(&iter);
- g_array_append_val(numbers, last_line_num);
+ gtk_source_gutter_set_cell_data_func (gutter,
+ GTK_CELL_RENDERER (self->priv->line_renderer),
+ (GtkSourceGutterDataFunc)line_renderer_data_func,
+ self,
+ NULL);
- ++count;
+ gtk_source_gutter_set_cell_size_func (gutter,
+ GTK_CELL_RENDERER (self->priv->line_renderer),
+ (GtkSourceGutterSizeFunc)line_renderer_size_func,
+ self,
+ NULL);
- if ((y + height) >= last_y)
- break;
-
- gtk_text_iter_forward_line(&iter);
- }
-
- if (gtk_text_iter_is_end(&iter))
- {
- gint y, height;
- gint line_num;
-
- gtk_text_view_get_line_yrange(text_view, &iter, &y, &height);
-
- line_num = gtk_text_iter_get_line(&iter);
-
- if (line_num != last_line_num)
- {
- g_array_append_val(buffer_coords, y);
-
- if (line_heights)
- g_array_append_val(line_heights, height);
-
- g_array_append_val(numbers, line_num);
- ++count;
- }
- }
+ g_signal_connect (self, "notify::buffer", G_CALLBACK (on_buffer_set), NULL);
+}
- *countp = count;
+GitgDiffView *
+gitg_diff_view_new ()
+{
+ return g_object_new (GITG_TYPE_DIFF_VIEW, NULL);
}
static gint
@@ -353,13 +334,17 @@ index_compare(gconstpointer a, gconstpointer b, gpointer userdata)
}
static void
-ensure_max_line(GitgDiffView *view, Hunk *hunk)
+ensure_max_line (GitgDiffView *view, Hunk *hunk)
{
guint num = hunk->region.next ? hunk->region.next->line - hunk->region.line : 0;
- guint m = MAX(hunk->new + num, hunk->old + num);
+ guint m = MAX (hunk->new + num, hunk->old + num);
if (m > view->priv->max_line_count)
+ {
view->priv->max_line_count = m;
+
+ gtk_source_gutter_queue_draw (gtk_source_view_get_gutter (GTK_SOURCE_VIEW (view), GTK_TEXT_WINDOW_LEFT));
+ }
}
static void
@@ -371,7 +356,9 @@ add_region(GitgDiffView *view, Region *region)
region->prev = view->priv->last_region;
if (view->priv->last_region->type == GITG_DIFF_ITER_TYPE_HUNK)
+ {
ensure_max_line(view, (Hunk *)view->priv->last_region);
+ }
}
else
{
@@ -387,9 +374,13 @@ add_region(GitgDiffView *view, Region *region)
iter.userdata2 = region;
if (region->type == GITG_DIFF_ITER_TYPE_HEADER)
+ {
g_signal_emit(view, diff_view_signals[HEADER_ADDED], 0, &iter);
+ }
else if (region->type == GITG_DIFF_ITER_TYPE_HUNK)
+ {
g_signal_emit(view, diff_view_signals[HUNK_ADDED], 0, &iter);
+ }
}
static void
@@ -407,7 +398,9 @@ parse_hunk_info(Hunk *hunk, GtkTextIter *iter)
gchar *new = g_utf8_strchr(text, -1, '+');
if (!old || !new)
+ {
return;
+ }
hunk->old = atoi(old + 1);
hunk->new = atoi(new + 1);
@@ -429,12 +422,16 @@ ensure_scan(GitgDiffView *view, guint last_line)
GtkTextIter end = iter;
if (!gtk_text_iter_forward_line(&iter))
+ {
break;
+ }
++view->priv->last_scan_line;
if (!gtk_text_iter_forward_chars(&end, 3))
+ {
continue;
+ }
gchar *text = gtk_text_iter_get_text(&start, &end);
@@ -457,7 +454,9 @@ ensure_scan(GitgDiffView *view, guint last_line)
g_free(text);
if (!gtk_text_iter_forward_chars(&end, 7))
+ {
continue;
+ }
text = gtk_text_iter_get_text(&start, &end);
@@ -479,7 +478,9 @@ ensure_scan(GitgDiffView *view, guint last_line)
}
if (view->priv->last_region && view->priv->last_region->type == GITG_DIFF_ITER_TYPE_HUNK)
+ {
ensure_max_line(view, (Hunk *)view->priv->last_region);
+ }
}
static Region *
@@ -491,14 +492,18 @@ find_current_region(GitgDiffView *view, guint line)
iter = g_sequence_search(view->priv->regions_index, &tmp, index_compare, NULL);
if (!iter || g_sequence_iter_is_begin(iter))
+ {
return NULL;
+ }
if (!g_sequence_iter_is_end(iter))
{
Region *ret = (Region *)g_sequence_get(iter);
if (ret->line == line)
+ {
return ret->visible ? ret : NULL;
+ }
}
Region *ret = (Region *)g_sequence_get(g_sequence_iter_prev(iter));
@@ -513,8 +518,11 @@ line_has_prefix(GitgDiffView *view, guint line, gchar const *prefix)
gtk_text_buffer_get_iter_at_line(view->priv->current_buffer, &iter, line);
GtkTextIter end = iter;
+
if (!gtk_text_iter_forward_chars(&end, g_utf8_strlen(prefix, -1)))
+ {
return FALSE;
+ }
gchar *text = gtk_text_iter_get_text(&iter, &end);
gboolean ret = g_str_has_prefix(text, prefix);
@@ -553,146 +561,88 @@ get_initial_counters(GitgDiffView *view, Region *region, guint line, guint count
}
static void
-paint_line_numbers(GitgDiffView *view, GdkEventExpose *event)
+line_renderer_size_func (GtkSourceGutter *gutter,
+ GtkCellRenderer *cell,
+ GitgDiffView *view)
{
- GtkTextView *text_view;
- GdkWindow *win;
- PangoLayout *layout;
- GArray *numbers;
- GArray *pixels;
- gchar str_old[16]; /* we don't expect more than ten million lines ;-) */
- gchar str_new[16];
- gint y1, y2;
- gint count;
- gint margin_width;
- gint text_width;
- gint i;
- GtkTextIter cur;
-
- text_view = GTK_TEXT_VIEW(view);
- win = gtk_text_view_get_window(text_view, GTK_TEXT_WINDOW_LEFT);
-
- y1 = event->area.y;
- y2 = y1 + event->area.height;
-
- /* get the extents of the line printing */
- gtk_text_view_window_to_buffer_coords(text_view, GTK_TEXT_WINDOW_LEFT, 0, y1, NULL, &y1);
- gtk_text_view_window_to_buffer_coords(text_view, GTK_TEXT_WINDOW_LEFT, 0, y2, NULL, &y2);
-
- numbers = g_array_new(FALSE, FALSE, sizeof(gint));
- pixels = g_array_new(FALSE, FALSE, sizeof(gint));
-
- /* get the line numbers and y coordinates. */
- get_lines(text_view, y1, y2, pixels, NULL, numbers, &count);
-
- /* A zero-lined document should display a "1"; we don't need to worry about
- scrolling effects of the text widget in this special case */
-
- if (count == 0)
- {
- gint y = 0;
- gint n = 0;
- count = 1;
- g_array_append_val(pixels, y);
- g_array_append_val(numbers, n);
- }
-
- /* Ensure scanned until last needed line */
- guint last = g_array_index(numbers, gint, count - 1);
- ensure_scan(view, last);
-
- /* set size */
- g_snprintf(str_old, sizeof(str_old), "%d", MAX(99, view->priv->max_line_count));
- layout = gtk_widget_create_pango_layout(GTK_WIDGET(view), str_old);
-
- pango_layout_get_pixel_size(layout, &text_width, NULL);
-
- /* determine the width of the left margin. */
- margin_width = text_width * 2 + 9;
-
- guint extra_width = 0;
-
- if (gtk_source_view_get_show_line_marks(GTK_SOURCE_VIEW(view)))
- extra_width = 20;
-
- pango_layout_set_width(layout, text_width);
- pango_layout_set_alignment(layout, PANGO_ALIGN_RIGHT);
+ g_object_set (cell,
+ "line_old", view->priv->max_line_count,
+ "line_new", view->priv->max_line_count,
+ NULL);
+}
- gtk_text_view_set_border_window_size(GTK_TEXT_VIEW(text_view), GTK_TEXT_WINDOW_LEFT, margin_width + extra_width);
- gtk_text_buffer_get_iter_at_mark(text_view->buffer, &cur, gtk_text_buffer_get_insert(text_view->buffer));
+static void
+line_renderer_data_func (GtkSourceGutter *gutter,
+ GtkCellRenderer *cell,
+ gint line_number,
+ gboolean current_line,
+ GitgDiffView *view)
+{
+ gint line_old = -1;
+ gint line_new = -1;
+ Region **current = &view->priv->lines_current_region;
- Region *current = NULL;
- guint counters[2];
+ ensure_scan (view, line_number);
- for (i = 0; i < count; ++i)
+ if (!*current)
{
- gint pos;
- gint line_to_paint;
-
- gtk_text_view_buffer_to_window_coords(text_view, GTK_TEXT_WINDOW_LEFT, 0, g_array_index(pixels, gint, i), NULL, &pos);
- line_to_paint = g_array_index(numbers, gint, i);
+ *current = find_current_region (view, line_number);
- if (!current)
+ if (*current)
{
- current = find_current_region(view, line_to_paint);
-
- if (current)
- get_initial_counters(view, current, line_to_paint, counters);
+ get_initial_counters (view,
+ *current,
+ line_number,
+ view->priv->lines_counters);
}
+ }
- *str_old = '\0';
- *str_new = '\0';
+ if (*current &&
+ (*current)->type == GITG_DIFF_ITER_TYPE_HUNK &&
+ line_number != (*current)->line)
+ {
+ Hunk *hunk = (Hunk *)*current;
- if (current && current->type == GITG_DIFF_ITER_TYPE_HUNK && line_to_paint != current->line)
+ if (draw_old (view, line_number))
{
- Hunk *hunk = (Hunk *)current;
-
- if (draw_old(view, line_to_paint))
- g_snprintf(str_old, sizeof(str_old), "%d", hunk->old + counters[0]++);
-
- if (draw_new(view, line_to_paint))
- g_snprintf(str_new, sizeof(str_new), "%d", hunk->new + counters[1]++);
+ line_old = hunk->old + view->priv->lines_counters[0]++;
}
- pango_layout_set_markup(layout, str_old, -1);
- gtk_paint_layout(GTK_WIDGET(view)->style, win, GTK_WIDGET_STATE(view), FALSE, NULL, GTK_WIDGET(view), NULL, margin_width - 7 - text_width, pos, layout);
-
- pango_layout_set_markup(layout, str_new, -1);
- gtk_paint_layout(GTK_WIDGET(view)->style, win, GTK_WIDGET_STATE(view), FALSE, NULL, GTK_WIDGET(view), NULL, margin_width - 2, pos, layout);
-
- if (current && current->next && line_to_paint == current->next->line - 1)
+ if (draw_new (view, line_number))
{
- counters[0] = counters[1] = 0;
- current = current->next->visible ? current->next : NULL;
+ line_new = hunk->new + view->priv->lines_counters[1]++;
}
}
- gtk_paint_vline(GTK_WIDGET(view)->style, win, GTK_WIDGET_STATE(view), NULL, GTK_WIDGET(view), NULL, event->area.y, event->area.y + event->area.height, 4 + text_width);
+ g_object_set (cell, "line_old", line_old, "line_new", line_new, NULL);
- g_array_free(pixels, TRUE);
- g_array_free(numbers, TRUE);
-
- g_object_unref(G_OBJECT(layout));
+ if (*current && (*current)->next && line_number == (*current)->next->line - 1)
+ {
+ view->priv->lines_counters[0] = view->priv->lines_counters[1] = 0;
+ *current = (*current)->next->visible ? (*current)->next : NULL;
+ }
}
-static gint
-gitg_diff_view_expose(GtkWidget *widget, GdkEventExpose *event)
+static gint
+gitg_diff_view_expose (GtkWidget *widget,
+ GdkEventExpose *event)
{
- gboolean ret = FALSE;
- GtkTextView *text_view = GTK_TEXT_VIEW(widget);
- GitgDiffView *view = GITG_DIFF_VIEW(widget);
+ GitgDiffView *view = GITG_DIFF_VIEW (widget);
+
+ /* Prepare for new round of expose on the line renderer */
+ view->priv->lines_current_region = NULL;
+ view->priv->lines_previous_line = -1;
+ view->priv->lines_counters[0] = 0;
+ view->priv->lines_counters[1] = 0;
- if (event->window == gtk_text_view_get_window(text_view, GTK_TEXT_WINDOW_LEFT) &&
- view->priv->diff_enabled && gtk_source_view_get_show_line_numbers(GTK_SOURCE_VIEW(view)))
+ if (GTK_WIDGET_CLASS (gitg_diff_view_parent_class)->expose_event)
{
- paint_line_numbers(GITG_DIFF_VIEW(widget), event);
- ret = TRUE;
+ return GTK_WIDGET_CLASS (gitg_diff_view_parent_class)->expose_event (widget, event);
+ }
+ else
+ {
+ return FALSE;
}
-
- if (GTK_WIDGET_CLASS(gitg_diff_view_parent_class)->expose_event)
- ret = ret || GTK_WIDGET_CLASS(gitg_diff_view_parent_class)->expose_event(widget, event);
-
- return ret;
}
void
diff --git a/gitg/gitg-window.ui b/gitg/gitg-window.ui
index 04c02a1..0d7aa88 100644
--- a/gitg/gitg-window.ui
+++ b/gitg/gitg-window.ui
@@ -374,7 +374,7 @@
<object class="GitgDiffView" id="revision_diff">
<property name="editable">False</property>
<property name="cursor_visible">False</property>
- <property name="show_line_numbers">True</property>
+ <property name="show_line_numbers">False</property>
<property name="tab_width">4</property>
</object>
</child>
@@ -574,7 +574,7 @@
<property name="left_margin">2</property>
<property name="right_margin">2</property>
<property name="cursor_visible">False</property>
- <property name="show_line_numbers">True</property>
+ <property name="show_line_numbers">False</property>
<property name="tab_width">4</property>
</object>
</child>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]