2007-12-14 Emmanuele Bassi <ebassi@openedhand.com>

* clutter/clutter-behaviour.c:
	(clutter_knot_get_type): Use the I_() macro.

	* clutter/clutter-model.[ch]: Make ClutterModel and ClutterModelIter
	abstract classes; also, provide more virtual functions inside the
	ClutterModel vtable, to allow subclasses and language bindings to
	override the entire ClutterModel using other/native data types
	to store the rows.
	
	* clutter/clutter-model-default.[ch]: ClutterModelDefault is a
	default implementation of ClutterModel and ClutterModelIter using
	GSequence.

	* clutter/Makefile.am:
	* clutter/clutter.h: Build glue for ClutterModelDefault.

	* tests/test-model.c: Update for constructor changes.

	* tests/test-shader.c: Fix a typo.
This commit is contained in:
Emmanuele Bassi 2007-12-14 17:25:55 +00:00
parent 9a2a4ef7b3
commit 6193beb8be
15 changed files with 1364 additions and 943 deletions

View File

@ -1,3 +1,25 @@
2007-12-14 Emmanuele Bassi <ebassi@openedhand.com>
* clutter/clutter-behaviour.c:
(clutter_knot_get_type): Use the I_() macro.
* clutter/clutter-model.[ch]: Make ClutterModel and ClutterModelIter
abstract classes; also, provide more virtual functions inside the
ClutterModel vtable, to allow subclasses and language bindings to
override the entire ClutterModel using other/native data types
to store the rows.
* clutter/clutter-model-default.[ch]: ClutterModelDefault is a
default implementation of ClutterModel and ClutterModelIter using
GSequence.
* clutter/Makefile.am:
* clutter/clutter.h: Build glue for ClutterModelDefault.
* tests/test-model.c: Update for constructor changes.
* tests/test-shader.c: Fix a typo.
2007-12-14 Matthew Allum <mallum@openedhand.com>
* clutter/cogl/gl/cogl-defines.h.in:

View File

@ -65,6 +65,7 @@ source_h = \
$(srcdir)/clutter-main.h \
$(srcdir)/clutter-media.h \
$(srcdir)/clutter-model.h \
$(srcdir)/clutter-model-default.h \
$(srcdir)/clutter-rectangle.h \
$(srcdir)/clutter-score.h \
$(srcdir)/clutter-script.h \
@ -149,6 +150,7 @@ source_c = \
clutter-marshal.c \
clutter-media.c \
clutter-model.c \
clutter-model-default.c \
clutter-rectangle.c \
clutter-score.c \
clutter-script.c \
@ -163,8 +165,8 @@ source_c = \
$(NULL)
source_h_priv = \
clutter-keysyms-table.h \
clutter-debug.h \
clutter-keysyms-table.h \
clutter-private.h \
clutter-script-private.h \
$(NULL)

View File

