На первый взгляд никаких проблем быть не должно: создаем GtkTreeViewColumn, в которую упаковываем GtkCellRendererToggle и GtkCellRendererText. Создали, упаковали - выглядит так, как и хотелось, но вот работает не так как надо. А именно, флажки переключаются даже тогда, когда пользователь щелкает по GtkCellRendererText с именем файла/директории. Подобное поведение может очень сильно раздражать, когда, например, пользователь ввиду слишком длинного списка с большим уровнем вложенности захочет просто кликнуть по имени файла, чтобы выделить всю строку и тем самым подсветить остальные колонки GtkTreeView, которых может быть довольно большое количество (размер, время модификации, тип файла и т. п.).
Как и в прошлый раз, для решения проблемы придется модифицировать внутренние структуры GTK, т. к. штатными средствами данную проблему похоже решить не удасться. Все, что нам нужно - это определить собственный обработчик сигнала для GtkCellRendererToggle. Пример того, как это можно сделать, представлен ниже. Все, что необходимо программисту - это вызвать функцию activate_cell_renderer_toggle_tree_mode(). После ее вызова все GtkCellRendererToggle'ы будут работать так, как требуется. Способ работает как с GTK, так и с Gtkmm.
#include <gtk/gtkcellrenderertoggle.h> /// Модифицированный обработчик сигнала на активацию GtkCellRendererToggle. static gint gtk_cell_renderer_toggle_activate( GtkCellRenderer* cell, GdkEvent* event, GtkWidget* widget, const gchar* path, GdkRectangle* background_area, GdkRectangle* cell_area, GtkCellRendererState flags) { GtkCellRendererToggle* celltoggle = GTK_CELL_RENDERER_TOGGLE(cell); if(celltoggle->activatable) { if ( !event || event->type != GDK_BUTTON_PRESS || ( event->button.x >= cell_area->x && event->button.x < cell_area->x + cell_area->width && event->button.y >= cell_area->y && event->button.y < cell_area->y + cell_area->height ) ) { g_signal_emit_by_name(cell, "toggled", path); return TRUE; } } return FALSE; } /// Активизирует "режим дерева" для GtkCellRendererToggle. /// Модифицирует внутренние структуры GTK так, чтобы при упаковке /// GtkCellRendererToggle в одну колонку с другими GtkCellRenderer'ами /// GtkCellRendererToggle активизировался только в том случае, если /// пользователь кликнул мышкой именно по нему, а не по любому /// GtkCellRenderer'у данной колонки. void activate_cell_renderer_toggle_tree_mode(void) { GtkCellRendererClass *cell_class; GtkCellRendererToggle *toggle_renderer; toggle_renderer = GTK_CELL_RENDERER_TOGGLE(gtk_cell_renderer_toggle_new()); cell_class = GTK_CELL_RENDERER_CLASS(GTK_WIDGET_GET_CLASS(toggle_renderer)); cell_class->activate = gtk_cell_renderer_toggle_activate; gtk_object_destroy(GTK_OBJECT(toggle_renderer)); }
1 комментарий:
Спасибо, мужик!
Очень интересно.
Отправить комментарий