[gnome-builder/wip/chergert/gutter] wip
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/chergert/gutter] wip
- Date: Mon, 18 Sep 2017 04:11:30 +0000 (UTC)
commit 54d4cc2993028862a44b4ab4e54efec5129f9766
Author: Christian Hergert <chergert redhat com>
Date: Sun Sep 17 03:39:02 2017 -0700
wip
data/style-schemes/builder-dark.xml | 4 +-
data/style-schemes/builder.xml | 5 +-
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 | 1181 ++++++++++++++++++++
.../ide-omni-gutter-renderer.h} | 15 +-
libide/sourceview/ide-source-view.c | 60 +-
8 files changed, 1218 insertions(+), 190 deletions(-)
---
diff --git a/data/style-schemes/builder-dark.xml b/data/style-schemes/builder-dark.xml
index 6b00aef..814c913 100644
--- a/data/style-schemes/builder-dark.xml
+++ b/data/style-schemes/builder-dark.xml
@@ -81,8 +81,8 @@
<style name="snippet::area" background="#rgba(86,114,151,.5)"/>
<!-- Debugger -->
- <style
- name="debugger::current-breakpoint" foreground="#2e3436" background="#fcaf3e"/>
+ <style name="debugger::current-breakpoint" foreground="#2e3436" background="#fcaf3e"/>
+ <style name="debugger::breakpoint" foreground="#ffffff" background="#204a87"/>
<!-- Hover links -->
<style name="action::hover-definition" background="#41464c" underline="true"/>
diff --git a/data/style-schemes/builder.xml b/data/style-schemes/builder.xml
index 4f4eead..2abf4f4 100644
--- a/data/style-schemes/builder.xml
+++ b/data/style-schemes/builder.xml
@@ -76,7 +76,7 @@
<style name="map-overlay" background="#rgba(193,203,210,0.55)"/>
<style name="cursor" foreground="aluminium4"/>
<style name="current-line" background="#rgba(238,238,236,.75)"/>
- <style name="current-line-number" background="#rgba(238,238,236,.75)"/>
+ <style name="current-line-number" background="#rgba(238,238,236,.75)" bold="true"/>
<style name="draw-spaces" foreground="aluminium3"/>
<style name="line-numbers" foreground="line1" background="bg1"/>
<style name="background-pattern" background="#rgba(.125,.125,.125,.025)"/>
@@ -87,6 +87,9 @@
<style name="diagnostician::note" underline="error" underline-color="blue1"/>
<style name="diagnostician::warning" underline="error" underline-color="orange1"/>
+ <!-- Debugger -->
+ <style name="debugger::breakpoint" background="#4a90d9" foreground="#ffffff"/>
+
<!-- Snippets -->
<style name="snippet::tab-stop" background="#fcaf3e" foreground="text1"/>
<style name="snippet::area" background="#rgba(32,74,135,.1)"/>
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..e2109c6
--- /dev/null
+++ b/libide/sourceview/ide-omni-gutter-renderer.c
@@ -0,0 +1,1181 @@
+/* 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
+
+#define IS_BREAKPOINT(i) ((i)->is_breakpoint || (i)->is_countpoint || (i)->is_watchpoint)
+#define IS_DIAGNOSTIC(i) ((i)->is_error || (i)->is_warning || (i)->is_note)
+
+struct _IdeOmniGutterRenderer
+{
+ GtkSourceGutterRenderer parent_instance;
+
+ IdeDebuggerBreakpoints *breakpoints;
+
+ GArray *lines;
+
+ DzlSignalGroup *view_signals;
+ DzlSignalGroup *buffer_signals;
+
+ cairo_surface_t *note_surface;
+ cairo_surface_t *warning_surface;
+ cairo_surface_t *error_surface;
+ cairo_surface_t *note_selected_surface;
+ cairo_surface_t *warning_selected_surface;
+ cairo_surface_t *error_selected_surface;
+
+ struct {
+ GdkRGBA fg;
+ GdkRGBA bg;
+ gboolean bold;
+ } text, current, bkpt;
+ GdkRGBA stopped_bg;
+ struct {
+ GdkRGBA add;
+ GdkRGBA remove;
+ GdkRGBA change;
+ } changes;
+
+ PangoLayout *layout;
+ PangoAttrList *bold_attrs;
+
+ guint n_chars;
+ guint begin_line;
+ gint stopped_line;
+ guint resize_source;
+ gint number_width;
+};
+
+enum {
+ FOREGROUND,
+ BACKGROUND,
+};
+
+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 gboolean
+get_style_boolean (GtkSourceStyleScheme *scheme,
+ const gchar *style_name,
+ const gchar *property,
+ gboolean *val)
+{
+ GtkSourceStyle *style;
+
+ g_assert (!scheme || GTK_SOURCE_IS_STYLE_SCHEME (scheme));
+ g_assert (style_name != NULL);
+ g_assert (property != NULL);
+ g_assert (val != NULL);
+
+ *val = FALSE;
+
+ if (scheme == NULL)
+ return FALSE;
+
+ style = gtk_source_style_scheme_get_style (scheme, style_name);
+
+ if (style != NULL)
+ {
+ g_autofree gchar *property_set = g_strdup_printf ("%s-set", property);
+ gboolean set = FALSE;
+
+ g_object_get (style,
+ property, val,
+ property_set, &set,
+ NULL);
+
+ return set;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+get_style_rgba (GtkSourceStyleScheme *scheme,
+ const gchar *style_name,
+ int type,
+ GdkRGBA *rgba)
+{
+ GtkSourceStyle *style;
+
+ g_assert (!scheme || GTK_SOURCE_IS_STYLE_SCHEME (scheme));
+ g_assert (style_name != NULL);
+ g_assert (type == FOREGROUND || type == BACKGROUND);
+ g_assert (rgba != NULL);
+
+ memset (rgba, 0, sizeof *rgba);
+
+ if (scheme == NULL)
+ return FALSE;
+
+ style = gtk_source_style_scheme_get_style (scheme, style_name);
+
+ if (style != NULL)
+ {
+ g_autofree gchar *str = NULL;
+ gboolean set = FALSE;
+
+ g_object_get (style,
+ type ? "background" : "foreground", &str,
+ type ? "background-set" : "foreground-set", &set,
+ NULL);
+
+ if (str != NULL && set)
+ {
+ gdk_rgba_parse (rgba, str);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static void
+reload_style_colors (IdeOmniGutterRenderer *self,
+ GtkSourceStyleScheme *scheme)
+{
+ GtkStyleContext *context;
+ GtkTextView *view;
+ GtkStateFlags state;
+ GdkRGBA fg;
+ GdkRGBA bg;
+
+ g_assert (IDE_IS_OMNI_GUTTER_RENDERER (self));
+ g_assert (!scheme || GTK_SOURCE_IS_STYLE_SCHEME (scheme));
+
+ view = gtk_source_gutter_renderer_get_view (GTK_SOURCE_GUTTER_RENDERER (self));
+ if (view == NULL)
+ return;
+
+ context = gtk_widget_get_style_context (GTK_WIDGET (view));
+ state = gtk_style_context_get_state (context);
+ gtk_style_context_get_color (context, state, &fg);
+ G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
+ gtk_style_context_get_background_color (context, state, &bg);
+ G_GNUC_END_IGNORE_DEPRECATIONS;
+
+ if (!get_style_rgba (scheme, "line-numbers", FOREGROUND, &self->text.fg))
+ self->text.fg = fg;
+
+ if (!get_style_rgba (scheme, "line-numbers", BACKGROUND, &self->text.bg))
+ self->text.bg = bg;
+
+ if (!get_style_boolean (scheme, "line-numbers", "bold", &self->text.bold))
+ self->text.bold = FALSE;
+
+ if (!get_style_rgba (scheme, "current-line-number", FOREGROUND, &self->current.fg))
+ self->current.fg = fg;
+
+ if (!get_style_rgba (scheme, "current-line-number", BACKGROUND, &self->current.bg))
+ self->current.bg = bg;
+
+ if (!get_style_boolean (scheme, "current-line-number", "bold", &self->current.bold))
+ self->current.bold = TRUE;
+
+ if (!get_style_rgba (scheme, "debugger::current-breakpoint", BACKGROUND, &self->stopped_bg))
+ gdk_rgba_parse (&self->stopped_bg, "#fcaf3e");
+
+ if (!get_style_rgba (scheme, "debugger::breakpoint", FOREGROUND, &self->bkpt.fg))
+ get_style_rgba (scheme, "selection", FOREGROUND, &self->bkpt.fg);
+
+ if (!get_style_rgba (scheme, "debugger::breakpoint", BACKGROUND, &self->bkpt.bg))
+ get_style_rgba (scheme, "selection", BACKGROUND, &self->bkpt.bg);
+
+ if (!get_style_boolean (scheme, "debugger::breakpoint", "bold", &self->bkpt.bold))
+ self->bkpt.bold = FALSE;
+
+ if (!get_style_rgba (scheme, "gutter::added-line", FOREGROUND, &self->changes.add))
+ gdk_rgba_parse (&self->changes.add, "#8ae234");
+
+ if (!get_style_rgba (scheme, "gutter::changed-line", FOREGROUND, &self->changes.change))
+ gdk_rgba_parse (&self->changes.change, "#fcaf3e");
+
+ if (!get_style_rgba (scheme, "gutter::removed-line", FOREGROUND, &self->changes.remove))
+ gdk_rgba_parse (&self->changes.remove, "#ef2929");
+}
+
+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 +
+ ARROW_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;
+ GtkTextTagTable *table;
+ GtkTextBuffer *buffer;
+ IdeSourceView *view;
+ GtkTextTag *tag;
+ GtkTextIter bkpt;
+ 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);
+
+ self->stopped_line = -1;
+
+ buffer = gtk_text_iter_get_buffer (begin);
+ table = gtk_text_buffer_get_tag_table (buffer);
+ tag = gtk_text_tag_table_lookup (table, "debugger::current-breakpoint");
+
+ /*
+ * Locate the current stopped breakpoint if any.
+ */
+
+ if (tag != NULL)
+ {
+ bkpt = *begin;
+ gtk_text_iter_backward_char (&bkpt);
+ if (gtk_text_iter_forward_to_tag_toggle (&bkpt, tag) &&
+ gtk_text_iter_starts_tag (&bkpt, tag))
+ self->stopped_line = gtk_text_iter_get_line (&bkpt);
+ }
+
+ /*
+ * 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
+animate_at_iter (IdeOmniGutterRenderer *self,
+ GdkRectangle *area,
+ GtkTextIter *iter)
+{
+ DzlBoxTheatric *theatric;
+ GtkTextView *view;
+
+ g_assert (IDE_IS_OMNI_GUTTER_RENDERER (self));
+ g_assert (area != NULL);
+ g_assert (iter != NULL);
+
+#define ANIMATION_X_GROW 50
+#define ANIMATION_Y_GROW 30
+
+ view = gtk_source_gutter_renderer_get_view (GTK_SOURCE_GUTTER_RENDERER (self));
+
+ theatric = g_object_new (DZL_TYPE_BOX_THEATRIC,
+ "alpha", 0.3,
+ "background", "#729fcf",
+ "height", area->height,
+ "target", view,
+ "width", area->width,
+ "x", area->x,
+ "y", area->y,
+ NULL);
+
+ dzl_object_animate_full (theatric,
+ DZL_ANIMATION_EASE_IN_CUBIC,
+ 100,
+ gtk_widget_get_frame_clock (GTK_WIDGET (view)),
+ g_object_unref,
+ theatric,
+ "x", area->x + 250,
+ "alpha", 0.0,
+ 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);
+ animate_at_iter (self, area, iter);
+ }
+ 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,
+ LineInfo *info,
+ GtkSourceGutterRendererState state)
+{
+ GdkRectangle area;
+ GdkRGBA rgba;
+
+ 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;
+ area.height = bg_area->height;
+ area.width = bg_area->width;
+
+ cairo_move_to (cr, area.x, area.y);
+ cairo_line_to (cr,
+ dzl_cairo_rectangle_x2 (&area) - ARROW_WIDTH,
+ area.y);
+ cairo_line_to (cr,
+ dzl_cairo_rectangle_x2 (&area),
+ dzl_cairo_rectangle_middle (&area));
+ cairo_line_to (cr,
+ dzl_cairo_rectangle_x2 (&area) - ARROW_WIDTH,
+ dzl_cairo_rectangle_y2 (&area));
+ cairo_line_to (cr, area.x, dzl_cairo_rectangle_y2 (&area));
+ cairo_close_path (cr);
+
+ rgba = self->bkpt.bg;
+
+ if ((state & GTK_SOURCE_GUTTER_RENDERER_STATE_PRELIT) != 0)
+ {
+ if (IS_BREAKPOINT (info))
+ rgba.alpha *= 0.8;
+ else
+ rgba.alpha *= 0.4;
+ }
+
+ gdk_cairo_set_source_rgba (cr, &rgba);
+ 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 - 2 - CHANGE_WIDTH,
+ area->y,
+ CHANGE_WIDTH,
+ area->y + area->height);
+
+ 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);
+}
+
+static void
+draw_diagnostic (IdeOmniGutterRenderer *self,
+ cairo_t *cr,
+ GdkRectangle *area,
+ LineInfo *info,
+ GtkSourceGutterRendererState state)
+{
+ cairo_surface_t *surface = NULL;
+
+ g_assert (IDE_IS_OMNI_GUTTER_RENDERER (self));
+ g_assert (cr != NULL);
+ g_assert (area != NULL);
+
+ if (IS_BREAKPOINT (info) || (state & GTK_SOURCE_GUTTER_RENDERER_STATE_PRELIT))
+ {
+ if (info->is_error)
+ surface = self->error_selected_surface;
+ else if (info->is_warning)
+ surface = self->warning_selected_surface;
+ else if (info->is_note)
+ surface = self->note_selected_surface;
+ }
+ else
+ {
+ if (info->is_error)
+ surface = self->error_surface;
+ else if (info->is_warning)
+ surface = self->warning_surface;
+ else if (info->is_note)
+ surface = self->note_surface;
+ }
+
+ if (surface != NULL)
+ {
+ cairo_rectangle (cr,
+ area->x + 2,
+ area->y + ((area->height - DIAGNOSTICS_SIZE) / 2),
+ DIAGNOSTICS_SIZE, DIAGNOSTICS_SIZE);
+ cairo_set_source_surface (cr,
+ surface,
+ area->x + 2,
+ area->y + ((area->height - DIAGNOSTICS_SIZE) / 2));
+ cairo_paint (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;
+ GtkTextView *view;
+ gboolean has_focus;
+ 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);
+
+ view = gtk_source_gutter_renderer_get_view (GTK_SOURCE_GUTTER_RENDERER (self));
+ has_focus = gtk_widget_has_focus (GTK_WIDGET (view));
+
+ 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 active = state & GTK_SOURCE_GUTTER_RENDERER_STATE_PRELIT;
+ gboolean has_breakpoint = FALSE;
+ gboolean bold = FALSE;
+ gchar linestr[16];
+ gint len;
+
+ if (line == self->stopped_line)
+ {
+ gdk_cairo_rectangle (cr, bg_area);
+ gdk_cairo_set_source_rgba (cr, &self->stopped_bg);
+ cairo_fill (cr);
+ }
+ else if (has_focus && (state & GTK_SOURCE_GUTTER_RENDERER_STATE_CURSOR))
+ {
+ gdk_cairo_rectangle (cr, bg_area);
+ gdk_cairo_set_source_rgba (cr, &self->current.bg);
+ cairo_fill (cr);
+ }
+
+ if (info->is_add || info->is_change)
+ draw_add_change (self, cr, cell_area, info, state);
+
+ if (self->breakpoints != NULL)
+ {
+ has_breakpoint = IS_BREAKPOINT (info);
+ if (has_breakpoint || active)
+ draw_breakpoint_bg (self, cr, cell_area, info, state);
+ }
+
+ if (IS_DIAGNOSTIC (info))
+ 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 || active)
+ {
+ gdk_cairo_set_source_rgba (cr, &self->bkpt.fg);
+ bold = self->bkpt.bold;
+ }
+ else if (state & GTK_SOURCE_GUTTER_RENDERER_STATE_CURSOR)
+ {
+ gdk_cairo_set_source_rgba (cr, &self->current.fg);
+ bold = self->current.bold;
+ }
+ else
+ {
+ gdk_cairo_set_source_rgba (cr, &self->text.fg);
+ bold = self->text.bold;
+ }
+
+ if (state & GTK_SOURCE_GUTTER_RENDERER_STATE_CURSOR)
+ bold |= self->current.bold;
+
+ pango_layout_set_attributes (self->layout, bold ? self->bold_attrs : NULL);
+
+ pango_cairo_show_layout (cr, self->layout);
+ }
+}
+
+static cairo_surface_t *
+get_icon_surface (IdeOmniGutterRenderer *self,
+ GtkWidget *widget,
+ const gchar *icon_name,
+ gint size,
+ gboolean selected)
+{
+ GtkIconTheme *icon_theme;
+ GtkIconInfo *info;
+ GdkScreen *screen;
+ GtkIconLookupFlags flags;
+ gint scale;
+
+ g_assert (IDE_IS_OMNI_GUTTER_RENDERER (self));
+ g_assert (GTK_IS_WIDGET (widget));
+ g_assert (icon_name != NULL);
+
+ screen = gtk_widget_get_screen (widget);
+ icon_theme = gtk_icon_theme_get_for_screen (screen);
+
+ flags = GTK_ICON_LOOKUP_USE_BUILTIN;
+ scale = gtk_widget_get_scale_factor (widget);
+
+ info = gtk_icon_theme_lookup_icon_for_scale (icon_theme, icon_name, size, scale, flags);
+
+ if (info != NULL)
+ {
+ g_autoptr(GdkPixbuf) pixbuf = NULL;
+
+ if (gtk_icon_info_is_symbolic (info))
+ {
+ GdkRGBA fg;
+
+ if (selected)
+ fg = self->bkpt.fg;
+ else
+ fg = self->text.fg;
+
+ pixbuf = gtk_icon_info_load_symbolic (info, &fg, &fg, &fg, &fg, NULL, NULL);
+ }
+ else
+ pixbuf = gtk_icon_info_load_icon (info, NULL);
+
+ if (pixbuf != NULL)
+ return gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, NULL);
+ }
+
+ return NULL;
+}
+
+static void
+ide_omni_gutter_renderer_reload_icons (IdeOmniGutterRenderer *self)
+{
+ GtkTextView *view;
+
+ g_assert (IDE_IS_OMNI_GUTTER_RENDERER (self));
+
+ g_clear_pointer (&self->note_surface, cairo_surface_destroy);
+ g_clear_pointer (&self->warning_surface, cairo_surface_destroy);
+ g_clear_pointer (&self->error_surface, cairo_surface_destroy);
+ g_clear_pointer (&self->note_selected_surface, cairo_surface_destroy);
+ g_clear_pointer (&self->warning_selected_surface, cairo_surface_destroy);
+ g_clear_pointer (&self->error_selected_surface, cairo_surface_destroy);
+
+ view = gtk_source_gutter_renderer_get_view (GTK_SOURCE_GUTTER_RENDERER (self));
+ if (view == NULL)
+ return;
+
+ self->note_surface = get_icon_surface (self, GTK_WIDGET (view), "dialog-information-symbolic",
DIAGNOSTICS_SIZE, FALSE);
+ self->warning_surface = get_icon_surface (self, GTK_WIDGET (view), "dialog-warning-symbolic",
DIAGNOSTICS_SIZE, FALSE);
+ self->error_surface = get_icon_surface (self, GTK_WIDGET (view), "process-stop-symbolic",
DIAGNOSTICS_SIZE, FALSE);
+
+ self->note_selected_surface = get_icon_surface (self, GTK_WIDGET (view), "dialog-information-symbolic",
DIAGNOSTICS_SIZE, TRUE);
+ self->warning_selected_surface = get_icon_surface (self, GTK_WIDGET (view), "dialog-warning-symbolic",
DIAGNOSTICS_SIZE, TRUE);
+ self->error_selected_surface = get_icon_surface (self, GTK_WIDGET (view), "process-stop-symbolic",
DIAGNOSTICS_SIZE, TRUE);
+}
+
+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_reload_icons (self);
+ ide_omni_gutter_renderer_recalculate_size (self, IDE_SOURCE_VIEW (view));
+}
+
+static void
+ide_omni_gutter_renderer_bind_view (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_notify_style_scheme (IdeOmniGutterRenderer *self,
+ GParamSpec *pspec,
+ IdeBuffer *buffer)
+{
+ GtkSourceStyleScheme *scheme;
+
+ g_assert (IDE_IS_OMNI_GUTTER_RENDERER (self));
+ g_assert (IDE_IS_BUFFER (buffer));
+
+ scheme = gtk_source_buffer_get_style_scheme (GTK_SOURCE_BUFFER (buffer));
+ reload_style_colors (self, scheme);
+ ide_omni_gutter_renderer_reload_icons (self);
+}
+
+static void
+ide_omni_gutter_renderer_bind_buffer (IdeOmniGutterRenderer *self,
+ IdeBuffer *buffer,
+ DzlSignalGroup *buffer_signals)
+{
+ g_assert (IDE_IS_OMNI_GUTTER_RENDERER (self));
+ g_assert (IDE_IS_BUFFER (buffer));
+ g_assert (DZL_IS_SIGNAL_GROUP (buffer_signals));
+
+ ide_omni_gutter_renderer_notify_style_scheme (self, NULL, buffer);
+}
+
+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->note_surface, cairo_surface_destroy);
+ g_clear_pointer (&self->warning_surface, cairo_surface_destroy);
+ g_clear_pointer (&self->error_surface, cairo_surface_destroy);
+ g_clear_pointer (&self->note_selected_surface, cairo_surface_destroy);
+ g_clear_pointer (&self->warning_selected_surface, cairo_surface_destroy);
+ g_clear_pointer (&self->error_selected_surface, cairo_surface_destroy);
+
+ g_clear_pointer (&self->lines, g_array_unref);
+
+ g_clear_object (&self->layout);
+ g_clear_pointer (&self->bold_attrs, pango_attr_list_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;
+}
+
+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);
+
+ g_signal_connect_swapped (self->buffer_signals,
+ "bind",
+ G_CALLBACK (ide_omni_gutter_renderer_bind_buffer),
+ self);
+
+ 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,
+ "notify::style-scheme",
+ G_CALLBACK (ide_omni_gutter_renderer_notify_style_scheme),
+ 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_view),
+ 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);
+
+ self->bold_attrs = pango_attr_list_new ();
+ pango_attr_list_insert (self->bold_attrs, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
+}
+
+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]