@ -131,7 +131,7 @@ clutter_knot_get_type (void)
if (G_UNLIKELY (!our_type))
{
our_type =
g_boxed_type_register_static ("ClutterKnot",
g_boxed_type_register_static (I_("ClutterKnot"),
(GBoxedCopyFunc) clutter_knot_copy,
(GBoxedFreeFunc) clutter_knot_free);
}

View File

@ -0,0 +1,636 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.com>
* Neil Jagdish Patel <njp@o-hand.com>
* Emmanuele Bassi <ebassi@openedhand.com>
*
* Copyright (C) 2006 OpenedHand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* SECTION:clutter-model-default:
* @short_description: Default model implementation
*
* #ClutterModelDefault is a #ClutterModel implementation provided by
* Clutter. #ClutterModelDefault uses a #GSequence for storing the
* values for each row, so it's optimized for insertion and look up
* in sorted lists.
*
* #ClutterModelDefault is a terminal class: it cannot be subclassed,
* only instantiated.
*
* #ClutterModelDefault is available since Clutter 0.6
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <string.h>
#include <glib-object.h>
#include "clutter-model.h"
#include "clutter-model-default.h"
#include "clutter-private.h"
#include "clutter-debug.h"
#define CLUTTER_MODEL_DEFAULT_ITER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), \
CLUTTER_TYPE_MODEL_DEFAULT_ITER, \
ClutterModelDefaultIterClass))
#define CLUTTER_IS_MODEL_DEFAULT_ITER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
CLUTTER_TYPE_MODEL_DEFAULT_ITER))
#define CLUTTER_MODEL_DEFAULT_ITER_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
CLUTTER_TYPE_MODEL_DEFAULT_ITER, \
ClutterModelDefaultIterClass))
#define CLUTTER_MODEL_DEFAULT_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), \
CLUTTER_TYPE_MODEL_DEFAULT, \
ClutterModelDefaultClass))
#define CLUTTER_IS_MODEL_DEFAULT_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
CLUTTER_TYPE_MODEL_DEFAULT))
#define CLUTTER_MODEL_DEFAULT_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
CLUTTER_TYPE_MODEL_DEFAULT, \
ClutterModelDefaultClass))
typedef struct _ClutterModelIterClass ClutterModelDefaultIterClass;
typedef struct _ClutterModelClass ClutterModelDefaultClass;
struct _ClutterModelDefault
{
ClutterModel parent_instance;
GSequence *sequence;
};
struct _ClutterModelDefaultIter
{
ClutterModelIter parent_instance;
GSequenceIter *seq_iter;
};
/*
* ClutterModelDefault
*/
G_DEFINE_TYPE (ClutterModelDefaultIter,
clutter_model_default_iter,
CLUTTER_TYPE_MODEL_ITER);
static void
clutter_model_default_iter_get_value (ClutterModelIter *iter,
guint column,
GValue *value)
{
ClutterModelDefaultIter *iter_default;
GValueArray *value_array;
GValue *iter_value;
GValue real_value = { 0, };
gboolean converted = FALSE;
iter_default = CLUTTER_MODEL_DEFAULT_ITER (iter);
g_assert (iter_default->seq_iter != NULL);
value_array = g_sequence_get (iter_default->seq_iter);
iter_value = g_value_array_get_nth (value_array, column);
g_assert (iter_value != NULL);
if (!g_type_is_a (G_VALUE_TYPE (value), G_VALUE_TYPE (iter_value)))
{
if (!g_value_type_compatible (G_VALUE_TYPE (value),
G_VALUE_TYPE (iter_value)) &&
!g_value_type_compatible (G_VALUE_TYPE (iter_value),
G_VALUE_TYPE (value)))
{
g_warning ("%s: Unable to convert from %s to %s",
G_STRLOC,
g_type_name (G_VALUE_TYPE (value)),
g_type_name (G_VALUE_TYPE (iter_value)));
return;
}
if (!g_value_transform (value, &real_value))
{
g_warning ("%s: Unable to make conversion from %s to %s",
G_STRLOC,
g_type_name (G_VALUE_TYPE (value)),
g_type_name (G_VALUE_TYPE (iter_value)));
g_value_unset (&real_value);
}
converted = TRUE;
}
if (converted)
{
g_value_copy (&real_value, value);
g_value_unset (&real_value);
}
else
g_value_copy (iter_value, value);
}
static void
clutter_model_default_iter_set_value (ClutterModelIter *iter,
guint column,
const GValue *value)
{
ClutterModelDefaultIter *iter_default;
GValueArray *value_array;
GValue *iter_value;
GValue real_value = { 0, };
gboolean converted = FALSE;
iter_default = CLUTTER_MODEL_DEFAULT_ITER (iter);
g_assert (iter_default->seq_iter != NULL);
value_array = g_sequence_get (iter_default->seq_iter);
iter_value = g_value_array_get_nth (value_array, column);
g_assert (iter_value != NULL);
if (!g_type_is_a (G_VALUE_TYPE (value), G_VALUE_TYPE (iter_value)))
{
if (!g_value_type_compatible (G_VALUE_TYPE (value),
G_VALUE_TYPE (iter_value)) &&
!g_value_type_compatible (G_VALUE_TYPE (iter_value),
G_VALUE_TYPE (value)))
{
g_warning ("%s: Unable to convert from %s to %s\n",
G_STRLOC,
g_type_name (G_VALUE_TYPE (value)),
g_type_name (G_VALUE_TYPE (iter_value)));
return;
}
if (!g_value_transform (value, &real_value))
{
g_warning ("%s: Unable to make conversion from %s to %s\n",
G_STRLOC,
g_type_name (G_VALUE_TYPE (value)),
g_type_name (G_VALUE_TYPE (iter_value)));
g_value_unset (&real_value);
}
converted = TRUE;
}
if (converted)
{
g_value_copy (&real_value, iter_value);
g_value_unset (&real_value);
}
else
g_value_copy (value, iter_value);
}
static gboolean
clutter_model_default_iter_is_first (ClutterModelIter *iter)
{
ClutterModelDefaultIter *iter_default;
ClutterModel *model;
ClutterModelIter *temp_iter;
GSequenceIter *begin, *end;
guint row;
iter_default = CLUTTER_MODEL_DEFAULT_ITER (iter);
g_assert (iter_default->seq_iter != NULL);
model = clutter_model_iter_get_model (iter);
row = clutter_model_iter_get_row (iter);
begin = g_sequence_get_begin_iter (CLUTTER_MODEL_DEFAULT (model)->sequence);
end = iter_default->seq_iter;
temp_iter = g_object_new (CLUTTER_TYPE_MODEL_DEFAULT_ITER,
"model", model,
NULL);
while (!g_sequence_iter_is_begin (begin))
{
CLUTTER_MODEL_DEFAULT_ITER (temp_iter)->seq_iter = begin;
g_object_set (G_OBJECT (temp_iter), "row", row, NULL);
if (clutter_model_filter_iter (model, temp_iter))
{
end = begin;
break;
}
begin = g_sequence_iter_next (begin);
row += 1;
}
g_object_unref (temp_iter);
/* This is because the 'begin_iter' is always *before* the last valid
* iter, otherwise we'd have endless loops
*/
end = g_sequence_iter_prev (end);
return iter_default->seq_iter == end;
}
static gboolean
clutter_model_default_iter_is_last (ClutterModelIter *iter)
{
ClutterModelDefaultIter *iter_default;
ClutterModelIter *temp_iter;
ClutterModel *model;
GSequenceIter *begin, *end;
guint row;
iter_default = CLUTTER_MODEL_DEFAULT_ITER (iter);
g_assert (iter_default->seq_iter != NULL);
if (g_sequence_iter_is_end (iter_default->seq_iter))
return TRUE;
model = clutter_model_iter_get_model (iter);
row = clutter_model_iter_get_row (iter);
begin = g_sequence_get_end_iter (CLUTTER_MODEL_DEFAULT (model)->sequence);
begin = g_sequence_iter_prev (begin);
end = iter_default->seq_iter;
temp_iter = g_object_new (CLUTTER_TYPE_MODEL_DEFAULT_ITER,
"model", model,
NULL);
while (!g_sequence_iter_is_begin (begin))
{
CLUTTER_MODEL_DEFAULT_ITER (temp_iter)->seq_iter = begin;
g_object_set (G_OBJECT (temp_iter), "row", row, NULL);
if (clutter_model_filter_iter (model, temp_iter))
{
end = begin;
break;
}
begin = g_sequence_iter_prev (begin);
row += 1;
}
g_object_unref (temp_iter);
/* This is because the 'end_iter' is always *after* the last valid iter.
* Otherwise we'd have endless loops
*/
end = g_sequence_iter_next (end);
return iter_default->seq_iter == end;
}
static ClutterModelIter *
clutter_model_default_iter_next (ClutterModelIter *iter)
{
ClutterModelDefaultIter *iter_default;
ClutterModelDefaultIter *retval;
ClutterModelIter *temp_iter;
ClutterModel *model = NULL;
GSequenceIter *filter_next;
guint row;
iter_default = CLUTTER_MODEL_DEFAULT_ITER (iter);
g_assert (iter_default->seq_iter != NULL);
model = clutter_model_iter_get_model (iter);
row = clutter_model_iter_get_row (iter) + 1;
filter_next = g_sequence_iter_next (iter_default->seq_iter);
g_assert (filter_next != NULL);
temp_iter = g_object_new (CLUTTER_TYPE_MODEL_DEFAULT_ITER,
"model", model,
NULL);
while (!g_sequence_iter_is_end (filter_next))
{
CLUTTER_MODEL_DEFAULT_ITER (temp_iter)->seq_iter = filter_next;
g_object_set (G_OBJECT (temp_iter), "row", row, NULL);
if (clutter_model_filter_iter (model, temp_iter))
break;
filter_next = g_sequence_iter_next (filter_next);
row += 1;
}
g_object_unref (temp_iter);
/* We do this because the 'end_iter' is always *after* the last valid iter.
* Otherwise loops will go on forever
*/
if (filter_next == iter_default->seq_iter)
filter_next = g_sequence_iter_next (filter_next);
retval = g_object_new (CLUTTER_TYPE_MODEL_DEFAULT_ITER,
"model", model,
"row", row,
NULL);
retval->seq_iter = filter_next;
return CLUTTER_MODEL_ITER (retval);
}
static ClutterModelIter *
clutter_model_default_iter_prev (ClutterModelIter *iter)
{
ClutterModelDefaultIter *iter_default;
ClutterModelDefaultIter *retval;
ClutterModelIter *temp_iter;
ClutterModel *model;
GSequenceIter *filter_prev;
guint row;
iter_default = CLUTTER_MODEL_DEFAULT_ITER (iter);
g_assert (iter_default->seq_iter != NULL);
model = clutter_model_iter_get_model (iter);
row = clutter_model_iter_get_row (iter) - 1;
filter_prev = g_sequence_iter_prev (iter_default->seq_iter);
g_assert (filter_prev != NULL);
temp_iter = g_object_new (CLUTTER_TYPE_MODEL_DEFAULT_ITER,
"model", model,
NULL);
while (!g_sequence_iter_is_begin (filter_prev))
{
CLUTTER_MODEL_DEFAULT_ITER (temp_iter)->seq_iter = filter_prev;
g_object_set (G_OBJECT (temp_iter), "row", row, NULL);
if (clutter_model_filter_iter (model, temp_iter))
break;
filter_prev = g_sequence_iter_prev (filter_prev);
row -= 1;
}
g_object_unref (temp_iter);
/* We do this because the 'end_iter' is always *after* the last valid iter.
* Otherwise loops will go on forever
*/
if (filter_prev == iter_default->seq_iter)
filter_prev = g_sequence_iter_prev (filter_prev);
retval = g_object_new (CLUTTER_TYPE_MODEL_DEFAULT_ITER,
"model", model,
"row", row,
NULL);
retval->seq_iter = filter_prev;
return CLUTTER_MODEL_ITER (retval);
}
static void
clutter_model_default_iter_class_init (ClutterModelDefaultIterClass *klass)
{
ClutterModelIterClass *iter_class = CLUTTER_MODEL_ITER_CLASS (klass);
iter_class->get_value = clutter_model_default_iter_get_value;
iter_class->set_value = clutter_model_default_iter_set_value;
iter_class->is_first = clutter_model_default_iter_is_first;
iter_class->is_last = clutter_model_default_iter_is_last;
iter_class->next = clutter_model_default_iter_next;
iter_class->prev = clutter_model_default_iter_prev;
}
static void
clutter_model_default_iter_init (ClutterModelDefaultIter *iter)
{
iter->seq_iter = NULL;
}
/*
* ClutterModelDefault
*/
G_DEFINE_TYPE (ClutterModelDefault, clutter_model_default, CLUTTER_TYPE_MODEL);
static ClutterModelIter *
clutter_model_default_get_iter_at_row (ClutterModel *model,
guint row)
{
ClutterModelDefault *model_default = CLUTTER_MODEL_DEFAULT (model);
ClutterModelDefaultIter *retval;
if (row > g_sequence_get_length (model_default->sequence))
return NULL;
retval = g_object_new (CLUTTER_TYPE_MODEL_DEFAULT_ITER,
"model", model,
"row", row,
NULL);
retval->seq_iter = g_sequence_get_iter_at_pos (model_default->sequence, row);
return CLUTTER_MODEL_ITER (retval);
}
static ClutterModelIter *
clutter_model_default_insert_row (ClutterModel *model,
gint index_)
{
ClutterModelDefault *model_default = CLUTTER_MODEL_DEFAULT (model);
ClutterModelDefaultIter *retval;
guint n_columns, i, pos;
GValueArray *array;
GSequenceIter *seq_iter;
n_columns = clutter_model_get_n_columns (model);
array = g_value_array_new (n_columns);
for (i = 0; i < n_columns; i++)
{
GValue *value = NULL;
g_value_array_append (array, NULL);
value = g_value_array_get_nth (array, i);
g_value_init (value, clutter_model_get_column_type (model, i));
}
if (index_ < 0)
{
seq_iter = g_sequence_append (model_default->sequence, array);
pos = g_sequence_get_length (model_default->sequence) - 1;
}
else if (index_ == 0)
{
seq_iter = g_sequence_prepend (model_default->sequence, array);
pos = 0;
}
else
{
seq_iter = g_sequence_get_iter_at_pos (model_default->sequence, index_);
seq_iter = g_sequence_insert_before (seq_iter, array);
pos = index_;
}
retval = g_object_new (CLUTTER_TYPE_MODEL_DEFAULT_ITER,
"model", model,
"row", pos,
NULL);
retval->seq_iter = seq_iter;
return CLUTTER_MODEL_ITER (retval);
}
static void
clutter_model_default_remove_row (ClutterModel *model,
guint row)
{
ClutterModelDefault *model_default = CLUTTER_MODEL_DEFAULT (model);
GSequenceIter *seq_iter;
guint pos = 0;
seq_iter = g_sequence_get_begin_iter (model_default->sequence);
while (!g_sequence_iter_is_end (seq_iter))
{
if (clutter_model_filter_row (model, pos))
{
if (pos == row)
{
ClutterModelIter *iter;
GValueArray *array;
iter = g_object_new (CLUTTER_TYPE_MODEL_DEFAULT_ITER,
"model", model,
"row", pos,
NULL);
CLUTTER_MODEL_DEFAULT_ITER (iter)->seq_iter = seq_iter;
g_signal_emit_by_name (model, "row-removed", iter);
g_object_unref (iter);
array = g_sequence_get (seq_iter);
g_value_array_free (array);
g_sequence_remove (seq_iter);
break;
}
}
pos += 1;
seq_iter = g_sequence_iter_next (seq_iter);
}
}
static guint
clutter_model_default_get_n_rows (ClutterModel *model)
{
ClutterModelDefault *model_default = CLUTTER_MODEL_DEFAULT (model);
return g_sequence_get_length (model_default->sequence);
}
typedef struct
{
ClutterModel *model;
guint column;
ClutterModelSortFunc func;
gpointer data;
} SortClosure;
static gint
sort_model_default (gconstpointer a,
gconstpointer b,
gpointer data)
{
GValueArray *row_a = (GValueArray *) a;
GValueArray *row_b = (GValueArray *) b;
SortClosure *clos = data;
return clos->func (clos->model,
g_value_array_get_nth (row_a, clos->column),
g_value_array_get_nth (row_b, clos->column),
clos->data);
}
static void
clutter_model_default_resort (ClutterModel *model,
ClutterModelSortFunc func,
gpointer data)
{
SortClosure sort_closure = { NULL, 0, NULL, NULL };
sort_closure.model = model;
sort_closure.column = clutter_model_get_sorting_column (model);
sort_closure.func = func;
sort_closure.data = data;
g_sequence_sort (CLUTTER_MODEL_DEFAULT (model)->sequence,
sort_model_default,
&sort_closure);
}
static void
clutter_model_default_finalize (GObject *gobject)
{
ClutterModelDefault *model = CLUTTER_MODEL_DEFAULT (gobject);
GSequenceIter *iter;
iter = g_sequence_get_begin_iter (model->sequence);
while (!g_sequence_iter_is_end (iter))
{
GValueArray *value_array = g_sequence_get (iter);
g_value_array_free (value_array);
iter = g_sequence_iter_next (iter);
}
g_sequence_free (model->sequence);
G_OBJECT_CLASS (clutter_model_default_parent_class)->finalize (gobject);
}
static void
clutter_model_default_class_init (ClutterModelDefaultClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
ClutterModelClass *model_class = CLUTTER_MODEL_CLASS (klass);
gobject_class->finalize = clutter_model_default_finalize;
model_class->get_n_rows = clutter_model_default_get_n_rows;
model_class->get_iter_at_row = clutter_model_default_get_iter_at_row;
model_class->insert_row = clutter_model_default_insert_row;
model_class->remove_row = clutter_model_default_remove_row;
model_class->resort = clutter_model_default_resort;
}
static void
clutter_model_default_init (ClutterModelDefault *model)
{
model->sequence = g_sequence_new (NULL);
}

