[gnome-builder/wip/gtk4-port: 85/1774] libide/sourceview: untested port of gutter renderer
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/gtk4-port: 85/1774] libide/sourceview: untested port of gutter renderer
- Date: Mon, 11 Jul 2022 22:30:56 +0000 (UTC)
commit dcff62ee0f7a9a482057bf60ef2b220bd835982c
Author: Christian Hergert <chergert redhat com>
Date: Sat Mar 26 23:42:38 2022 -0700
libide/sourceview: untested port of gutter renderer
This is a minimal port of the simple gutter renderer to GTK 4 and
GtkSourceView 5. It has not been tested (like most of the port so far).
.../sourceview/ide-line-change-gutter-renderer.c | 259 +++++----------------
.../sourceview/ide-line-change-gutter-renderer.h | 3 +-
2 files changed, 65 insertions(+), 197 deletions(-)
---
diff --git a/src/libide/sourceview/ide-line-change-gutter-renderer.c
b/src/libide/sourceview/ide-line-change-gutter-renderer.c
index 839bd0382..df25f55bc 100644
--- a/src/libide/sourceview/ide-line-change-gutter-renderer.c
+++ b/src/libide/sourceview/ide-line-change-gutter-renderer.c
@@ -36,15 +36,9 @@ struct _IdeLineChangeGutterRenderer
{
GtkSourceGutterRenderer parent_instance;
- GtkTextView *text_view;
- gulong text_view_notify_buffer;
-
- GtkTextBuffer *buffer;
+ GtkSourceBuffer *buffer;
gulong buffer_notify_style_scheme;
- GArray *lines;
- guint begin_line;
-
struct {
GdkRGBA add;
GdkRGBA remove;
@@ -79,6 +73,10 @@ enum {
BACKGROUND,
};
+static GQuark added_quark;
+static GQuark changed_quark;
+static GQuark deleted_quark;
+
G_DEFINE_FINAL_TYPE (IdeLineChangeGutterRenderer, ide_line_change_gutter_renderer,
GTK_SOURCE_TYPE_GUTTER_RENDERER)
static gboolean
@@ -139,28 +137,15 @@ disconnect_buffer (IdeLineChangeGutterRenderer *self)
}
}
-static void
-disconnect_view (IdeLineChangeGutterRenderer *self)
-{
- disconnect_buffer (self);
-
- if (self->text_view && self->text_view_notify_buffer)
- {
- g_signal_handler_disconnect (self->text_view, self->text_view_notify_buffer);
- self->text_view_notify_buffer = 0;
- g_clear_weak_pointer (&self->text_view);
- }
-}
-
static void
connect_style_scheme (IdeLineChangeGutterRenderer *self)
{
GtkSourceStyleScheme *scheme;
GtkTextBuffer *buffer;
- GtkTextView *view;
+ GtkSourceView *view;
if (!(view = gtk_source_gutter_renderer_get_view (GTK_SOURCE_GUTTER_RENDERER (self))) ||
- !(buffer = gtk_text_view_get_buffer (view)) ||
+ !(buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))) ||
!GTK_SOURCE_IS_BUFFER (buffer))
return;
@@ -188,9 +173,7 @@ notify_style_scheme_cb (GtkTextBuffer *buffer,
static void
connect_buffer (IdeLineChangeGutterRenderer *self)
{
- GtkTextBuffer *buffer;
-
- buffer = gtk_text_view_get_buffer (self->text_view);
+ GtkSourceBuffer *buffer = gtk_source_gutter_renderer_get_buffer (GTK_SOURCE_GUTTER_RENDERER (self));
if (buffer)
{
@@ -204,37 +187,11 @@ connect_buffer (IdeLineChangeGutterRenderer *self)
}
static void
-notify_buffer_cb (GtkTextView *text_view,
- GParamSpec *pspec,
- IdeLineChangeGutterRenderer *self)
-{
- disconnect_buffer (self);
- connect_buffer (self);
-}
-
-static void
-connect_view (IdeLineChangeGutterRenderer *self)
-{
- GtkTextView *view;
-
- view = gtk_source_gutter_renderer_get_view (GTK_SOURCE_GUTTER_RENDERER (self));
-
- if (view)
- {
- g_set_weak_pointer (&self->text_view, view);
- self->text_view_notify_buffer = g_signal_connect (self->text_view,
- "notify::buffer",
- G_CALLBACK (notify_buffer_cb),
- self);
- connect_buffer (self);
- }
-}
-
-static void
-ide_line_change_gutter_renderer_notify_view (IdeLineChangeGutterRenderer *self)
+ide_line_change_gutter_renderer_change_buffer (GtkSourceGutterRenderer *renderer,
+ GtkSourceBuffer *old_buffer)
{
- disconnect_view (self);
- connect_view (self);
+ disconnect_buffer (IDE_LINE_CHANGE_GUTTER_RENDERER (renderer));
+ connect_buffer (IDE_LINE_CHANGE_GUTTER_RENDERER (renderer));
}
static void
@@ -242,171 +199,80 @@ populate_changes_cb (guint line,
IdeBufferLineChange change,
gpointer user_data)
{
- LineInfo *info;
- struct {
- GArray *lines;
- guint begin_line;
- guint end_line;
- } *state = user_data;
- guint pos;
+ GtkSourceGutterLines *lines = user_data;
- g_assert (line >= state->begin_line);
- g_assert (line <= state->end_line);
+ if (change & IDE_BUFFER_LINE_CHANGE_ADDED)
+ gtk_source_gutter_lines_add_qclass (lines, line, added_quark);
- pos = line - state->begin_line;
+ if (change & IDE_BUFFER_LINE_CHANGE_CHANGED)
+ gtk_source_gutter_lines_add_qclass (lines, line, changed_quark);
- info = &g_array_index (state->lines, LineInfo, pos);
- info->is_add = !!(change & IDE_BUFFER_LINE_CHANGE_ADDED);
- info->is_change = !!(change & IDE_BUFFER_LINE_CHANGE_CHANGED);
- info->is_delete = !!(change & IDE_BUFFER_LINE_CHANGE_DELETED);
-
- if (pos > 0)
- {
- LineInfo *last = &g_array_index (state->lines, LineInfo, pos - 1);
-
- info->is_prev_delete = last->is_delete;
- last->is_next_delete = info->is_delete;
- }
+ if (change & IDE_BUFFER_LINE_CHANGE_DELETED)
+ gtk_source_gutter_lines_add_qclass (lines, line, deleted_quark);
}
static void
ide_line_change_gutter_renderer_begin (GtkSourceGutterRenderer *renderer,
- cairo_t *cr,
- GdkRectangle *bg_area,
- GdkRectangle *cell_area,
- GtkTextIter *begin,
- GtkTextIter *end)
+ GtkSourceGutterLines *lines)
{
IdeLineChangeGutterRenderer *self = (IdeLineChangeGutterRenderer *)renderer;
IdeBufferChangeMonitor *monitor;
- GtkTextBuffer *buffer;
- GtkTextView *view;
- struct {
- GArray *lines;
- guint begin_line;
- guint end_line;
- } state;
+ int first;
+ int last;
g_assert (IDE_IS_LINE_CHANGE_GUTTER_RENDERER (self));
- g_assert (cr != NULL);
- g_assert (bg_area != NULL);
- g_assert (cell_area != NULL);
- g_assert (begin != NULL);
- g_assert (end != NULL);
-
- if (!(view = gtk_source_gutter_renderer_get_view (renderer)) ||
- !(buffer = gtk_text_view_get_buffer (view)) ||
- !IDE_IS_BUFFER (buffer) ||
- !(monitor = ide_buffer_get_change_monitor (IDE_BUFFER (buffer))))
- return;
-
- self->begin_line = state.begin_line = gtk_text_iter_get_line (begin);
- state.end_line = gtk_text_iter_get_line (end);
- state.lines = g_array_new (FALSE, TRUE, sizeof (LineInfo));
- g_array_set_size (state.lines, state.end_line - state.begin_line + 1);
-
- ide_buffer_change_monitor_foreach_change (monitor,
- state.begin_line,
- state.end_line,
- populate_changes_cb,
- &state);
+ g_assert (lines != NULL);
- g_clear_pointer (&self->lines, g_array_unref);
- self->lines = g_steal_pointer (&state.lines);
-}
-
-static void
-draw_line_change (IdeLineChangeGutterRenderer *self,
- cairo_t *cr,
- GdkRectangle *area,
- LineInfo *info,
- GtkSourceGutterRendererState state)
-{
- g_assert (IDE_IS_LINE_CHANGE_GUTTER_RENDERER (self));
- g_assert (cr != NULL);
- g_assert (area != NULL);
-
- /*
- * Draw a simple line with the appropriate color from the style scheme
- * based on the type of change we have.
- */
-
- if (info->is_add || info->is_change)
- {
- gdk_cairo_rectangle (cr, area);
-
- if (info->is_add)
- gdk_cairo_set_source_rgba (cr, &self->changes.add);
- else
- gdk_cairo_set_source_rgba (cr, &self->changes.change);
-
- cairo_fill (cr);
- }
+ if (!IDE_IS_BUFFER (self->buffer) ||
+ !(monitor = ide_buffer_get_change_monitor (IDE_BUFFER (self->buffer))))
+ return;
- if (info->is_next_delete && !info->is_delete)
- {
- cairo_rectangle (cr,
- area->x,
- area->y + area->width / 2.0,
- area->width,
- area->height / 2.0);
- gdk_cairo_set_source_rgba (cr, &self->changes.remove);
- cairo_fill (cr);
- }
+ first = MAX (0, (int)gtk_source_gutter_lines_get_first (lines) - 1);
+ last = gtk_source_gutter_lines_get_last (lines) + 1;
- if (info->is_delete && !info->is_prev_delete)
- {
- cairo_rectangle (cr,
- area->x,
- area->y,
- area->width,
- area->height / 2.0);
- gdk_cairo_set_source_rgba (cr, &self->changes.remove);
- cairo_fill (cr);
- }
+ ide_buffer_change_monitor_foreach_change (monitor, first, last, populate_changes_cb, lines);
}
static void
-ide_line_change_gutter_renderer_draw (GtkSourceGutterRenderer *renderer,
- cairo_t *cr,
- GdkRectangle *bg_area,
- GdkRectangle *cell_area,
- GtkTextIter *begin,
- GtkTextIter *end,
- GtkSourceGutterRendererState state)
+ide_line_change_gutter_renderer_snapshot_line (GtkSourceGutterRenderer *renderer,
+ GtkSnapshot *snapshot,
+ GtkSourceGutterLines *lines,
+ guint line)
{
IdeLineChangeGutterRenderer *self = (IdeLineChangeGutterRenderer *)renderer;
- guint line;
-
- g_assert (IDE_IS_LINE_CHANGE_GUTTER_RENDERER (self));
- g_assert (cr != NULL);
- g_assert (bg_area != NULL);
- g_assert (cell_area != NULL);
- g_assert (begin != NULL);
- g_assert (end != NULL);
-
- if (self->lines == NULL)
+ gboolean is_add = gtk_source_gutter_lines_has_qclass (lines, line, added_quark);
+ gboolean is_change = gtk_source_gutter_lines_has_qclass (lines, line, changed_quark);
+ gboolean is_delete = gtk_source_gutter_lines_has_qclass (lines, line, deleted_quark);
+ guint line_y;
+ guint line_height;
+ int width;
+
+ if (!is_add && !is_change && !is_delete)
return;
- line = gtk_text_iter_get_line (begin);
+ gtk_source_gutter_lines_get_yrange (lines, line, &line_y, &line_height);
+ width = gtk_widget_get_width (GTK_WIDGET (renderer));
- if ((line - self->begin_line) < self->lines->len)
- {
- LineInfo *info = &g_array_index (self->lines, LineInfo, line - self->begin_line);
+ if (is_add || is_change)
+ gtk_snapshot_append_color (snapshot,
+ is_add ? &self->changes.add : &self->changes.change,
+ &GRAPHENE_RECT_INIT (0, line_y, width, line_height));
- if (IS_LINE_CHANGE (info))
- draw_line_change (self, cr, cell_area, info, state);
- }
+ if (!is_delete && gtk_source_gutter_lines_has_qclass (lines, line+1, deleted_quark))
+ gtk_snapshot_append_color (snapshot,
+ &self->changes.remove,
+ &GRAPHENE_RECT_INIT (0, line_y+line_height/2., width, line_height/2.));
+
+ if (is_delete && line > 0 && gtk_source_gutter_lines_has_qclass (lines, line-1, deleted_quark))
+ gtk_snapshot_append_color (snapshot,
+ &self->changes.remove,
+ &GRAPHENE_RECT_INIT (0, line_y, width, line_height/2.));
}
static void
ide_line_change_gutter_renderer_dispose (GObject *object)
{
- IdeLineChangeGutterRenderer *self = (IdeLineChangeGutterRenderer *)object;
-
- disconnect_view (IDE_LINE_CHANGE_GUTTER_RENDERER (object));
-
- g_clear_pointer (&self->lines, g_array_unref);
+ disconnect_buffer (IDE_LINE_CHANGE_GUTTER_RENDERER (object));
G_OBJECT_CLASS (ide_line_change_gutter_renderer_parent_class)->dispose (object);
}
@@ -420,14 +286,15 @@ ide_line_change_gutter_renderer_class_init (IdeLineChangeGutterRendererClass *kl
object_class->dispose = ide_line_change_gutter_renderer_dispose;
renderer_class->begin = ide_line_change_gutter_renderer_begin;
- renderer_class->draw = ide_line_change_gutter_renderer_draw;
+ renderer_class->snapshot_line = ide_line_change_gutter_renderer_snapshot_line;
+ renderer_class->change_buffer = ide_line_change_gutter_renderer_change_buffer;
+
+ added_quark = g_quark_from_static_string ("added");
+ changed_quark = g_quark_from_static_string ("changed");
+ deleted_quark = g_quark_from_static_string ("deleted");
}
static void
ide_line_change_gutter_renderer_init (IdeLineChangeGutterRenderer *self)
{
- g_signal_connect (self,
- "notify::view",
- G_CALLBACK (ide_line_change_gutter_renderer_notify_view),
- NULL);
}
diff --git a/src/libide/sourceview/ide-line-change-gutter-renderer.h
b/src/libide/sourceview/ide-line-change-gutter-renderer.h
index 244e6bb89..1d86ddf63 100644
--- a/src/libide/sourceview/ide-line-change-gutter-renderer.h
+++ b/src/libide/sourceview/ide-line-change-gutter-renderer.h
@@ -21,13 +21,14 @@
#pragma once
#include <gtksourceview/gtksource.h>
+
#include <libide-core.h>
G_BEGIN_DECLS
#define IDE_TYPE_LINE_CHANGE_GUTTER_RENDERER (ide_line_change_gutter_renderer_get_type())
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (IdeLineChangeGutterRenderer, ide_line_change_gutter_renderer, IDE,
LINE_CHANGE_GUTTER_RENDERER, GtkSourceGutterRenderer)
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]