1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
// SPDX-FileCopyrightText: 2020 Andy Holmes <andrew.g.r.holmes@gmail.com>
import GObject from 'gi://GObject';
import Gio from '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.
*/
export let GjsListStore = GObject.registerClass({
GTypeName: 'GjsListStore',
Implements: [Gio.ListModel],
}, class MyList extends GObject.Object {
constructor() {
super();
/* 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);
}
});
|