GtkSourceGutter - Как отобразить значок или текст в определенной строке
Я вставил нестандартный исходный рендерер gtk pixbuf и хочу отобразить значок в определенной строке.
В справочном API говорится, что интерфейс очень похож на интерфейс GtkTreeView, но не работает с древовидной моделью. Итак... как я должен отрисовывать данные в определенной строке, если GtkSourceGutter не работает с моделью дерева?
Я проверил каждую функцию во всей библиотеке, все предложенные api и дочерние объекты и ничего даже не намекало на это.
Это просто не имеет смысла. Страница man говорит, что GtkSourceGutterRendererPixbuf используется для отображения значка IN A CELL. дела gtk_source_gutter_renderer_pixbuf_set_pixbuf(renderer, pixbuf);
отобразит значок для всех ячеек в желобе. И если единственный способ - нарисовать pixbuf вручную, используя cairo... какой смысл в этих средствах визуализации?
Как мне рендерить pixbuf в определенной строке, используя gtksourcegutterrenderer?
2 ответа
Я лично не могу просто согласиться с утверждением, что создание пользовательских объектов легко. Это не легко, не всем.
Главным образом потому, что этот вопрос помечен 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);
}
Примечания:
GtkSourceMark совместно использует интерфейс GtkSourceGutterRenderer, поэтому вы можете захотеть отфильтровать другие исходные метки, указав категорию исходной метки, которая применяется к определенной строке. В противном случае ваш пользовательский рендерер pixbuf также будет отображаться слева от ваших других исходных меток.
Вы должны указать точный pixbuf, который вы хотите визуализировать внутри. Делая это, вам не придется звонить
gtk_source_gutter_renderer_pixbuf_set_pixbuf()
, Вы позволяете API выполнять обработку ресурсов.
Я не работал с GtkSourceView, но я могу дать вам некоторые подсказки.
Как это сделано автором GtkSourceView
Прежде всего, нам нужно несколько ссылок:
- Исходный код GtkSourceGutterRendererMarks
- Исходный код GtkSourceGutterRendererPixbuf
- Документация GtkSourceGutterRenderer
Давайте начнем с GtkSourceGutterRendererPixbuf. Из этого class_init
метод, который мы узнаем, что он переопределяет только draw
метод. Его единственная цель - визуализировать pixbuf или значок. Чистый рисунок.
Тем не менее, документация GtkSourceGutterRenderer говорит, что есть query-data
сигнал, который можно использовать для настройки внутреннего состояния рендерера. На этом этапе мы должны взглянуть на GtkSourceGutterRendererMarks, который унаследован от RendererPixbuf. Не переопределяет 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
, Похоже, это самый минимум.
Не стесняйтесь задавать любые дополнительные вопросы.