[rhythmbox] add simple list model



commit 89080a83ba19102d333fb5346d795f576b2674eb
Author: Jonathan Matthew <jonathan d14n org>
Date:   Tue May 14 20:43:24 2013 +1000

    add simple list model

 lib/Makefile.am     |    4 +-
 lib/rb-list-model.c |  279 +++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/rb-list-model.h |   64 ++++++++++++
 3 files changed, 346 insertions(+), 1 deletions(-)
---
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 4ed8e5f..9c8d553 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -8,6 +8,7 @@ rbinclude_HEADERS =                                     \
        rb-builder-helpers.h                            \
        rb-debug.h                                      \
        rb-file-helpers.h                               \
+       rb-list-model.h                                 \
        rb-stock-icons.h                                \
        rb-string-value-map.h                           \
        rb-util.h
@@ -37,7 +38,8 @@ librb_la_SOURCES =                                    \
        rb-async-copy.c                                 \
        rb-async-copy.h                                 \
        rb-chunk-loader.c                               \
-       rb-chunk-loader.h
+       rb-chunk-loader.h                               \
+       rb-list-model.c
 
 INCLUDES =                                             \
        -DGNOMELOCALEDIR=\""$(datadir)/locale"\"        \
diff --git a/lib/rb-list-model.c b/lib/rb-list-model.c
new file mode 100644
index 0000000..b13219a
--- /dev/null
+++ b/lib/rb-list-model.c
@@ -0,0 +1,279 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ *  Copyright (C) 2013 Jonathan Matthew <jonathan d14n org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The Rhythmbox authors hereby grant permission for non-GPL compatible
+ *  GStreamer plugins to be used and distributed together with GStreamer
+ *  and Rhythmbox. This permission is above and beyond the permissions granted
+ *  by the GPL license by which Rhythmbox is covered. If you modify this code
+ *  you may extend this exception to your version of the code, but you are not
+ *  obligated to do so. If you do not wish to do so, delete this exception
+ *  statement from your version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
+ *
+ */
+
+#include <config.h>
+
+#include <lib/rb-list-model.h>
+
+enum {
+       ITEMS_CHANGED,
+       LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+struct _RBListModel
+{
+       GObject parent;
+
+       GType item_type;
+       GArray *items;
+};
+
+struct _RBListModelClass
+{
+       GObjectClass parent;
+};
+
+G_DEFINE_TYPE (RBListModel, rb_list_model, G_TYPE_OBJECT);
+
+static void rb_list_model_class_init (RBListModelClass *klass);
+static void rb_list_model_init (RBListModel *model);
+
+/**
+ * SECTION:rb-list-model
+ * @short_description: simple list model
+ *
+ * Stores a list of items and emits notification signals on changes.
+ */
+
+static void
+impl_finalize (GObject *object)
+{
+       RBListModel *model = RB_LIST_MODEL (object);
+
+       g_array_free (model->items, TRUE);
+
+       G_OBJECT_CLASS (rb_list_model_parent_class)->finalize (object);
+}
+
+static void
+rb_list_model_init (RBListModel *model)
+{
+}
+
+static void
+rb_list_model_class_init (RBListModelClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+       object_class->finalize = impl_finalize;
+
+       signals[ITEMS_CHANGED] =
+               g_signal_new ("items-changed",
+                             G_OBJECT_CLASS_TYPE (object_class),
+                             G_SIGNAL_RUN_LAST,
+                             0,
+                             NULL, NULL, NULL,
+                             G_TYPE_NONE,
+                             3, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
+}
+
+/**
+ * rb_list_model_new:
+ * @item_type: a #GType for items in the list
+ * @destroy_item: callback for destroying list items
+ *
+ * Creates a new empty list model.
+ *
+ * Return value: (transfer full): the model
+ */
+RBListModel *
+rb_list_model_new (GType item_type, GDestroyNotify destroy_item)
+{
+       RBListModel *model = RB_LIST_MODEL (g_object_new (RB_TYPE_LIST_MODEL, NULL));
+       model->item_type = item_type;
+       model->items = g_array_new (FALSE, FALSE, sizeof (gpointer));
+       g_array_set_clear_func (model->items, destroy_item);
+
+       return model;
+}
+
+/**
+ * rb_list_model_get_item_type:
+ * @model: an #RBListModel
+ *
+ * Returns the list entry type.
+ *
+ * Return value: list entry type
+ */
+GType
+rb_list_model_get_item_type (RBListModel *model)
+{
+       return model->item_type;
+}
+
+/**
+ * rb_list_model_n_items:
+ * @model: an #RBListModel
+ *
+ * Returns the length of the list.
+ *
+ * Return value: list length
+ */
+int
+rb_list_model_n_items (RBListModel *model)
+{
+       return model->items->len;
+}
+
+/**
+ * rb_list_model_get:
+ * @model: an #RBListModel
+ * @index: item to retrieve
+ *
+ * Returns an item from the list.
+ *
+ * Return value: item at the specified index
+ */
+gpointer
+rb_list_model_get (RBListModel *model, int index)
+{
+       g_return_val_if_fail (RB_IS_LIST_MODEL (model), NULL);
+       g_return_val_if_fail (index >= 0, NULL);
+       g_return_val_if_fail (index < model->items->len, NULL);
+
+       return g_array_index (model->items, gpointer, index);
+}
+
+/**
+ * rb_list_model_find:
+ * @model: an #RBListModel
+ * @item: item to find
+ *
+ * Returns the lowest index at which @item appears in the list,
+ * or -1 if the item is not in the list.
+ *
+ * Return value: list index
+ */
+int
+rb_list_model_find (RBListModel *model, gpointer item)
+{
+       int i;
+       g_return_val_if_fail (RB_IS_LIST_MODEL (model), -1);
+       if (model->item_type != G_TYPE_NONE) {
+               g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (item, model->item_type), -1);
+       }
+
+       for (i = 0; i < model->items->len; i++) {
+               if (g_array_index (model->items, gpointer, i) == item)
+                       return i;
+       }
+       return -1;
+}
+
+static void
+items_changed (RBListModel *model, int position, int removed, int added)
+{
+       g_signal_emit (model, signals[ITEMS_CHANGED], 0, position, removed, added);
+}
+
+/**
+ * rb_list_model_insert:
+ * @model: an #RBListModel
+ * @index: position to insert the item at
+ * @item: item to insert
+ *
+ * Inserts at item into the list.  If @index is less than zero or
+ * greater than the length of the list, the item is appended to the
+ * list.
+ */
+void
+rb_list_model_insert (RBListModel *model, int index, gpointer item)
+{
+       g_return_if_fail (RB_IS_LIST_MODEL (model));
+       if (model->item_type != G_TYPE_NONE) {
+               g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (item, model->item_type));
+       }
+
+       if (index < 0 || index > model->items->len)
+               index = model->items->len;
+
+       g_array_insert_val (model->items, index, item);
+       items_changed (model, index, 0, 1);
+}
+
+/**
+ * rb_list_model_append:
+ * @model: an #RBListModel
+ * @item: item to append
+ *
+ * Appends @item to the list.
+ */
+void
+rb_list_model_append (RBListModel *model, gpointer item)
+{
+       rb_list_model_insert (model, -1, item);
+}
+
+/**
+ * rb_list_model_prepend:
+ * @model: an #RBListModel
+ * @item: item to prepend
+ *
+ * Prepends @item to the list.
+ */
+void
+rb_list_model_prepend (RBListModel *model, gpointer item)
+{
+       rb_list_model_insert (model, 0, item);
+}
+
+/**
+ * rb_list_model_remove:
+ * @model: an #RBListModel
+ * @index: index of the item to remove
+ *
+ * Removes the item at @index from the list.
+ */
+void
+rb_list_model_remove (RBListModel *model, int index)
+{
+       g_return_if_fail (RB_IS_LIST_MODEL (model));
+       g_return_if_fail (index >= 0);
+       g_return_if_fail (index < model->items->len);
+
+       g_array_remove_index (model->items, index);
+       items_changed (model, index, 1, 0);
+}
+
+/**
+ * rb_list_model_remove_item:
+ * @model: an #RBListModel
+ * @item: item to remove
+ *
+ * Removes @item from the list.  If the item appears in the
+ * list multiple times, only the first instance is removed.
+ */
+void
+rb_list_model_remove_item (RBListModel *model, gpointer item)
+{
+       int index;
+
+       index = rb_list_model_find (model, item);
+       rb_list_model_remove (model, index);
+}
diff --git a/lib/rb-list-model.h b/lib/rb-list-model.h
new file mode 100644
index 0000000..f35c048
--- /dev/null
+++ b/lib/rb-list-model.h
@@ -0,0 +1,64 @@
+/*
+ *  Copyright (C) 2013 Jonathan Matthew  <jonathan d14n org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The Rhythmbox authors hereby grant permission for non-GPL compatible
+ *  GStreamer plugins to be used and distributed together with GStreamer
+ *  and Rhythmbox. This permission is above and beyond the permissions granted
+ *  by the GPL license by which Rhythmbox is covered. If you modify this code
+ *  you may extend this exception to your version of the code, but you are not
+ *  obligated to do so. If you do not wish to do so, delete this exception
+ *  statement from your version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
+ *
+ */
+
+#ifndef RB_LIST_MODEL_H
+#define RB_LIST_MODEL_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define RB_TYPE_LIST_MODEL         (rb_list_model_get_type ())
+#define RB_LIST_MODEL(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_LIST_MODEL, RBListModel))
+#define RB_LIST_MODEL_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), RB_TYPE_LIST_MODEL, RBListModelClass))
+#define RB_IS_LIST_MODEL(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), RB_TYPE_LIST_MODEL))
+#define RB_IS_LIST_MODEL_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_LIST_MODEL))
+#define RB_LIST_MODEL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_LIST_MODEL, RBListModelClass))
+
+typedef struct _RBListModel RBListModel;
+typedef struct _RBListModelClass RBListModelClass;
+typedef struct _RBListModelPrivate RBListModelPrivate;
+
+GType          rb_list_model_get_type          (void);
+
+RBListModel *  rb_list_model_new               (GType item_type, GDestroyNotify destroy_item);
+
+GType          rb_list_model_get_item_type     (RBListModel *model);
+int            rb_list_model_n_items           (RBListModel *model);
+gpointer       rb_list_model_get               (RBListModel *model, int index);
+int            rb_list_model_find              (RBListModel *model, gpointer item);
+
+void           rb_list_model_insert            (RBListModel *model, int index, gpointer item);
+void           rb_list_model_append            (RBListModel *model, gpointer item);
+void           rb_list_model_prepend           (RBListModel *model, gpointer item);
+
+void           rb_list_model_remove            (RBListModel *model, int index);
+void           rb_list_model_remove_item       (RBListModel *model, gpointer item);
+
+G_END_DECLS
+
+#endif /* RB_LIST_MODEL_H */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]