2007-11-28 Emmanuele Bassi <ebassi@openedhand.com>

Add more introspection capabilities to the base model class

	* clutter/clutter-model.h:
	* clutter/clutter-model.c:
	(clutter_model_finalize): Do no leak the column types array.

	(clutter_model_get_n_columns): Function for getting the number
	of columns inside a model.

	(clutter_model_set_names): Add API for setting the names of the
	columns.

	(clutter_model_get_column_name),
	(_model_get_column_type): Add API for getting each column's name
	and the default implementation for ClutterModel.

	(clutter_model_get_column_type),
	(_model_get_iter_at_row): Add API for getting each column's type
	and the default implementation for ClutterModel.

	* clutter.symbols: Add ClutterModel and ClutterModelIter symbols,
	and keep the symbols file sorted.
This commit is contained in:
Emmanuele Bassi 2007-11-28 18:04:24 +00:00
parent 132296dcc3
commit 9800eb0639
4 changed files with 749 additions and 534 deletions

View File

@ -1,3 +1,28 @@
2007-11-28 Emmanuele Bassi <ebassi@openedhand.com>
Add more introspection capabilities to the base model class
* clutter/clutter-model.h:
* clutter/clutter-model.c:
(clutter_model_finalize): Do no leak the column types array.
(clutter_model_get_n_columns): Function for getting the number
of columns inside a model.
(clutter_model_set_names): Add API for setting the names of the
columns.
(clutter_model_get_column_name),
(_model_get_column_type): Add API for getting each column's name
and the default implementation for ClutterModel.
(clutter_model_get_column_type),
(_model_get_iter_at_row): Add API for getting each column's type
and the default implementation for ClutterModel.
* clutter.symbols: Add ClutterModel and ClutterModelIter symbols,
and keep the symbols file sorted.
2007-11-28 Tomas Frydrych <tf@openedhand.com> 2007-11-28 Tomas Frydrych <tf@openedhand.com>
* clutter/clutter-actor.c: * clutter/clutter-actor.c:

File diff suppressed because it is too large Load Diff

View File

