GtkSourceGutter - 如何在特定行上呈现图标或文字

时间:2018-05-18 21:48:19

标签: c windows gtk gtksourceview gutter

我已插入自定义gtk源gutter渲染器pixbuf,我想在特定行上渲染图标。

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

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

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

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

enter image description here

2 个答案:

答案 0 :(得分: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_line上使用GtkTextIter *start。看起来这是最低限度的。

随意提出任何进一步的问题。

答案 1 :(得分:1)

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

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

这是一个阅读和练习的问题。

所以如果你不知道怎么做就不要惊慌,比如创建你自己的小部件。

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

只需将GtkSourceGutterRenderer上的query-data信号连接到信号处理程序,如下所示:

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执行资源处理。