4 * An OpenGL based 'interactive canvas' library.
6 * Authored By Matthew Allum <mallum@openedhand.com>
7 * Neil Jagdish Patel <njp@o-hand.com>
8 * Emmanuele Bassi <ebassi@openedhand.com>
10 * Copyright (C) 2006 OpenedHand
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2 of the License, or (at your option) any later version.
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the
24 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25 * Boston, MA 02111-1307, USA.
27 * NB: Inspiration for column storage taken from GtkListStore
31 * SECTION:clutter-model
32 * @short_description: A generic model implementation
34 * #ClutterModel is a generic list model API which can be used to implement
35 * the model-view-controller architectural pattern in Clutter.
37 * The #ClutterModel class is a list model which can accept most GObject
38 * types as a column type.
40 * Creating a simple clutter model:
41 * <informalexample><programlisting>
51 * ClutterModel *model;
54 * model = clutter_model_default_new (N_COLUMNS,
55 * /<!-- -->* column type, column title *<!-- -->/
56 * G_TYPE_INT, "my integers",
57 * G_TYPE_STRING, "my strings");
58 * for (i = 0; i < 10; i++)
60 * gchar *string = g_strdup_printf ("String %d", i);
61 * clutter_model_append (model,
63 * COLUMN_STRING, string,
70 * </programlisting></informalexample>
72 * Iterating through the model consists of retrieving a new #ClutterModelIter
73 * pointing to the starting row, and calling clutter_model_iter_next() or
74 * clutter_model_iter_prev() to move forward or backwards, repectively.
76 * A valid #ClutterModelIter represents the position between two rows in the
77 * model. For example, the "first" iterator represents the gap immediately
78 * before the first row, and the "last" iterator represents the gap immediately
79 * after the last row. In an empty sequence, the first and last iterators are
82 * Iterating a #ClutterModel:
83 * <informalexample><programlisting>
93 * ClutterModel *model;
94 * ClutterModelIter *iter = NULL;
96 * /<!-- -->* Fill the model *<!-- -->/
97 * model = populate_model ();
99 * /<!-- -->* Get the first iter *<!-- -->/
100 * iter = clutter_model_get_first_iter (model);
101 * while (!clutter_model_iter_is_last (iter))
105 * iter = clutter_model_iter_next (iter);
108 * /<!-- -->* Make sure to unref the iter *<!-- -->/
109 * g_object_unref (iter);
111 * </programlisting></informalexample>
113 * #ClutterModel is an abstract class. Clutter provides a list model
114 * implementation called #ClutterListModel which has been optimised
115 * for insertion and look up in sorted lists.
117 * #ClutterModel is available since Clutter 0.6
126 #include <glib-object.h>
127 #include <gobject/gvaluecollector.h>
129 #include "clutter-model.h"
130 #include "clutter-model-private.h"
132 #include "clutter-marshal.h"
133 #include "clutter-private.h"
134 #include "clutter-debug.h"
136 G_DEFINE_ABSTRACT_TYPE (ClutterModel, clutter_model, G_TYPE_OBJECT);
157 static guint model_signals[LAST_SIGNAL] = { 0, };
159 #define CLUTTER_MODEL_GET_PRIVATE(obj) \
160 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_MODEL, ClutterModelPrivate))
162 struct _ClutterModelPrivate
165 gchar **column_names;
168 ClutterModelFilterFunc filter_func;
169 gpointer filter_data;
170 GDestroyNotify filter_notify;
173 ClutterModelSortFunc sort_func;
175 GDestroyNotify sort_notify;
179 clutter_model_real_get_column_type (ClutterModel *model,
182 ClutterModelPrivate *priv = model->priv;
184 if (column < 0 || column >= clutter_model_get_n_columns (model))
185 return G_TYPE_INVALID;
187 return priv->column_types[column];
191 clutter_model_real_get_column_name (ClutterModel *model,
194 ClutterModelPrivate *priv = model->priv;
196 if (column < 0 || column >= clutter_model_get_n_columns (model))
199 if (priv->column_names && priv->column_names[column])
200 return priv->column_names[column];
202 return g_type_name (priv->column_types[column]);
206 clutter_model_real_get_n_columns (ClutterModel *model)
208 return model->priv->n_columns;
212 clutter_model_finalize (GObject *object)
214 ClutterModelPrivate *priv = CLUTTER_MODEL (object)->priv;
217 if (priv->sort_notify)
218 priv->sort_notify (priv->sort_data);
220 if (priv->filter_notify)
221 priv->filter_notify (priv->filter_data);
223 g_free (priv->column_types);
225 if (priv->column_names != NULL)
227 /* the column_names vector might have holes in it, so we need
228 * to use the columns number to clear up everything
230 for (i = 0; i < priv->n_columns; i++)
231 g_free (priv->column_names[i]);
233 g_free (priv->column_names);
236 G_OBJECT_CLASS (clutter_model_parent_class)->finalize (object);
240 clutter_model_get_property (GObject *gobject,
245 ClutterModelPrivate *priv = CLUTTER_MODEL (gobject)->priv;
249 case PROP_FILTER_SET:
250 g_value_set_boolean (value, priv->filter_func != NULL);
254 G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
260 clutter_model_class_init (ClutterModelClass *klass)
262 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
265 gobject_class->get_property = clutter_model_get_property;
266 gobject_class->finalize = clutter_model_finalize;
268 g_type_class_add_private (gobject_class, sizeof (ClutterModelPrivate));
270 klass->get_column_name = clutter_model_real_get_column_name;
271 klass->get_column_type = clutter_model_real_get_column_type;
272 klass->get_n_columns = clutter_model_real_get_n_columns;
275 * ClutterModel:filter-set:
277 * Whether the #ClutterModel has a filter set
279 * This property is set to %TRUE if a filter function has been
280 * set using clutter_model_set_filter()
284 pspec = g_param_spec_boolean ("filter-set",
286 "Whether the model has a filter",
288 CLUTTER_PARAM_READABLE);
289 g_object_class_install_property (gobject_class, PROP_FILTER_SET, pspec);
292 * ClutterModel::row-added:
293 * @model: the #ClutterModel on which the signal is emitted
294 * @iter: a #ClutterModelIter pointing to the new row
296 * The ::row-added signal is emitted when a new row has been added.
297 * The data on the row has already been set when the ::row-added signal
302 model_signals[ROW_ADDED] =
303 g_signal_new ("row-added",
304 G_TYPE_FROM_CLASS (gobject_class),
306 G_STRUCT_OFFSET (ClutterModelClass, row_added),
308 clutter_marshal_VOID__OBJECT,
310 CLUTTER_TYPE_MODEL_ITER);
312 * ClutterModel::row-removed:
313 * @model: the #ClutterModel on which the signal is emitted
314 * @iter: a #ClutterModelIter pointing to the removed row
316 * The ::row-removed signal is emitted when a row has been removed.
317 * The data on the row pointed by the passed iterator is still valid
318 * when the ::row-removed signal has been emitted.
322 model_signals[ROW_REMOVED] =
323 g_signal_new ("row-removed",
324 G_TYPE_FROM_CLASS (gobject_class),
326 G_STRUCT_OFFSET (ClutterModelClass, row_removed),
328 clutter_marshal_VOID__OBJECT,
330 CLUTTER_TYPE_MODEL_ITER);
332 * ClutterModel::row-changed:
333 * @model: the #ClutterModel on which the signal is emitted
334 * @iter: a #ClutterModelIter pointing to the changed row
336 * The ::row-removed signal is emitted when a row has been changed.
337 * The data on the row has already been updated when the ::row-changed
338 * signal has been emitted.
342 model_signals[ROW_CHANGED] =
343 g_signal_new ("row-changed",
344 G_TYPE_FROM_CLASS (gobject_class),
346 G_STRUCT_OFFSET (ClutterModelClass, row_changed),
348 clutter_marshal_VOID__OBJECT,
350 CLUTTER_TYPE_MODEL_ITER);
352 * ClutterModel::sort-changed:
353 * @model: the #ClutterModel on which the signal is emitted
355 * The ::sort-changed signal is emitted after the model has been sorted
359 model_signals[SORT_CHANGED] =
360 g_signal_new ("sort-changed",
361 G_TYPE_FROM_CLASS (gobject_class),
363 G_STRUCT_OFFSET (ClutterModelClass, sort_changed),
365 clutter_marshal_VOID__VOID,
368 * ClutterModel::filter-changed:
369 * @model: the #ClutterModel on which the signal is emitted
371 * The ::filter-changed signal is emitted when a new filter has been applied
375 model_signals[FILTER_CHANGED] =
376 g_signal_new ("filter-changed",
377 G_TYPE_FROM_CLASS (gobject_class),
379 G_STRUCT_OFFSET (ClutterModelClass, filter_changed),
381 clutter_marshal_VOID__VOID,
386 clutter_model_init (ClutterModel *self)
388 ClutterModelPrivate *priv;
390 self->priv = priv = CLUTTER_MODEL_GET_PRIVATE (self);
392 priv->n_columns = -1;
393 priv->column_types = NULL;
394 priv->column_names = NULL;
396 priv->filter_func = NULL;
397 priv->filter_data = NULL;
398 priv->filter_notify = NULL;
400 priv->sort_column = -1;
401 priv->sort_func = NULL;
402 priv->sort_data = NULL;
403 priv->sort_notify = NULL;
406 /* XXX - is this whitelist really necessary? we accept every fundamental
410 clutter_model_check_type (GType gtype)
413 static const GType type_list[] =
435 if (! G_TYPE_IS_VALUE_TYPE (gtype))
438 while (type_list[i] != G_TYPE_INVALID)
440 if (g_type_is_a (gtype, type_list[i]))
450 * clutter_model_resort:
451 * @model: a #ClutterModel
453 * Force a resort on the @model. This function should only be
454 * used by subclasses of #ClutterModel.
459 clutter_model_resort (ClutterModel *model)
461 ClutterModelPrivate *priv;
462 ClutterModelClass *klass;
464 g_return_if_fail (CLUTTER_IS_MODEL (model));
467 klass = CLUTTER_MODEL_GET_CLASS (model);
470 klass->resort (model, priv->sort_func, priv->sort_data);
474 * clutter_model_filter_row:
475 * @model: a #ClutterModel
476 * @row: the row to filter
478 * Checks whether @row should be filtered or not using the
479 * filtering function set on @model.
481 * This function should be used only by subclasses of #ClutterModel.
483 * Return value: %TRUE if the row should be displayed,
489 clutter_model_filter_row (ClutterModel *model,
492 ClutterModelPrivate *priv;
493 ClutterModelIter *iter;
496 g_return_val_if_fail (CLUTTER_IS_MODEL (model), TRUE);
500 if (!priv->filter_func)
503 iter = clutter_model_get_iter_at_row (model, row);
507 res = priv->filter_func (model, iter, priv->filter_data);
509 g_object_unref (iter);
515 * clutter_model_filter_iter:
516 * @model: a #ClutterModel
517 * @iter: the row to filter
519 * Checks whether the row pointer by @iter should be filtered or not using
520 * the filtering function set on @model.
522 * This function should be used only by subclasses of #ClutterModel.
524 * Return value: %TRUE if the row should be displayed,
530 clutter_model_filter_iter (ClutterModel *model,
531 ClutterModelIter *iter)
533 ClutterModelPrivate *priv;
535 g_return_val_if_fail (CLUTTER_IS_MODEL (model), TRUE);
536 g_return_val_if_fail (CLUTTER_IS_MODEL_ITER (iter), TRUE);
540 if (!priv->filter_func)
543 return priv->filter_func (model, iter, priv->filter_data);
547 * clutter_model_set_n_columns:
548 * @model: a #ClutterModel
549 * @n_columns: number of columns
550 * @set_types: set the columns type
551 * @set_names: set the columns name
553 * Sets the number of columns in @model to @n_columns. If @set_types
554 * or @set_names are %TRUE, initialises the columns type and name
557 * This function can only be called once.
560 clutter_model_set_n_columns (ClutterModel *model,
565 ClutterModelPrivate *priv = model->priv;
567 if (priv->n_columns > 0 && priv->n_columns != n_columns)
570 priv->n_columns = n_columns;
572 if (set_types && !priv->column_types)
573 priv->column_types = g_new0 (GType, n_columns);
575 if (set_names && !priv->column_names)
576 priv->column_names = g_new0 (gchar*, n_columns);
580 * clutter_model_set_column_type:
581 * @model: a #ClutterModel
582 * @column: column index
583 * @gtype: type of the column
585 * Sets the type of @column inside @model
588 clutter_model_set_column_type (ClutterModel *model,
592 ClutterModelPrivate *priv = model->priv;
594 priv->column_types[column] = gtype;
598 * clutter_model_set_column_name:
599 * @model: a #ClutterModel
600 * @column: column index
601 * @name: name of the column, or %NULL
603 * Sets the name of @column inside @model
606 clutter_model_set_column_name (ClutterModel *model,
610 ClutterModelPrivate *priv = model->priv;
612 priv->column_names[column] = g_strdup (name);
616 * clutter_model_set_types:
617 * @model: a #ClutterModel
618 * @n_columns: number of columns for the model
619 * @types: (array length=n_columns): an array of #GType types
621 * Sets the types of the columns inside a #ClutterModel.
623 * This function is meant primarily for #GObjects that inherit from
624 * #ClutterModel, and should only be used when contructing a #ClutterModel.
625 * It will not work after the initial creation of the #ClutterModel.
630 clutter_model_set_types (ClutterModel *model,
634 ClutterModelPrivate *priv;
637 g_return_if_fail (CLUTTER_IS_MODEL (model));
638 g_return_if_fail (n_columns > 0);
642 g_return_if_fail (priv->n_columns < 0 || priv->n_columns == n_columns);
643 g_return_if_fail (priv->column_types == NULL);
645 clutter_model_set_n_columns (model, n_columns, TRUE, FALSE);
647 for (i = 0; i < n_columns; i++)
649 if (!clutter_model_check_type (types[i]))
651 g_warning ("%s: Invalid type %s\n", G_STRLOC, g_type_name (types[i]));
655 clutter_model_set_column_type (model, i, types[i]);
660 * clutter_model_set_names:
661 * @model: a #ClutterModel
662 * @n_columns: the number of column names
663 * @names: (array length=n_columns): an array of strings
665 * Assigns a name to the columns of a #ClutterModel.
667 * This function is meant primarily for #GObjects that inherit from
668 * #ClutterModel, and should only be used when contructing a #ClutterModel.
669 * It will not work after the initial creation of the #ClutterModel.
674 clutter_model_set_names (ClutterModel *model,
676 const gchar * const names[])
678 ClutterModelPrivate *priv;
681 g_return_if_fail (CLUTTER_IS_MODEL (model));
682 g_return_if_fail (n_columns > 0);
686 g_return_if_fail (priv->n_columns < 0 || priv->n_columns == n_columns);
687 g_return_if_fail (priv->column_names == NULL);
689 clutter_model_set_n_columns (model, n_columns, FALSE, TRUE);
691 for (i = 0; i < n_columns; i++)
692 clutter_model_set_column_name (model, i, names[i]);
696 * clutter_model_get_n_columns:
697 * @model: a #ClutterModel
699 * Retrieves the number of columns inside @model.
701 * Return value: the number of columns
706 clutter_model_get_n_columns (ClutterModel *model)
708 g_return_val_if_fail (CLUTTER_IS_MODEL (model), 0);
710 return CLUTTER_MODEL_GET_CLASS (model)->get_n_columns (model);
714 * clutter_model_appendv:
715 * @model: a #ClutterModel
716 * @n_columns: the number of columns and values
717 * @columns: (array length=n_columns): a vector with the columns to set
718 * @values: (array length=n_columns): a vector with the values
720 * Creates and appends a new row to the #ClutterModel, setting the row
721 * values for the given @columns upon creation.
726 clutter_model_appendv (ClutterModel *model,
731 ClutterModelPrivate *priv;
732 ClutterModelIter *iter;
734 gboolean resort = FALSE;
736 g_return_if_fail (CLUTTER_IS_MODEL (model));
737 g_return_if_fail (n_columns <= clutter_model_get_n_columns (model));
738 g_return_if_fail (columns != NULL);
739 g_return_if_fail (values != NULL);
743 iter = CLUTTER_MODEL_GET_CLASS (model)->insert_row (model, -1);
744 g_assert (CLUTTER_IS_MODEL_ITER (iter));
746 for (i = 0; i < n_columns; i++)
748 if (priv->sort_column == columns[i])
751 clutter_model_iter_set_value (iter, columns[i], &values[i]);
754 g_signal_emit (model, model_signals[ROW_ADDED], 0, iter);
757 clutter_model_resort (model);
759 g_object_unref (iter);
762 /* forward declaration */
763 static void clutter_model_iter_set_internal_valist (ClutterModelIter *iter,
767 * clutter_model_append:
768 * @model: a #ClutterModel
769 * @Varargs: pairs of column number and value, terminated with -1
771 * Creates and appends a new row to the #ClutterModel, setting the
772 * row values upon creation. For example, to append a new row where
773 * column 0 is type %G_TYPE_INT and column 1 is of type %G_TYPE_STRING:
775 * <informalexample><programlisting>
776 * ClutterModel *model;
777 * model = clutter_model_default_new (2,
778 * G_TYPE_INT, "Score",
779 * G_TYPE_STRING, "Team");
780 * clutter_model_append (model, 0, 42, 1, "Team #1", -1);
781 * </programlisting></informalexample>
786 clutter_model_append (ClutterModel *model,
789 ClutterModelIter *iter;
792 g_return_if_fail (CLUTTER_IS_MODEL (model));
794 iter = CLUTTER_MODEL_GET_CLASS (model)->insert_row (model, -1);
795 g_assert (CLUTTER_IS_MODEL_ITER (iter));
797 /* do not emit the ::row-changed signal */
798 va_start (args, model);
799 clutter_model_iter_set_internal_valist (iter, args);
802 g_signal_emit (model, model_signals[ROW_ADDED], 0, iter);
804 g_object_unref (iter);
808 * clutter_model_prependv:
809 * @model: a #ClutterModel
810 * @n_columns: the number of columns and values to set
811 * @columns: (array length=n_columns): a vector containing the columns to set
812 * @values: (array length=n_columns): a vector containing the values for the cells
814 * Creates and prepends a new row to the #ClutterModel, setting the row
815 * values for the given @columns upon creation.
820 clutter_model_prependv (ClutterModel *model,
825 ClutterModelPrivate *priv;
826 ClutterModelIter *iter;
828 gboolean resort = FALSE;
830 g_return_if_fail (CLUTTER_IS_MODEL (model));
831 g_return_if_fail (n_columns <= clutter_model_get_n_columns (model));
832 g_return_if_fail (columns != NULL);
833 g_return_if_fail (values != NULL);
837 iter = CLUTTER_MODEL_GET_CLASS (model)->insert_row (model, 0);
838 g_assert (CLUTTER_IS_MODEL_ITER (iter));
840 for (i = 0; i < n_columns; i++)
842 if (priv->sort_column == columns[i])
845 clutter_model_iter_set_value (iter, columns[i], &values[i]);
848 g_signal_emit (model, model_signals[ROW_ADDED], 0, iter);
851 clutter_model_resort (model);
853 g_object_unref (iter);
857 * clutter_model_prepend:
858 * @model: a #ClutterModel
859 * @Varargs: pairs of column number and value, terminated with -1
861 * Creates and prepends a new row to the #ClutterModel, setting the row
862 * values upon creation. For example, to prepend a new row where column 0
863 * is type %G_TYPE_INT and column 1 is of type %G_TYPE_STRING:
865 * <informalexample><programlisting>
866 * ClutterModel *model;
867 * model = clutter_model_default_new (2,
868 * G_TYPE_INT, "Score",
869 * G_TYPE_STRING, "Team");
870 * clutter_model_prepend (model, 0, 42, 1, "Team #1", -1);
871 * </programlisting></informalexample>
876 clutter_model_prepend (ClutterModel *model,
879 ClutterModelIter *iter;
882 g_return_if_fail (CLUTTER_IS_MODEL (model));
884 iter = CLUTTER_MODEL_GET_CLASS (model)->insert_row (model, 0);
885 g_assert (CLUTTER_IS_MODEL_ITER (iter));
887 va_start (args, model);
888 clutter_model_iter_set_internal_valist (iter, args);
891 g_signal_emit (model, model_signals[ROW_ADDED], 0, iter);
893 g_object_unref (iter);
898 * clutter_model_insert:
899 * @model: a #ClutterModel
900 * @row: the position to insert the new row
901 * @Varargs: pairs of column number and value, terminated with -1
903 * Inserts a new row to the #ClutterModel at @row, setting the row
904 * values upon creation. For example, to insert a new row at index 100,
905 * where column 0 is type %G_TYPE_INT and column 1 is of type
908 * <informalexample><programlisting>
909 * ClutterModel *model;
910 * model = clutter_model_default_new (2,
911 * G_TYPE_INT, "Score",
912 * G_TYPE_STRING, "Team");
913 * clutter_model_insert (model, 3, 0, 42, 1, "Team #1", -1);
914 * </programlisting></informalexample>
919 clutter_model_insert (ClutterModel *model,
923 ClutterModelIter *iter;
926 g_return_if_fail (CLUTTER_IS_MODEL (model));
928 iter = CLUTTER_MODEL_GET_CLASS (model)->insert_row (model, row);
929 g_assert (CLUTTER_IS_MODEL_ITER (iter));
931 /* set_valist() will call clutter_model_resort() if one of the
932 * passed columns matches the model sorting column index
934 va_start (args, row);
935 clutter_model_iter_set_internal_valist (iter, args);
938 g_signal_emit (model, model_signals[ROW_ADDED], 0, iter);
940 g_object_unref (iter);
944 * clutter_model_insertv:
945 * @model: a #ClutterModel
947 * @n_columns: the number of columns and values to set
948 * @columns: (array length=n_columns): a vector containing the columns to set
949 * @values: (array length=n_columns): a vector containing the values for the cells
951 * Inserts data at @row into the #ClutterModel, setting the row
952 * values for the given @columns upon creation.
957 clutter_model_insertv (ClutterModel *model,
963 ClutterModelPrivate *priv;
964 ClutterModelIter *iter;
966 gboolean resort = FALSE;
968 g_return_if_fail (CLUTTER_IS_MODEL (model));
969 g_return_if_fail (n_columns <= clutter_model_get_n_columns (model));
970 g_return_if_fail (columns != NULL);
971 g_return_if_fail (values != NULL);
975 iter = CLUTTER_MODEL_GET_CLASS (model)->insert_row (model, row);
976 g_assert (CLUTTER_IS_MODEL_ITER (iter));
978 for (i = 0; i < n_columns; i++)
980 if (priv->sort_column == columns[i])
983 clutter_model_iter_set_value (iter, columns[i], &values[i]);
986 g_signal_emit (model, model_signals[ROW_ADDED], 0, iter);
989 clutter_model_resort (model);
991 g_object_unref (iter);
995 * clutter_model_insert_value:
996 * @model: a #ClutterModel
997 * @row: position of the row to modify
998 * @column: column to modify
999 * @value: new value for the cell
1001 * Sets the data in the cell specified by @iter and @column. The type of
1002 * @value must be convertable to the type of the column. If the row does
1003 * not exist then it is created.
1008 clutter_model_insert_value (ClutterModel *model,
1011 const GValue *value)
1013 ClutterModelPrivate *priv;
1014 ClutterModelClass *klass;
1015 ClutterModelIter *iter;
1016 gboolean added = FALSE;
1018 g_return_if_fail (CLUTTER_IS_MODEL (model));
1021 klass = CLUTTER_MODEL_GET_CLASS (model);
1023 iter = klass->get_iter_at_row (model, row);
1026 iter = klass->insert_row (model, row);
1030 g_assert (CLUTTER_IS_MODEL_ITER (iter));
1032 clutter_model_iter_set_value (iter, column, value);
1035 g_signal_emit (model, model_signals[ROW_ADDED], 0, iter);
1037 if (priv->sort_column == column)
1038 clutter_model_resort (model);
1040 g_object_unref (iter);
1044 * clutter_model_remove:
1045 * @model: a #ClutterModel
1046 * @row: position of row to remove
1048 * Removes the row at the given position from the model.
1053 clutter_model_remove (ClutterModel *model,
1056 ClutterModelClass *klass;
1058 g_return_if_fail (CLUTTER_IS_MODEL (model));
1060 klass = CLUTTER_MODEL_GET_CLASS (model);
1061 if (klass->remove_row)
1062 klass->remove_row (model, row);
1066 * clutter_model_get_column_name:
1067 * @model: #ClutterModel
1068 * @column: the column number
1070 * Retrieves the name of the @column
1072 * Return value: the name of the column. The model holds the returned
1073 * string, and it should not be modified or freed
1077 G_CONST_RETURN gchar *
1078 clutter_model_get_column_name (ClutterModel *model,
1081 ClutterModelClass *klass;
1083 g_return_val_if_fail (CLUTTER_IS_MODEL (model), NULL);
1085 if (column < 0 || column >= clutter_model_get_n_columns (model))
1087 g_warning ("%s: Invalid column id value %d\n", G_STRLOC, column);
1091 klass = CLUTTER_MODEL_GET_CLASS (model);
1092 if (klass->get_column_name)
1093 return klass->get_column_name (model, column);
1099 * clutter_model_get_column_type:
1100 * @model: #ClutterModel
1101 * @column: the column number
1103 * Retrieves the type of the @column.
1105 * Return value: the type of the column.
1110 clutter_model_get_column_type (ClutterModel *model,
1113 ClutterModelClass *klass;
1115 g_return_val_if_fail (CLUTTER_IS_MODEL (model), G_TYPE_INVALID);
1117 if (column < 0 || column >= clutter_model_get_n_columns (model))
1119 g_warning ("%s: Invalid column id value %d\n", G_STRLOC, column);
1120 return G_TYPE_INVALID;
1123 klass = CLUTTER_MODEL_GET_CLASS (model);
1124 if (klass->get_column_type)
1125 return klass->get_column_type (model, column);
1127 return G_TYPE_INVALID;
1131 * clutter_model_get_iter_at_row:
1132 * @model: a #ClutterModel
1133 * @row: position of the row to retrieve
1135 * Retrieves a #ClutterModelIter representing the row at the given index.
1137 * If a filter function has been set using clutter_model_set_filter()
1138 * then the @model implementation will return the first non filtered
1141 * Return value: (transfer full): A new #ClutterModelIter, or %NULL if @row was
1142 * out of bounds. When done using the iterator object, call g_object_unref()
1143 * to deallocate its resources
1148 clutter_model_get_iter_at_row (ClutterModel *model,
1151 ClutterModelClass *klass;
1153 g_return_val_if_fail (CLUTTER_IS_MODEL (model), NULL);
1155 klass = CLUTTER_MODEL_GET_CLASS (model);
1156 if (klass->get_iter_at_row)
1157 return klass->get_iter_at_row (model, row);
1164 * clutter_model_get_first_iter:
1165 * @model: a #ClutterModel
1167 * Retrieves a #ClutterModelIter representing the first non-filtered
1170 * Return value: (transfer full): A new #ClutterModelIter.
1171 * Call g_object_unref() when done using it
1176 clutter_model_get_first_iter (ClutterModel *model)
1178 ClutterModelIter *retval;
1180 g_return_val_if_fail (CLUTTER_IS_MODEL (model), NULL);
1182 retval = clutter_model_get_iter_at_row (model, 0);
1185 g_assert (clutter_model_filter_iter (model, retval) != FALSE);
1186 g_assert (clutter_model_iter_get_row (retval) == 0);
1193 * clutter_model_get_last_iter:
1194 * @model: a #ClutterModel
1196 * Retrieves a #ClutterModelIter representing the last non-filtered
1199 * Return value: (transfer full): A new #ClutterModelIter.
1200 * Call g_object_unref() when done using it
1205 clutter_model_get_last_iter (ClutterModel *model)
1207 ClutterModelIter *retval;
1210 g_return_val_if_fail (CLUTTER_IS_MODEL (model), NULL);
1212 length = clutter_model_get_n_rows (model);
1213 retval = clutter_model_get_iter_at_row (model, length - 1);
1215 g_assert (clutter_model_filter_iter (model, retval) != FALSE);
1221 * clutter_model_get_n_rows:
1222 * @model: a #ClutterModel
1224 * Retrieves the number of rows inside @model, eventually taking
1225 * into account any filtering function set using clutter_model_set_filter().
1227 * Return value: The length of the @model. If there is a filter set, then
1228 * the length of the filtered @model is returned.
1233 clutter_model_get_n_rows (ClutterModel *model)
1235 ClutterModelClass *klass;
1238 g_return_val_if_fail (CLUTTER_IS_MODEL (model), 0);
1240 klass = CLUTTER_MODEL_GET_CLASS (model);
1241 if (klass->get_n_rows)
1242 row_count = klass->get_n_rows (model);
1245 ClutterModelIter *iter;
1247 iter = clutter_model_get_first_iter (model);
1252 while (!clutter_model_iter_is_last (iter))
1254 if (clutter_model_filter_iter (model, iter))
1257 iter = clutter_model_iter_next (iter);
1260 g_object_unref (iter);
1268 * clutter_model_set_sorting_column:
1269 * @model: a #ClutterModel
1270 * @column: the column of the @model to sort, or -1
1272 * Sets the model to sort by @column. If @column is a negative value
1273 * the sorting column will be unset.
1278 clutter_model_set_sorting_column (ClutterModel *model,
1281 ClutterModelPrivate *priv;
1283 g_return_if_fail (CLUTTER_IS_MODEL (model));
1286 /* The extra comparison for >= 0 is because column gets promoted to
1287 unsigned in the second comparison */
1288 if (column >= 0 && column >= clutter_model_get_n_columns (model))
1290 g_warning ("%s: Invalid column id value %d\n", G_STRLOC, column);
1294 priv->sort_column = column;
1296 if (priv->sort_column >= 0)
1297 clutter_model_resort (model);
1299 g_signal_emit (model, model_signals[SORT_CHANGED], 0);
1303 * clutter_model_get_sorting_column:
1304 * @model: a #ClutterModel
1306 * Retrieves the number of column used for sorting the @model.
1308 * Return value: a column number, or -1 if the model is not sorted
1313 clutter_model_get_sorting_column (ClutterModel *model)
1315 g_return_val_if_fail (CLUTTER_IS_MODEL (model), -1);
1317 return model->priv->sort_column;
1321 * clutter_model_foreach:
1322 * @model: a #ClutterModel
1323 * @func: a #ClutterModelForeachFunc
1324 * @user_data: user data to pass to @func
1326 * Calls @func for each row in the model.
1331 clutter_model_foreach (ClutterModel *model,
1332 ClutterModelForeachFunc func,
1335 ClutterModelIter *iter;
1337 g_return_if_fail (CLUTTER_IS_MODEL (model));
1339 iter = clutter_model_get_first_iter (model);
1343 while (!clutter_model_iter_is_last (iter))
1345 if (clutter_model_filter_iter (model, iter))
1347 if (!func (model, iter, user_data))
1351 iter = clutter_model_iter_next (iter);
1354 g_object_unref (iter);
1358 * clutter_model_set_sort:
1359 * @model: a #ClutterModel
1360 * @column: the column to sort on
1361 * @func: a #ClutterModelSortFunc, or #NULL
1362 * @user_data: user data to pass to @func, or #NULL
1363 * @notify: destroy notifier of @user_data, or #NULL
1365 * Sorts @model using the given sorting function.
1370 clutter_model_set_sort (ClutterModel *model,
1372 ClutterModelSortFunc func,
1374 GDestroyNotify notify)
1376 ClutterModelPrivate *priv;
1378 g_return_if_fail (CLUTTER_IS_MODEL (model));
1379 g_return_if_fail ((func != NULL && column >= 0) ||
1380 (func == NULL && column == -1));
1384 if (priv->sort_notify)
1385 priv->sort_notify (priv->sort_data);
1387 priv->sort_func = func;
1388 priv->sort_data = user_data;
1389 priv->sort_notify = notify;
1391 /* This takes care of calling _model_sort & emitting the signal*/
1392 clutter_model_set_sorting_column (model, column);
1396 * clutter_model_set_filter:
1397 * @model: a #ClutterModel
1398 * @func: a #ClutterModelFilterFunc, or #NULL
1399 * @user_data: user data to pass to @func, or #NULL
1400 * @notify: destroy notifier of @user_data, or #NULL
1402 * Filters the @model using the given filtering function.
1407 clutter_model_set_filter (ClutterModel *model,
1408 ClutterModelFilterFunc func,
1410 GDestroyNotify notify)
1412 ClutterModelPrivate *priv;
1414 g_return_if_fail (CLUTTER_IS_MODEL (model));
1417 if (priv->filter_notify)
1418 priv->filter_notify (priv->filter_data);
1420 priv->filter_func = func;
1421 priv->filter_data = user_data;
1422 priv->filter_notify = notify;
1424 g_signal_emit (model, model_signals[FILTER_CHANGED], 0);
1425 g_object_notify (G_OBJECT (model), "filter-set");
1429 * clutter_model_get_filter_set:
1430 * @model: a #ClutterModel
1432 * Returns whether the @model has a filter in place, set
1433 * using clutter_model_set_filter()
1435 * Return value: %TRUE if a filter is set
1440 clutter_model_get_filter_set (ClutterModel *model)
1442 g_return_val_if_fail (CLUTTER_IS_MODEL (model), FALSE);
1444 return model->priv->filter_func != NULL;
1448 * ClutterModelIter Object
1452 * SECTION:clutter-model-iter
1453 * @short_description: Iterates through a model
1455 * #ClutterModelIter is an object used for iterating through all the rows
1456 * of a #ClutterModel. It allows setting and getting values on the row
1457 * which is currently pointing at.
1459 * A #ClutterModelIter represents a position between two elements
1460 * of the sequence. For example, the iterator returned by
1461 * clutter_model_get_first_iter() represents the gap immediately before
1462 * the first row of the #ClutterModel, and the iterator returned by
1463 * clutter_model_get_last_iter() represents the gap immediately after the
1466 * A #ClutterModelIter can only be created by a #ClutterModel implementation
1467 * and it is valid as long as the model does not change.
1469 * #ClutterModelIter is available since Clutter 0.6
1472 G_DEFINE_ABSTRACT_TYPE (ClutterModelIter, clutter_model_iter, G_TYPE_OBJECT);
1474 #define CLUTTER_MODEL_ITER_GET_PRIVATE(obj) \
1475 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
1476 CLUTTER_TYPE_MODEL_ITER, ClutterModelIterPrivate))
1478 struct _ClutterModelIterPrivate
1480 ClutterModel *model;
1484 guint ignore_sort : 1;
1495 static ClutterModel *
1496 clutter_model_iter_real_get_model (ClutterModelIter *iter)
1498 return iter->priv->model;
1502 clutter_model_iter_real_get_row (ClutterModelIter *iter)
1504 return iter->priv->row;
1507 /* private function */
1509 clutter_model_iter_set_row (ClutterModelIter *iter,
1512 iter->priv->row = row;
1516 clutter_model_iter_get_value_unimplemented (ClutterModelIter *iter,
1520 g_warning ("%s: Iterator of type '%s' does not implement the "
1521 "ClutterModelIter::get_value() virtual function",
1523 g_type_name (G_OBJECT_TYPE (iter)));
1527 clutter_model_iter_set_value_unimplemented (ClutterModelIter *iter,
1529 const GValue *value)
1531 g_warning ("%s: Iterator of type '%s' does not implement the "
1532 "ClutterModelIter::set_value() virtual function",
1534 g_type_name (G_OBJECT_TYPE (iter)));
1538 clutter_model_iter_is_first_unimplemented (ClutterModelIter *iter)
1540 g_warning ("%s: Iterator of type '%s' does not implement the "
1541 "ClutterModelIter::is_first() virtual function",
1543 g_type_name (G_OBJECT_TYPE (iter)));
1548 clutter_model_iter_is_last_unimplemented (ClutterModelIter *iter)
1550 g_warning ("%s: Iterator of type '%s' does not implement the "
1551 "ClutterModelIter::is_last() virtual function",
1553 g_type_name (G_OBJECT_TYPE (iter)));
1557 static ClutterModelIter *
1558 clutter_model_iter_next_unimplemented (ClutterModelIter *iter)
1560 g_warning ("%s: Iterator of type '%s' does not implement the "
1561 "ClutterModelIter::next() virtual function",
1563 g_type_name (G_OBJECT_TYPE (iter)));
1567 static ClutterModelIter *
1568 clutter_model_iter_prev_unimplemented (ClutterModelIter *iter)
1570 g_warning ("%s: Iterator of type '%s' does not implement the "
1571 "ClutterModelIter::prev() virtual function",
1573 g_type_name (G_OBJECT_TYPE (iter)));
1577 static ClutterModelIter *
1578 clutter_model_iter_copy_unimplemented (ClutterModelIter *iter)
1580 g_warning ("%s: Iterator of type '%s' does not implement the "
1581 "ClutterModelIter::copy() virtual function",
1583 g_type_name (G_OBJECT_TYPE (iter)));
1588 clutter_model_iter_get_property (GObject *object,
1593 ClutterModelIter *iter = CLUTTER_MODEL_ITER (object);
1594 ClutterModelIterPrivate *priv = iter->priv;
1598 case ITER_PROP_MODEL:
1599 g_value_set_object (value, priv->model);
1602 g_value_set_uint (value, priv->row);
1605 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1611 clutter_model_iter_set_property (GObject *object,
1613 const GValue *value,
1616 ClutterModelIter *iter = CLUTTER_MODEL_ITER (object);
1617 ClutterModelIterPrivate *priv = iter->priv;
1621 case ITER_PROP_MODEL:
1622 priv->model = g_value_get_object (value);
1625 priv->row = g_value_get_uint (value);
1628 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1634 clutter_model_iter_class_init (ClutterModelIterClass *klass)
1636 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
1639 gobject_class->get_property = clutter_model_iter_get_property;
1640 gobject_class->set_property = clutter_model_iter_set_property;
1642 klass->get_model = clutter_model_iter_real_get_model;
1643 klass->get_row = clutter_model_iter_real_get_row;
1644 klass->is_first = clutter_model_iter_is_first_unimplemented;
1645 klass->is_last = clutter_model_iter_is_last_unimplemented;
1646 klass->next = clutter_model_iter_next_unimplemented;
1647 klass->prev = clutter_model_iter_prev_unimplemented;
1648 klass->get_value = clutter_model_iter_get_value_unimplemented;
1649 klass->set_value = clutter_model_iter_set_value_unimplemented;
1650 klass->copy = clutter_model_iter_copy_unimplemented;
1655 * ClutterModelIter:model:
1657 * A reference to the #ClutterModel that this iter belongs to.
1661 pspec = g_param_spec_object ("model",
1663 "The model to which the iterator belongs to",
1665 CLUTTER_PARAM_READWRITE);
1666 g_object_class_install_property (gobject_class, ITER_PROP_MODEL, pspec);
1669 * ClutterModelIter:row:
1671 * The row number to which this iter points to.
1675 pspec = g_param_spec_uint ("row",
1677 "The row to which the iterator points to",
1679 CLUTTER_PARAM_READWRITE);
1680 g_object_class_install_property (gobject_class, ITER_PROP_ROW, pspec);
1682 g_type_class_add_private (gobject_class, sizeof (ClutterModelIterPrivate));
1686 clutter_model_iter_init (ClutterModelIter *self)
1688 ClutterModelIterPrivate *priv;
1690 self->priv = priv = CLUTTER_MODEL_ITER_GET_PRIVATE (self);
1695 priv->ignore_sort = FALSE;
1703 clutter_model_iter_set_internal_valist (ClutterModelIter *iter,
1706 ClutterModel *model;
1707 ClutterModelIterPrivate *priv;
1709 gboolean sort = FALSE;
1712 model = priv->model;
1713 g_assert (CLUTTER_IS_MODEL (model));
1715 column = va_arg (args, gint);
1717 /* Don't want to sort while setting lots of fields, leave that till the end
1719 priv->ignore_sort = TRUE;
1720 while (column != -1)
1722 GValue value = { 0, };
1723 gchar *error = NULL;
1725 if (column < 0 || column >= clutter_model_get_n_columns (model))
1727 g_warning ("%s: Invalid column number %d added to iter "
1728 "(remember to end you list of columns with a -1)",
1732 g_value_init (&value, clutter_model_get_column_type (model, column));
1734 G_VALUE_COLLECT (&value, args, 0, &error);
1737 g_warning ("%s: %s", G_STRLOC, error);
1740 /* Leak value as it might not be in a sane state */
1744 clutter_model_iter_set_value (iter, column, &value);
1746 g_value_unset (&value);
1748 if (column == clutter_model_get_sorting_column (model))
1751 column = va_arg (args, gint);
1754 priv->ignore_sort = FALSE;
1756 clutter_model_resort (model);
1760 * clutter_model_iter_set_valist:
1761 * @iter: a #ClutterModelIter
1762 * @args: va_list of column/value pairs, terminiated by -1
1764 * See clutter_model_iter_set(); this version takes a va_list for language
1770 clutter_model_iter_set_valist (ClutterModelIter *iter,
1773 ClutterModelIterPrivate *priv;
1774 ClutterModel *model;
1776 g_return_if_fail (CLUTTER_IS_MODEL_ITER (iter));
1778 clutter_model_iter_set_internal_valist (iter, args);
1781 model = priv->model;
1782 g_assert (CLUTTER_IS_MODEL (model));
1784 g_signal_emit (model, model_signals[ROW_CHANGED], 0, iter);
1788 * clutter_model_iter_get:
1789 * @iter: a #ClutterModelIter
1790 * @Varargs: a list of column/return location pairs, terminated by -1
1792 * Gets the value of one or more cells in the row referenced by @iter. The
1793 * variable argument list should contain integer column numbers, each column
1794 * column number followed by a place to store the value being retrieved. The
1795 * list is terminated by a -1.
1797 * For example, to get a value from column 0 with type %G_TYPE_STRING use:
1798 * <informalexample><programlisting>
1799 * clutter_model_iter_get (iter, 0, &place_string_here, -1);
1800 * </programlisting></informalexample>
1802 * where place_string_here is a gchar* to be filled with the string. If
1803 * appropriate, the returned values have to be freed or unreferenced.
1808 clutter_model_iter_get (ClutterModelIter *iter,
1813 g_return_if_fail (CLUTTER_IS_MODEL_ITER (iter));
1815 va_start (args, iter);
1816 clutter_model_iter_get_valist (iter, args);
1821 * clutter_model_iter_get_value:
1822 * @iter: a #ClutterModelIter
1823 * @column: column number to retrieve the value from
1824 * @value: an empty #GValue to set
1826 * Sets an initializes @value to that at @column. When done with @value,
1827 * g_value_unset() needs to be called to free any allocated memory.
1832 clutter_model_iter_get_value (ClutterModelIter *iter,
1836 ClutterModelIterClass *klass;
1837 ClutterModel *model;
1839 g_return_if_fail (CLUTTER_IS_MODEL_ITER (iter));
1841 model = iter->priv->model;
1843 g_value_init (value, clutter_model_get_column_type (model, column));
1845 klass = CLUTTER_MODEL_ITER_GET_CLASS (iter);
1846 if (klass && klass->get_value)
1847 klass->get_value (iter, column, value);
1851 * clutter_model_iter_get_valist:
1852 * @iter: a #ClutterModelIter
1853 * @args: a list of column/return location pairs, terminated by -1
1855 * See clutter_model_iter_get(). This version takes a va_list for language
1861 clutter_model_iter_get_valist (ClutterModelIter *iter,
1864 ClutterModelIterPrivate *priv;
1865 ClutterModel *model;
1868 g_return_if_fail (CLUTTER_IS_MODEL_ITER (iter));
1871 model = priv->model;
1872 g_assert (CLUTTER_IS_MODEL (model));
1874 column = va_arg (args, gint);
1876 while (column != -1)
1878 GValue value = { 0, };
1879 gchar *error = NULL;
1881 if (column < 0 || column >= clutter_model_get_n_columns (model))
1883 g_warning ("%s: Invalid column number %d added to iter "
1884 "(remember to end you list of columns with a -1)",
1889 /* this one will take care of initialising value to the
1892 clutter_model_iter_get_value (iter, column, &value);
1894 G_VALUE_LCOPY (&value, args, 0, &error);
1897 g_warning ("%s: %s", G_STRLOC, error);
1900 /* Leak value as it might not be in a sane state */
1904 g_value_unset (&value);
1906 column = va_arg (args, gint);
1911 * clutter_model_iter_set:
1912 * @iter: a #ClutterModelIter
1913 * @Varargs: a list of column/return location pairs, terminated by -1
1915 * Sets the value of one or more cells in the row referenced by @iter. The
1916 * variable argument list should contain integer column numbers, each column
1917 * column number followed by the value to be set. The list is terminated by a
1920 * For example, to set column 0 with type %G_TYPE_STRING, use:
1921 * <informalexample><programlisting>
1922 * clutter_model_iter_set (iter, 0, "foo", -1);
1923 * </programlisting></informalexample>
1928 clutter_model_iter_set (ClutterModelIter *iter,
1933 g_return_if_fail (CLUTTER_IS_MODEL_ITER (iter));
1935 va_start (args, iter);
1936 clutter_model_iter_set_valist (iter, args);
1942 * clutter_model_iter_set_value:
1943 * @iter: a #ClutterModelIter
1944 * @column: column number to retrieve the value from
1945 * @value: new value for the cell
1947 * Sets the data in the cell specified by @iter and @column. The type of
1948 * @value must be convertable to the type of the column.
1953 clutter_model_iter_set_value (ClutterModelIter *iter,
1955 const GValue *value)
1957 ClutterModelIterClass *klass;
1959 g_return_if_fail (CLUTTER_IS_MODEL_ITER (iter));
1961 klass = CLUTTER_MODEL_ITER_GET_CLASS (iter);
1962 if (klass && klass->set_value)
1963 klass->set_value (iter, column, value);
1967 * clutter_model_iter_is_first:
1968 * @iter: a #ClutterModelIter
1970 * Gets whether the current iterator is at the beginning of the model
1971 * to which it belongs.
1973 * Return value: #TRUE if @iter is the first iter in the filtered model
1978 clutter_model_iter_is_first (ClutterModelIter *iter)
1980 ClutterModelIterClass *klass;
1982 g_return_val_if_fail (CLUTTER_IS_MODEL_ITER (iter), FALSE);
1984 klass = CLUTTER_MODEL_ITER_GET_CLASS (iter);
1985 if (klass && klass->is_first)
1986 return klass->is_first (iter);
1992 * clutter_model_iter_is_last:
1993 * @iter: a #ClutterModelIter
1995 * Gets whether the iterator is at the end of the model to which it
1998 * Return value: #TRUE if @iter is the last iter in the filtered model.
2003 clutter_model_iter_is_last (ClutterModelIter *iter)
2005 ClutterModelIterClass *klass;
2007 g_return_val_if_fail (CLUTTER_IS_MODEL_ITER (iter), FALSE);
2009 klass = CLUTTER_MODEL_ITER_GET_CLASS (iter);
2010 if (klass && klass->is_last)
2011 return klass->is_last (iter);
2017 * clutter_model_iter_next:
2018 * @iter: a #ClutterModelIter
2020 * Updates the @iter to point at the next position in the model.
2021 * The model implementation should take into account the presence of
2022 * a filter function.
2024 * Return value: (transfer none): The passed iterator, updated to point at the next
2030 clutter_model_iter_next (ClutterModelIter *iter)
2032 ClutterModelIterClass *klass;
2034 g_return_val_if_fail (CLUTTER_IS_MODEL_ITER (iter), NULL);
2036 klass = CLUTTER_MODEL_ITER_GET_CLASS (iter);
2037 if (klass && klass->next)
2038 return klass->next (iter);
2044 * clutter_model_iter_prev:
2045 * @iter: a #ClutterModelIter
2047 * Sets the @iter to point at the previous position in the model.
2048 * The model implementation should take into account the presence of
2049 * a filter function.
2051 * Return value: (transfer none): The passed iterator, updated to point at the previous
2057 clutter_model_iter_prev (ClutterModelIter *iter)
2059 ClutterModelIterClass *klass;
2061 g_return_val_if_fail (CLUTTER_IS_MODEL_ITER (iter), NULL);
2063 klass = CLUTTER_MODEL_ITER_GET_CLASS (iter);
2064 if (klass && klass->prev)
2065 return klass->prev (iter);
2071 * clutter_model_iter_get_model:
2072 * @iter: a #ClutterModelIter
2074 * Retrieves a pointer to the #ClutterModel that this iter is part of.
2076 * Return value: (transfer none): a pointer to a #ClutterModel.
2081 clutter_model_iter_get_model (ClutterModelIter *iter)
2083 ClutterModelIterClass *klass;
2085 g_return_val_if_fail (CLUTTER_IS_MODEL_ITER (iter), NULL);
2087 klass = CLUTTER_MODEL_ITER_GET_CLASS (iter);
2088 if (klass && klass->get_model)
2089 return klass->get_model (iter);
2095 * clutter_model_iter_get_row:
2096 * @iter: a #ClutterModelIter
2098 * Retrieves the position of the row that the @iter points to.
2100 * Return value: the position of the @iter in the model
2105 clutter_model_iter_get_row (ClutterModelIter *iter)
2107 ClutterModelIterClass *klass;
2109 g_return_val_if_fail (CLUTTER_IS_MODEL_ITER (iter), 0);
2111 klass = CLUTTER_MODEL_ITER_GET_CLASS (iter);
2112 if (klass && klass->get_row)
2113 return klass->get_row (iter);
2119 * clutter_model_iter_copy:
2120 * @iter: a #ClutterModelIter
2122 * Copies the passed iterator.
2124 * Return value: a copy of the iterator, or %NULL
2129 clutter_model_iter_copy (ClutterModelIter *iter)
2131 ClutterModelIterClass *klass;
2133 g_return_val_if_fail (CLUTTER_IS_MODEL_ITER (iter), NULL);
2135 klass = CLUTTER_MODEL_ITER_GET_CLASS (iter);
2137 return klass->copy (iter);