Make sure that all timeouts in HildonBanner are removed
[hildon] / examples / hildon-pannable-area-tuning-example.c
1 /*
2  * This file is a part of hildon examples
3  *
4  * Copyright (C) 2009 Nokia Corporation, all rights reserved.
5  * Copyright (C) 2006 Claudio Saavedra
6  *
7  * Author: Claudio Saavedra <csaavedra@alumnos.utalca.cl>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; version 2.1 of
12  * the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22  * 02110-1301 USA
23  */
24
25 /* This example is based on other example written by Claudio for
26    EOG */
27
28 #include <stdlib.h>
29 #include <string.h>
30 #include <gtk/gtk.h>
31 #include <glib/gprintf.h>
32 #include <hildon/hildon.h>
33
34 typedef struct {
35     GtkWidget *pannable;
36     GtkWidget *treeview;
37 } ApplicationContext;
38
39 enum {
40     PIXBUF_COLUMN,
41     TEXT_COLUMN,
42     N_COLUMNS};
43
44 enum {
45     COLUMN_PROP_NAME = 0,
46     COLUMN_PROP_VALUE,
47     COLUMN_PROP_TYPE,
48     N_COLS
49 };
50
51 static GtkListStore *
52 create_list_store (void)
53 {
54     GtkListStore *store;
55
56     store = gtk_list_store_new (N_COLS,
57                                 G_TYPE_STRING,
58                                 G_TYPE_STRING,
59                                 G_TYPE_GTYPE);
60
61     return store;
62 }
63
64 static void
65 list_store_fill (GtkListStore *store,
66                  GObject *object)
67 {
68     guint n_properties, i;
69     GParamSpec **param_specs;
70     GtkTreeIter iter;
71     GObjectClass *objectclass;
72     gdouble f_value;
73     gint i_value;
74     gchar *s_value = NULL;
75
76     objectclass = G_OBJECT_GET_CLASS (object);
77     param_specs = g_object_class_list_properties (objectclass,
78                                                   &n_properties);
79
80     for (i = 0; i < n_properties; i++) {
81         if (param_specs [i]->owner_type == G_TYPE_FROM_CLASS (objectclass)) {
82             switch (param_specs[i]->value_type) {
83             case G_TYPE_DOUBLE:
84                 g_object_get (object,
85                               param_specs[i]->name, &f_value, NULL);
86                 s_value = g_strdup_printf ("%f", f_value);
87                 break;
88             case G_TYPE_OBJECT:
89                 break;
90            case G_TYPE_BOOLEAN:
91            case G_TYPE_ENUM:
92            case G_TYPE_UINT:
93            case G_TYPE_INT:
94                 g_object_get (object,
95                               param_specs[i]->name, &i_value, NULL);
96                 s_value = g_strdup_printf ("%d", i_value);
97                 break;
98             }
99
100             if (s_value) {
101                 gtk_list_store_append (store, &iter);
102                 gtk_list_store_set (store, &iter,
103                                     COLUMN_PROP_NAME, param_specs[i]->name,
104                                     COLUMN_PROP_VALUE, s_value,
105                                     COLUMN_PROP_TYPE, param_specs[i]->value_type,
106                                     -1);
107
108                 g_free (s_value);
109                 s_value = NULL;
110             }
111         }
112     }
113
114     g_free (param_specs);
115 }
116
117 static void
118 cell_edited_cb (GtkCellRendererText *renderer,
119                 gchar               *path_string,
120                 gchar               *s_value,
121                 gpointer             user_data)
122 {
123     ApplicationContext *app_ctx;
124     GObjectClass *objectclass;
125     GParamSpec **param_specs;
126     gint column;
127     GtkTreePath *path;
128     GtkTreeModel *model;
129     gdouble f_value;
130     gint i_value;
131     gchar *p_name;
132     GtkTreeIter iter;
133     guint n_properties, i = 0;
134
135     app_ctx = (ApplicationContext *)user_data;
136
137     objectclass = G_OBJECT_GET_CLASS (app_ctx->pannable);
138
139     model = gtk_tree_view_get_model (GTK_TREE_VIEW (app_ctx->treeview));
140     path = gtk_tree_path_new_from_string (path_string);
141     gtk_tree_model_get_iter (model, &iter, path);
142     gtk_tree_path_free (path);
143
144     gtk_tree_model_get (model, &iter,
145                         COLUMN_PROP_NAME, &p_name,
146                         -1);
147
148     param_specs = g_object_class_list_properties (objectclass,
149                                                   &n_properties);
150
151     column = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (renderer),
152                                                  "column"));
153
154     while (strcmp (param_specs[i]->name, p_name)) i++;
155
156     switch (param_specs[i]->value_type) {
157     case G_TYPE_DOUBLE:
158         f_value = g_ascii_strtod (s_value, NULL);
159         g_object_set (G_OBJECT (app_ctx->pannable),
160                       p_name, f_value, NULL);
161         break;
162     case G_TYPE_BOOLEAN:
163     case G_TYPE_ENUM:
164     case G_TYPE_UINT:
165     case G_TYPE_INT:
166         i_value = atoi (s_value);
167         g_object_set (G_OBJECT (app_ctx->pannable),
168                       p_name, i_value, NULL);
169         break;
170     }
171
172     gtk_list_store_set (GTK_LIST_STORE (model), &iter,
173                         column, s_value,
174                         -1);
175
176     g_free (param_specs);
177
178     g_free (p_name);
179 }
180
181 static GtkWidget *
182 create_attributes_treeview (ApplicationContext *app_ctx)
183 {
184     GtkCellRenderer *renderer;
185     GtkTreeViewColumn *column;
186     GtkTreeView *treeview;
187
188     treeview = GTK_TREE_VIEW (gtk_tree_view_new ());
189
190     renderer = gtk_cell_renderer_text_new ();
191     column = gtk_tree_view_column_new_with_attributes ("Property",
192                                                        renderer,
193                                                        "text",
194                                                        COLUMN_PROP_NAME,
195                                                        NULL);
196     gtk_tree_view_column_set_sort_column_id (column, COLUMN_PROP_NAME);
197     gtk_tree_view_append_column (treeview, column);
198
199     renderer = gtk_cell_renderer_text_new ();
200     g_object_set (renderer, "editable", TRUE, NULL);
201     column = gtk_tree_view_column_new_with_attributes ("Value",
202                                                        renderer,
203                                                        "text", COLUMN_PROP_VALUE,
204                                                        NULL);
205     gtk_tree_view_column_set_sort_column_id (column, COLUMN_PROP_VALUE);
206     gtk_tree_view_append_column (treeview, column);
207     g_signal_connect (renderer, "edited",
208                       G_CALLBACK (cell_edited_cb), app_ctx);
209     g_object_set_data (G_OBJECT (renderer), "column",
210                        GINT_TO_POINTER (COLUMN_PROP_VALUE));
211
212     return GTK_WIDGET (treeview);
213 }
214
215 static void
216 on_notify_cb (GObject *object,
217               GParamSpec *param_spec,
218               gpointer user_data)
219 {
220     GtkTreeModel *store;
221     GtkTreeIter iter;
222     gchar *par_name;
223     gfloat f_value;
224     gchar s_value[128];
225
226     store = GTK_TREE_MODEL (user_data);
227
228     gtk_tree_model_get_iter_first (store, &iter);
229
230     do {
231
232       gtk_tree_model_get (store, &iter,
233                           COLUMN_PROP_NAME, &par_name,
234                           -1);
235       if (strcmp (par_name, param_spec->name) == 0 &&
236           param_spec->value_type == G_TYPE_FLOAT) {
237         g_object_get (object,
238                       param_spec->name, &f_value,
239                       NULL);
240         g_sprintf (s_value, "%f", f_value);
241         gtk_list_store_set (GTK_LIST_STORE (store), &iter,
242                             COLUMN_PROP_VALUE, s_value,
243                             -1);
244       }
245
246       g_free (par_name);
247
248     } while (gtk_tree_model_iter_next (store, &iter));
249 }
250
251 static GtkWidget*
252 create_pannable_treeview (void)
253 {
254     GtkWidget *tv;
255     GtkTreeViewColumn *col;
256     GtkCellRenderer *renderer;
257     GtkListStore *store;
258     GSList *stocks, *item;
259     gint i;
260
261     /* Create a treeview */
262     tv = gtk_tree_view_new ();
263
264     g_object_set (tv, "fixed-height-mode", TRUE, NULL);
265
266     col = gtk_tree_view_column_new ();
267     gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_FIXED);
268     gtk_tree_view_column_set_title (col, "Title");
269
270     g_object_set (tv, "fixed-height-mode", TRUE, NULL);
271     renderer = gtk_cell_renderer_pixbuf_new ();
272     gtk_cell_renderer_set_fixed_size (renderer, 48, 48);
273     gtk_tree_view_column_pack_start (col, renderer, FALSE);
274     gtk_tree_view_column_set_attributes (col, renderer, "stock-id", PIXBUF_COLUMN, NULL);
275
276     renderer = gtk_cell_renderer_text_new ();
277     gtk_tree_view_column_pack_start (col, renderer, FALSE);
278     gtk_tree_view_column_set_attributes (col, renderer, "text", TEXT_COLUMN, NULL);
279     gtk_tree_view_append_column (GTK_TREE_VIEW(tv), col);
280
281     /* Add some rows to the treeview */
282     stocks = gtk_stock_list_ids ();
283     item = stocks;
284     store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
285     for (i = 0; i < 100; i++) {
286       GtkTreeIter iter;
287       GtkStockItem stock_item;
288       gchar *stock_id;
289
290       stock_id = (gchar *)item->data;
291       gtk_stock_lookup (stock_id, &stock_item);
292       gtk_list_store_append (store, &iter);
293       gtk_list_store_set (store, &iter, PIXBUF_COLUMN, stock_id, TEXT_COLUMN, stock_item.label, -1);
294
295       item = item->next? item->next : stocks;
296     }
297     gtk_tree_view_set_model (GTK_TREE_VIEW (tv), GTK_TREE_MODEL (store));
298     g_object_unref (store);
299
300     g_slist_foreach (stocks, (GFunc)g_free, NULL);
301     g_slist_free (stocks);
302
303     return tv;
304 }
305 gint
306 main (gint argc, gchar **argv)
307 {
308     HildonProgram *program;
309     GtkWidget *window;
310     GtkWidget *pannable;
311     GtkWidget *hbox, *vbox;
312     GtkWidget *treeview, *pannable_treeview;
313     GtkWidget *sw;
314     GtkListStore *store;
315     ApplicationContext *app_ctx = NULL;
316
317     hildon_gtk_init (&argc, &argv);
318
319     program = hildon_program_get_instance ();
320
321     /* Create the main window */
322     window = hildon_window_new ();
323     hildon_program_add_window (program, HILDON_WINDOW (window));
324
325     gtk_container_set_border_width (GTK_CONTAINER (window), 5);
326
327     g_signal_connect (G_OBJECT (window), "delete-event",
328                       G_CALLBACK (gtk_main_quit), NULL);
329
330     pannable = hildon_pannable_area_new ();
331
332     app_ctx = g_new0 (ApplicationContext, 1);
333     app_ctx->pannable = pannable;
334
335     pannable_treeview = create_pannable_treeview();
336
337     gtk_container_add (GTK_CONTAINER (pannable),
338                        pannable_treeview);
339
340     treeview = create_attributes_treeview (app_ctx);
341
342     app_ctx->treeview = treeview;
343     store = create_list_store ();
344
345     gtk_tree_view_set_model (GTK_TREE_VIEW (treeview),
346                              GTK_TREE_MODEL (store));
347
348     list_store_fill (store, G_OBJECT (pannable));
349
350     sw = gtk_scrolled_window_new (NULL, NULL);
351     gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
352                                          GTK_SHADOW_ETCHED_IN);
353     gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
354                                     GTK_POLICY_NEVER,
355                                     GTK_POLICY_AUTOMATIC);
356
357     gtk_container_add (GTK_CONTAINER (sw), treeview);
358
359     hbox = gtk_hbox_new (FALSE, 10);
360
361     vbox = gtk_vbox_new (FALSE, 10);
362     gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 10);
363
364     gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 10);
365
366 /*     vbox = gtk_vbox_new (FALSE, 10); */
367 /*     gtk_box_pack_start (GTK_BOX (vbox), pannable, TRUE, TRUE, 10); */
368     gtk_box_pack_start (GTK_BOX (hbox), pannable, TRUE, TRUE, 10);
369
370     g_signal_connect_after (pannable, "notify",
371                             G_CALLBACK (on_notify_cb), store);
372
373     gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
374     gtk_container_add (GTK_CONTAINER (window), hbox);
375
376     gtk_widget_show_all (window);
377
378     gtk_main ();
379
380     g_free (app_ctx);
381
382     return 0;
383 }