[gnome-builder/wip/chergert/gutter: 5/5] wip
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/chergert/gutter: 5/5] wip
- Date: Sun, 17 Sep 2017 18:58:28 +0000 (UTC)
commit 56513cecefc30ce04ec7eeaa17889cd6d84db213
Author: Christian Hergert <chergert redhat com>
Date: Sun Sep 17 03:39:02 2017 -0700
wip
libide/debugger/ide-debugger-editor-view-addin.c | 135 ----
libide/debugger/ide-debugger-plugin.c | 4 -
libide/meson.build | 4 +-
libide/sourceview/ide-omni-gutter-renderer.c | 751 ++++++++++++++++++++
.../ide-omni-gutter-renderer.h} | 15 +-
libide/sourceview/ide-source-view.c | 60 +--
6 files changed, 782 insertions(+), 187 deletions(-)
---
diff --git a/libide/debugger/ide-debugger-plugin.c b/libide/debugger/ide-debugger-plugin.c
index 6ecb5a6..5feb415 100644
--- a/libide/debugger/ide-debugger-plugin.c
+++ b/libide/debugger/ide-debugger-plugin.c
@@ -19,7 +19,6 @@
#include <libpeas/peas.h>
#include "debugger/ide-debugger-editor-addin.h"
-#include "debugger/ide-debugger-editor-view-addin.h"
#include "editor/ide-editor-addin.h"
#include "editor/ide-editor-view-addin.h"
@@ -29,7 +28,4 @@ ide_debugger_register_types (PeasObjectModule *module)
peas_object_module_register_extension_type (module,
IDE_TYPE_EDITOR_ADDIN,
IDE_TYPE_DEBUGGER_EDITOR_ADDIN);
- peas_object_module_register_extension_type (module,
- IDE_TYPE_EDITOR_VIEW_ADDIN,
- IDE_TYPE_DEBUGGER_EDITOR_VIEW_ADDIN);
}
diff --git a/libide/meson.build b/libide/meson.build
index acec572..ff0d242 100644
--- a/libide/meson.build
+++ b/libide/meson.build
@@ -517,8 +517,6 @@ libide_sources = libide_generated_headers + libide_public_sources + [
'debugger/ide-debugger-disassembly-view.h',
'debugger/ide-debugger-editor-addin.c',
'debugger/ide-debugger-editor-addin.h',
- 'debugger/ide-debugger-editor-view-addin.c',
- 'debugger/ide-debugger-editor-view-addin.h',
'debugger/ide-debugger-fallbacks.c',
'debugger/ide-debugger-gutter-renderer.c',
'debugger/ide-debugger-gutter-renderer.h',
@@ -595,6 +593,8 @@ libide_sources = libide_generated_headers + libide_public_sources + [
'snippets/ide-source-snippet-parser.c',
'snippets/ide-source-snippet-parser.h',
'snippets/ide-source-snippet-private.h',
+ 'sourceview/ide-omni-gutter-renderer.c',
+ 'sourceview/ide-omni-gutter-renderer.h',
'sourceview/ide-line-change-gutter-renderer.c',
'sourceview/ide-line-change-gutter-renderer.h',
'sourceview/ide-line-diagnostics-gutter-renderer.c',
diff --git a/libide/sourceview/ide-omni-gutter-renderer.c b/libide/sourceview/ide-omni-gutter-renderer.c
new file mode 100644
index 0000000..1be054f
--- /dev/null
+++ b/libide/sourceview/ide-omni-gutter-renderer.c
@@ -0,0 +1,751 @@
+/* ide-omni-gutter-renderer.c
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "ide-omni-gutter-renderer"
+
+#include <dazzle.h>
+#include <string.h>
+
+#include "ide-context.h"
+#include "ide-debug.h"
+
+#include "buffers/ide-buffer.h"
+#include "debugger/ide-debug-manager.h"
+#include "debugger/ide-debugger-breakpoint.h"
+#include "debugger/ide-debugger-breakpoints.h"
+#include "debugger/ide-debugger-private.h"
+#include "files/ide-file.h"
+#include "sourceview/ide-omni-gutter-renderer.h"
+#include "sourceview/ide-source-view.h"
+
+#define DIAGNOSTICS_SIZE 16
+#define ARROW_WIDTH 7
+#define CHANGE_WIDTH 2
+
+struct _IdeOmniGutterRenderer
+{
+ GtkSourceGutterRenderer parent_instance;
+
+ IdeDebuggerBreakpoints *breakpoints;
+
+ GArray *lines;
+ guint begin_line;
+
+ DzlSignalGroup *view_signals;
+ DzlSignalGroup *buffer_signals;
+
+ PangoLayout *layout;
+
+ guint n_chars;
+
+ guint resize_source;
+
+ int number_width;
+};
+
+typedef struct
+{
+ guint is_breakpoint : 1;
+ guint is_countpoint : 1;
+ guint is_watchpoint : 1;
+ guint is_add : 1;
+ guint is_change : 1;
+ guint is_delete : 1;
+ guint is_warning : 1;
+ guint is_note : 1;
+ guint is_error : 1;
+} LineInfo;
+
+G_DEFINE_TYPE (IdeOmniGutterRenderer, ide_omni_gutter_renderer, GTK_SOURCE_TYPE_GUTTER_RENDERER)
+
+static GdkRGBA rgbaAdded;
+static GdkRGBA rgbaChanged;
+static GdkRGBA rgbaRemoved;
+
+static void
+collect_breakpoint_info (IdeDebuggerBreakpoint *breakpoint,
+ gpointer user_data)
+{
+ struct {
+ GArray *lines;
+ guint begin;
+ guint end;
+ } *bkpt_info = user_data;
+ guint line;
+
+ if (!(line = ide_debugger_breakpoint_get_line (breakpoint)))
+ return;
+
+ line--;
+
+ if (line >= bkpt_info->begin && line <= bkpt_info->end)
+ {
+ IdeDebuggerBreakMode mode = ide_debugger_breakpoint_get_mode (breakpoint);
+ LineInfo *info = &g_array_index (bkpt_info->lines, LineInfo, line - bkpt_info->begin);
+
+ info->is_watchpoint = !!(mode & IDE_DEBUGGER_BREAK_WATCHPOINT);
+ info->is_countpoint = !!(mode & IDE_DEBUGGER_BREAK_COUNTPOINT);
+ info->is_breakpoint = !!(mode & IDE_DEBUGGER_BREAK_BREAKPOINT);
+ }
+}
+
+static void
+ide_omni_gutter_renderer_load_breakpoints (IdeOmniGutterRenderer *self,
+ GtkTextIter *begin,
+ GtkTextIter *end,
+ GArray *lines)
+{
+ struct {
+ GArray *lines;
+ guint begin;
+ guint end;
+ } bkpt_info;
+
+ g_assert (IDE_IS_OMNI_GUTTER_RENDERER (self));
+ g_assert (begin != NULL);
+ g_assert (lines != NULL);
+ g_assert (lines->len > 0);
+
+ bkpt_info.lines = lines;
+ bkpt_info.begin = gtk_text_iter_get_line (begin);
+ bkpt_info.end = gtk_text_iter_get_line (end);
+
+ if (self->breakpoints != NULL)
+ ide_debugger_breakpoints_foreach (self->breakpoints,
+ (GFunc)collect_breakpoint_info,
+ &bkpt_info);
+}
+
+static void
+ide_omni_gutter_renderer_load_basic (IdeOmniGutterRenderer *self,
+ GtkTextIter *begin,
+ GArray *lines)
+{
+ IdeBuffer *buffer;
+ guint line;
+
+ g_assert (IDE_IS_OMNI_GUTTER_RENDERER (self));
+ g_assert (begin != NULL);
+ g_assert (lines != NULL);
+ g_assert (lines->len > 0);
+
+ buffer = (IdeBuffer *)gtk_text_iter_get_buffer (begin);
+
+ if (!IDE_IS_BUFFER (buffer))
+ return;
+
+ line = gtk_text_iter_get_line (begin);
+
+ if (buffer != NULL)
+ {
+ for (guint i = 0; i < lines->len; i++)
+ {
+ LineInfo *info = &g_array_index (lines, LineInfo, i);
+ IdeBufferLineFlags flags = ide_buffer_get_line_flags (buffer, line + i);
+
+ info->is_add = !!(flags & IDE_BUFFER_LINE_FLAGS_ADDED);
+ info->is_change = !!(flags & IDE_BUFFER_LINE_FLAGS_CHANGED);
+ info->is_delete = !!(flags & IDE_BUFFER_LINE_FLAGS_DELETED);
+ info->is_warning = !!(flags & IDE_BUFFER_LINE_FLAGS_WARNING);
+ info->is_note = !!(flags & IDE_BUFFER_LINE_FLAGS_NOTE);
+ info->is_error = !!(flags & IDE_BUFFER_LINE_FLAGS_ERROR);
+ }
+ }
+}
+
+static inline gint
+count_num_digits (gint num_lines)
+{
+ if (num_lines < 100)
+ return 2;
+ else if (num_lines < 1000)
+ return 3;
+ else if (num_lines < 10000)
+ return 4;
+ else if (num_lines < 100000)
+ return 5;
+ else if (num_lines < 1000000)
+ return 6;
+ else
+ return 10;
+}
+
+static void
+ide_omni_gutter_renderer_recalculate_size (IdeOmniGutterRenderer *self,
+ IdeSourceView *view)
+{
+ const PangoFontDescription *font_desc;
+ g_autofree gchar *numbers = NULL;
+ GtkTextBuffer *buffer;
+ PangoLayout *layout;
+ GtkTextIter end;
+ guint line;
+ int height;
+
+ g_assert (IDE_IS_OMNI_GUTTER_RENDERER (self));
+ g_assert (IDE_IS_SOURCE_VIEW (view));
+
+ /*
+ * First, we need to get the size of the text for the last line of the
+ * buffer, which will be the longest. We size the font with '9' since it
+ * will generally be the widest of the numbers. Although, we only support
+ * monospace anyway, so it shouldn't matter.
+ */
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+ gtk_text_buffer_get_end_iter (buffer, &end);
+ line = gtk_text_iter_get_line (&end) + 1;
+
+ self->n_chars = count_num_digits (line);
+ numbers = g_strnfill (self->n_chars, '9');
+
+ font_desc = ide_source_view_get_font_desc (view);
+ layout = gtk_widget_create_pango_layout (GTK_WIDGET (view), numbers);
+ pango_layout_set_font_description (layout, font_desc);
+ pango_layout_get_pixel_size (layout, &self->number_width, &height);
+ g_clear_object (&layout);
+
+ /*
+ * The spacing for the different items in the gutter looks like:
+ *
+ * Spacing (2px) Diagnostics (16px) Numbers(N) Changes(2) Spacing(2px)
+ */
+
+ gtk_source_gutter_renderer_set_size (GTK_SOURCE_GUTTER_RENDERER (self),
+ (2 +
+ DIAGNOSTICS_SIZE +
+ 2 +
+ self->number_width +
+ 2 +
+ CHANGE_WIDTH +
+ 2));
+
+ gtk_source_gutter_renderer_queue_draw (GTK_SOURCE_GUTTER_RENDERER (self));
+}
+
+static void
+ide_omni_gutter_renderer_notify_font_desc (IdeOmniGutterRenderer *self,
+ GParamSpec *pspec,
+ IdeSourceView *view)
+{
+ g_assert (IDE_IS_OMNI_GUTTER_RENDERER (self));
+ g_assert (IDE_IS_SOURCE_VIEW (view));
+
+ ide_omni_gutter_renderer_recalculate_size (self, view);
+}
+
+static void
+ide_omni_gutter_renderer_end (GtkSourceGutterRenderer *renderer)
+{
+ IdeOmniGutterRenderer *self = (IdeOmniGutterRenderer *)renderer;
+
+ g_assert (IDE_IS_OMNI_GUTTER_RENDERER (self));
+
+ g_clear_object (&self->layout);
+}
+
+static void
+ide_omni_gutter_renderer_begin (GtkSourceGutterRenderer *renderer,
+ cairo_t *cr,
+ GdkRectangle *bg_area,
+ GdkRectangle *cell_area,
+ GtkTextIter *begin,
+ GtkTextIter *end)
+{
+ IdeOmniGutterRenderer *self = (IdeOmniGutterRenderer *)renderer;
+ IdeSourceView *view;
+ guint end_line;
+
+ g_assert (IDE_IS_OMNI_GUTTER_RENDERER (renderer));
+ g_assert (cr != NULL);
+ g_assert (bg_area != NULL);
+ g_assert (cell_area != NULL);
+ g_assert (begin != NULL);
+ g_assert (end != NULL);
+
+ /*
+ * This function is called before we render any of the lines in
+ * the gutter. To reduce our overhead, we want to collect information
+ * for all of the line numbers upfront.
+ */
+
+ view = IDE_SOURCE_VIEW (gtk_source_gutter_renderer_get_view (renderer));
+
+ self->begin_line = gtk_text_iter_get_line (begin);
+ end_line = gtk_text_iter_get_line (end);
+
+ g_array_set_size (self->lines, end_line - self->begin_line + 1);
+ memset (self->lines->data, 0, self->lines->len * sizeof (LineInfo));
+
+ ide_omni_gutter_renderer_load_basic (self, begin, self->lines);
+ ide_omni_gutter_renderer_load_breakpoints (self, begin, end, self->lines);
+
+ self->layout = gtk_widget_create_pango_layout (GTK_WIDGET (view), "");
+ pango_layout_set_alignment (self->layout, PANGO_ALIGN_RIGHT);
+ pango_layout_set_width (self->layout, (cell_area->width - ARROW_WIDTH - 4) * PANGO_SCALE);
+ pango_layout_set_font_description (self->layout,
+ ide_source_view_get_font_desc (view));
+}
+
+static gboolean
+ide_omni_gutter_renderer_query_activatable (GtkSourceGutterRenderer *renderer,
+ GtkTextIter *begin,
+ GdkRectangle *area,
+ GdkEvent *event)
+{
+ IdeOmniGutterRenderer *self = (IdeOmniGutterRenderer *)renderer;
+
+ g_assert (IDE_IS_OMNI_GUTTER_RENDERER (self));
+ g_assert (begin != NULL);
+ g_assert (area != NULL);
+ g_assert (event != NULL);
+
+ return (self->breakpoints != NULL);
+}
+
+static void
+ide_omni_gutter_renderer_activate (GtkSourceGutterRenderer *renderer,
+ GtkTextIter *iter,
+ GdkRectangle *area,
+ GdkEvent *event)
+{
+ IdeOmniGutterRenderer *self = (IdeOmniGutterRenderer *)renderer;
+ IdeDebuggerBreakpoint *breakpoint;
+ IdeDebuggerBreakMode break_type = IDE_DEBUGGER_BREAK_NONE;
+ g_autofree gchar *path = NULL;
+ IdeDebugManager *debug_manager;
+ GtkTextBuffer *buffer;
+ IdeContext *context;
+ GFile *file;
+ guint line;
+
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_OMNI_GUTTER_RENDERER (self));
+ g_assert (iter != NULL);
+ g_assert (area != NULL);
+ g_assert (event != NULL);
+ g_assert (self->breakpoints != NULL);
+
+ buffer = gtk_text_iter_get_buffer (iter);
+ context = ide_buffer_get_context (IDE_BUFFER (buffer));
+ debug_manager = ide_context_get_debug_manager (context);
+
+ line = gtk_text_iter_get_line (iter) + 1;
+ file = ide_debugger_breakpoints_get_file (self->breakpoints);
+ path = g_file_get_path (file);
+
+ /* TODO: Should we show a Popover here to select the type? */
+ IDE_TRACE_MSG ("Toggle breakpoint on line %u [breakpoints=%p]",
+ line, self->breakpoints);
+
+ breakpoint = ide_debugger_breakpoints_get_line (self->breakpoints, line);
+ if (breakpoint != NULL)
+ break_type = ide_debugger_breakpoint_get_mode (breakpoint);
+
+ switch (break_type)
+ {
+ case IDE_DEBUGGER_BREAK_NONE:
+ {
+ g_autoptr(IdeDebuggerBreakpoint) to_insert = NULL;
+
+ to_insert = ide_debugger_breakpoint_new (NULL);
+
+ ide_debugger_breakpoint_set_line (to_insert, line);
+ ide_debugger_breakpoint_set_file (to_insert, path);
+ ide_debugger_breakpoint_set_mode (to_insert, IDE_DEBUGGER_BREAK_BREAKPOINT);
+ ide_debugger_breakpoint_set_enabled (to_insert, TRUE);
+
+ _ide_debug_manager_add_breakpoint (debug_manager, to_insert);
+ }
+ break;
+
+ case IDE_DEBUGGER_BREAK_BREAKPOINT:
+ case IDE_DEBUGGER_BREAK_COUNTPOINT:
+ case IDE_DEBUGGER_BREAK_WATCHPOINT:
+ if (breakpoint != NULL)
+ _ide_debug_manager_remove_breakpoint (debug_manager, breakpoint);
+ break;
+
+ default:
+ g_return_if_reached ();
+ }
+
+ /*
+ * We will wait for changes to be applied to the #IdeDebuggerBreakpoints
+ * by the #IdeDebugManager. That will cause the gutter to be invalidated
+ * and redrawn.
+ */
+
+ IDE_EXIT;
+}
+
+static void
+draw_breakpoint_bg (IdeOmniGutterRenderer *self,
+ cairo_t *cr,
+ GdkRectangle *bg_area,
+ GtkSourceGutterRendererState state)
+{
+ GdkRectangle area;
+
+ g_assert (GTK_SOURCE_IS_GUTTER_RENDERER (self));
+ g_assert (cr != NULL);
+ g_assert (bg_area != NULL);
+
+ area.x = bg_area->x;
+ area.y = bg_area->y + 1;
+ area.height = bg_area->height - 2;
+ area.width = bg_area->width;
+
+ cairo_move_to (cr, area.x, area.y);
+ cairo_line_to (cr,
+ dzl_cairo_rectangle_x2 (bg_area) - ARROW_WIDTH,
+ area.y);
+ cairo_line_to (cr,
+ dzl_cairo_rectangle_x2 (bg_area),
+ dzl_cairo_rectangle_middle (bg_area));
+ cairo_line_to (cr,
+ dzl_cairo_rectangle_x2 (bg_area) - ARROW_WIDTH,
+ dzl_cairo_rectangle_y2 (bg_area));
+ cairo_line_to (cr, area.x, dzl_cairo_rectangle_y2 (bg_area));
+ cairo_close_path (cr);
+
+ if (state & GTK_SOURCE_GUTTER_RENDERER_STATE_PRELIT)
+ cairo_set_source_rgba (cr, 0x4a / 255., 0x90 / 255., 0xd9 / 255., 0.3);
+ else
+ cairo_set_source_rgb (cr, 0x4a / 255., 0x90 / 255., 0xd9 / 255.);
+
+ cairo_fill (cr);
+}
+
+static void
+draw_add_change (IdeOmniGutterRenderer *self,
+ cairo_t *cr,
+ GdkRectangle *area,
+ LineInfo *info,
+ GtkSourceGutterRendererState state)
+{
+ g_assert (IDE_IS_OMNI_GUTTER_RENDERER (self));
+ g_assert (cr != NULL);
+ g_assert (area != NULL);
+
+ cairo_rectangle (cr,
+ area->x + area->width - ARROW_WIDTH + 1,
+ area->y,
+ CHANGE_WIDTH,
+ area->y + area->height);
+
+ if (info->is_add)
+ gdk_cairo_set_source_rgba (cr, &rgbaAdded);
+ else
+ gdk_cairo_set_source_rgba (cr, &rgbaChanged);
+
+ cairo_fill (cr);
+}
+
+static void
+draw_diagnostic (IdeOmniGutterRenderer *self,
+ cairo_t *cr,
+ GdkRectangle *area,
+ LineInfo *info,
+ GtkSourceGutterRendererState state)
+{
+ g_assert (IDE_IS_OMNI_GUTTER_RENDERER (self));
+ g_assert (cr != NULL);
+ g_assert (area != NULL);
+
+ cairo_rectangle (cr, area->x + 1, area->y, DIAGNOSTICS_SIZE, area->y + area->height);
+ gdk_cairo_set_source_rgba (cr, &rgbaRemoved);
+ cairo_fill (cr);
+}
+
+static void
+ide_omni_gutter_renderer_draw (GtkSourceGutterRenderer *renderer,
+ cairo_t *cr,
+ GdkRectangle *bg_area,
+ GdkRectangle *cell_area,
+ GtkTextIter *begin,
+ GtkTextIter *end,
+ GtkSourceGutterRendererState state)
+{
+ IdeOmniGutterRenderer *self = (IdeOmniGutterRenderer *)renderer;
+ guint line;
+
+ g_assert (IDE_IS_OMNI_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);
+
+ line = gtk_text_iter_get_line (begin);
+
+ if ((line - self->begin_line) < self->lines->len)
+ {
+ LineInfo *info = &g_array_index (self->lines, LineInfo, line - self->begin_line);
+ gboolean has_breakpoint = FALSE;
+ gchar linestr[16];
+ gint len;
+
+ if (info->is_add || info->is_change)
+ draw_add_change (self, cr, cell_area, info, state);
+
+ if (self->breakpoints != NULL)
+ {
+ has_breakpoint = info->is_breakpoint | info->is_countpoint | info->is_watchpoint;
+ if (has_breakpoint || (state & GTK_SOURCE_GUTTER_RENDERER_STATE_PRELIT) != 0)
+ draw_breakpoint_bg (self, cr, cell_area, state);
+ }
+
+ if (info->is_warning || info->is_error || info->is_note)
+ draw_diagnostic (self, cr, cell_area, info, state);
+
+ len = g_snprintf (linestr, sizeof linestr, "%u", line + 1);
+ pango_layout_set_text (self->layout, linestr, len);
+
+ cairo_move_to (cr, cell_area->x, cell_area->y);
+ if (has_breakpoint)
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ else
+ cairo_set_source_rgba (cr, 0, 0, 0, 0.4);
+ pango_cairo_show_layout (cr, self->layout);
+ }
+}
+
+static void
+ide_omni_gutter_renderer_reload (IdeOmniGutterRenderer *self)
+{
+ g_autoptr(IdeDebuggerBreakpoints) breakpoints = NULL;
+ GtkSourceLanguage *language;
+ GtkTextBuffer *buffer;
+ GtkTextView *view;
+ const gchar *id = NULL;
+
+ g_assert (IDE_IS_OMNI_GUTTER_RENDERER (self));
+
+ view = gtk_source_gutter_renderer_get_view (GTK_SOURCE_GUTTER_RENDERER (self));
+ buffer = gtk_text_view_get_buffer (view);
+
+ if (NULL != (language = gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (buffer))))
+ id = gtk_source_language_get_id (language);
+
+ if (IDE_IS_BUFFER (buffer))
+ {
+ IdeContext *context = ide_buffer_get_context (IDE_BUFFER (buffer));
+ IdeDebugManager *debug_manager = ide_context_get_debug_manager (context);
+
+ if (ide_debug_manager_supports_language (debug_manager, id))
+ {
+ IdeFile *file = ide_buffer_get_file (IDE_BUFFER (buffer));
+ GFile *gfile = ide_file_get_file (file);
+
+ breakpoints = ide_debug_manager_get_breakpoints_for_file (debug_manager, gfile);
+ }
+ }
+
+ g_set_object (&self->breakpoints, breakpoints);
+
+ ide_omni_gutter_renderer_recalculate_size (self, IDE_SOURCE_VIEW (view));
+}
+
+static void
+ide_omni_gutter_renderer_bind (IdeOmniGutterRenderer *self,
+ IdeSourceView *view,
+ DzlSignalGroup *view_signals)
+{
+ g_assert (IDE_IS_OMNI_GUTTER_RENDERER (self));
+ g_assert (IDE_IS_SOURCE_VIEW (view));
+ g_assert (DZL_IS_SIGNAL_GROUP (view_signals));
+
+ if (self->buffer_signals != NULL)
+ {
+ GtkTextBuffer *buffer;
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+ if (IDE_IS_BUFFER (buffer))
+ dzl_signal_group_set_target (self->buffer_signals, buffer);
+
+ ide_omni_gutter_renderer_reload (self);
+ }
+}
+
+static void
+ide_omni_gutter_renderer_notify_buffer (IdeOmniGutterRenderer *self,
+ GParamSpec *pspec,
+ IdeSourceView *view)
+{
+ GtkTextBuffer *buffer;
+
+ g_assert (IDE_IS_OMNI_GUTTER_RENDERER (self));
+ g_assert (pspec != NULL);
+ g_assert (IDE_IS_SOURCE_VIEW (view));
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+ if (IDE_IS_BUFFER (buffer))
+ dzl_signal_group_set_target (self->buffer_signals, buffer);
+
+ ide_omni_gutter_renderer_reload (self);
+}
+
+static void
+ide_omni_gutter_renderer_notify_file (IdeOmniGutterRenderer *self,
+ GParamSpec *pspec,
+ IdeBuffer *buffer)
+{
+ g_assert (IDE_IS_OMNI_GUTTER_RENDERER (self));
+ g_assert (pspec != NULL);
+ g_assert (IDE_IS_BUFFER (buffer));
+
+ ide_omni_gutter_renderer_reload (self);
+}
+
+static void
+ide_omni_gutter_renderer_notify_view (IdeOmniGutterRenderer *self)
+{
+ GtkTextView *view;
+
+ g_assert (IDE_IS_OMNI_GUTTER_RENDERER (self));
+
+ view = gtk_source_gutter_renderer_get_view (GTK_SOURCE_GUTTER_RENDERER (self));
+ dzl_signal_group_set_target (self->view_signals, view);
+}
+
+static gboolean
+ide_omni_gutter_renderer_do_recalc (gpointer data)
+{
+ IdeOmniGutterRenderer *self = data;
+ GtkTextView *view;
+
+ g_assert (IDE_IS_OMNI_GUTTER_RENDERER (self));
+
+ self->resize_source = 0;
+
+ view = gtk_source_gutter_renderer_get_view (GTK_SOURCE_GUTTER_RENDERER (self));
+ if (IDE_IS_SOURCE_VIEW (view))
+ ide_omni_gutter_renderer_recalculate_size (self, IDE_SOURCE_VIEW (view));
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+ide_omni_gutter_renderer_buffer_changed (IdeOmniGutterRenderer *self,
+ IdeBuffer *buffer)
+{
+ g_assert (IDE_IS_OMNI_GUTTER_RENDERER (self));
+ g_assert (IDE_IS_BUFFER (buffer));
+
+ if (self->resize_source == 0)
+ self->resize_source = gdk_threads_add_idle_full (G_PRIORITY_HIGH,
+ ide_omni_gutter_renderer_do_recalc,
+ g_object_ref (self),
+ g_object_unref);
+}
+
+static void
+ide_omni_gutter_renderer_constructed (GObject *object)
+{
+ IdeOmniGutterRenderer *self = (IdeOmniGutterRenderer *)object;
+ GtkTextView *view;
+
+ g_assert (IDE_IS_OMNI_GUTTER_RENDERER (self));
+
+ G_OBJECT_CLASS (ide_omni_gutter_renderer_parent_class)->constructed (object);
+
+ view = gtk_source_gutter_renderer_get_view (GTK_SOURCE_GUTTER_RENDERER (self));
+ dzl_signal_group_set_target (self->view_signals, view);
+}
+
+static void
+ide_omni_gutter_renderer_dispose (GObject *object)
+{
+ IdeOmniGutterRenderer *self = (IdeOmniGutterRenderer *)object;
+
+ ide_clear_source (&self->resize_source);
+ g_clear_pointer (&self->lines, g_array_unref);
+ g_clear_object (&self->breakpoints);
+ g_clear_object (&self->buffer_signals);
+ g_clear_object (&self->view_signals);
+
+ G_OBJECT_CLASS (ide_omni_gutter_renderer_parent_class)->dispose (object);
+}
+
+static void
+ide_omni_gutter_renderer_class_init (IdeOmniGutterRendererClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkSourceGutterRendererClass *renderer_class = GTK_SOURCE_GUTTER_RENDERER_CLASS (klass);
+
+ object_class->constructed = ide_omni_gutter_renderer_constructed;
+ object_class->dispose = ide_omni_gutter_renderer_dispose;
+
+ renderer_class->draw = ide_omni_gutter_renderer_draw;
+ renderer_class->begin = ide_omni_gutter_renderer_begin;
+ renderer_class->end = ide_omni_gutter_renderer_end;
+ renderer_class->query_activatable = ide_omni_gutter_renderer_query_activatable;
+ renderer_class->activate = ide_omni_gutter_renderer_activate;
+
+ gdk_rgba_parse (&rgbaAdded, "#8ae234");
+ gdk_rgba_parse (&rgbaChanged, "#fcaf3e");
+ gdk_rgba_parse (&rgbaRemoved, "#ff0000");
+}
+
+static void
+ide_omni_gutter_renderer_init (IdeOmniGutterRenderer *self)
+{
+ self->lines = g_array_new (FALSE, FALSE, sizeof (LineInfo));
+
+ g_signal_connect (self,
+ "notify::view",
+ G_CALLBACK (ide_omni_gutter_renderer_notify_view),
+ NULL);
+
+ self->buffer_signals = dzl_signal_group_new (IDE_TYPE_BUFFER);
+
+ dzl_signal_group_connect_swapped (self->buffer_signals,
+ "notify::file",
+ G_CALLBACK (ide_omni_gutter_renderer_notify_file),
+ self);
+
+ dzl_signal_group_connect_swapped (self->buffer_signals,
+ "changed",
+ G_CALLBACK (ide_omni_gutter_renderer_buffer_changed),
+ self);
+
+ self->view_signals = dzl_signal_group_new (IDE_TYPE_SOURCE_VIEW);
+
+ g_signal_connect_swapped (self->view_signals,
+ "bind",
+ G_CALLBACK (ide_omni_gutter_renderer_bind),
+ self);
+
+ dzl_signal_group_connect_swapped (self->view_signals,
+ "notify::buffer",
+ G_CALLBACK (ide_omni_gutter_renderer_notify_buffer),
+ self);
+
+ dzl_signal_group_connect_swapped (self->view_signals,
+ "notify::font-desc",
+ G_CALLBACK (ide_omni_gutter_renderer_notify_font_desc),
+ self);
+}
+
+IdeOmniGutterRenderer *
+ide_omni_gutter_renderer_new (void)
+{
+ return g_object_new (IDE_TYPE_OMNI_GUTTER_RENDERER, NULL);
+}
diff --git a/libide/debugger/ide-debugger-editor-view-addin.h b/libide/sourceview/ide-omni-gutter-renderer.h
similarity index 63%
rename from libide/debugger/ide-debugger-editor-view-addin.h
rename to libide/sourceview/ide-omni-gutter-renderer.h
index 2e221ca..b666daa 100644
--- a/libide/debugger/ide-debugger-editor-view-addin.h
+++ b/libide/sourceview/ide-omni-gutter-renderer.h
@@ -1,4 +1,4 @@
-/* ide-debugger-editor-view-addin.h
+/* ide-omni-gutter-renderer.h
*
* Copyright (C) 2017 Christian Hergert <chergert redhat com>
*
@@ -16,14 +16,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#pragma once
+#ifndef IDE_OMNI_GUTTER_RENDERER_H
+#define IDE_OMNI_GUTTER_RENDERER_H
-#include "editor/ide-editor-view-addin.h"
+#include <gtksourceview/gtksource.h>
G_BEGIN_DECLS
-#define IDE_TYPE_DEBUGGER_EDITOR_VIEW_ADDIN (ide_debugger_editor_view_addin_get_type())
+#define IDE_TYPE_OMNI_GUTTER_RENDERER (ide_omni_gutter_renderer_get_type())
-G_DECLARE_FINAL_TYPE (IdeDebuggerEditorViewAddin, ide_debugger_editor_view_addin, IDE,
DEBUGGER_EDITOR_VIEW_ADDIN, GObject)
+G_DECLARE_FINAL_TYPE (IdeOmniGutterRenderer, ide_omni_gutter_renderer, IDE, OMNI_GUTTER_RENDERER,
GtkSourceGutterRenderer)
+
+IdeOmniGutterRenderer *ide_omni_gutter_renderer_new (void);
G_END_DECLS
+
+#endif /* IDE_OMNI_GUTTER_RENDERER_H */
diff --git a/libide/sourceview/ide-source-view.c b/libide/sourceview/ide-source-view.c
index b763bf1..7730d4a 100644
--- a/libide/sourceview/ide-source-view.c
+++ b/libide/sourceview/ide-source-view.c
@@ -48,8 +48,7 @@
#include "sourceview/ide-completion-provider.h"
#include "sourceview/ide-cursor.h"
#include "sourceview/ide-indenter.h"
-#include "sourceview/ide-line-change-gutter-renderer.h"
-#include "sourceview/ide-line-diagnostics-gutter-renderer.h"
+#include "sourceview/ide-omni-gutter-renderer.h"
#include "sourceview/ide-source-iter.h"
#include "sourceview/ide-source-view-capture.h"
#include "sourceview/ide-source-view-mode.h"
@@ -94,8 +93,6 @@ typedef struct
GtkCssProvider *css_provider;
PangoFontDescription *font_desc;
IdeExtensionAdapter *indenter_adapter;
- GtkSourceGutterRenderer *line_change_renderer;
- GtkSourceGutterRenderer *line_diagnostics_renderer;
IdeSourceViewCapture *capture;
gchar *display_name;
IdeSourceViewMode *mode;
@@ -1415,11 +1412,10 @@ ide_source_view__buffer_notify_highlight_diagnostics_cb (IdeSourceView *self,
GParamSpec *pspec,
IdeBuffer *buffer)
{
- IdeSourceViewPrivate *priv = ide_source_view_get_instance_private (self);
-
g_assert (IDE_IS_SOURCE_VIEW (self));
g_assert (IDE_IS_BUFFER (buffer));
+#if 0
if (priv->line_diagnostics_renderer != NULL)
{
gboolean visible;
@@ -1429,21 +1425,20 @@ ide_source_view__buffer_notify_highlight_diagnostics_cb (IdeSourceView *self,
"visible", visible,
NULL);
}
+#endif
}
static void
ide_source_view__buffer_line_flags_changed_cb (IdeSourceView *self,
IdeBuffer *buffer)
{
- IdeSourceViewPrivate *priv = ide_source_view_get_instance_private (self);
-
IDE_ENTRY;
g_assert (IDE_IS_SOURCE_VIEW (self));
g_assert (IDE_IS_BUFFER (buffer));
- gtk_source_gutter_renderer_queue_draw (priv->line_change_renderer);
- gtk_source_gutter_renderer_queue_draw (priv->line_diagnostics_renderer);
+ gtk_source_gutter_queue_draw (gtk_source_view_get_gutter (GTK_SOURCE_VIEW (self),
+ GTK_TEXT_WINDOW_LEFT));
IDE_EXIT;
}
@@ -4492,9 +4487,7 @@ ide_source_view_constructed (GObject *object)
{
IdeSourceView *self = (IdeSourceView *)object;
IdeSourceViewPrivate *priv = ide_source_view_get_instance_private (self);
- GtkSourceGutter *gutter;
GtkSourceCompletion *completion;
- gboolean visible;
G_OBJECT_CLASS (ide_source_view_parent_class)->constructed (object);
@@ -4519,31 +4512,19 @@ ide_source_view_constructed (GObject *object)
self,
G_CONNECT_SWAPPED | G_CONNECT_AFTER);
- gutter = gtk_source_view_get_gutter (GTK_SOURCE_VIEW (self), GTK_TEXT_WINDOW_LEFT);
-
- priv->line_change_renderer = g_object_new (IDE_TYPE_LINE_CHANGE_GUTTER_RENDERER,
- "show-line-deletions", TRUE,
- "size", 2,
- "visible", priv->show_line_changes,
- "xpad", 3,
- NULL);
- g_object_ref (priv->line_change_renderer);
- gtk_source_gutter_insert (gutter, priv->line_change_renderer, 0);
-
- visible = ((priv->buffer != NULL) &&
- priv->show_line_diagnostics &&
- ide_buffer_get_highlight_diagnostics (priv->buffer));
- priv->line_diagnostics_renderer = g_object_new (IDE_TYPE_LINE_DIAGNOSTICS_GUTTER_RENDERER,
- "size", 16,
- "visible", visible,
- "xpad", 2,
- NULL);
- g_object_ref (priv->line_diagnostics_renderer);
- gtk_source_gutter_insert (gutter, priv->line_diagnostics_renderer, -100);
- g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_SHOW_LINE_DIAGNOSTICS]);
-
priv->definition_src_location = NULL;
ide_source_view_reset_definition_highlight (self);
+
+ {
+ IdeOmniGutterRenderer *renderer;
+ GtkSourceGutter *gutter = gtk_source_view_get_gutter (GTK_SOURCE_VIEW (self), GTK_TEXT_WINDOW_LEFT);
+
+ renderer = g_object_new (IDE_TYPE_OMNI_GUTTER_RENDERER,
+ "size", 20,
+ "visible", TRUE,
+ NULL);
+ gtk_source_gutter_insert (gutter, GTK_SOURCE_GUTTER_RENDERER (renderer), 1000);
+ }
}
static void
@@ -6287,8 +6268,6 @@ ide_source_view_dispose (GObject *object)
g_clear_object (&priv->capture);
g_clear_object (&priv->indenter_adapter);
- g_clear_object (&priv->line_change_renderer);
- g_clear_object (&priv->line_diagnostics_renderer);
g_clear_object (&priv->snippets_provider);
g_clear_object (&priv->css_provider);
g_clear_object (&priv->mode);
@@ -7711,8 +7690,7 @@ ide_source_view_set_show_line_changes (IdeSourceView *self,
if (show_line_changes != priv->show_line_changes)
{
priv->show_line_changes = show_line_changes;
- if (priv->line_change_renderer)
- gtk_source_gutter_renderer_set_visible (priv->line_change_renderer, show_line_changes);
+ /* TODO: Update omni renderer */
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_SHOW_LINE_CHANGES]);
}
}
@@ -7739,16 +7717,16 @@ ide_source_view_set_show_line_diagnostics (IdeSourceView *self,
if (show_line_diagnostics != priv->show_line_diagnostics)
{
- gboolean visible;
-
priv->show_line_diagnostics = show_line_diagnostics;
+#if 0
if ((priv->buffer != NULL) && (priv->line_diagnostics_renderer != NULL))
{
visible = (priv->show_line_diagnostics &&
ide_buffer_get_highlight_diagnostics (priv->buffer));
gtk_source_gutter_renderer_set_visible (priv->line_diagnostics_renderer, visible);
}
+#endif
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_SHOW_LINE_CHANGES]);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]