Toggle cell on a sorted treeviewcolumn loses selection (sample code)
- From: Nicolas Soubeiran <nicolas soubeiran gmail com>
- To: gtk-app-devel-list gnome org
- Subject: Toggle cell on a sorted treeviewcolumn loses selection (sample code)
- Date: Wed, 26 Aug 2009 12:33:06 +0200
Hi all
If the column is sorted, when one activates the toggle, the tree is
re-sorted (normal) but the selected row is changed (unexpected). I
investigated and I found that when clicking on a toggle cell renderer, the
"activate" callback is send which update the treemodel. After re-ordering,
the function gtk_tree_view_button_press is called. This function checks
which row is under the cursor and selects it. I am looking for a way to trap
this event to keep the selection on the "activated" row (like when one edits
a text)
here is a simple example of the "bug" (toggle the cell of the 3rd row to see
the bug).
<code>
#include <gtk/gtk.h>
/* Treemodel column enum */
enum {
STRING_COLUMN = 0,
NUMERIC_COLUMN,
/*count */
N_COLUMN
};
/* toggle renderer display function */
static void _is_number_odd (GtkTreeViewColumn *tree_column,
GtkCellRenderer *cell,
GtkTreeModel *tree_model,
GtkTreeIter *iter,
gpointer data)
{
gint numeric_data;
gboolean isOdd;
gtk_tree_model_get(tree_model, iter, NUMERIC_COLUMN, &numeric_data, -1);
isOdd = numeric_data % 2 ? TRUE : FALSE;
g_object_set(G_OBJECT(cell),
"active", isOdd, NULL);
}
/* toggle renderer activate callback */
static void _toggle_odd_column (GtkCellRendererToggle *cell_renderer,
gchar *path,
GtkListStore* list_store)
{
gint numeric_data;
GtkTreeIter iter;
GtkTreePath* tree_path;
tree_path = gtk_tree_path_new_from_string (path);
if( gtk_tree_model_get_iter(GTK_TREE_MODEL(list_store),
&iter, tree_path))
{
gtk_tree_model_get(GTK_TREE_MODEL(list_store), &iter,
NUMERIC_COLUMN, &numeric_data,
-1);
/* increment numeric */
gtk_list_store_set (list_store, &iter,
NUMERIC_COLUMN, ++numeric_data,
-1);
}
}
/* fill the list store model */
static void _fill_model(GtkListStore* list_store)
{
gint i ;
GtkTreeIter iter;
for (i = 0; i < 10; ++i)
{
gchar* string_data ;
gint numeric_data = i;
string_data = g_strdup_printf("row number %d", numeric_data);
/* Add a new row to the model */
gtk_list_store_append (list_store, &iter);
gtk_list_store_set (list_store, &iter,
STRING_COLUMN , string_data,
NUMERIC_COLUMN, numeric_data,
-1);
}
}
/* sort function : we group odd and even */
static gint _compare_odd (GtkTreeModel *model,
GtkTreeIter *a,
GtkTreeIter *b,
gpointer user_data)
{
gint numeric_data_a, numeric_data_b;
gtk_tree_model_get(model, a,
NUMERIC_COLUMN, &numeric_data_a,
-1);
gtk_tree_model_get(model, b,
NUMERIC_COLUMN, &numeric_data_b,
-1);
if( (numeric_data_a % 2) == (numeric_data_b % 2))
{ /* if both are odd or even return the differnce */
return numeric_data_a - numeric_data_b;
}
else
{
if(numeric_data_a % 2 == 0)
{
return 1;
}
else
{
return -1;
}
}
}
/* tree model creation */
static GtkTreeModel* _create_model()
{
GtkListStore* list_store;
list_store = gtk_list_store_new(N_COLUMN,
G_TYPE_STRING,
G_TYPE_INT);
_fill_model(list_store);
gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(list_store),
NUMERIC_COLUMN, _compare_odd, NULL, NULL);
gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(list_store),
NUMERIC_COLUMN, GTK_SORT_ASCENDING);
return GTK_TREE_MODEL(list_store);
}
/* tree view creation */
static GtkWidget* _create_treeview()
{
GtkWidget* tree_view;
GtkCellRenderer* cell_renderer;
GtkTreeModel *sorted_model = _create_model();
tree_view = gtk_tree_view_new_with_model(sorted_model);
/* insert columns */
cell_renderer = gtk_cell_renderer_text_new();
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree_view), -1,
"name",
cell_renderer, "text", STRING_COLUMN, NULL);
cell_renderer = gtk_cell_renderer_text_new();
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree_view), -1,
"ID",
cell_renderer, "text", NUMERIC_COLUMN, NULL);
/* technical column */
cell_renderer = gtk_cell_renderer_toggle_new();
g_object_set(G_OBJECT(cell_renderer),
"activatable", TRUE,
"mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE,
NULL);
g_signal_connect(G_OBJECT(cell_renderer), "toggled",
G_CALLBACK(_toggle_odd_column), sorted_model);
gtk_tree_view_insert_column_with_data_func(GTK_TREE_VIEW(tree_view), -1,
"odd", cell_renderer,
_is_number_odd, NULL, NULL);
return tree_view;
}
/* init the main window */
static GtkWidget* _init_window( )
{
GtkWidget* top_level = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(G_OBJECT(top_level),
"delete-event", G_CALLBACK(gtk_main_quit), NULL);
return top_level;
}
/* main */
gint main(gint argc, gchar** argv)
{
GtkWidget* top_level;
GtkWidget* tree_view;
gtk_disable_setlocale();
gtk_init(&argc,&argv);
top_level = _init_window();
tree_view = _create_treeview();
gtk_container_add(GTK_CONTAINER(top_level), tree_view);
gtk_widget_show_all(top_level);
gtk_main();
return 0;
}
</code>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]