]> Pileus Git - ~andy/gtk/blob - tests/testtreeedit.c
712dad41282d6039d705eb6e66ab923690319bac
[~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, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include "config.h"
22 #include <gtk/gtk.h>
23
24 typedef struct {
25   const gchar *string;
26   gboolean is_editable;
27   gint progress;
28 } ListEntry;
29
30 enum {
31   STRING_COLUMN,
32   IS_EDITABLE_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, 0 },
42   {"Another string!", TRUE, 10 },
43   {"Guess what, a third string. This one can't be edited", FALSE, 47 },
44   {"And then a fourth string. Neither can this", FALSE, 48 },
45   {"Multiline\nFun!", TRUE, 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                               GDK_TYPE_PIXBUF,
67                               GDK_TYPE_PIXBUF,
68                               G_TYPE_INT);
69
70   for (i = 0; model_strings[i].string != NULL; i++)
71     {
72       gtk_tree_store_append (model, &iter, NULL);
73
74       gtk_tree_store_set (model, &iter,
75                           STRING_COLUMN, model_strings[i].string,
76                           IS_EDITABLE_COLUMN, model_strings[i].is_editable,
77                           PIXBUF_COLUMN, foo,
78                           LAST_PIXBUF_COLUMN, bar,
79                           PROGRESS_COLUMN, model_strings[i].progress,
80                           -1);
81     }
82   
83   return GTK_TREE_MODEL (model);
84 }
85
86 static void
87 toggled (GtkCellRendererToggle *cell,
88          gchar                 *path_string,
89          gpointer               data)
90 {
91   GtkTreeModel *model = GTK_TREE_MODEL (data);
92   GtkTreeIter iter;
93   GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
94   gboolean value;
95
96   gtk_tree_model_get_iter (model, &iter, path);
97   gtk_tree_model_get (model, &iter, IS_EDITABLE_COLUMN, &value, -1);
98
99   value = !value;
100   gtk_tree_store_set (GTK_TREE_STORE (model), &iter, IS_EDITABLE_COLUMN, value, -1);
101
102   gtk_tree_path_free (path);
103 }
104
105 static void
106 edited (GtkCellRendererText *cell,
107         gchar               *path_string,
108         gchar               *new_text,
109         gpointer             data)
110 {
111   GtkTreeModel *model = GTK_TREE_MODEL (data);
112   GtkTreeIter iter;
113   GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
114
115   gtk_tree_model_get_iter (model, &iter, path);
116   gtk_tree_store_set (GTK_TREE_STORE (model), &iter, STRING_COLUMN, new_text, -1);
117
118   gtk_tree_path_free (path);
119 }
120
121 static gboolean
122 button_press_event (GtkWidget *widget, GdkEventButton *event, gpointer callback_data)
123 {
124         /* Deselect if people click outside any row. */
125         if (event->window == gtk_tree_view_get_bin_window (GTK_TREE_VIEW (widget))
126             && !gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget),
127                                                event->x, event->y, NULL, NULL, NULL, NULL)) {
128                 gtk_tree_selection_unselect_all (gtk_tree_view_get_selection (GTK_TREE_VIEW (widget)));
129         }
130
131         /* Let the default code run in any case; it won't reselect anything. */
132         return FALSE;
133 }
134
135 typedef struct {
136   GtkCellArea     *area;
137   GtkCellRenderer *renderer;
138 } CallbackData;
139
140 static void
141 align_cell_toggled (GtkToggleButton  *toggle,
142                     CallbackData     *data)
143 {
144   gboolean active = gtk_toggle_button_get_active (toggle);
145
146   gtk_cell_area_cell_set (data->area, data->renderer, "align", active, NULL);
147 }
148
149 static void
150 expand_cell_toggled (GtkToggleButton  *toggle,
151                      CallbackData     *data)
152 {
153   gboolean active = gtk_toggle_button_get_active (toggle);
154
155   gtk_cell_area_cell_set (data->area, data->renderer, "expand", active, NULL);
156 }
157
158 static void
159 fixed_cell_toggled (GtkToggleButton  *toggle,
160                     CallbackData     *data)
161 {
162   gboolean active = gtk_toggle_button_get_active (toggle);
163
164   gtk_cell_area_cell_set (data->area, data->renderer, "fixed-size", active, NULL);
165 }
166
167 enum {
168   CNTL_EXPAND,
169   CNTL_ALIGN,
170   CNTL_FIXED
171 };
172
173 static void
174 create_control (GtkWidget *box, gint number, gint cntl, CallbackData *data)
175 {
176   GtkWidget *checkbutton;
177   GCallback  callback = NULL;
178   gchar *name = NULL;
179
180   switch (cntl)
181     {
182     case CNTL_EXPAND: 
183       name = g_strdup_printf ("Expand Cell #%d", number); 
184       callback = G_CALLBACK (expand_cell_toggled);
185       break;
186     case CNTL_ALIGN: 
187       name = g_strdup_printf ("Align Cell #%d", number); 
188       callback = G_CALLBACK (align_cell_toggled);
189       break;
190     case CNTL_FIXED: 
191       name = g_strdup_printf ("Fix size Cell #%d", number); 
192       callback = G_CALLBACK (fixed_cell_toggled);
193       break;
194     }
195
196   checkbutton = gtk_check_button_new_with_label (name);
197   gtk_widget_show (checkbutton);
198   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton), cntl == CNTL_FIXED);
199   gtk_box_pack_start (GTK_BOX (box), checkbutton, FALSE, FALSE, 0);
200
201   g_signal_connect (G_OBJECT (checkbutton), "toggled", callback, data);
202   g_free (name);
203 }
204
205 gint
206 main (gint argc, gchar **argv)
207 {
208   GtkWidget *window;
209   GtkWidget *scrolled_window;
210   GtkWidget *tree_view;
211   GtkWidget *vbox, *hbox, *cntl_vbox;
212   GtkTreeModel *tree_model;
213   GtkCellRenderer *renderer;
214   GtkTreeViewColumn *column;
215   GtkCellArea *area;
216   CallbackData callback[4];
217   
218   gtk_init (&argc, &argv);
219
220   if (g_getenv ("RTL"))
221     gtk_widget_set_default_direction (GTK_TEXT_DIR_RTL);
222
223   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
224   gtk_window_set_title (GTK_WINDOW (window), "GtkTreeView editing sample");
225   g_signal_connect (window, "destroy", gtk_main_quit, NULL);
226
227   vbox = gtk_vbox_new (FALSE, 6);
228   gtk_widget_show (vbox);
229   gtk_container_add (GTK_CONTAINER (window), vbox);
230
231   scrolled_window = gtk_scrolled_window_new (NULL, NULL);
232   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_ETCHED_IN);
233   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), 
234                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
235   gtk_box_pack_start (GTK_BOX (vbox), scrolled_window, TRUE, TRUE, 0);
236
237   tree_model = create_model ();
238   tree_view = gtk_tree_view_new_with_model (tree_model);
239   g_signal_connect (tree_view, "button_press_event", G_CALLBACK (button_press_event), NULL);
240   gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tree_view), TRUE);
241   gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tree_view), TRUE);
242
243   column = gtk_tree_view_column_new ();
244   gtk_tree_view_column_set_title (column, "String");
245   area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (column));
246
247   renderer = gtk_cell_renderer_pixbuf_new ();
248   gtk_tree_view_column_pack_start (column, renderer, FALSE);
249   gtk_tree_view_column_set_attributes (column, renderer,
250                                        "pixbuf", PIXBUF_COLUMN, NULL);
251   callback[0].area = area;
252   callback[0].renderer = renderer;
253
254   renderer = gtk_cell_renderer_text_new ();
255   gtk_tree_view_column_pack_start (column, renderer, FALSE);
256   gtk_tree_view_column_set_attributes (column, renderer,
257                                        "text", STRING_COLUMN,
258                                        "editable", IS_EDITABLE_COLUMN,
259                                        NULL);
260   callback[1].area = area;
261   callback[1].renderer = renderer;
262   g_signal_connect (renderer, "edited",
263                     G_CALLBACK (edited), tree_model);
264
265   renderer = gtk_cell_renderer_text_new ();
266   gtk_tree_view_column_pack_start (column, renderer, FALSE);
267   gtk_tree_view_column_set_attributes (column, renderer,
268                                        "text", STRING_COLUMN,
269                                        "editable", IS_EDITABLE_COLUMN,
270                                        NULL);
271   callback[2].area = area;
272   callback[2].renderer = renderer;
273   g_signal_connect (renderer, "edited",
274                     G_CALLBACK (edited), tree_model);
275
276   renderer = gtk_cell_renderer_pixbuf_new ();
277   g_object_set (renderer,
278                 "xalign", 0.0,
279                 NULL);
280   gtk_tree_view_column_pack_start (column, renderer, FALSE);
281   gtk_tree_view_column_set_attributes (column, renderer,
282                                        "pixbuf", LAST_PIXBUF_COLUMN, NULL);
283   callback[3].area = area;
284   callback[3].renderer = renderer;
285
286   gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
287
288   renderer = gtk_cell_renderer_toggle_new ();
289   g_signal_connect (renderer, "toggled",
290                     G_CALLBACK (toggled), tree_model);
291   
292   g_object_set (renderer,
293                 "xalign", 0.0,
294                 NULL);
295   gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
296                                                -1, "Editable",
297                                                renderer,
298                                                "active", IS_EDITABLE_COLUMN,
299                                                NULL);
300
301   renderer = gtk_cell_renderer_progress_new ();
302   gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
303                                                -1, "Progress",
304                                                renderer,
305                                                "value", PROGRESS_COLUMN,
306                                                NULL);
307
308   gtk_container_add (GTK_CONTAINER (scrolled_window), tree_view);
309   
310   gtk_window_set_default_size (GTK_WINDOW (window),
311                                800, 250);
312
313   hbox = gtk_hbox_new (FALSE, 6);
314   gtk_widget_show (hbox);
315   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
316
317   /* Alignment controls */
318   cntl_vbox = gtk_vbox_new (FALSE, 2);
319   gtk_widget_show (cntl_vbox);
320   gtk_box_pack_start (GTK_BOX (hbox), cntl_vbox, FALSE, FALSE, 0);
321
322   create_control (cntl_vbox, 1, CNTL_ALIGN, &callback[0]);
323   create_control (cntl_vbox, 2, CNTL_ALIGN, &callback[1]);
324   create_control (cntl_vbox, 3, CNTL_ALIGN, &callback[2]);
325   create_control (cntl_vbox, 4, CNTL_ALIGN, &callback[3]);
326
327   /* Expand controls */
328   cntl_vbox = gtk_vbox_new (FALSE, 2);
329   gtk_widget_show (cntl_vbox);
330   gtk_box_pack_start (GTK_BOX (hbox), cntl_vbox, FALSE, FALSE, 0);
331
332   create_control (cntl_vbox, 1, CNTL_EXPAND, &callback[0]);
333   create_control (cntl_vbox, 2, CNTL_EXPAND, &callback[1]);
334   create_control (cntl_vbox, 3, CNTL_EXPAND, &callback[2]);
335   create_control (cntl_vbox, 4, CNTL_EXPAND, &callback[3]);
336
337   /* Fixed controls */
338   cntl_vbox = gtk_vbox_new (FALSE, 2);
339   gtk_widget_show (cntl_vbox);
340   gtk_box_pack_start (GTK_BOX (hbox), cntl_vbox, FALSE, FALSE, 0);
341
342   create_control (cntl_vbox, 1, CNTL_FIXED, &callback[0]);
343   create_control (cntl_vbox, 2, CNTL_FIXED, &callback[1]);
344   create_control (cntl_vbox, 3, CNTL_FIXED, &callback[2]);
345   create_control (cntl_vbox, 4, CNTL_FIXED, &callback[3]);
346
347   gtk_widget_show_all (window);
348   gtk_main ();
349
350   return 0;
351 }