It seems that in many cases when people want to know the cell renderer a click event happened on, they do not really need to know the cell renderer, but rather want to modify an individual cell in a particular column. For this you do not need to know the cell renderer. Use gtk_tree_view_get_path_at_pos to get a tree path from the x and y coordinates of the button event that is passed to you in a "button-press-event" signal callback (if you use the "row-activated" signal to catch double-clicks you get the tree path passed directly into the callback function). Then convert that tree path into an iter using gtk_tree_model_get_iter and modify the data in the cell you want to modify with gtk_list_store_set or gtk_tree_store_set.
If you really do need to know the cell renderer where a button press event happened, that is a bit more tricky. Here is a suggestion on how to approach this issue (the function has not been well-tested and might not work correctly if the content rendered by one renderer in different columns varies in width; please send suggestions on how to fix or improve this function to the author):
static gboolean tree_view_get_cell_from_pos(GtkTreeView *view, guint x, guint y, GtkCellRenderer **cell) { GtkTreeViewColumn *col = NULL; GList *node, *columns, *cells; guint colx = 0; g_return_val_if_fail ( view != NULL, FALSE ); g_return_val_if_fail ( cell != NULL, FALSE ); /* (1) find column and column x relative to tree view coordinates */ columns = gtk_tree_view_get_columns(view); for (node = columns; node != NULL && col == NULL; node = node->next) { GtkTreeViewColumn *checkcol = (GtkTreeViewColumn*) node->data; if (x >= colx && x < (colx + checkcol->width)) col = checkcol; else colx += checkcol->width; } g_list_free(columns); if (col == NULL) return FALSE; /* not found */ /* (2) find the cell renderer within the column */ cells = gtk_tree_view_column_get_cell_renderers(col); for (node = cells; node != NULL; node = node->next) { GtkCellRenderer *checkcell = (GtkCellRenderer*) node->data; guint width = 0, height = 0; /* Will this work for all packing modes? doesn't that * return a random width depending on the last content * rendered? */ gtk_cell_renderer_get_size(checkcell, GTK_WIDGET(view), NULL, NULL, NULL, &width, NULL); if (x >= colx && x < (colx + width)) { *cell = checkcell; g_list_free(cells); return TRUE; } colx += width; } g_list_free(cells); return FALSE; /* not found */ } static gboolean onButtonPress (GtkWidget *view, GdkEventButton *bevent, gpointer data) { GtkCellRenderer *renderer = NULL; if (tree_view_get_cell_from_pos(GTK_TREE_VIEW(view), bevent->x, bevent->y, &renderer)) g_print ("Renderer found\n"); else g_print ("Renderer not found!\n"); } |