@ -144,6 +144,7 @@ struct _ClutterModelPrivate
GSequence *sequence; GSequence *sequence;
GType *column_types; GType *column_types;
gchar **column_names;
gint n_columns; gint n_columns;
ClutterModelFilterFunc filter; ClutterModelFilterFunc filter;
@ -157,23 +158,15 @@ struct _ClutterModelPrivate
}; };
/* Forwards */ /* Forwards */
static const gchar * _model_get_column_name (ClutterModel *model,
guint column);
static GType _model_get_column_type (ClutterModel *model,
guint column);
static ClutterModelIter * _model_get_iter_at_row (ClutterModel *model, static ClutterModelIter * _model_get_iter_at_row (ClutterModel *model,
guint index_); guint row);
static void clutter_model_real_remove (ClutterModel *model, static void clutter_model_real_remove (ClutterModel *model,
GSequenceIter *iter); GSequenceIter *iter);
/* GObject stuff */
static void
clutter_model_dispose (GObject *object)
{
ClutterModel *self = CLUTTER_MODEL(object);
ClutterModelPrivate *priv;
priv = self->priv;
G_OBJECT_CLASS (clutter_model_parent_class)->dispose (object);
}
static void static void
clutter_model_finalize (GObject *object) clutter_model_finalize (GObject *object)
{ {
@ -188,12 +181,14 @@ clutter_model_finalize (GObject *object)
} }
g_sequence_free (priv->sequence); g_sequence_free (priv->sequence);
if (priv->sort && priv->sort_data && priv->sort_notify) if (priv->sort_notify)
priv->sort_notify (priv->sort_data); priv->sort_notify (priv->sort_data);
if (priv->filter && priv->filter_data && priv->filter_notify) if (priv->filter_notify)
priv->filter_notify (priv->filter_data); priv->filter_notify (priv->filter_data);
g_free (priv->column_types);
g_strfreev (priv->column_names);
G_OBJECT_CLASS (clutter_model_parent_class)->finalize (object); G_OBJECT_CLASS (clutter_model_parent_class)->finalize (object);
} }
@ -204,9 +199,10 @@ clutter_model_class_init (ClutterModelClass *klass)
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = clutter_model_finalize; gobject_class->finalize = clutter_model_finalize;
gobject_class->dispose = clutter_model_dispose;
klass->get_iter_at_row = _model_get_iter_at_row; klass->get_iter_at_row = _model_get_iter_at_row;
klass->get_column_name = _model_get_column_name;
klass->get_column_type = _model_get_column_type;
/** /**
* ClutterModel::row-added: * ClutterModel::row-added:
@ -414,14 +410,12 @@ _model_filter (ClutterModel *model, ClutterModelIter *iter)
static void static void
clutter_model_set_n_columns (ClutterModel *model, gint n_columns) clutter_model_set_n_columns (ClutterModel *model,
gint n_columns)
{ {
ClutterModelPrivate *priv; ClutterModelPrivate *priv = model->priv;
GType *new_columns; GType *new_columns;
g_return_if_fail (CLUTTER_IS_MODEL (model));
priv = model->priv;
new_columns = g_new0 (GType, n_columns); new_columns = g_new0 (GType, n_columns);
priv->column_types = new_columns; priv->column_types = new_columns;
@ -433,10 +427,7 @@ clutter_model_set_column_type (ClutterModel *model,
gint column, gint column,
GType type) GType type)
{ {
ClutterModelPrivate *priv; ClutterModelPrivate *priv = model->priv;
g_return_if_fail (CLUTTER_IS_MODEL (model));
priv = model->priv;
priv->column_types[column] = type; priv->column_types[column] = type;
} }
@ -532,9 +523,11 @@ clutter_model_newv (guint n_columns,
* @n_columns: number of columns for the model * @n_columns: number of columns for the model
* @types: an array of #GType types * @types: an array of #GType types
* *
* Sets the types of the columns inside a #ClutterModel.
*
* This function is meant primarily for #GObjects that inherit from * This function is meant primarily for #GObjects that inherit from
* #ClutterModel, and should only be used when contructing a #ClutterModel. It * #ClutterModel, and should only be used when contructing a #ClutterModel.
* will not work after the initial creation of the #ClutterModel. * It will not work after the initial creation of the #ClutterModel.
* *
* Since 0.6 * Since 0.6
*/ */
@ -565,6 +558,55 @@ clutter_model_set_types (ClutterModel *model,
} }
} }
/**
* clutter_model_set_names:
* @model: a #ClutterModel
* @n_columns: the number of column names
* @names: an array of strings
*
* Assigns a name to the columns of a #ClutterModel. This function
* cannot be called twice on the same model.
*
* Since: 0.6
*/
void
clutter_model_set_names (ClutterModel *model,
guint n_columns,
const gchar * const names[])
{
ClutterModelPrivate *priv;
gint i;
g_return_if_fail (CLUTTER_IS_MODEL (model));
g_return_if_fail (n_columns > 0);
priv = model->priv;
g_return_if_fail (priv->column_names == NULL);
g_return_if_fail (n_columns <= priv->n_columns);
priv->column_names = g_new (gchar*, n_columns);
for (i = 0; i < n_columns; i++)
priv->column_names[i] = g_strdup (names[i]);
}
/**
* clutter_model_get_n_columns:
* @model: a #ClutterModel
*
* Retrieves the number of columns inside @model.
*
* Return value: the number of columns
*
* Since: 0.6
*/
guint
clutter_model_get_n_columns (ClutterModel *model)
{
g_return_val_if_fail (CLUTTER_IS_MODEL (model), 0);
return model->priv->n_columns;
}
static GValueArray * static GValueArray *
clutter_model_new_row (ClutterModel *model) clutter_model_new_row (ClutterModel *model)
@ -624,6 +666,7 @@ clutter_model_append (ClutterModel *model,
"model", model, "model", model,
"iter", seq_iter, "iter", seq_iter,
NULL); NULL);
va_start (args, model); va_start (args, model);
clutter_model_iter_set_valist (iter, args); clutter_model_iter_set_valist (iter, args);
va_end (args); va_end (args);
@ -683,10 +726,10 @@ clutter_model_prepend (ClutterModel *model,
/** /**
* clutter_model_insert: * clutter_model_insert:
* @model: a #ClutterModel * @model: a #ClutterModel
* @index_: the position to insert the new row * @row: the position to insert the new row
* @Varargs: pairs of column number and value, terminated with -1 * @Varargs: pairs of column number and value, terminated with -1
* *
* Inserts a new row to the #ClutterModel at @index_, setting the rows values * Inserts a new row to the #ClutterModel at @row, setting the rows values
* upon creation. For example, to insert a new row at index 100, where column 0 * upon creation. For example, to insert a new row at index 100, where column 0
* is type G_TYPE_INT and column 1 is of type G_TYPE_STRING, you would write * is type G_TYPE_INT and column 1 is of type G_TYPE_STRING, you would write
* <literal>clutter_model_insert (model, 100, 0, 100, 1, "string", -1); * <literal>clutter_model_insert (model, 100, 0, 100, 1, "string", -1);
@ -698,29 +741,29 @@ clutter_model_prepend (ClutterModel *model,
*/ */
gboolean gboolean
clutter_model_insert (ClutterModel *model, clutter_model_insert (ClutterModel *model,
guint index_, guint row,
...) ...)
{ {
ClutterModelPrivate *priv; ClutterModelPrivate *priv;
ClutterModelIter *iter; ClutterModelIter *iter;
GValueArray *row; GValueArray *row_array;
GSequenceIter *seq_iter; GSequenceIter *seq_iter;
va_list args; va_list args;
g_return_val_if_fail (CLUTTER_IS_MODEL (model), FALSE); g_return_val_if_fail (CLUTTER_IS_MODEL (model), FALSE);
priv = model->priv; priv = model->priv;
row = clutter_model_new_row (model); row_array = clutter_model_new_row (model);
seq_iter = g_sequence_get_iter_at_pos (priv->sequence, index_); seq_iter = g_sequence_get_iter_at_pos (priv->sequence, row);
seq_iter = g_sequence_insert_before (seq_iter, row); seq_iter = g_sequence_insert_before (seq_iter, row_array);
iter = g_object_new (CLUTTER_TYPE_MODEL_ITER, iter = g_object_new (CLUTTER_TYPE_MODEL_ITER,
"model", model, "model", model,
"iter", seq_iter, "iter", seq_iter,
NULL); NULL);
va_start (args, index_); va_start (args, row);
clutter_model_iter_set_valist (iter, args); clutter_model_iter_set_valist (iter, args);
va_end (args); va_end (args);
@ -734,7 +777,7 @@ clutter_model_insert (ClutterModel *model,
/** /**
* clutter_model_insert_value: * clutter_model_insert_value:
* @model: a #ClutterModel * @model: a #ClutterModel
* @index_: position of the row to modify * @row: position of the row to modify
* @column: column to modify * @column: column to modify
* @value: new value for the cell * @value: new value for the cell
* *
@ -747,7 +790,7 @@ clutter_model_insert (ClutterModel *model,
*/ */
gboolean gboolean
clutter_model_insert_value (ClutterModel *model, clutter_model_insert_value (ClutterModel *model,
guint index_, guint row,
guint column, guint column,
const GValue *value) const GValue *value)
{ {
@ -758,7 +801,7 @@ clutter_model_insert_value (ClutterModel *model,
g_return_val_if_fail (CLUTTER_IS_MODEL (model), FALSE); g_return_val_if_fail (CLUTTER_IS_MODEL (model), FALSE);
priv = model->priv; priv = model->priv;
seq_iter = g_sequence_get_iter_at_pos (priv->sequence, index_); seq_iter = g_sequence_get_iter_at_pos (priv->sequence, row);
iter = g_object_new (CLUTTER_TYPE_MODEL_ITER, iter = g_object_new (CLUTTER_TYPE_MODEL_ITER,
"model", model, "model", model,
@ -791,15 +834,15 @@ clutter_model_real_remove (ClutterModel *model,
/** /**
* clutter_model_remove: * clutter_model_remove:
* @model: a #ClutterModel * @model: a #ClutterModel
* @index_: position of row to remove * @row: position of row to remove
* *
* Removes a row at @index_ from the model. * Removes the row at the given position from the model.
* *
* Since 0.6 * Since 0.6
*/ */
void void
clutter_model_remove (ClutterModel *model, clutter_model_remove (ClutterModel *model,
guint index_) guint row)
{ {
ClutterModelPrivate *priv; ClutterModelPrivate *priv;
ClutterModelIter *iter; ClutterModelIter *iter;
@ -817,7 +860,7 @@ clutter_model_remove (ClutterModel *model,
g_object_set (iter, "iter", seq_iter, NULL); g_object_set (iter, "iter", seq_iter, NULL);
if (_model_filter (model, iter)) if (_model_filter (model, iter))
{ {
if (i == index_) if (i == row)
{ {
g_signal_emit (model, model_signals[ROW_REMOVED], 0, iter); g_signal_emit (model, model_signals[ROW_REMOVED], 0, iter);
clutter_model_real_remove (model, seq_iter); clutter_model_real_remove (model, seq_iter);
@ -831,32 +874,126 @@ clutter_model_remove (ClutterModel *model,
g_object_unref (iter); g_object_unref (iter);
} }
static ClutterModelIter * static const gchar *
_model_get_iter_at_row (ClutterModel *model, _model_get_column_name (ClutterModel *model,
guint index_) guint column)
{ {
ClutterModelPrivate *priv = model->priv;
if (column < 0 || column >= priv->n_columns)
return NULL;
if (priv->column_names && priv->column_names[column])
return priv->column_names[column];
return g_type_name (priv->column_types[column]);
}
/**
* clutter_model_get_column_name:
* @model: #ClutterModel
* @column: the column number
*
* Retrieves the name of the @column
*
* Return value: the name of the column. The model holds the returned
* string, and it should not be modified or freed
*
* Since: 0.6
*/
G_CONST_RETURN gchar *
clutter_model_get_column_name (ClutterModel *model,
guint column)
{
ClutterModelPrivate *priv;
ClutterModelClass *klass;
g_return_val_if_fail (CLUTTER_IS_MODEL (model), NULL); g_return_val_if_fail (CLUTTER_IS_MODEL (model), NULL);
priv = model->priv;
if (column < 0 || column > priv->n_columns)
{
g_warning ("%s: Invalid column id value %d\n", G_STRLOC, column);
return NULL;
}
klass = CLUTTER_MODEL_GET_CLASS (model);
if (klass->get_column_name)
return klass->get_column_name (model, column);
return NULL;
}
static GType
_model_get_column_type (ClutterModel *model,
guint column)
{
ClutterModelPrivate *priv = model->priv;
if (column < 0 || column >= priv->n_columns)
return G_TYPE_INVALID;
return priv->column_types[column];
}
/**
* clutter_model_get_column_type:
* @model: #ClutterModel
* @column: the column number
*
* Retrieves the type of the @column.
*
* Return value: the type of the column.
*
* Since: 0.6
*/
GType
clutter_model_get_column_type (ClutterModel *model,
guint column)
{
ClutterModelPrivate *priv;
ClutterModelClass *klass;
g_return_val_if_fail (CLUTTER_IS_MODEL (model), G_TYPE_INVALID);
priv = model->priv;
if (column < 0 || column > priv->n_columns)
{
g_warning ("%s: Invalid column id value %d\n", G_STRLOC, column);
return G_TYPE_INVALID;
}
klass = CLUTTER_MODEL_GET_CLASS (model);
if (klass->get_column_type)
return klass->get_column_type (model, column);
return G_TYPE_INVALID;
}
static ClutterModelIter *
_model_get_iter_at_row (ClutterModel *model,
guint row)
{
return g_object_new (CLUTTER_TYPE_MODEL_ITER, return g_object_new (CLUTTER_TYPE_MODEL_ITER,
"model", model, "model", model,
"row", index_, "row", row,
NULL); NULL);
} }
/** /**
* clutter_model_get_iter_at_row: * clutter_model_get_iter_at_row:
* @model: a #ClutterModel * @model: a #ClutterModel
* @index_: position of the row to retrieve * @row: position of the row to retrieve
* *
* Retrieves a #ClutterModelIter representing the row at @index_. * Retrieves a #ClutterModelIter representing the row at the given position.
* *
* Return value: A new #ClutterModelIter, or NULL if @index_ was out-of-bounds * Return value: A new #ClutterModelIter, or %NULL if @row was out-of-bounds
* *
* Since 0.6 * Since 0.6
**/ **/
ClutterModelIter * ClutterModelIter *
clutter_model_get_iter_at_row (ClutterModel *model, clutter_model_get_iter_at_row (ClutterModel *model,
guint index_) guint row)
{ {
ClutterModelClass *klass; ClutterModelClass *klass;
@ -864,7 +1001,7 @@ clutter_model_get_iter_at_row (ClutterModel *model,
klass = CLUTTER_MODEL_GET_CLASS (model); klass = CLUTTER_MODEL_GET_CLASS (model);
if (klass->get_iter_at_row) if (klass->get_iter_at_row)
return klass->get_iter_at_row (model, index_); return klass->get_iter_at_row (model, row);
return NULL; return NULL;
} }
@ -874,8 +1011,7 @@ clutter_model_get_iter_at_row (ClutterModel *model,
* clutter_model_get_first_iter: * clutter_model_get_first_iter:
* @model: a #ClutterModel * @model: a #ClutterModel
* *
* Retrieves a #ClutterModelIter representing the first row in @model. It calls * Retrieves a #ClutterModelIter representing the first row in @model.
* #clutter_model_get_iter_at_row with 0 as the index_ parameter.
* *
* Return value: A new #ClutterModelIter * Return value: A new #ClutterModelIter
* *
@ -893,8 +1029,7 @@ clutter_model_get_first_iter (ClutterModel *model)
* clutter_model_get_last_iter: * clutter_model_get_last_iter:
* @model: a #ClutterModel * @model: a #ClutterModel
* *
* Retrieves a #ClutterModelIter representing the last row in @model. It calls * Retrieves a #ClutterModelIter representing the last row in @model.
* #clutter_model_get_iter_at_row with model_length -1 as the index_ parameter.
* *
* Return value: A new #ClutterModelIter * Return value: A new #ClutterModelIter
* *
@ -1658,10 +1793,11 @@ _model_iter_set_row (ClutterModelIter *iter, guint row)
g_return_if_fail (CLUTTER_IS_MODEL (model)); g_return_if_fail (CLUTTER_IS_MODEL (model));
model_priv = model->priv; model_priv = model->priv;
filter_next = g_sequence_get_begin_iter (model_priv->sequence);
temp_iter = g_object_new (CLUTTER_TYPE_MODEL_ITER, temp_iter = g_object_new (CLUTTER_TYPE_MODEL_ITER,
"model", model, NULL); "model", model,
NULL);
filter_next = g_sequence_get_begin_iter (model_priv->sequence);
while (!g_sequence_iter_is_end (filter_next)) while (!g_sequence_iter_is_end (filter_next))
{ {
g_object_set (temp_iter, "iter", filter_next, NULL); g_object_set (temp_iter, "iter", filter_next, NULL);
@ -1672,10 +1808,13 @@ _model_iter_set_row (ClutterModelIter *iter, guint row)
iter_priv->seq_iter = filter_next; iter_priv->seq_iter = filter_next;
break; break;
} }
i++; i++;
} }
filter_next = g_sequence_iter_next (filter_next); filter_next = g_sequence_iter_next (filter_next);
} }
g_object_unref (temp_iter); g_object_unref (temp_iter);
} }

View File

@ -135,8 +135,12 @@ struct _ClutterModelClass
/*< public >*/ /*< public >*/
/* vtable */ /* vtable */
const gchar * (* get_column_name) (ClutterModel *model,
guint column);
GType (* get_column_type) (ClutterModel *model,
guint column);
ClutterModelIter *(* get_iter_at_row) (ClutterModel *model, ClutterModelIter *(* get_iter_at_row) (ClutterModel *model,
guint index_); guint row);
/* signals */ /* signals */
void (* row_added) (ClutterModel *model, void (* row_added) (ClutterModel *model,
@ -168,29 +172,41 @@ ClutterModel * clutter_model_newv (guint n_columns,
void clutter_model_set_types (ClutterModel *model, void clutter_model_set_types (ClutterModel *model,
guint n_columns, guint n_columns,
GType *types); GType *types);
void clutter_model_set_names (ClutterModel *model,
guint n_columns,
const gchar * const names[]);
gboolean clutter_model_append (ClutterModel *model, gboolean clutter_model_append (ClutterModel *model,
...); ...);
gboolean clutter_model_prepend (ClutterModel *model, gboolean clutter_model_prepend (ClutterModel *model,
...); ...);
gboolean clutter_model_insert (ClutterModel *model, gboolean clutter_model_insert (ClutterModel *model,
guint index_, guint row,
...); ...);
gboolean clutter_model_insert_value (ClutterModel *model, gboolean clutter_model_insert_value (ClutterModel *model,
guint index_, guint row,
guint column, guint column,
const GValue *value); const GValue *value);
void clutter_model_remove (ClutterModel *model, void clutter_model_remove (ClutterModel *model,
guint index_); guint row);
guint clutter_model_get_n_rows (ClutterModel *model); guint clutter_model_get_n_rows (ClutterModel *model);
G_CONST_RETURN gchar *clutter_model_get_column_name (ClutterModel *model,
guint column);
GType clutter_model_get_column_type (ClutterModel *model,
guint column);
guint clutter_model_get_n_columns (ClutterModel *model);
ClutterModelIter * clutter_model_get_first_iter (ClutterModel *model); ClutterModelIter * clutter_model_get_first_iter (ClutterModel *model);
ClutterModelIter * clutter_model_get_last_iter (ClutterModel *model); ClutterModelIter * clutter_model_get_last_iter (ClutterModel *model);
ClutterModelIter * clutter_model_get_iter_at_row (ClutterModel *model, ClutterModelIter * clutter_model_get_iter_at_row (ClutterModel *model,
guint index_); guint row);
void clutter_model_set_sorting_column (ClutterModel *model, void clutter_model_set_sorting_column (ClutterModel *model,
guint column); guint column);
guint clutter_model_get_sorting_column (ClutterModel *model); guint clutter_model_get_sorting_column (ClutterModel *model);
void clutter_model_foreach (ClutterModel *model, void clutter_model_foreach (ClutterModel *model,
ClutterModelForeachFunc func, ClutterModelForeachFunc func,
gpointer user_data); gpointer user_data);