View File

@ -0,0 +1,59 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.com>
* Neil Jagdish Patel <njp@o-hand.com>
* Emmanuele Bassi <ebassi@openedhand.com>
*
* Copyright (C) 2006 OpenedHand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* NB: Inspiration for column storage taken from GtkListStore
*/
#ifndef __CLUTTER_MODEL_DEFAULT_H__
#define __CLUTTER_MODEL_DEFAULT_H__
#include <clutter/clutter-model.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_MODEL_DEFAULT_ITER (clutter_model_default_iter_get_type ())
#define CLUTTER_MODEL_DEFAULT_ITER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_MODEL_DEFAULT_ITER, ClutterModelDefaultIter))
#define CLUTTER_IS_MODEL_DEFAULT_ITER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_MODEL_DEFAULT_ITER))
#define CLUTTER_TYPE_MODEL_DEFAULT (clutter_model_default_get_type ())
#define CLUTTER_MODEL_DEFAULT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_MODEL_DEFAULT, ClutterModelDefault))
#define CLUTTER_IS_MODEL_DEFAULT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_MODEL_DEFAULT))
typedef struct _ClutterModelDefaultIter ClutterModelDefaultIter;
typedef struct _ClutterModelDefault ClutterModelDefault;
GType clutter_model_default_iter_get_type (void) G_GNUC_CONST;
GType clutter_model_default_get_type (void) G_GNUC_CONST;
ClutterModel *clutter_model_default_new (guint n_columns,
...);
ClutterModel *clutter_model_default_newv (guint n_columns,
GType *types,
const gchar * const names[]);
G_END_DECLS
#endif /* __CLUTTER_MODEL_DEFAULT_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -78,7 +78,7 @@ typedef gboolean (*ClutterModelFilterFunc) (ClutterModel *model,
*
* Since: 0.6
*/
typedef gboolean (*ClutterModelSortFunc) (ClutterModel *model,
typedef gint (*ClutterModelSortFunc) (ClutterModel *model,
const GValue *a,
const GValue *b,
gpointer user_data);
@ -127,6 +127,16 @@ struct _ClutterModel
* @get_column_type: virtual function for returning the type of a column
* @get_iter_at_row: virtual function for returning an iterator for the
* given row
* @get_n_rows: virtual function for returning the number of rows
* of the model, not considering any filter function if present
* @get_n_columns: virtual function for retuning the number of columns
* of the model
* @resort: virtual function for sorting the model using the passed
* sorting function
* @insert_row: virtual function for inserting a row at the given index
* and returning an iterator pointing to it; if the index is a negative
* integer, the row should be appended to the model
* @remove_row: virtual function for removing a row at the given index
*
* Class for #ClutterModel instances.
*
@ -139,12 +149,21 @@ struct _ClutterModelClass
/*< public >*/
/* vtable */
guint (* get_n_rows) (ClutterModel *model);
guint (* get_n_columns) (ClutterModel *model);
const gchar * (* get_column_name) (ClutterModel *model,
guint column);
GType (* get_column_type) (ClutterModel *model,
guint column);
ClutterModelIter *(* insert_row) (ClutterModel *model,
gint index_);
void (* remove_row) (ClutterModel *model,
guint row);
ClutterModelIter *(* get_iter_at_row) (ClutterModel *model,
guint row);
void (* resort) (ClutterModel *model,
ClutterModelSortFunc func,
gpointer data);
/* signals */
void (* row_added) (ClutterModel *model,
@ -153,7 +172,6 @@ struct _ClutterModelClass
ClutterModelIter *iter);
void (* row_changed) (ClutterModel *model,
ClutterModelIter *iter);
void (* sort_changed) (ClutterModel *model);
void (* filter_changed) (ClutterModel *model);
@ -165,15 +183,8 @@ struct _ClutterModelClass
void (*_clutter_model_4) (void);
};
GType clutter_model_get_type (void) G_GNUC_CONST;
ClutterModel * clutter_model_new (guint n_columns,
...);
ClutterModel * clutter_model_newv (guint n_columns,
GType *types,
const gchar * const names[]);
void clutter_model_set_types (ClutterModel *model,
guint n_columns,
GType *types);
@ -202,12 +213,11 @@ void clutter_model_remove (ClutterModel *model,
guint row);
guint clutter_model_get_n_rows (ClutterModel *model);
guint clutter_model_get_n_columns (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_last_iter (ClutterModel *model);
@ -231,6 +241,11 @@ void clutter_model_set_filter (ClutterModel *model,
gpointer user_data,
GDestroyNotify notify);
void clutter_model_resort (ClutterModel *model);
gboolean clutter_model_filter_row (ClutterModel *model,
guint row);
gboolean clutter_model_filter_iter (ClutterModel *model,
ClutterModelIter *iter);
/*
* ClutterModelIter
@ -246,9 +261,9 @@ void clutter_model_set_filter (ClutterModel *model,
/**
* ClutterModelIter:
*
* Base class for list models iters. The #ClutterModelIter structure contains
* only private data and should be manipulated using the provided
* API.
* Base class for list models iters. The #ClutterModelIter structure
* contains only private data and should be manipulated using the
* provided API.
*
* Since: 0.6
*/
@ -262,6 +277,18 @@ struct _ClutterModelIter
/**
* ClutterModelIterClass:
* @get_value: Virtual function for retrieving the value at the given
* column of the row pointed by the iterator
* @set_value: Virtual function for setting the value at the given
* column of the row pointer by the iterator
* @is_last: Virtual function for knowing whether the iterator points
* at the last row in the model
* @is_first: Virtual function for knowing whether the iterator points
* at the first row in the model
* @get_model: Virtual function for getting the model to which the
* iterator belongs to
* @get_row: Virtual function for getting the row to which the iterator
* points
*
* Class for #ClutterModelIter instances.
*
@ -273,7 +300,6 @@ struct _ClutterModelIterClass
GObjectClass parent_class;
/*< public >*/
/* vtable not signals */
void (* get_value) (ClutterModelIter *iter,
guint column,
@ -301,7 +327,6 @@ struct _ClutterModelIterClass
GType clutter_model_iter_get_type (void) G_GNUC_CONST;
void clutter_model_iter_get (ClutterModelIter *iter,
...);
void clutter_model_iter_get_valist (ClutterModelIter *iter,
@ -316,10 +341,15 @@ void clutter_model_iter_set_valist (ClutterModelIter *iter,
void clutter_model_iter_set_value (ClutterModelIter *iter,
guint column,
const GValue *value);
gboolean clutter_model_iter_is_first (ClutterModelIter *iter);
gboolean clutter_model_iter_is_last (ClutterModelIter *iter);
gboolean clutter_model_iter_has_next (ClutterModelIter *iter);
gboolean clutter_model_iter_has_prev (ClutterModelIter *iter);
ClutterModelIter *clutter_model_iter_next (ClutterModelIter *iter);
ClutterModelIter *clutter_model_iter_prev (ClutterModelIter *iter);
ClutterModel * clutter_model_iter_get_model (ClutterModelIter *iter);
guint clutter_model_iter_get_row (ClutterModelIter *iter);

View File

@ -52,6 +52,7 @@
#include "clutter-main.h"
#include "clutter-media.h"
#include "clutter-model.h"
#include "clutter-model-default.h"
#include "clutter-stage.h"
#include "clutter-texture.h"
#include "clutter-timeout-pool.h"

View File

@ -1,3 +1,10 @@
2007-12-14 Emmanuele Bassi <ebassi@openedhand.com>
* Makefile.am:
* clutter-docs.sgml:
* clutter-sections.txt:
* clutter.types: Update for ClutterModel changes.
2007-12-10 Emmanuele Bassi <ebassi@openedhand.com>
* clutter-sections.txt: Add the new ClutterModel API.

View File

@ -51,14 +51,14 @@ CFILE_GLOB=$(top_srcdir)/clutter/*.c
IGNORE_HFILES=\
clutter.h \
clutter-debug.h \
clutter-private.h \
clutter-marshal.h \
clutter-deprecated.h \
clutter-enum-types.h \
clutter-json.h \
clutter-keysyms.h \
clutter-keysyms-table.h \
clutter-enum-types.h \
clutter-marshal.h \
clutter-private.h \
clutter-script-private.h \
clutter-json.h \
clutter-deprecated.h \
stamp-clutter-enum-types.h \
stamp-clutter-marshal.h \
cogl \

View File

@ -159,6 +159,7 @@
<xi:include href="xml/clutter-model.xml"/>
<xi:include href="xml/clutter-model-iter.xml"/>
<xi:include href="xml/clutter-model-default.xml"/>
</chapter>
</part>

View File

@ -1143,8 +1143,6 @@ ClutterModelClass
ClutterModelFilterFunc
ClutterModelSortFunc
ClutterModelForeachFunc
clutter_model_new
clutter_model_newv
clutter_model_set_names
clutter_model_set_types
clutter_model_append
@ -1208,6 +1206,25 @@ ClutterModelIterPrivate
clutter_model_iter_get_type
</SECTION>
<SECTION>
<FILE>clutter-model-default</FILE>
<TITLE>ClutterModelDefault</TITLE>
ClutterModelDefault
ClutterModelDefaultIter
clutter_model_default_new
clutter_model_default_newv
<SUBSECTION Standard>
CLUTTER_TYPE_MODEL_DEFAULT
CLUTTER_TYPE_MODEL_DEFAULT_ITER
CLUTTER_MODEL_DEFAULT
CLUTTER_MODEL_DEFAULT_ITER
CLUTTER_IS_MODEL_DEFAULT
CLUTTER_IS_MODEL_DEFAULT_ITER
<SUBSECTION Private>
clutter_model_default_get_type
clutter_model_default_iter_get_type
</SECTION>
<SECTION>
<FILE>clutter-score</FILE>
<TITLE>ClutterScore</TITLE>

View File

@ -24,5 +24,7 @@ clutter_script_get_type
clutter_scriptable_get_type
clutter_model_get_type
clutter_model_iter_get_type
clutter_model_default_get_type
clutter_model_default_iter_get_type
clutter_score_get_type
clutter_shader_get_type

View File

@ -10,16 +10,19 @@ enum
};
static void
print_iter (ClutterModelIter *iter, const gchar *text)
print_iter (ClutterModelIter *iter,
const gchar *text)
{
ClutterModel *model;
gint i;
gchar *string;
model = clutter_model_iter_get_model (iter);
clutter_model_iter_get (iter, COLUMN_FOO, &i, COLUMN_BAR, &string, -1);
g_print ("%s: (%s: %d), (%s: %s)\n",
g_print ("[row:%02d]: %s: (%s: %d), (%s: %s)\n",
clutter_model_iter_get_row (iter),
text,
clutter_model_get_column_name (model, COLUMN_FOO), i,
clutter_model_get_column_name (model, COLUMN_BAR), string);
@ -28,20 +31,28 @@ print_iter (ClutterModelIter *iter, const gchar *text)
}
static gboolean
foreach_func (ClutterModel *model, ClutterModelIter *iter, gpointer null)
foreach_func (ClutterModel *model,
ClutterModelIter *iter,
gpointer dummy)
{
gint i;
gchar *string;
clutter_model_iter_get (iter, COLUMN_FOO, &i, COLUMN_BAR, &string, -1);
g_print ("Foreach: %d: %s\n", i, string);
g_print ("[row:%02d]: Foreach: %d, %s\n",
clutter_model_iter_get_row (iter),
i, string);
g_free (string);
return TRUE;
}
static gboolean
filter_func (ClutterModel *model, ClutterModelIter *iter, gpointer null)
filter_func (ClutterModel *model,
ClutterModelIter *iter,
gpointer dummy)
{
gint i = 0;
@ -54,13 +65,14 @@ static gint
sort_func (ClutterModel *model,
const GValue *a,
const GValue *b,
gpointer null)
gpointer dummy)
{
return -1 * strcmp (g_value_get_string (a), g_value_get_string (b));
}
static void
on_row_changed (ClutterModel *model, ClutterModelIter *iter)
on_row_changed (ClutterModel *model,
ClutterModelIter *iter)
{
print_iter (iter, "Changed");
}
@ -70,21 +82,22 @@ filter_model (ClutterModel *model)
{
ClutterModelIter *iter;
g_print ("* Filter function: even rows\n");
clutter_model_set_filter (model, filter_func, NULL, NULL);
iter = clutter_model_get_first_iter (model);
while (!clutter_model_iter_is_last (iter))
{
print_iter (iter, "Filtered Forward Iteration");
iter = clutter_model_iter_next (iter);
}
g_object_unref (iter);
g_print ("* Sorting function: reverse alpha\n");
clutter_model_set_sort (model, COLUMN_BAR, sort_func, NULL, NULL);
g_signal_connect (model, "row-changed",
G_CALLBACK (on_row_changed), NULL);
g_signal_connect (model, "row-changed", G_CALLBACK (on_row_changed), NULL);
iter = clutter_model_get_iter_at_row (model, 0);
clutter_model_iter_set (iter, COLUMN_BAR, "Changed string of 0th row, "
@ -94,11 +107,11 @@ filter_model (ClutterModel *model)
clutter_model_foreach (model, foreach_func, NULL);
g_print ("* Unset filter\n");
clutter_model_set_filter (model, NULL, NULL, NULL);
while (clutter_model_get_n_rows (model))
{
clutter_model_remove (model, 0);
}
clutter_main_quit ();
}
@ -155,20 +168,26 @@ populate_model (ClutterModel *model)
}
static void
on_row_added (ClutterModel *model, ClutterModelIter *iter, gpointer null)
on_row_added (ClutterModel *model,
ClutterModelIter *iter,
gpointer dummy)
{
gint i;
gchar *string;
clutter_model_iter_get (iter, COLUMN_FOO, &i, COLUMN_BAR, &string, -1);
g_print ("Added: %d, %s\n", i, string);
g_print ("[row:%02d]: Added: %d, %s\n",
clutter_model_iter_get_row (iter),
i, string);
g_free (string);
}
static void
on_row_removed (ClutterModel *model, ClutterModelIter *iter, gpointer null)
on_row_removed (ClutterModel *model,
ClutterModelIter *iter,
gpointer dummy)
{
print_iter (iter, "Removed");
}
@ -176,14 +195,14 @@ on_row_removed (ClutterModel *model, ClutterModelIter *iter, gpointer null)
static void
on_sort_changed (ClutterModel *model)
{
g_print ("\nSort Changed\n\n");
g_print ("\n*** Sort Changed ***\n\n");
clutter_model_foreach (model, foreach_func, NULL);
}
static void
on_filter_changed (ClutterModel *model)
{
g_print ("\nFilter Changed\n\n");
g_print ("\n*** Filter Changed ***\n\n");
}
int
@ -193,11 +212,11 @@ main (int argc, char *argv[])
clutter_init (&argc, &argv);
model = clutter_model_new (N_COLUMNS,
model = clutter_model_default_new (N_COLUMNS,
G_TYPE_INT, "Foo",
G_TYPE_STRING, "Bar");
g_timeout_add (1000, (GSourceFunc)populate_model, model);
g_timeout_add (1000, (GSourceFunc) populate_model, model);
g_signal_connect (model, "row-added",
G_CALLBACK (on_row_added), NULL);

View File

@ -210,7 +210,7 @@ main (gint argc,
shader = clutter_shader_new ();
error = NULL;
clutter_shader_set_fragment_source (shader, shaders[shader_no].source, NULL);
clutter_shader_set_fragment_source (shader, shaders[shader_no].source, -1);
clutter_shader_bind (shader, &error);
if (error)
{