1

我已经插入了自定义 gtk 源排水沟渲染器 pixbuf,我想在特定行上渲染图标。

参考 API 声明该接口与 GtkTreeView 上的接口非常相似,但不适用于树模型。那么......如果 GtkSourceGutter 不适用于树模型,我应该如何将数据呈现到特定行?

我检查了整个库中的每个函数,每个建议的 api 和子对象,甚至没有任何提示。

这没有任何意义。手册页说 GtkSourceGutterRendererPixbuf 用于在 CELL 中显示图标。这样做 gtk_source_gutter_renderer_pixbuf_set_pixbuf(renderer, pixbuf);将为装订线中的所有单元格呈现图标。如果唯一的方法是使用 cairo 手动绘制 pixbuf ..这些渲染器有什么意义?

如何使用 gtksourcegutterrenderer在特定行中渲染 pixbuf ?


在此处输入图像描述

4

2 回答 2

2

我没有使用过 GtkSourceView,但我可以给你一些线索。


GtkSourceView 的作者是如何做到的

首先,我们需要一些链接:

让我们从 GtkSourceGutterRendererPixbuf 开始。从它的class_init方法中我们发现,它只覆盖了draw方法。它的唯一目的是呈现一个 pixbuf 或图标。纯绘图。

然而,GtkSourceGutterRenderer 文档说,有一个query-data信号可以用来调整渲染器的内部状态。此时我们应该看一下继承自 RendererPixbuf 的 GtkSourceGutterRendererMarks。它不覆盖draw,而是覆盖query_data(由于某种原因GtkSourceGutterRendererClass,文档中没有描述。我不知道为什么。)

/* Read my comments. */
static void
gutter_renderer_query_data (GtkSourceGutterRenderer      *renderer,
                            GtkTextIter                  *start,
                            GtkTextIter                  *end,
                            GtkSourceGutterRendererState  state)
{
  GSList *marks;
  GdkPixbuf *pixbuf = NULL;
  
  view = GTK_SOURCE_VIEW (gtk_source_gutter_renderer_get_view (renderer));
  buffer = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));

  marks = gtk_source_buffer_get_source_marks_at_iter (buffer,
                                                      start,
                                                      NULL);
  
  /* If there are marks, we find a pixbuf for one of them. 
   * Otherwise pixbuf is NULL. */
  if (marks != NULL)
  {
    size = measure_line_height (view);
    pixbuf = composite_marks (view, marks, size);

    g_slist_free (marks);
  }
  
  /* Now tell parent class to render certain pixbuf
   * It will render nothing if pixbuf is NULL. */
  g_object_set (G_OBJECT (renderer),
                   "pixbuf", pixbuf,
                   NULL);
}

我的建议。

您想在某些行上绘制标记(例如,要突出显示当前调试器行)。如果我是你,我会从 RendererPixbuf 继承,覆盖query_data并使用gtk_text_iter_get_lineon GtkTextIter *start。看起来这是最低限度的。

随时问任何进一步的问题。

于 2018-05-21T22:00:14.277 回答
1

我个人不能简单地同意创建自定义对象很容易的说法。这并不容易,对每个人都不是。

主要是因为这个问题被标记c了,不了解面向对象编程的人可能不熟悉它的概念。

这是阅读和练习的问题。

因此,如果您不知道如何创建自己的小部件,请不要惊慌。

我能想到的最简单的解决方案,不涉及创建自己的渲染器,而是告诉渲染器如何查询渲染数据。

只需将GtkSourceGutterRenderer 上的查询数据信号连接到如下所示的信号处理程序:

G_MODULE_EXPORT void gutter_renderer_query_data (GtkSourceGutterRenderer *renderer, GtkTextIter *start, GtkTextIter *end, GtkSourceGutterRendererState state)
{
    GtkSourceView*      view    = NULL;
    GtkSourceBuffer*    buffer  = NULL;
    GSList*             marks   = NULL;
    GdkPixbuf*          pixbuf  = NULL;

    view    = GTK_SOURCE_VIEW(gtk_source_gutter_renderer_get_view(renderer));
    buffer  = GTK_SOURCE_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(view)));

    marks   = gtk_source_buffer_get_source_marks_at_iter(buffer, start, NULL);

    if(marks != NULL)
    {
        char *category = gtk_source_mark_get_category(marks->data);

        if(!g_strcmp0(category, "CERTAIN_CATEGORY")) /* See note 1) */
            pixbuf = gtk_image_get_pixbuf(gtk_image_new_from_file("icon_file_here")); /* See note 2) */

        g_slist_free(marks);
    }

    g_object_set(G_OBJECT(renderer), "pixbuf", pixbuf, "yalign", 0.5, NULL);
}

备注

  1. GtkSourceMark 共享 GtkSourceGutterRenderer 接口,因此您可能希望通过指定应用于特定行的源标记的类别来过滤其他源标记。否则,您的自定义渲染器 pixbuf 也将被渲染到您的其他源标记。

  2. 您应该指定要在内部渲染的确切 pixbuf。这样做,您将不必调用gtk_source_gutter_renderer_pixbuf_set_pixbuf(). 您让 API 进行资源处理。

于 2018-05-26T18:45:34.123 回答