
На первый взгляд никаких проблем быть не должно: создаем 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));
}
Спасибо, мужик!
ОтветитьУдалитьОчень интересно.