]> Pileus Git - ~andy/gtk/blob - tests/testtreeedit.c
Merge branch 'master' into treeview-refactor
[~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 (blah, GTK_STOCK_NEW, GTK_ICON_SIZE_MENU, NULL);
60   bar = gtk_widget_render_icon (blah, GTK_STOCK_DELETE, GTK_ICON_SIZE_MENU, NULL);
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 create_control (GtkWidget *box, gint number, gboolean align, CallbackData *data)
160 {
161   GtkWidget *checkbutton;
162   gchar *name;
163
164   if (align)
165     name = g_strdup_printf ("Align Cell #%d", number);
166   else
167     name = g_strdup_printf ("Expand Cell #%d", number);
168
169   checkbutton = gtk_check_button_new_with_label (name);
170   gtk_widget_show (checkbutton);
171   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton), align);
172   gtk_box_pack_start (GTK_BOX (box), checkbutton, FALSE, FALSE, 0);
173
174   if (align)
175     g_signal_connect (G_OBJECT (checkbutton), "toggled",
176                       G_CALLBACK (align_cell_toggled), data);
177   else
178     g_signal_connect (G_OBJECT (checkbutton), "toggled",
179                       G_CALLBACK (expand_cell_toggled), data);
180 }
181
182 gint
183 main (gint argc, gchar **argv)
184 {
185   GtkWidget *window;
186   GtkWidget *scrolled_window;
187   GtkWidget *tree_view;
188   GtkWidget *vbox, *hbox, *cntl_vbox;
189   GtkTreeModel *tree_model;
190   GtkCellRenderer *renderer;
191   GtkTreeViewColumn *column;
192   GtkCellArea *area;
193   CallbackData callback[4];
194   
195   gtk_init (&argc, &argv);
196
197   if (g_getenv ("RTL"))
198     gtk_widget_set_default_direction (GTK_TEXT_DIR_RTL);
199
200   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
201   gtk_window_set_title (GTK_WINDOW (window), "GtkTreeView editing sample");
202   g_signal_connect (window, "destroy", gtk_main_quit, NULL);
203
204   vbox = gtk_vbox_new (FALSE, 6);
205   gtk_widget_show (vbox);
206   gtk_container_add (GTK_CONTAINER (window), vbox);
207
208   scrolled_window = gtk_scrolled_window_new (NULL, NULL);
209   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_ETCHED_IN);
210   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), 
211                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
212   gtk_box_pack_start (GTK_BOX (vbox), scrolled_window, TRUE, TRUE, 0);
213
214   tree_model = create_model ();
215   tree_view = gtk_tree_view_new_with_model (tree_model);
216   g_signal_connect (tree_view, "button_press_event", G_CALLBACK (button_press_event), NULL);
217   gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tree_view), TRUE);
218   gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tree_view), TRUE);
219
220   column = gtk_tree_view_column_new ();
221   gtk_tree_view_column_set_title (column, "String");
222   area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (column));
223
224   renderer = gtk_cell_renderer_pixbuf_new ();
225   gtk_tree_view_column_pack_start (column, renderer, FALSE);
226   gtk_tree_view_column_set_attributes (column, renderer,
227                                        "pixbuf", PIXBUF_COLUMN, NULL);
228   callback[0].area = area;
229   callback[0].renderer = renderer;
230
231   renderer = gtk_cell_renderer_text_new ();
232   gtk_tree_view_column_pack_start (column, renderer, FALSE);
233   gtk_tree_view_column_set_attributes (column, renderer,
234                                        "text", STRING_COLUMN,
235                                        "editable", IS_EDITABLE_COLUMN,
236                                        NULL);
237   callback[1].area = area;
238   callback[1].renderer = renderer;
239   g_signal_connect (renderer, "edited",
240                     G_CALLBACK (edited), tree_model);
241
242   renderer = gtk_cell_renderer_text_new ();
243   gtk_tree_view_column_pack_start (column, renderer, FALSE);
244   gtk_tree_view_column_set_attributes (column, renderer,
245                                        "text", STRING_COLUMN,
246                                        "editable", IS_EDITABLE_COLUMN,
247                                        NULL);
248   callback[2].area = area;
249   callback[2].renderer = renderer;
250   g_signal_connect (renderer, "edited",
251                     G_CALLBACK (edited), tree_model);
252
253   renderer = gtk_cell_renderer_pixbuf_new ();
254   g_object_set (renderer,
255                 "xalign", 0.0,
256                 NULL);
257   gtk_tree_view_column_pack_start (column, renderer, FALSE);
258   gtk_tree_view_column_set_attributes (column, renderer,
259                                        "pixbuf", LAST_PIXBUF_COLUMN, NULL);
260   callback[3].area = area;
261   callback[3].renderer = renderer;
262
263   gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
264
265   renderer = gtk_cell_renderer_toggle_new ();
266   g_signal_connect (renderer, "toggled",
267                     G_CALLBACK (toggled), tree_model);
268   
269   g_object_set (renderer,
270                 "xalign", 0.0,
271                 NULL);
272   gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
273                                                -1, "Editable",
274                                                renderer,
275                                                "active", IS_EDITABLE_COLUMN,
276                                                NULL);
277
278   renderer = gtk_cell_renderer_progress_new ();
279   gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
280                                                -1, "Progress",
281                                                renderer,
282                                                "value", PROGRESS_COLUMN,
283                                                NULL);
284
285   gtk_container_add (GTK_CONTAINER (scrolled_window), tree_view);
286   
287   gtk_window_set_default_size (GTK_WINDOW (window),
288                                800, 250);
289
290   hbox = gtk_hbox_new (FALSE, 6);
291   gtk_widget_show (hbox);
292   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
293
294   /* Alignment controls */
295   cntl_vbox = gtk_vbox_new (FALSE, 2);
296   gtk_widget_show (cntl_vbox);
297   gtk_box_pack_start (GTK_BOX (hbox), cntl_vbox, FALSE, FALSE, 0);
298
299   create_control (cntl_vbox, 1, TRUE, &callback[0]);
300   create_control (cntl_vbox, 2, TRUE, &callback[1]);
301   create_control (cntl_vbox, 3, TRUE, &callback[2]);
302   create_control (cntl_vbox, 4, TRUE, &callback[3]);
303
304   /* Expand controls */
305   cntl_vbox = gtk_vbox_new (FALSE, 2);
306   gtk_widget_show (cntl_vbox);
307   gtk_box_pack_start (GTK_BOX (hbox), cntl_vbox, FALSE, FALSE, 0);
308
309   create_control (cntl_vbox, 1, FALSE, &callback[0]);
310   create_control (cntl_vbox, 2, FALSE, &callback[1]);
311   create_control (cntl_vbox, 3, FALSE, &callback[2]);
312   create_control (cntl_vbox, 4, FALSE, &callback[3]);
313
314   gtk_widget_show_all (window);
315   gtk_main ();
316
317   return 0;
318 }