[gjs: 1/2] examples: add GListModel implementation



commit 7b7f9ee798aaccc594d0ae59c300d158f03fce90
Author: Andy Holmes <andrew g r holmes gmail com>
Date:   Sun Jun 21 13:41:29 2020 -0700

    examples: add GListModel implementation
    
    Add a simple implementation of GListModel, primarily as a demonstration
    of implementing interfaces in genera, but particularly this interface as
    it will be used quite a bit in Gtk4.

 examples/glistmodel.js | 137 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 137 insertions(+)
---
diff --git a/examples/glistmodel.js b/examples/glistmodel.js
new file mode 100644
index 00000000..4a04e77e
--- /dev/null
+++ b/examples/glistmodel.js
@@ -0,0 +1,137 @@
+/* exported GjsListStore */
+
+'use strict';
+
+const GObject = imports.gi.GObject;
+const Gio = imports.gi.Gio;
+
+
+
+/**
+ * An example of implementing the GListModel interface in GJS. The only real
+ * requirement here is that the class be derived from some GObject.
+ */
+var GjsListStore = GObject.registerClass({
+    GTypeName: 'GjsListStore',
+    Implements: [Gio.ListModel],
+}, class MyList extends GObject.Object {
+    _init() {
+        super._init();
+
+        /* We'll use a native Array as internal storage for the list model */
+        this._items = [];
+    }
+
+    /* Implementing this function amounts to returning a GType. This could be a
+     * more specific GType, but must be a subclass of GObject. */
+    vfunc_get_item_type() {
+        return GObject.Object.$gtype;
+    }
+
+    /* Implementing this function just requires returning the GObject at
+     * @position or %null if out-of-range. This must explicitly return %null,
+     * not `undefined`. */
+    vfunc_get_item(position) {
+        return this._items[position] || null;
+    }
+
+    /* Implementing this function is as simple as return the length of the
+     * storage object, in this case an Array. */
+    vfunc_get_n_items() {
+        return this._items.length;
+    }
+
+    /**
+     * Insert an item in the list. If @position is greater than the number of
+     * items in the list or less than `0` it will be appended to the end of the
+     * list.
+     *
+     * @param {GObject.Object} item - the item to add
+     * @param {number} position - the position to add the item
+     */
+    insertItem(item, position) {
+        if (!(item instanceof GObject.Object))
+            throw new TypeError('not a GObject');
+
+        if (position < 0 || position > this._items.length)
+            position = this._items.length;
+
+        this._items.splice(position, 0, item);
+        this.items_changed(position, 0, 1);
+    }
+
+    /**
+     * Append an item to the list.
+     *
+     * @param {GObject.Object} item - the item to add
+     */
+    appendItem(item) {
+        if (!(item instanceof GObject.Object))
+            throw new TypeError('not a GObject');
+
+        let position = this._items.length;
+
+        this._items.push(item);
+        this.items_changed(position, 0, 1);
+    }
+
+    /**
+     * Prepend an item to the list.
+     *
+     * @param {GObject.Object} item - the item to add
+     */
+    prependItem(item) {
+        if (!(item instanceof GObject.Object))
+            throw new TypeError('not a GObject');
+
+        this._items.unshift(item);
+        this.items_changed(0, 0, 1);
+    }
+
+    /**
+     * Remove @item from the list. If @item is not in the list, this function
+     * does nothing.
+     *
+     * @param {GObject.Object} item - the item to remove
+     */
+    removeItem(item) {
+        if (!(item instanceof GObject.Object))
+            throw new TypeError('not a GObject');
+
+        let position = this._items.indexOf(item);
+
+        if (position === -1)
+            return;
+
+        this._items.splice(position, 1);
+        this.items_changed(position, 1, 0);
+    }
+
+    /**
+     * Remove the item at @position. If @position is outside the length of the
+     * list, this function does nothing.
+     *
+     * @param {number} position - the position of the item to remove
+     */
+    removePosition(position) {
+        if (position < 0 || position >= this._items.length)
+            return;
+
+        this._items.splice(position, 1);
+        this.items_changed(position, 1, 0);
+    }
+
+    /**
+     * Clear the list of all items.
+     */
+    clear() {
+        let length = this._items.length;
+
+        if (length === 0)
+            return;
+
+        this._items = [];
+        this.items_changed(0, length, 0);
+    }
+});
+


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