Attachment 'gtk-simple-list-20sep2008.diff'
Download 1 diff --git a/gtk/Makefile.am b/gtk/Makefile.am
2 index 2d11750..1d83fb1 100644
3 --- a/gtk/Makefile.am
4 +++ b/gtk/Makefile.am
5 @@ -274,6 +274,7 @@ gtk_public_h_sources = \
6 gtkseparatortoolitem.h \
7 gtkshow.h \
8 gtksettings.h \
9 + gtksimplelist.h \
10 gtksizegroup.h \
11 gtksocket.h \
12 gtkspinbutton.h \
13 @@ -535,6 +536,7 @@ gtk_base_c_sources = \
14 gtkseparatormenuitem.c \
15 gtkseparatortoolitem.c \
16 gtksettings.c \
17 + gtksimplelist.c \
18 gtksizegroup.c \
19 gtkshow.c \
20 gtksocket.c \
21 diff --git a/gtk/gtk.h b/gtk/gtk.h
22 index c3d7a4d..195b920 100644
23 --- a/gtk/gtk.h
24 +++ b/gtk/gtk.h
25 @@ -160,6 +160,7 @@
26 #include <gtk/gtkseparatortoolitem.h>
27 #include <gtk/gtksettings.h>
28 #include <gtk/gtkshow.h>
29 +#include <gtk/gtksimplelist.h>
30 #include <gtk/gtksizegroup.h>
31 #include <gtk/gtksocket.h>
32 #include <gtk/gtkspinbutton.h>
33 diff --git a/gtk/gtksimplelist.c b/gtk/gtksimplelist.c
34 new file mode 100644
35 index 0000000..c6cc688
36 --- /dev/null
37 +++ b/gtk/gtksimplelist.c
38 @@ -0,0 +1,865 @@
39 +/* gtksimplelist.c
40 + * Copyright (C) 2008 Kristian Rietveld <kris@gtk.org>
41 + *
42 + * This library is free software; you can redistribute it and/or
43 + * modify it under the terms of the GNU Library General Public
44 + * License as published by the Free Software Foundation; either
45 + * version 2 of the License, or (at your option) any later version.
46 + *
47 + * This library is distributed in the hope that it will be useful,
48 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
49 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
50 + * Library General Public License for more details.
51 + *
52 + * You should have received a copy of the GNU Library General Public
53 + * License along with this library; if not, write to the
54 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
55 + * Boston, MA 02111-1307, USA.
56 + */
57 +
58 +#include "config.h"
59 +
60 +#include "gtksimplelist.h"
61 +#include "gtktreeselection.h"
62 +#include "gtkcellrenderertext.h"
63 +#include "gtkcellrendererpixbuf.h"
64 +#include "gtkcellrenderertoggle.h"
65 +#include "gtkcellrendererprogress.h"
66 +#include "gtkmarshalers.h"
67 +#include "gtkintl.h"
68 +#include "gtkprivate.h"
69 +#include "gtkalias.h"
70 +
71 +#include <gobject/gvaluecollector.h>
72 +
73 +#define GTK_SIMPLE_LIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_SIMPLE_LIST, GtkSimpleListPrivate))
74 +
75 +struct _GtkSimpleListPrivate
76 +{
77 + int n_columns;
78 + GtkSimpleListColumn *columns;
79 +
80 + guint is_sortable : 1;
81 + guint is_resizable : 1;
82 +
83 + guint is_updating_selection : 1;
84 +};
85 +
86 +/* Signals */
87 +enum
88 +{
89 + SELECTION_CHANGED,
90 + INDEX_ACTIVATED,
91 + LAST_SIGNAL
92 +};
93 +
94 +/* Properties */
95 +enum
96 +{
97 + PROP_0,
98 +};
99 +
100 +
101 +static void gtk_simple_list_class_init (GtkSimpleListClass *klass);
102 +static void gtk_simple_list_init (GtkSimpleList *simple_list);
103 +static void gtk_simple_list_finalize (GObject *object);
104 +
105 +static void gtk_simple_list_row_activated (GtkTreeView *tree_view,
106 + GtkTreePath *path,
107 + GtkTreeViewColumn *column,
108 + gpointer user_data);
109 +static void gtk_simple_list_selection_changed (GtkTreeSelection *selection,
110 + gpointer user_data);
111 +
112 +
113 +static guint simple_list_signals[LAST_SIGNAL] = { 0, };
114 +
115 +G_DEFINE_TYPE (GtkSimpleList, gtk_simple_list, GTK_TYPE_TREE_VIEW);
116 +
117 +static void
118 +gtk_simple_list_class_init (GtkSimpleListClass *klass)
119 +{
120 + GObjectClass *object_class;
121 +
122 + g_type_class_add_private (klass, sizeof (GtkSimpleListPrivate));
123 +
124 + object_class = G_OBJECT_CLASS (klass);
125 +
126 + object_class->finalize = gtk_simple_list_finalize;
127 +
128 + simple_list_signals[SELECTION_CHANGED] =
129 + g_signal_new ("selection-changed",
130 + G_TYPE_FROM_CLASS (klass),
131 + G_SIGNAL_RUN_FIRST,
132 + G_STRUCT_OFFSET (GtkSimpleListClass, selection_changed),
133 + NULL, NULL,
134 + _gtk_marshal_VOID__POINTER,
135 + G_TYPE_NONE, 1,
136 + G_TYPE_POINTER);
137 +
138 + simple_list_signals[INDEX_ACTIVATED] =
139 + g_signal_new ("index-activated",
140 + G_TYPE_FROM_CLASS (klass),
141 + G_SIGNAL_RUN_FIRST,
142 + G_STRUCT_OFFSET (GtkSimpleListClass, index_activated),
143 + NULL, NULL,
144 + _gtk_marshal_VOID__INT,
145 + G_TYPE_NONE, 1,
146 + G_TYPE_INT);
147 +}
148 +
149 +static void
150 +gtk_simple_list_init (GtkSimpleList *simple_list)
151 +{
152 + GtkTreeSelection *selection;
153 +
154 + simple_list->priv = GTK_SIMPLE_LIST_GET_PRIVATE (simple_list);
155 +
156 + simple_list->priv->columns = NULL;
157 +
158 + g_signal_connect (simple_list, "row-activated",
159 + G_CALLBACK (gtk_simple_list_row_activated), NULL);
160 +
161 + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (simple_list));
162 + g_signal_connect (selection, "changed",
163 + G_CALLBACK (gtk_simple_list_selection_changed), simple_list);
164 +}
165 +
166 +static void
167 +gtk_simple_list_finalize (GObject *object)
168 +{
169 + GtkSimpleList *list = GTK_SIMPLE_LIST (object);
170 +
171 + if (list->priv->columns)
172 + {
173 + g_free (list->priv->columns);
174 + list->priv->columns = NULL;
175 + }
176 +
177 + G_OBJECT_CLASS (gtk_simple_list_parent_class)->finalize (object);
178 +}
179 +
180 +static void
181 +gtk_simple_list_row_activated (GtkTreeView *tree_view,
182 + GtkTreePath *path,
183 + GtkTreeViewColumn *column,
184 + gpointer user_data)
185 +{
186 + int index;
187 +
188 + index = gtk_tree_path_get_indices (path)[0];
189 +
190 + g_signal_emit (tree_view, simple_list_signals[INDEX_ACTIVATED],
191 + 0, index);
192 +}
193 +
194 +static void
195 +gtk_simple_list_selection_changed (GtkTreeSelection *selection,
196 + gpointer user_data)
197 +{
198 + int *array;
199 + GtkSimpleList *list = GTK_SIMPLE_LIST (user_data);
200 +
201 + if (list->priv->is_updating_selection)
202 + return;
203 +
204 + array = gtk_simple_list_get_selected_indices (list);
205 + g_signal_emit (list, simple_list_signals[SELECTION_CHANGED],
206 + 0, array);
207 + g_free (array);
208 +}
209 +
210 +/* converting between GtkSimpleListColumn and other value types */
211 +static inline GType
212 +gtk_simple_list_column_to_gtype (GtkSimpleListColumn column_type)
213 +{
214 + switch (column_type)
215 + {
216 + case GTK_SIMPLE_LIST_COLUMN_TEXT:
217 + return G_TYPE_STRING;
218 +
219 + case GTK_SIMPLE_LIST_COLUMN_INT:
220 + return G_TYPE_INT;
221 +
222 + case GTK_SIMPLE_LIST_COLUMN_FLOAT:
223 + return G_TYPE_FLOAT;
224 +
225 + case GTK_SIMPLE_LIST_COLUMN_PIXBUF:
226 + return GDK_TYPE_PIXBUF;
227 +
228 + case GTK_SIMPLE_LIST_COLUMN_TOGGLE:
229 + return G_TYPE_BOOLEAN;
230 +
231 + case GTK_SIMPLE_LIST_COLUMN_PROGRESS:
232 + return G_TYPE_INT;
233 +
234 + default:
235 + g_warning ("%s: Invalid GtkSimpleListColumn type passed.\n", G_STRLOC);
236 + /* fall through */
237 + }
238 +
239 + /* Our fallback */
240 + return G_TYPE_STRING;
241 +}
242 +
243 +static GtkCellRenderer *
244 +gtk_simple_list_column_to_renderer (GtkSimpleListColumn column_type)
245 +{
246 + switch (column_type)
247 + {
248 + case GTK_SIMPLE_LIST_COLUMN_TEXT:
249 + case GTK_SIMPLE_LIST_COLUMN_INT:
250 + case GTK_SIMPLE_LIST_COLUMN_FLOAT:
251 + return gtk_cell_renderer_text_new ();
252 +
253 + case GTK_SIMPLE_LIST_COLUMN_PIXBUF:
254 + return gtk_cell_renderer_pixbuf_new ();
255 +
256 + case GTK_SIMPLE_LIST_COLUMN_TOGGLE:
257 + return gtk_cell_renderer_toggle_new ();
258 +
259 + case GTK_SIMPLE_LIST_COLUMN_PROGRESS:
260 + return gtk_cell_renderer_progress_new ();
261 +
262 + default:
263 + g_warning ("%s: Invalid GtkSimpleListColumn type passed.\n", G_STRLOC);
264 + /* fall through */
265 + }
266 +
267 + /* Our fallback */
268 + return gtk_cell_renderer_text_new ();
269 +}
270 +
271 +static const gchar *
272 +gtk_simple_list_column_to_attribute (GtkSimpleListColumn column_type)
273 +{
274 + switch (column_type)
275 + {
276 + case GTK_SIMPLE_LIST_COLUMN_TEXT:
277 + case GTK_SIMPLE_LIST_COLUMN_INT:
278 + case GTK_SIMPLE_LIST_COLUMN_FLOAT:
279 + return "text";
280 +
281 + case GTK_SIMPLE_LIST_COLUMN_PIXBUF:
282 + return "pixbuf";
283 +
284 + case GTK_SIMPLE_LIST_COLUMN_TOGGLE:
285 + return "active";
286 +
287 + case GTK_SIMPLE_LIST_COLUMN_PROGRESS:
288 + return "value";
289 +
290 + default:
291 + g_warning ("%s: Invalid GtkSimpleListColumn type passed.\n", G_STRLOC);
292 + /* fall through */
293 + }
294 +
295 + /* Our fallback */
296 + return "text";
297 +}
298 +
299 +
300 +/* constructors */
301 +GtkWidget *
302 +gtk_simple_list_new (int n_columns,
303 + ...)
304 +{
305 + int i;
306 + GtkSimpleListColumn *columns;
307 + va_list args;
308 + GtkWidget *retval;
309 +
310 + g_return_val_if_fail (n_columns > 0, NULL);
311 +
312 + va_start (args, n_columns);
313 +
314 + columns = g_new (GtkSimpleListColumn, n_columns);
315 + for (i = 0; i < n_columns; i++)
316 + columns[i] = va_arg (args, GtkSimpleListColumn);
317 +
318 + va_end (args);
319 +
320 + retval = gtk_simple_list_newv (n_columns, columns);
321 +
322 + g_free (columns);
323 +
324 + return retval;
325 +}
326 +
327 +GtkWidget *
328 +gtk_simple_list_newv (int n_columns,
329 + GtkSimpleListColumn *column_types)
330 +{
331 + int i;
332 + GType *types;
333 + GtkWidget *retval;
334 + GtkListStore *store;
335 + GtkSimpleList *list;
336 +
337 + g_return_val_if_fail (n_columns > 0, NULL);
338 +
339 + types = g_new0 (GType, n_columns);
340 + for (i = 0; i < n_columns; i++)
341 + types[i] = gtk_simple_list_column_to_gtype (column_types[i]);
342 +
343 + retval = g_object_new (GTK_TYPE_SIMPLE_LIST, NULL);
344 + list = GTK_SIMPLE_LIST (retval);
345 +
346 + store = gtk_list_store_newv (n_columns, types);
347 +
348 + g_free (types);
349 +
350 + if (!store)
351 + {
352 + g_warning ("%s: Model creation failed\n", G_STRLOC);
353 + g_object_unref (retval);
354 + return NULL;
355 + }
356 +
357 + gtk_tree_view_set_model (GTK_TREE_VIEW (retval), GTK_TREE_MODEL (store));
358 + g_object_unref (store);
359 +
360 + list->priv->columns = g_new0 (GtkSimpleListColumn, n_columns);
361 +
362 + /* Create the tree view columns */
363 + for (i = 0; i < n_columns; i++)
364 + {
365 + const gchar *attribute;
366 + GtkCellRenderer *renderer;
367 +
368 + list->priv->columns[i] = column_types[i];
369 +
370 + renderer = gtk_simple_list_column_to_renderer (column_types[i]);
371 + attribute = gtk_simple_list_column_to_attribute (column_types[i]);
372 +
373 + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (retval),
374 + i, NULL,
375 + renderer,
376 + attribute, i,
377 + NULL);
378 + }
379 +
380 + list->priv->n_columns = n_columns;
381 +
382 + return retval;
383 +}
384 +
385 +/* General settings */
386 +void
387 +gtk_simple_list_set_sortable (GtkSimpleList *list,
388 + gboolean sortable)
389 +{
390 + int i;
391 + GList *l;
392 + GList *columns;
393 +
394 + g_return_if_fail (GTK_IS_SIMPLE_LIST (list));
395 +
396 + if (list->priv->is_sortable == !!sortable)
397 + return;
398 +
399 + list->priv->is_sortable = sortable;
400 +
401 + columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (list));
402 +
403 + for (i = 0, l = columns; i < list->priv->n_columns; i++, l = l->next)
404 + gtk_tree_view_column_set_sort_column_id (l->data,
405 + sortable ? i : -1);
406 +
407 + g_list_free (columns);
408 +}
409 +
410 +void
411 +gtk_simple_list_set_columns_resizable (GtkSimpleList *list,
412 + gboolean resizable)
413 +{
414 + GList *l;
415 + GList *columns;
416 +
417 + g_return_if_fail (GTK_IS_SIMPLE_LIST (list));
418 +
419 + if (list->priv->is_resizable == !!resizable)
420 + return;
421 +
422 + list->priv->is_resizable = resizable;
423 +
424 + columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (list));
425 +
426 + for (l = columns; l; l = l->next)
427 + gtk_tree_view_column_set_resizable (l->data, resizable);
428 +
429 + g_list_free (columns);
430 +}
431 +
432 +
433 +/* Insert/remove data */
434 +void
435 +gtk_simple_list_append_row (GtkSimpleList *list,
436 + ...)
437 +{
438 + va_list args;
439 + GtkTreeIter iter;
440 + GtkListStore *store;
441 +
442 + g_return_if_fail (GTK_IS_SIMPLE_LIST (list));
443 +
444 + va_start (args, list);
445 +
446 + store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (list)));
447 + gtk_list_store_append (store, &iter);
448 + gtk_list_store_set_valist (store, &iter, args);
449 +
450 + va_end (args);
451 +}
452 +
453 +void
454 +gtk_simple_list_append_rowv (GtkSimpleList *list,
455 + GValue *values)
456 +{
457 + int i;
458 + int *columns;
459 + GtkTreeIter iter;
460 + GtkListStore *store;
461 +
462 + g_return_if_fail (GTK_IS_SIMPLE_LIST (list));
463 +
464 + store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (list)));
465 + gtk_list_store_append (store, &iter);
466 +
467 + columns = g_new0 (int, list->priv->n_columns);
468 + for (i = 0; i < list->priv->n_columns; i++)
469 + columns[i] = i;
470 +
471 + gtk_list_store_set_valuesv (store, &iter, columns, values,
472 + list->priv->n_columns);
473 +
474 + g_free (columns);
475 +}
476 +
477 +void
478 +gtk_simple_list_insert_row (GtkSimpleList *list,
479 + int position,
480 + ...)
481 +{
482 + va_list args;
483 + GtkTreeIter iter;
484 + GtkListStore *store;
485 +
486 + g_return_if_fail (GTK_IS_SIMPLE_LIST (list));
487 +
488 + va_start (args, position);
489 +
490 + store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (list)));
491 + gtk_list_store_insert (store, &iter, position);
492 + gtk_list_store_set_valist (store, &iter, args);
493 +
494 + va_end (args);
495 +}
496 +
497 +void
498 +gtk_simple_list_insert_rowv (GtkSimpleList *list,
499 + int position,
500 + GValue *values)
501 +{
502 + int i;
503 + int *columns;
504 + GtkTreeIter iter;
505 + GtkListStore *store;
506 +
507 + g_return_if_fail (GTK_IS_SIMPLE_LIST (list));
508 +
509 + store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (list)));
510 + gtk_list_store_insert (store, &iter, position);
511 +
512 + columns = g_new0 (int, list->priv->n_columns);
513 + for (i = 0; i < list->priv->n_columns; i++)
514 + columns[i] = i;
515 +
516 + gtk_list_store_set_valuesv (store, &iter, columns, values,
517 + list->priv->n_columns);
518 +
519 + g_free (columns);
520 +}
521 +
522 +void
523 +gtk_simple_list_remove_row (GtkSimpleList *list,
524 + int position)
525 +{
526 + GtkTreeIter iter;
527 + GtkTreeModel *model;
528 +
529 + g_return_if_fail (GTK_SIMPLE_LIST (list));
530 + model = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
531 +
532 + if (!gtk_tree_model_iter_nth_child (model, &iter, NULL, position))
533 + {
534 + g_warning ("%s: Cannot find row at position %d\n", G_STRLOC, position);
535 + return;
536 + }
537 +
538 + gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
539 +}
540 +
541 +void
542 +gtk_simple_list_set_row (GtkSimpleList *list,
543 + int position,
544 + ...)
545 +{
546 + va_list args;
547 + GtkTreeIter iter;
548 + GtkTreeModel *model;
549 +
550 + g_return_if_fail (GTK_IS_SIMPLE_LIST (list));
551 +
552 + va_start (args, position);
553 +
554 + model = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
555 + g_return_if_fail (gtk_tree_model_iter_nth_child (model, &iter, NULL, position));
556 + gtk_list_store_set_valist (GTK_LIST_STORE (model), &iter, args);
557 +
558 + va_end (args);
559 +}
560 +
561 +void
562 +gtk_simple_list_set_rowv (GtkSimpleList *list,
563 + int position,
564 + GValue *values)
565 +{
566 + int i;
567 + int *columns;
568 + GtkTreeIter iter;
569 + GtkTreeModel *model;
570 +
571 + g_return_if_fail (GTK_IS_SIMPLE_LIST (list));
572 +
573 + model = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
574 + g_return_if_fail (gtk_tree_model_iter_nth_child (model, &iter, NULL, position));
575 +
576 + columns = g_new0 (int, list->priv->n_columns);
577 + for (i = 0; i < list->priv->n_columns; i++)
578 + columns[i] = i;
579 +
580 + gtk_list_store_set_valuesv (GTK_LIST_STORE (model), &iter, columns, values,
581 + list->priv->n_columns);
582 +
583 + g_free (columns);
584 +}
585 +
586 +void
587 +gtk_simple_list_get_row (GtkSimpleList *list,
588 + int position,
589 + ...)
590 +{
591 + int i;
592 + GtkTreeIter iter;
593 + GtkTreeModel *model;
594 + va_list args;
595 +
596 + g_return_if_fail (GTK_IS_SIMPLE_LIST (list));
597 +
598 + model = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
599 + g_return_if_fail (gtk_tree_model_iter_nth_child (model, &iter, NULL, position));
600 +
601 + va_start (args, position);
602 + gtk_tree_model_get_valist (model, &iter, args);
603 + va_end (args);
604 +}
605 +
606 +void
607 +gtk_simple_list_get_rowv (GtkSimpleList *list,
608 + int position,
609 + GValue *values)
610 +{
611 + int i;
612 + GtkTreeIter iter;
613 + GtkTreeModel *model;
614 +
615 + g_return_if_fail (GTK_IS_SIMPLE_LIST (list));
616 +
617 + model = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
618 + g_return_if_fail (gtk_tree_model_iter_nth_child (model, &iter, NULL, position));
619 +
620 + for (i = 0; i < list->priv->n_columns; i++)
621 + gtk_tree_model_get_value (model, &iter, i, &values[i]);
622 +}
623 +
624 +/* Selection */
625 +void
626 +gtk_simple_list_set_selection_mode (GtkSimpleList *list,
627 + GtkSelectionMode mode)
628 +{
629 + GtkTreeSelection *selection;
630 +
631 + g_return_if_fail (GTK_IS_SIMPLE_LIST (list));
632 +
633 + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
634 + gtk_tree_selection_set_mode (selection, mode);
635 +}
636 +
637 +void
638 +gtk_simple_list_select_indices (GtkSimpleList *list,
639 + ...)
640 +{
641 + int index;
642 + va_list args;
643 + GtkTreeSelection *selection;
644 +
645 + g_return_if_fail (GTK_IS_SIMPLE_LIST (list));
646 +
647 + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
648 +
649 + list->priv->is_updating_selection = TRUE;
650 +
651 + va_start (args, list);
652 +
653 + while ((index = va_arg (args, int)) != -1)
654 + {
655 + GtkTreePath *path;
656 +
657 + path = gtk_tree_path_new_from_indices (index, -1);
658 + gtk_tree_selection_select_path (selection, path);
659 + gtk_tree_path_free (path);
660 + }
661 +
662 + va_end (args);
663 +
664 + list->priv->is_updating_selection = FALSE;
665 +
666 + gtk_simple_list_selection_changed (selection, list);
667 +}
668 +
669 +void
670 +gtk_simple_list_select_indicesv (GtkSimpleList *list,
671 + int n,
672 + int *indices)
673 +{
674 + int i;
675 + GtkTreeSelection *selection;
676 +
677 + g_return_if_fail (GTK_IS_SIMPLE_LIST (list));
678 + g_return_if_fail (n >= 0);
679 + g_return_if_fail (indices != NULL);
680 +
681 + list->priv->is_updating_selection = TRUE;
682 +
683 + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
684 + for (i = 0; i < n; i++)
685 + {
686 + GtkTreePath *path;
687 +
688 + path = gtk_tree_path_new_from_indices (indices[i], -1);
689 + gtk_tree_selection_select_path (selection, path);
690 + gtk_tree_path_free (path);
691 + }
692 +
693 + list->priv->is_updating_selection = FALSE;
694 +
695 + gtk_simple_list_selection_changed (selection, list);
696 +}
697 +
698 +
699 +void
700 +gtk_simple_list_unselect_indices (GtkSimpleList *list,
701 + ...)
702 +{
703 + int index;
704 + va_list args;
705 + GtkTreeSelection *selection;
706 +
707 + g_return_if_fail (GTK_IS_SIMPLE_LIST (list));
708 +
709 + list->priv->is_updating_selection = TRUE;
710 +
711 + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
712 +
713 + va_start (args, list);
714 +
715 + while ((index = va_arg (args, int)) != -1)
716 + {
717 + GtkTreePath *path;
718 +
719 + path = gtk_tree_path_new_from_indices (index, -1);
720 + gtk_tree_selection_unselect_path (selection, path);
721 + gtk_tree_path_free (path);
722 + }
723 +
724 + va_end (args);
725 +
726 + list->priv->is_updating_selection = FALSE;
727 +
728 + gtk_simple_list_selection_changed (selection, list);
729 +}
730 +
731 +void
732 +gtk_simple_list_unselect_indicesv (GtkSimpleList *list,
733 + int n,
734 + int *indices)
735 +{
736 + int i;
737 + GtkTreeSelection *selection;
738 +
739 + g_return_if_fail (GTK_IS_SIMPLE_LIST (list));
740 + g_return_if_fail (n >= 0);
741 + g_return_if_fail (indices != NULL);
742 +
743 + list->priv->is_updating_selection = TRUE;
744 +
745 + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
746 + for (i = 0; i < n; i++)
747 + {
748 + GtkTreePath *path;
749 +
750 + path = gtk_tree_path_new_from_indices (indices[i], -1);
751 + gtk_tree_selection_unselect_path (selection, path);
752 + gtk_tree_path_free (path);
753 + }
754 +
755 + list->priv->is_updating_selection = FALSE;
756 +
757 + gtk_simple_list_selection_changed (selection, list);
758 +}
759 +
760 +/* Returns an array with selected indices, terminated with -1 */
761 +int *
762 +gtk_simple_list_get_selected_indices (GtkSimpleList *list)
763 +{
764 + int i;
765 + int *array;
766 + GList *slist, *item;
767 + GtkTreeSelection *selection;
768 +
769 + g_return_val_if_fail (GTK_IS_SIMPLE_LIST (list), NULL);
770 +
771 + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
772 + slist = gtk_tree_selection_get_selected_rows (selection, NULL);
773 +
774 + array = g_new0 (int, g_list_length (slist) + 1);
775 +
776 + for (item = slist, i = 0; item; item = item->next, i++)
777 + array[i] = gtk_tree_path_get_indices (item->data)[0];
778 + array[i] = -1;
779 +
780 + g_list_foreach (slist, (GFunc)gtk_tree_path_free, NULL);
781 + g_list_free (slist);
782 +
783 + return array;
784 +}
785 +
786 +/* Changing columns */
787 +void
788 +gtk_simple_list_column_set_title (GtkSimpleList *list,
789 + int column_index,
790 + const gchar *title)
791 +{
792 + GtkTreeViewColumn *column;
793 +
794 + g_return_if_fail (GTK_IS_SIMPLE_LIST (list));
795 + g_return_if_fail (column_index >= 0);
796 + g_return_if_fail (column_index < list->priv->n_columns);
797 +
798 + column = gtk_tree_view_get_column (GTK_TREE_VIEW (list), column_index);
799 +
800 + g_return_if_fail (column != NULL);
801 +
802 + gtk_tree_view_column_set_title (column, title);
803 +}
804 +
805 +static void
806 +gtk_simple_list_edited_callback (GtkCellRendererText *renderer,
807 + const gchar *path_string,
808 + const gchar *new_text,
809 + gpointer user_data)
810 +{
811 + int column = 0;
812 + GList *clist, *l;
813 + GtkTreeIter iter;
814 + GtkTreePath *path;
815 + GtkSimpleList *list;
816 + GtkTreeModel *model;
817 +
818 + list = GTK_SIMPLE_LIST (user_data);
819 + model = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
820 +
821 + /* We need to find the column containing this renderer */
822 + clist = gtk_tree_view_get_columns (GTK_TREE_VIEW (user_data));
823 +
824 + for (l = clist; l; l = l->next, column++)
825 + {
826 + GList *cells;
827 +
828 + cells = gtk_tree_view_column_get_cell_renderers (clist->data);
829 +
830 + if (cells->data == renderer)
831 + {
832 + g_list_free (cells);
833 + break;
834 + }
835 +
836 + g_list_free (cells);
837 + }
838 +
839 + g_return_if_fail (column <= list->priv->n_columns);
840 +
841 + path = gtk_tree_path_new_from_string (path_string);
842 + gtk_tree_model_get_iter (model, &iter, path);
843 + gtk_tree_path_free (path);
844 +
845 + gtk_list_store_set (GTK_LIST_STORE (model), &iter,
846 + column, new_text, -1);
847 +}
848 +
849 +
850 +void
851 +gtk_simple_list_column_set_editable (GtkSimpleList *list,
852 + int column_index,
853 + gboolean editable)
854 +{
855 + GList *cells;
856 + gboolean is_editable;
857 + GtkCellRenderer *renderer;
858 + GtkTreeViewColumn *column;
859 +
860 + /* This is going to be quite troublesome if people have been
861 + * fooling around with the columns themselves. For now, we will just
862 + * get and use the first cell in the column.
863 + */
864 +
865 + g_return_if_fail (GTK_IS_SIMPLE_LIST (list));
866 + g_return_if_fail (column_index <= list->priv->n_columns);
867 +
868 + column = gtk_tree_view_get_column (GTK_TREE_VIEW (list), column_index);
869 + cells = gtk_tree_view_column_get_cell_renderers (column);
870 + renderer = cells->data;
871 + g_list_free (cells);
872 +
873 + if (!GTK_IS_CELL_RENDERER_TEXT (renderer))
874 + return;
875 +
876 + g_object_get (renderer, "editable", &is_editable, NULL);
877 + if (editable == !!is_editable)
878 + return;
879 +
880 + g_object_set (renderer, "editable", editable, NULL);
881 +
882 + if (editable)
883 + {
884 + g_signal_connect (renderer, "edited",
885 + G_CALLBACK (gtk_simple_list_edited_callback), list);
886 + }
887 + else
888 + {
889 + g_signal_handlers_disconnect_by_func (renderer,
890 + gtk_simple_list_edited_callback,
891 + list);
892 + }
893 +}
894 +
895 +void
896 +gtk_simple_list_column_set_cell_renderer (GtkSimpleList *list,
897 + int column_index,
898 + GtkCellRenderer *renderer)
899 +{
900 +}
901 +
902 +#define __GTK_SIMPLE_LIST_C__
903 +#include "gtkaliasdef.c"
904 diff --git a/gtk/gtksimplelist.h b/gtk/gtksimplelist.h
905 new file mode 100644
906 index 0000000..a8f5ab1
907 --- /dev/null
908 +++ b/gtk/gtksimplelist.h
909 @@ -0,0 +1,146 @@
910 +/* gtksimplelist.h
911 + * Copyright (C) 2008 Kristian Rietveld <kris@gtk.org>
912 + *
913 + * This library is free software; you can redistribute it and/or
914 + * modify it under the terms of the GNU Library General Public
915 + * License as published by the Free Software Foundation; either
916 + * version 2 of the License, or (at your option) any later version.
917 + *
918 + * This library is distributed in the hope that it will be useful,
919 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
920 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
921 + * Library General Public License for more details.
922 + *
923 + * You should have received a copy of the GNU Library General Public
924 + * License along with this library; if not, write to the
925 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
926 + * Boston, MA 02111-1307, USA.
927 + */
928 +
929 +#if defined(GTK_DISABLE_SINGLE_INCLUDES) && !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
930 +#error "Only <gtk/gtk.h> can be included directly."
931 +#endif
932 +
933 +#ifndef __GTK_SIMPLE_LIST_H__
934 +#define __GTK_SIMPLE_LIST_H__
935 +
936 +#include <gtk/gtktreeview.h>
937 +
938 +G_BEGIN_DECLS
939 +
940 +#define GTK_TYPE_SIMPLE_LIST (gtk_simple_list_get_type ())
941 +#define GTK_SIMPLE_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SIMPLE_LIST, GtkSimpleList))
942 +#define GTK_SIMPLE_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_SIMPLE_LIST, GtkSimpleListClass))
943 +#define GTK_IS_SIMPLE_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SIMPLE_LIST))
944 +#define GTK_IS_SIMPLE_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SIMPLE_LIST))
945 +#define GTK_SIMPLE_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SIMPLE_LIST, GtkSimpleListClass))
946 +
947 +typedef struct _GtkSimpleList GtkSimpleList;
948 +typedef struct _GtkSimpleListClass GtkSimpleListClass;
949 +typedef struct _GtkSimpleListPrivate GtkSimpleListPrivate;
950 +
951 +typedef enum _GtkSimpleListColumn GtkSimpleListColumn;
952 +
953 +enum _GtkSimpleListColumn
954 +{
955 + GTK_SIMPLE_LIST_COLUMN_TEXT,
956 + GTK_SIMPLE_LIST_COLUMN_INT,
957 + GTK_SIMPLE_LIST_COLUMN_FLOAT,
958 + GTK_SIMPLE_LIST_COLUMN_PIXBUF,
959 + GTK_SIMPLE_LIST_COLUMN_TOGGLE,
960 + GTK_SIMPLE_LIST_COLUMN_PROGRESS
961 +};
962 +
963 +struct _GtkSimpleList
964 +{
965 + GtkTreeView parent;
966 +
967 + GtkSimpleListPrivate *GSEAL (priv);
968 +};
969 +
970 +struct _GtkSimpleListClass
971 +{
972 + GtkTreeViewClass parent_class;
973 +
974 + void (* selection_changed) (GtkSimpleList *list,
975 + int *array);
976 +
977 + void (* index_activated) (GtkSimpleList *list,
978 + int index);
979 +};
980 +
981 +GType gtk_simple_list_get_type (void) G_GNUC_CONST;
982 +GtkWidget *gtk_simple_list_new (int n_columns,
983 + ...);
984 +GtkWidget *gtk_simple_list_newv (int n_columns,
985 + GtkSimpleListColumn *column_types);
986 +
987 +/* General settings */
988 +void gtk_simple_list_set_sortable (GtkSimpleList *list,
989 + gboolean sortable);
990 +void gtk_simple_list_set_columns_resizable (GtkSimpleList *list,
991 + gboolean resizable);
992 +
993 +
994 +/* Insert/remove data */
995 +void gtk_simple_list_append_row (GtkSimpleList *list,
996 + ...);
997 +void gtk_simple_list_append_rowv (GtkSimpleList *list,
998 + GValue *values);
999 +void gtk_simple_list_insert_row (GtkSimpleList *list,
1000 + int position,
1001 + ...);
1002 +void gtk_simple_list_insert_rowv (GtkSimpleList *list,
1003 + int position,
1004 + GValue *values);
1005 +
1006 +void gtk_simple_list_remove_row (GtkSimpleList *list,
1007 + int position);
1008 +
1009 +void gtk_simple_list_set_row (GtkSimpleList *list,
1010 + int position,
1011 + ...);
1012 +void gtk_simple_list_set_rowv (GtkSimpleList *list,
1013 + int position,
1014 + GValue *values);
1015 +
1016 +void gtk_simple_list_get_row (GtkSimpleList *list,
1017 + int position,
1018 + ...);
1019 +void gtk_simple_list_get_rowv (GtkSimpleList *list,
1020 + int position,
1021 + GValue *values);
1022 +
1023 +/* Selection */
1024 +void gtk_simple_list_set_selection_mode (GtkSimpleList *list,
1025 + GtkSelectionMode mode);
1026 +void gtk_simple_list_select_indices (GtkSimpleList *list,
1027 + ...);
1028 +void gtk_simple_list_select_indicesv (GtkSimpleList *list,
1029 + int n,
1030 + int *indices);
1031 +
1032 +void gtk_simple_list_unselect_indices (GtkSimpleList *list,
1033 + ...);
1034 +void gtk_simple_list_unselect_indicesv (GtkSimpleList *list,
1035 + int n,
1036 + int *indices);
1037 +
1038 +int *gtk_simple_list_get_selected_indices (GtkSimpleList *list);
1039 +
1040 +/* Changing columns */
1041 +void gtk_simple_list_column_set_title (GtkSimpleList *list,
1042 + int column_index,
1043 + const gchar *title);
1044 +
1045 +void gtk_simple_list_column_set_editable (GtkSimpleList *list,
1046 + int column_index,
1047 + gboolean editable);
1048 +
1049 +void gtk_simple_list_column_set_cell_renderer (GtkSimpleList *list,
1050 + int column_index,
1051 + GtkCellRenderer *renderer);
1052 +
1053 +G_END_DECLS
1054 +
1055 +#endif /* __GTK_SIMPLE_LIST_H__ */
1056 diff --git a/tests/Makefile.am b/tests/Makefile.am
1057 index edd18b0..cde7bb0 100644
1058 --- a/tests/Makefile.am
1059 +++ b/tests/Makefile.am
1060 @@ -60,6 +60,7 @@ noinst_PROGRAMS = $(TEST_PROGS) \
1061 testrecentchoosermenu \
1062 testrichtext \
1063 testselection \
1064 + testsimplelist \
1065 $(testsocket_programs) \
1066 testspinbutton \
1067 teststatusicon \
1068 @@ -134,6 +135,7 @@ testrecentchoosermenu_DEPENDENCIES = $(TEST_DEPS)
1069 testrgb_DEPENDENCIES = $(TEST_DEPS)
1070 testrichtext_DEPENDENCIES = $(TEST_DEPS)
1071 testselection_DEPENDENCIES = $(TEST_DEPS)
1072 +testsimplelist_DEPENDENCIES = $(TEST_DEPS)
1073 testsocket_DEPENDENCIES = $(DEPS)
1074 testsocket_child_DEPENDENCIES = $(DEPS)
1075 testspinbutton_DEPENDENCIES = $(TEST_DEPS)
1076 @@ -188,6 +190,7 @@ testrecentchoosermenu_LDADD = $(LDADDS)
1077 testrgb_LDADD = $(LDADDS)
1078 testrichtext_LDADD = $(LDADDS)
1079 testselection_LDADD = $(LDADDS)
1080 +testsimplelist_LDADD = $(LDADDS)
1081 testsocket_LDADD = $(LDADDS)
1082 testsocket_child_LDADD = $(LDADDS)
1083 testspinbutton_LDADD = $(LDADDS)
1084 diff --git a/tests/testsimplelist.c b/tests/testsimplelist.c
1085 new file mode 100644
1086 index 0000000..8e5426a
1087 --- /dev/null
1088 +++ b/tests/testsimplelist.c
1089 @@ -0,0 +1,77 @@
1090 +#include <gtk/gtk.h>
1091 +
1092 +static void
1093 +index_activated_cb (GtkSimpleList *list, int index, gpointer user_data)
1094 +{
1095 + int number;
1096 + gchar *string;
1097 +
1098 + gtk_simple_list_get_row (list, index, 0, &string, 1, &number, -1);
1099 +
1100 + g_print ("item activated: %s, %d\n", string, number);
1101 +
1102 + g_free (string);
1103 +}
1104 +
1105 +int
1106 +main (int argc, char **argv)
1107 +{
1108 + GtkWidget *window;
1109 + GtkWidget *scrolled;
1110 + GtkWidget *list;
1111 + GdkPixbuf *pixbuf;
1112 +
1113 + gtk_init (&argc, &argv);
1114 +
1115 + window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1116 + gtk_window_set_title (GTK_WINDOW (window), "GtkSimpleList test");
1117 + g_signal_connect (window, "delete-event",
1118 + G_CALLBACK (gtk_main_quit), NULL);
1119 + gtk_container_set_border_width (GTK_CONTAINER (window), 5);
1120 +
1121 + scrolled = gtk_scrolled_window_new (NULL, NULL);
1122 + gtk_widget_set_size_request (scrolled, 320, 240);
1123 + gtk_container_add (GTK_CONTAINER (window), scrolled);
1124 +
1125 + pixbuf = gtk_widget_render_icon (scrolled, GTK_STOCK_INFO,
1126 + GTK_ICON_SIZE_SMALL_TOOLBAR,
1127 + NULL);
1128 +
1129 + list = gtk_simple_list_new (3,
1130 + GTK_SIMPLE_LIST_COLUMN_TEXT,
1131 + GTK_SIMPLE_LIST_COLUMN_INT,
1132 + GTK_SIMPLE_LIST_COLUMN_PIXBUF);
1133 +
1134 + gtk_simple_list_set_selection_mode (GTK_SIMPLE_LIST (list),
1135 + GTK_SELECTION_MULTIPLE);
1136 +
1137 + gtk_simple_list_column_set_title (GTK_SIMPLE_LIST (list), 0, "Name");
1138 + gtk_simple_list_column_set_title (GTK_SIMPLE_LIST (list), 1, "Count");
1139 +
1140 + gtk_simple_list_set_sortable (GTK_SIMPLE_LIST (list), TRUE);
1141 + gtk_simple_list_set_columns_resizable (GTK_SIMPLE_LIST (list), TRUE);
1142 +
1143 + gtk_simple_list_append_row (GTK_SIMPLE_LIST (list),
1144 + 0, "Hoi", 1, 3, 2, pixbuf, -1);
1145 + gtk_simple_list_append_row (GTK_SIMPLE_LIST (list), 0, "Boe", 1, 2, -1);
1146 + gtk_simple_list_append_row (GTK_SIMPLE_LIST (list), 0, "Bleh", 1, 5, -1);
1147 + gtk_simple_list_append_row (GTK_SIMPLE_LIST (list), 0, "Fooo", 1, 8, -1);
1148 + gtk_simple_list_append_row (GTK_SIMPLE_LIST (list),
1149 + 0, "Bier", 1, 1, 2, pixbuf, -1);
1150 +
1151 + gtk_simple_list_select_indices (GTK_SIMPLE_LIST (list), 1, 2, 3, 4, -1);
1152 + gtk_simple_list_unselect_indices (GTK_SIMPLE_LIST (list), 2, 4, -1);
1153 +
1154 + gtk_simple_list_column_set_editable (GTK_SIMPLE_LIST (list), 0, TRUE);
1155 +
1156 + g_signal_connect (list, "index-activated",
1157 + G_CALLBACK (index_activated_cb), NULL);
1158 +
1159 + gtk_container_add (GTK_CONTAINER (scrolled), list);
1160 +
1161 + gtk_widget_show_all (window);
1162 +
1163 + gtk_main ();
1164 +
1165 + return 0;
1166 +}
1167
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.