mirror of
https://github.com/brl/mutter.git
synced 2024-11-22 16:10:41 -05:00
[list-model] Make ClutterListModel subclassable
ClutterListModel has been added as a terminal class in case we decided to change API or implementation. Apparently, it's a lot more resilient than we expected -- or far too few are using it and reporting bugs. Once common issue, though, is that it cannot be subclassed, hence it's fairly limited in its usage. In the hope that more developers will start using it, here's a patch that makes ListModel a fully subclassable object. May whatever god you believe in have mercy on your eventual soul.
This commit is contained in:
parent
f17437124e
commit
0ac6d6637e
@ -34,9 +34,6 @@
|
|||||||
* values for each row, so it's optimized for insertion and look up
|
* values for each row, so it's optimized for insertion and look up
|
||||||
* in sorted lists.
|
* in sorted lists.
|
||||||
*
|
*
|
||||||
* #ClutterListModel is a terminal class: it cannot be subclassed,
|
|
||||||
* only instantiated.
|
|
||||||
*
|
|
||||||
* #ClutterListModel is available since Clutter 0.6
|
* #ClutterListModel is available since Clutter 0.6
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -76,27 +73,13 @@
|
|||||||
CLUTTER_TYPE_LIST_MODEL_ITER, \
|
CLUTTER_TYPE_LIST_MODEL_ITER, \
|
||||||
ClutterListModelIterClass))
|
ClutterListModelIterClass))
|
||||||
|
|
||||||
#define CLUTTER_LIST_MODEL_CLASS(klass) \
|
|
||||||
(G_TYPE_CHECK_CLASS_CAST ((klass), \
|
|
||||||
CLUTTER_TYPE_LIST_MODEL, \
|
|
||||||
ClutterListModelClass))
|
|
||||||
#define CLUTTER_IS_LIST_MODEL_CLASS(klass) \
|
|
||||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
|
|
||||||
CLUTTER_TYPE_LIST_MODEL))
|
|
||||||
#define CLUTTER_LIST_MODEL_GET_CLASS(obj) \
|
|
||||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
|
|
||||||
CLUTTER_TYPE_LIST_MODEL, \
|
|
||||||
ClutterListModelClass))
|
|
||||||
|
|
||||||
typedef struct _ClutterListModelIter ClutterListModelIter;
|
typedef struct _ClutterListModelIter ClutterListModelIter;
|
||||||
typedef struct _ClutterModelIterClass ClutterListModelIterClass;
|
typedef struct _ClutterModelIterClass ClutterListModelIterClass;
|
||||||
|
|
||||||
typedef struct _ClutterModelClass ClutterListModelClass;
|
#define CLUTTER_LIST_MODEL_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_LIST_MODEL, ClutterListModelPrivate))
|
||||||
|
|
||||||
struct _ClutterListModel
|
struct _ClutterListModelPrivate
|
||||||
{
|
{
|
||||||
ClutterModel parent_instance;
|
|
||||||
|
|
||||||
GSequence *sequence;
|
GSequence *sequence;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -229,6 +212,7 @@ clutter_list_model_iter_is_first (ClutterModelIter *iter)
|
|||||||
ClutterListModelIter *iter_default;
|
ClutterListModelIter *iter_default;
|
||||||
ClutterModel *model;
|
ClutterModel *model;
|
||||||
ClutterModelIter *temp_iter;
|
ClutterModelIter *temp_iter;
|
||||||
|
GSequence *sequence;
|
||||||
GSequenceIter *begin, *end;
|
GSequenceIter *begin, *end;
|
||||||
guint row;
|
guint row;
|
||||||
|
|
||||||
@ -238,7 +222,9 @@ clutter_list_model_iter_is_first (ClutterModelIter *iter)
|
|||||||
model = clutter_model_iter_get_model (iter);
|
model = clutter_model_iter_get_model (iter);
|
||||||
row = clutter_model_iter_get_row (iter);
|
row = clutter_model_iter_get_row (iter);
|
||||||
|
|
||||||
begin = g_sequence_get_begin_iter (CLUTTER_LIST_MODEL (model)->sequence);
|
sequence = CLUTTER_LIST_MODEL (model)->priv->sequence;
|
||||||
|
|
||||||
|
begin = g_sequence_get_begin_iter (sequence);
|
||||||
end = iter_default->seq_iter;
|
end = iter_default->seq_iter;
|
||||||
|
|
||||||
temp_iter = g_object_new (CLUTTER_TYPE_LIST_MODEL_ITER,
|
temp_iter = g_object_new (CLUTTER_TYPE_LIST_MODEL_ITER,
|
||||||
@ -276,6 +262,7 @@ clutter_list_model_iter_is_last (ClutterModelIter *iter)
|
|||||||
ClutterListModelIter *iter_default;
|
ClutterListModelIter *iter_default;
|
||||||
ClutterModelIter *temp_iter;
|
ClutterModelIter *temp_iter;
|
||||||
ClutterModel *model;
|
ClutterModel *model;
|
||||||
|
GSequence *sequence;
|
||||||
GSequenceIter *begin, *end;
|
GSequenceIter *begin, *end;
|
||||||
guint row;
|
guint row;
|
||||||
|
|
||||||
@ -288,7 +275,9 @@ clutter_list_model_iter_is_last (ClutterModelIter *iter)
|
|||||||
model = clutter_model_iter_get_model (iter);
|
model = clutter_model_iter_get_model (iter);
|
||||||
row = clutter_model_iter_get_row (iter);
|
row = clutter_model_iter_get_row (iter);
|
||||||
|
|
||||||
begin = g_sequence_get_end_iter (CLUTTER_LIST_MODEL (model)->sequence);
|
sequence = CLUTTER_LIST_MODEL (model)->priv->sequence;
|
||||||
|
|
||||||
|
begin = g_sequence_get_end_iter (sequence);
|
||||||
begin = g_sequence_iter_prev (begin);
|
begin = g_sequence_iter_prev (begin);
|
||||||
end = iter_default->seq_iter;
|
end = iter_default->seq_iter;
|
||||||
|
|
||||||
@ -476,16 +465,17 @@ clutter_list_model_get_iter_at_row (ClutterModel *model,
|
|||||||
guint row)
|
guint row)
|
||||||
{
|
{
|
||||||
ClutterListModel *model_default = CLUTTER_LIST_MODEL (model);
|
ClutterListModel *model_default = CLUTTER_LIST_MODEL (model);
|
||||||
|
GSequence *sequence = model_default->priv->sequence;
|
||||||
ClutterListModelIter *retval;
|
ClutterListModelIter *retval;
|
||||||
|
|
||||||
if (row >= g_sequence_get_length (model_default->sequence))
|
if (row >= g_sequence_get_length (sequence))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
retval = g_object_new (CLUTTER_TYPE_LIST_MODEL_ITER,
|
retval = g_object_new (CLUTTER_TYPE_LIST_MODEL_ITER,
|
||||||
"model", model,
|
"model", model,
|
||||||
"row", row,
|
"row", row,
|
||||||
NULL);
|
NULL);
|
||||||
retval->seq_iter = g_sequence_get_iter_at_pos (model_default->sequence, row);
|
retval->seq_iter = g_sequence_get_iter_at_pos (sequence, row);
|
||||||
|
|
||||||
return CLUTTER_MODEL_ITER (retval);
|
return CLUTTER_MODEL_ITER (retval);
|
||||||
}
|
}
|
||||||
@ -495,6 +485,7 @@ clutter_list_model_insert_row (ClutterModel *model,
|
|||||||
gint index_)
|
gint index_)
|
||||||
{
|
{
|
||||||
ClutterListModel *model_default = CLUTTER_LIST_MODEL (model);
|
ClutterListModel *model_default = CLUTTER_LIST_MODEL (model);
|
||||||
|
GSequence *sequence = model_default->priv->sequence;
|
||||||
ClutterListModelIter *retval;
|
ClutterListModelIter *retval;
|
||||||
guint n_columns, i, pos;
|
guint n_columns, i, pos;
|
||||||
GValueArray *array;
|
GValueArray *array;
|
||||||
@ -515,17 +506,17 @@ clutter_list_model_insert_row (ClutterModel *model,
|
|||||||
|
|
||||||
if (index_ < 0)
|
if (index_ < 0)
|
||||||
{
|
{
|
||||||
seq_iter = g_sequence_append (model_default->sequence, array);
|
seq_iter = g_sequence_append (sequence, array);
|
||||||
pos = g_sequence_get_length (model_default->sequence);
|
pos = g_sequence_get_length (sequence);
|
||||||
}
|
}
|
||||||
else if (index_ == 0)
|
else if (index_ == 0)
|
||||||
{
|
{
|
||||||
seq_iter = g_sequence_prepend (model_default->sequence, array);
|
seq_iter = g_sequence_prepend (sequence, array);
|
||||||
pos = 0;
|
pos = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
seq_iter = g_sequence_get_iter_at_pos (model_default->sequence, index_);
|
seq_iter = g_sequence_get_iter_at_pos (sequence, index_);
|
||||||
seq_iter = g_sequence_insert_before (seq_iter, array);
|
seq_iter = g_sequence_insert_before (seq_iter, array);
|
||||||
pos = index_;
|
pos = index_;
|
||||||
}
|
}
|
||||||
@ -544,10 +535,11 @@ clutter_list_model_remove_row (ClutterModel *model,
|
|||||||
guint row)
|
guint row)
|
||||||
{
|
{
|
||||||
ClutterListModel *model_default = CLUTTER_LIST_MODEL (model);
|
ClutterListModel *model_default = CLUTTER_LIST_MODEL (model);
|
||||||
|
GSequence *sequence = model_default->priv->sequence;
|
||||||
GSequenceIter *seq_iter;
|
GSequenceIter *seq_iter;
|
||||||
guint pos = 0;
|
guint pos = 0;
|
||||||
|
|
||||||
seq_iter = g_sequence_get_begin_iter (model_default->sequence);
|
seq_iter = g_sequence_get_begin_iter (sequence);
|
||||||
while (!g_sequence_iter_is_end (seq_iter))
|
while (!g_sequence_iter_is_end (seq_iter))
|
||||||
{
|
{
|
||||||
if (clutter_model_filter_row (model, pos))
|
if (clutter_model_filter_row (model, pos))
|
||||||
@ -587,7 +579,7 @@ clutter_list_model_get_n_rows (ClutterModel *model)
|
|||||||
{
|
{
|
||||||
ClutterListModel *model_default = CLUTTER_LIST_MODEL (model);
|
ClutterListModel *model_default = CLUTTER_LIST_MODEL (model);
|
||||||
|
|
||||||
return g_sequence_get_length (model_default->sequence);
|
return g_sequence_get_length (model_default->priv->sequence);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -625,7 +617,7 @@ clutter_list_model_resort (ClutterModel *model,
|
|||||||
sort_closure.func = func;
|
sort_closure.func = func;
|
||||||
sort_closure.data = data;
|
sort_closure.data = data;
|
||||||
|
|
||||||
g_sequence_sort (CLUTTER_LIST_MODEL (model)->sequence,
|
g_sequence_sort (CLUTTER_LIST_MODEL (model)->priv->sequence,
|
||||||
sort_model_default,
|
sort_model_default,
|
||||||
&sort_closure);
|
&sort_closure);
|
||||||
}
|
}
|
||||||
@ -650,9 +642,10 @@ static void
|
|||||||
clutter_list_model_finalize (GObject *gobject)
|
clutter_list_model_finalize (GObject *gobject)
|
||||||
{
|
{
|
||||||
ClutterListModel *model = CLUTTER_LIST_MODEL (gobject);
|
ClutterListModel *model = CLUTTER_LIST_MODEL (gobject);
|
||||||
|
GSequence *sequence = model->priv->sequence;
|
||||||
GSequenceIter *iter;
|
GSequenceIter *iter;
|
||||||
|
|
||||||
iter = g_sequence_get_begin_iter (model->sequence);
|
iter = g_sequence_get_begin_iter (sequence);
|
||||||
while (!g_sequence_iter_is_end (iter))
|
while (!g_sequence_iter_is_end (iter))
|
||||||
{
|
{
|
||||||
GValueArray *value_array = g_sequence_get (iter);
|
GValueArray *value_array = g_sequence_get (iter);
|
||||||
@ -660,7 +653,7 @@ clutter_list_model_finalize (GObject *gobject)
|
|||||||
g_value_array_free (value_array);
|
g_value_array_free (value_array);
|
||||||
iter = g_sequence_iter_next (iter);
|
iter = g_sequence_iter_next (iter);
|
||||||
}
|
}
|
||||||
g_sequence_free (model->sequence);
|
g_sequence_free (sequence);
|
||||||
|
|
||||||
G_OBJECT_CLASS (clutter_list_model_parent_class)->finalize (gobject);
|
G_OBJECT_CLASS (clutter_list_model_parent_class)->finalize (gobject);
|
||||||
}
|
}
|
||||||
@ -671,6 +664,8 @@ clutter_list_model_class_init (ClutterListModelClass *klass)
|
|||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
ClutterModelClass *model_class = CLUTTER_MODEL_CLASS (klass);
|
ClutterModelClass *model_class = CLUTTER_MODEL_CLASS (klass);
|
||||||
|
|
||||||
|
g_type_class_add_private (klass, sizeof (ClutterListModelPrivate));
|
||||||
|
|
||||||
gobject_class->finalize = clutter_list_model_finalize;
|
gobject_class->finalize = clutter_list_model_finalize;
|
||||||
|
|
||||||
model_class->get_n_rows = clutter_list_model_get_n_rows;
|
model_class->get_n_rows = clutter_list_model_get_n_rows;
|
||||||
@ -685,7 +680,9 @@ clutter_list_model_class_init (ClutterListModelClass *klass)
|
|||||||
static void
|
static void
|
||||||
clutter_list_model_init (ClutterListModel *model)
|
clutter_list_model_init (ClutterListModel *model)
|
||||||
{
|
{
|
||||||
model->sequence = g_sequence_new (NULL);
|
model->priv = CLUTTER_LIST_MODEL_GET_PRIVATE (model);
|
||||||
|
|
||||||
|
model->priv->sequence = g_sequence_new (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,11 +36,44 @@
|
|||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define CLUTTER_TYPE_LIST_MODEL (clutter_list_model_get_type ())
|
#define CLUTTER_TYPE_LIST_MODEL (clutter_list_model_get_type ())
|
||||||
#define CLUTTER_LIST_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_LIST_MODEL, ClutterListModel))
|
#define CLUTTER_LIST_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_LIST_MODEL, ClutterListModel))
|
||||||
#define CLUTTER_IS_LIST_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_LIST_MODEL))
|
#define CLUTTER_IS_LIST_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_LIST_MODEL))
|
||||||
|
#define CLUTTER_LIST_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_LIST_MODEL, ClutterListModeClass))
|
||||||
|
#define CLUTTER_IS_LIST_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_LIST_MODEL))
|
||||||
|
#define CLUTTER_LIST_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_LIST_MODEL, ClutterListModeClass))
|
||||||
|
|
||||||
typedef struct _ClutterListModel ClutterListModel;
|
typedef struct _ClutterListModel ClutterListModel;
|
||||||
|
typedef struct _ClutterListModelPrivate ClutterListModelPrivate;
|
||||||
|
typedef struct _ClutterListModelClass ClutterListModelClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterListModel:
|
||||||
|
*
|
||||||
|
* The #ClutterListModel struct contains only private data.
|
||||||
|
*
|
||||||
|
* Since: 0.6
|
||||||
|
*/
|
||||||
|
struct _ClutterListModel
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
ClutterModel parent_instance;
|
||||||
|
|
||||||
|
ClutterListModelPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterListModelClass:
|
||||||
|
*
|
||||||
|
* The #ClutterListModelClass struct contains only private data.
|
||||||
|
*
|
||||||
|
* Since: 0.6
|
||||||
|
*/
|
||||||
|
struct _ClutterListModelClass
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
ClutterModelClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
GType clutter_list_model_get_type (void) G_GNUC_CONST;
|
GType clutter_list_model_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user