1#include <gtk/gtk.h>
2
3static gboolean
4clicked_icon (GtkTreeView *tv,
5 int x,
6 int y,
7 GtkTreePath **path)
8{
9 GtkTreeViewColumn *col;
10 int cell_x, cell_y;
11 int cell_pos, cell_width;
12 GList *cells, *l;
13 int depth;
14 int level_indentation;
15 int expander_size;
16 int indent;
17
18 if (gtk_tree_view_get_path_at_pos (tree_view: tv, x, y, path, column: &col, cell_x: &cell_x, cell_y: &cell_y))
19 {
20 cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (col));
21
22#if 1
23 /* ugly workaround to fix the problem:
24 * manually calculate the indent for the row
25 */
26 depth = gtk_tree_path_get_depth (path: *path);
27 level_indentation = gtk_tree_view_get_level_indentation (tree_view: tv);
28 expander_size = 16; /* Hardcoded in gtktreeview.c */
29 expander_size += 4;
30 indent = (depth - 1) * level_indentation + depth * expander_size;
31#else
32 indent = 0;
33#endif
34
35 for (l = cells; l; l = l->next)
36 {
37 gtk_tree_view_column_cell_get_position (tree_column: col, cell_renderer: l->data, x_offset: &cell_pos, width: &cell_width);
38 if (cell_pos + indent <= cell_x && cell_x <= cell_pos + indent + cell_width)
39 {
40 g_print (format: "clicked in %s\n", g_type_name_from_instance (instance: l->data));
41 if (GTK_IS_CELL_RENDERER_PIXBUF (l->data))
42 {
43 g_list_free (list: cells);
44 return TRUE;
45 }
46 }
47 }
48
49 g_list_free (list: cells);
50 }
51
52 return FALSE;
53}
54
55static void
56release_event (GtkGestureClick *gesture,
57 guint n_press,
58 double x,
59 double y,
60 GtkTreeView *tv)
61{
62 GtkTreePath *path;
63 int tx, ty;
64
65 gtk_tree_view_convert_widget_to_tree_coords (tree_view: tv, wx: x, wy: y, tx: &tx, ty: &ty);
66
67 if (clicked_icon (tv, x: tx, y: ty, path: &path))
68 {
69 GtkTreeModel *model;
70 GtkTreeIter iter;
71 char *text;
72
73 model = gtk_tree_view_get_model (tree_view: tv);
74 gtk_tree_model_get_iter (tree_model: model, iter: &iter, path);
75 gtk_tree_model_get (tree_model: model, iter: &iter, 0, &text, -1);
76
77 g_print (format: "text was: %s\n", text);
78 g_free (mem: text);
79 gtk_tree_path_free (path);
80 }
81}
82
83int main (int argc, char *argv[])
84{
85 GtkWidget *window;
86 GtkWidget *sw;
87 GtkWidget *tv;
88 GtkTreeViewColumn *col;
89 GtkCellRenderer *cell;
90 GtkTreeStore *store;
91 GtkTreeIter iter;
92 GtkGesture *gesture;
93
94 gtk_init ();
95
96 window = gtk_window_new ();
97 sw = gtk_scrolled_window_new ();
98 gtk_window_set_child (GTK_WINDOW (window), child: sw);
99 tv = gtk_tree_view_new ();
100 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), child: tv);
101
102 col = gtk_tree_view_column_new ();
103 cell = gtk_cell_renderer_text_new ();
104 gtk_tree_view_column_pack_start (tree_column: col, cell, TRUE);
105 gtk_tree_view_column_add_attribute (tree_column: col, cell_renderer: cell, attribute: "text", column: 0);
106
107 cell = gtk_cell_renderer_toggle_new ();
108 gtk_tree_view_column_pack_start (tree_column: col, cell, FALSE);
109 gtk_tree_view_column_add_attribute (tree_column: col, cell_renderer: cell, attribute: "active", column: 1);
110
111 cell = gtk_cell_renderer_text_new ();
112 gtk_tree_view_column_pack_start (tree_column: col, cell, TRUE);
113 gtk_tree_view_column_add_attribute (tree_column: col, cell_renderer: cell, attribute: "text", column: 0);
114
115 cell = gtk_cell_renderer_pixbuf_new ();
116 gtk_tree_view_column_pack_start (tree_column: col, cell, FALSE);
117 gtk_tree_view_column_add_attribute (tree_column: col, cell_renderer: cell, attribute: "icon-name", column: 2);
118
119 cell = gtk_cell_renderer_toggle_new ();
120 gtk_tree_view_column_pack_start (tree_column: col, cell, FALSE);
121 gtk_tree_view_column_add_attribute (tree_column: col, cell_renderer: cell, attribute: "active", column: 1);
122
123 gtk_tree_view_append_column (GTK_TREE_VIEW (tv), column: col);
124
125 store = gtk_tree_store_new (n_columns: 3, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_STRING);
126 gtk_tree_store_insert_with_values (tree_store: store, NULL, NULL, position: 0, 0, "One row", 1, FALSE, 2, "document-open", -1);
127 gtk_tree_store_insert_with_values (tree_store: store, iter: &iter, NULL, position: 1, 0, "Two row", 1, FALSE, 2, "dialog-warning", -1);
128 gtk_tree_store_insert_with_values (tree_store: store, NULL, parent: &iter, position: 0, 0, "Three row", 1, FALSE, 2, "dialog-error", -1);
129
130 gtk_tree_view_set_model (GTK_TREE_VIEW (tv), GTK_TREE_MODEL (store));
131
132 gesture = gtk_gesture_click_new ();
133 gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
134 phase: GTK_PHASE_CAPTURE);
135 g_signal_connect (gesture, "released",
136 G_CALLBACK (release_event), tv);
137 gtk_widget_add_controller (widget: tv, GTK_EVENT_CONTROLLER (gesture));
138
139 gtk_widget_show (widget: window);
140
141 while (TRUE)
142 g_main_context_iteration (NULL, TRUE);
143
144 return 0;
145}
146

source code of gtk/tests/testtreepos.c