]> Pileus Git - ~andy/gtk/blob - tests/testtreeedit.c
gdk: Remove an unused enumeration
[~andy/gtk] / tests / testtreeedit.c
1 /* testtreeedit.c
2  * Copyright (C) 2001 Red Hat, Inc
3  * Author: Jonathan Blandford
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #include "config.h"
20 #include <gtk/gtk.h>
21
22 typedef struct {
23   const gchar *string;
24   gboolean is_editable;
25   gboolean is_sensitive;
26   gint progress;
27 } ListEntry;
28
29 enum {
30   STRING_COLUMN,
31   IS_EDITABLE_COLUMN,
32   IS_SENSITIVE_COLUMN,
33   PIXBUF_COLUMN,
34   LAST_PIXBUF_COLUMN,
35   PROGRESS_COLUMN,
36   NUM_COLUMNS
37 };
38
39 static ListEntry model_strings[] =
40 {
41   {"A simple string", TRUE, TRUE, 0 },
42   {"Another string!", TRUE, TRUE, 10 },
43   {"Guess what, a third string. This one can't be edited", FALSE, TRUE, 47 },
44   {"And then a fourth string. Neither can this", FALSE, TRUE, 48 },
45   {"Multiline\nFun!", TRUE, FALSE, 75 },
46   { NULL }
47 };
48
49 static GtkTreeModel *
50 create_model (void)
51 {
52   GtkTreeStore *model;
53   GtkTreeIter iter;
54   gint i;
55   GdkPixbuf *foo, *bar;
56   GtkWidget *blah;
57
58   blah = gtk_window_new (GTK_WINDOW_TOPLEVEL);
59   foo = gtk_widget_render_icon_pixbuf (blah, GTK_STOCK_NEW, GTK_ICON_SIZE_MENU);
60   bar = gtk_widget_render_icon_pixbuf (blah, GTK_STOCK_DELETE, GTK_ICON_SIZE_MENU);
61   gtk_widget_destroy (blah);
62   
63   model = gtk_tree_store_new (NUM_COLUMNS,
64                               G_TYPE_STRING,
65                               G_TYPE_BOOLEAN,
66                               G_TYPE_BOOLEAN,
67                               GDK_TYPE_PIXBUF,
68                               GDK_TYPE_PIXBUF,
69                               G_TYPE_INT);
70
71   for (i = 0; model_strings[i].string != NULL; i++)
72     {
73       gtk_tree_store_append (model, &iter, NULL);
74
75       gtk_tree_store_set (model, &iter,
76                           STRING_COLUMN, model_strings[i].string,
77                           IS_EDITABLE_COLUMN, model_strings[i].is_editable,
78                           IS_SENSITIVE_COLUMN, model_strings[i].is_sensitive,
79                           PIXBUF_COLUMN, foo,
80                           LAST_PIXBUF_COLUMN, bar,
81                           PROGRESS_COLUMN, model_strings[i].progress,
82                           -1);
83     }
84   
85   return GTK_TREE_MODEL (model);
86 }
87
88 static void
89 editable_toggled (GtkCellRendererToggle *cell,
90                   gchar                 *path_string,
91                   gpointer               data)
92 {
93   GtkTreeModel *model = GTK_TREE_MODEL (data);
94   GtkTreeIter iter;
95   GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
96   gboolean value;
97
98   gtk_tree_model_get_iter (model, &iter, path);
99   gtk_tree_model_get (model, &iter, IS_EDITABLE_COLUMN, &value, -1);
100
101   value = !value;
102   gtk_tree_store_set (GTK_TREE_STORE (model), &iter, IS_EDITABLE_COLUMN, value, -1);
103
104   gtk_tree_path_free (path);
105 }
106
107 static void
108 sensitive_toggled (GtkCellRendererToggle *cell,
109                    gchar                 *path_string,
110                    gpointer               data)
111 {
112   GtkTreeModel *model = GTK_TREE_MODEL (data);
113   GtkTreeIter iter;
114   GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
115   gboolean value;
116
117   gtk_tree_model_get_iter (model, &iter, path);
118   gtk_tree_model_get (model, &iter, IS_SENSITIVE_COLUMN, &value, -1);
119
120   value = !value;
121   gtk_tree_store_set (GTK_TREE_STORE (model), &iter, IS_SENSITIVE_COLUMN, value, -1);
122
123   gtk_tree_path_free (path);
124 }
125
126 static void
127 edited (GtkCellRendererText *cell,
128         gchar               *path_string,
129         gchar               *new_text,
130         gpointer             data)
131 {
132   GtkTreeModel *model = GTK_TREE_MODEL (data);
133   GtkTreeIter iter;
134   GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
135
136   gtk_tree_model_get_iter (model, &iter, path);
137   gtk_tree_store_set (GTK_TREE_STORE (model), &iter, STRING_COLUMN, new_text, -1);
138
139   gtk_tree_path_free (path);
140 }
141
142 static gboolean
143 button_press_event (GtkWidget *widget, GdkEventButton *event, gpointer callback_data)
144 {
145         /* Deselect if people click outside any row. */
146         if (event->window == gtk_tree_view_get_bin_window (GTK_TREE_VIEW (widget))
147             && !gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget),
148                                                event->x, event->y, NULL, NULL, NULL, NULL)) {
149                 gtk_tree_selection_unselect_all (gtk_tree_view_get_selection (GTK_TREE_VIEW (widget)));
150         }
151
152         /* Let the default code run in any case; it won't reselect anything. */
153         return FALSE;
154 }
155
156 typedef struct {
157   GtkCellArea     *area;
158   GtkCellRenderer *renderer;
159 } CallbackData;
160
161 static void
162 align_cell_toggled (GtkToggleButton  *toggle,
163                     CallbackData     *data)
164 {
165   gboolean active = gtk_toggle_button_get_active (toggle);
166
167   gtk_cell_area_cell_set (data->area, data->renderer, "align", active, NULL);
168 }
169
170 static void
171 expand_cell_toggled (GtkToggleButton  *toggle,
172                      CallbackData     *data)
173 {
174   gboolean active = gtk_toggle_button_get_active (toggle);
175
176   gtk_cell_area_cell_set (data->area, data->renderer, "expand", active, NULL);
177 }
178
179 static void
180 fixed_cell_toggled (GtkToggleButton  *toggle,
181                     CallbackData     *data)
182 {
183   gboolean active = gtk_toggle_button_get_active (toggle);
184
185   gtk_cell_area_cell_set (data->area, data->renderer, "fixed-size", active, NULL);
186 }
187
188 enum {
189   CNTL_EXPAND,
190   CNTL_ALIGN,
191   CNTL_FIXED
192 };
193
194 static void
195 create_control (GtkWidget *box, gint number, gint cntl, CallbackData *data)
196 {
197   GtkWidget *checkbutton;
198   GCallback  callback = NULL;
199   gchar *name = NULL;
200
201   switch (cntl)
202     {
203     case CNTL_EXPAND: 
204       name = g_strdup_printf ("Expand Cell #%d", number); 
205       callback = G_CALLBACK (expand_cell_toggled);
206       break;
207     case CNTL_ALIGN: 
208       name = g_strdup_printf ("Align Cell #%d", number); 
209       callback = G_CALLBACK (align_cell_toggled);
210       break;
211     case CNTL_FIXED: 
212       name = g_strdup_printf ("Fix size Cell #%d", number); 
213       callback = G_CALLBACK (fixed_cell_toggled);
214       break;
215     }
216
217   checkbutton = gtk_check_button_new_with_label (name);
218   gtk_widget_show (checkbutton);
219   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton), cntl == CNTL_FIXED);
220   gtk_box_pack_start (GTK_BOX (box), checkbutton, FALSE, FALSE, 0);
221
222   g_signal_connect (G_OBJECT (checkbutton), "toggled", callback, data);
223   g_free (name);
224 }
225
226 gint
227 main (gint argc, gchar **argv)
228 {
229   GtkWidget *window;
230   GtkWidget *scrolled_window;
231   GtkWidget *tree_view;
232   GtkWidget *vbox, *hbox, *cntl_vbox;
233   GtkTreeModel *tree_model;
234   GtkCellRenderer *renderer;
235   GtkTreeViewColumn *column;
236   GtkCellArea *area;
237   CallbackData callback[4];
238   
239   gtk_init (&argc, &argv);
240
241   if (g_getenv ("RTL"))
242     gtk_widget_set_default_direction (GTK_TEXT_DIR_RTL);
243
244   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
245   gtk_window_set_title (GTK_WINDOW (window), "GtkTreeView editing sample");
246   g_signal_connect (window, "destroy", gtk_main_quit, NULL);
247
248   vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
249   gtk_widget_show (vbox);
250   gtk_container_add (GTK_CONTAINER (window), vbox);
251
252   scrolled_window = gtk_scrolled_window_new (NULL, NULL);
253   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_ETCHED_IN);
254   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), 
255                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
256   gtk_box_pack_start (GTK_BOX (vbox), scrolled_window, TRUE, TRUE, 0);
257
258   tree_model = create_model ();
259   tree_view = gtk_tree_view_new_with_model (tree_model);
260   g_signal_connect (tree_view, "button_press_event", G_CALLBACK (button_press_event), NULL);
261   gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tree_view), TRUE);
262   gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tree_view), TRUE);
263
264   column = gtk_tree_view_column_new ();
265   gtk_tree_view_column_set_title (column, "String");
266   area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (column));
267
268   renderer = gtk_cell_renderer_pixbuf_new ();
269   gtk_tree_view_column_pack_start (column, renderer, FALSE);
270   gtk_tree_view_column_set_attributes (column, renderer,
271                                        "pixbuf", PIXBUF_COLUMN, 
272                                        "sensitive", IS_SENSITIVE_COLUMN,
273                                        NULL);
274   callback[0].area = area;
275   callback[0].renderer = renderer;
276
277   renderer = gtk_cell_renderer_text_new ();
278   gtk_tree_view_column_pack_start (column, renderer, FALSE);
279   gtk_tree_view_column_set_attributes (column, renderer,
280                                        "text", STRING_COLUMN,
281                                        "editable", IS_EDITABLE_COLUMN,
282                                        "sensitive", IS_SENSITIVE_COLUMN,
283                                        NULL);
284   callback[1].area = area;
285   callback[1].renderer = renderer;
286   g_signal_connect (renderer, "edited",
287                     G_CALLBACK (edited), tree_model);
288
289   renderer = gtk_cell_renderer_text_new ();
290   gtk_tree_view_column_pack_start (column, renderer, FALSE);
291   gtk_tree_view_column_set_attributes (column, renderer,
292                                        "text", STRING_COLUMN,
293                                        "editable", IS_EDITABLE_COLUMN,
294                                        "sensitive", IS_SENSITIVE_COLUMN,
295                                        NULL);
296   callback[2].area = area;
297   callback[2].renderer = renderer;
298   g_signal_connect (renderer, "edited",
299                     G_CALLBACK (edited), tree_model);
300
301   renderer = gtk_cell_renderer_pixbuf_new ();
302   g_object_set (renderer,
303                 "xalign", 0.0,
304                 NULL);
305   gtk_tree_view_column_pack_start (column, renderer, FALSE);
306   gtk_tree_view_column_set_attributes (column, renderer,
307                                        "pixbuf", LAST_PIXBUF_COLUMN, 
308                                        "sensitive", IS_SENSITIVE_COLUMN,
309                                        NULL);
310   callback[3].area = area;
311   callback[3].renderer = renderer;
312
313   gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
314
315   renderer = gtk_cell_renderer_toggle_new ();
316   g_signal_connect (renderer, "toggled",
317                     G_CALLBACK (editable_toggled), tree_model);
318   
319   g_object_set (renderer,
320                 "xalign", 0.0,
321                 NULL);
322   gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
323                                                -1, "Editable",
324                                                renderer,
325                                                "active", IS_EDITABLE_COLUMN,
326                                                NULL);
327
328   renderer = gtk_cell_renderer_toggle_new ();
329   g_signal_connect (renderer, "toggled",
330                     G_CALLBACK (sensitive_toggled), tree_model);
331   
332   g_object_set (renderer,
333                 "xalign", 0.0,
334                 NULL);
335   gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
336                                                -1, "Sensitive",
337                                                renderer,
338                                                "active", IS_SENSITIVE_COLUMN,
339                                                NULL);
340
341   renderer = gtk_cell_renderer_progress_new ();
342   gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
343                                                -1, "Progress",
344                                                renderer,
345                                                "value", PROGRESS_COLUMN,
346                                                NULL);
347
348   gtk_container_add (GTK_CONTAINER (scrolled_window), tree_view);
349   
350   gtk_window_set_default_size (GTK_WINDOW (window),
351                                800, 250);
352
353   hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
354   gtk_widget_show (hbox);
355   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
356
357   /* Alignment controls */
358   cntl_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
359   gtk_widget_show (cntl_vbox);
360   gtk_box_pack_start (GTK_BOX (hbox), cntl_vbox, FALSE, FALSE, 0);
361
362   create_control (cntl_vbox, 1, CNTL_ALIGN, &callback[0]);
363   create_control (cntl_vbox, 2, CNTL_ALIGN, &callback[1]);
364   create_control (cntl_vbox, 3, CNTL_ALIGN, &callback[2]);
365   create_control (cntl_vbox, 4, CNTL_ALIGN, &callback[3]);
366
367   /* Expand controls */
368   cntl_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
369   gtk_widget_show (cntl_vbox);
370   gtk_box_pack_start (GTK_BOX (hbox), cntl_vbox, FALSE, FALSE, 0);
371
372   create_control (cntl_vbox, 1, CNTL_EXPAND, &callback[0]);
373   create_control (cntl_vbox, 2, CNTL_EXPAND, &callback[1]);
374   create_control (cntl_vbox, 3, CNTL_EXPAND, &callback[2]);
375   create_control (cntl_vbox, 4, CNTL_EXPAND, &callback[3]);
376
377   /* Fixed controls */
378   cntl_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
379   gtk_widget_show (cntl_vbox);
380   gtk_box_pack_start (GTK_BOX (hbox), cntl_vbox, FALSE, FALSE, 0);
381
382   create_control (cntl_vbox, 1, CNTL_FIXED, &callback[0]);
383   create_control (cntl_vbox, 2, CNTL_FIXED, &callback[1]);
384   create_control (cntl_vbox, 3, CNTL_FIXED, &callback[2]);
385   create_control (cntl_vbox, 4, CNTL_FIXED, &callback[3]);
386
387   gtk_widget_show_all (window);
388   gtk_main ();
389
390   return 0;
391 }