slint-ui 1.9.0-nightly.2024092723 → 1.9.0-nightly.2024100103

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,278 @@
1
+ // Copyright © SixtyFPS GmbH <info@slint.dev>
2
+ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
3
+
4
+ import * as napi from "../rust-module.cjs";
5
+
6
+ class ModelIterator<T> implements Iterator<T> {
7
+ private row: number;
8
+ private model: Model<T>;
9
+
10
+ constructor(model: Model<T>) {
11
+ this.model = model;
12
+ this.row = 0;
13
+ }
14
+
15
+ public next(): IteratorResult<T> {
16
+ if (this.row < this.model.rowCount()) {
17
+ const row = this.row;
18
+ this.row++;
19
+ return {
20
+ done: false,
21
+ value: this.model.rowData(row),
22
+ };
23
+ }
24
+ return {
25
+ done: true,
26
+ value: undefined,
27
+ };
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Model<T> is the interface for feeding dynamic data into
33
+ * `.slint` views.
34
+ *
35
+ * A model is organized like a table with rows of data. The
36
+ * fields of the data type T behave like columns.
37
+ *
38
+ * @template T the type of the model's items.
39
+ *
40
+ * ### Example
41
+ * As an example let's see the implementation of {@link ArrayModel}
42
+ *
43
+ * ```js
44
+ * export class ArrayModel<T> extends Model<T> {
45
+ * private a: Array<T>
46
+ *
47
+ * constructor(arr: Array<T>) {
48
+ * super();
49
+ * this.a = arr;
50
+ * }
51
+ *
52
+ * rowCount() {
53
+ * return this.a.length;
54
+ * }
55
+ *
56
+ * rowData(row: number) {
57
+ * return this.a[row];
58
+ * }
59
+ *
60
+ * setRowData(row: number, data: T) {
61
+ * this.a[row] = data;
62
+ * this.notifyRowDataChanged(row);
63
+ * }
64
+ *
65
+ * push(...values: T[]) {
66
+ * let size = this.a.length;
67
+ * Array.prototype.push.apply(this.a, values);
68
+ * this.notifyRowAdded(size, arguments.length);
69
+ * }
70
+ *
71
+ * remove(index: number, size: number) {
72
+ * let r = this.a.splice(index, size);
73
+ * this.notifyRowRemoved(index, size);
74
+ * }
75
+ *
76
+ * get length(): number {
77
+ * return this.a.length;
78
+ * }
79
+ *
80
+ * values(): IterableIterator<T> {
81
+ * return this.a.values();
82
+ * }
83
+ *
84
+ * entries(): IterableIterator<[number, T]> {
85
+ * return this.a.entries()
86
+ * }
87
+ *}
88
+ * ```
89
+ */
90
+ export abstract class Model<T> implements Iterable<T> {
91
+ /**
92
+ * @hidden
93
+ */
94
+ modelNotify: napi.ExternalObject<napi.SharedModelNotify>;
95
+
96
+ /**
97
+ * @hidden
98
+ */
99
+ constructor(modelNotify?: napi.ExternalObject<napi.SharedModelNotify>) {
100
+ this.modelNotify = modelNotify ?? napi.jsModelNotifyNew(this);
101
+ }
102
+
103
+ // /**
104
+ // * Returns a new Model where all elements are mapped by the function `mapFunction`.
105
+ // * @template T the type of the source model's items.
106
+ // * @param mapFunction functions that maps
107
+ // * @returns a new {@link MapModel} that wraps the current model.
108
+ // */
109
+ // map<U>(
110
+ // mapFunction: (data: T) => U
111
+ // ): MapModel<T, U> {
112
+ // return new MapModel(this, mapFunction);
113
+ // }
114
+
115
+ /**
116
+ * Implementations of this function must return the current number of rows.
117
+ */
118
+ abstract rowCount(): number;
119
+ /**
120
+ * Implementations of this function must return the data at the specified row.
121
+ * @param row index in range 0..(rowCount() - 1).
122
+ * @returns undefined if row is out of range otherwise the data.
123
+ */
124
+ abstract rowData(row: number): T | undefined;
125
+
126
+ /**
127
+ * Implementations of this function must store the provided data parameter
128
+ * in the model at the specified row.
129
+ * @param _row index in range 0..(rowCount() - 1).
130
+ * @param _data new data item to store on the given row index
131
+ */
132
+ setRowData(_row: number, _data: T): void {
133
+ console.log(
134
+ "setRowData called on a model which does not re-implement this method. This happens when trying to modify a read-only model",
135
+ );
136
+ }
137
+
138
+ [Symbol.iterator](): Iterator<T> {
139
+ return new ModelIterator(this);
140
+ }
141
+
142
+ /**
143
+ * Notifies the view that the data of the current row is changed.
144
+ * @param row index of the changed row.
145
+ */
146
+ protected notifyRowDataChanged(row: number): void {
147
+ napi.jsModelNotifyRowDataChanged(this.modelNotify, row);
148
+ }
149
+
150
+ /**
151
+ * Notifies the view that multiple rows are added to the model.
152
+ * @param row index of the first added row.
153
+ * @param count the number of added items.
154
+ */
155
+ protected notifyRowAdded(row: number, count: number): void {
156
+ napi.jsModelNotifyRowAdded(this.modelNotify, row, count);
157
+ }
158
+
159
+ /**
160
+ * Notifies the view that multiple rows are removed to the model.
161
+ * @param row index of the first removed row.
162
+ * @param count the number of removed items.
163
+ */
164
+ protected notifyRowRemoved(row: number, count: number): void {
165
+ napi.jsModelNotifyRowRemoved(this.modelNotify, row, count);
166
+ }
167
+
168
+ /**
169
+ * Notifies the view that the complete data must be reload.
170
+ */
171
+ protected notifyReset(): void {
172
+ napi.jsModelNotifyReset(this.modelNotify);
173
+ }
174
+ }
175
+
176
+ /**
177
+ * ArrayModel wraps a JavaScript array for use in `.slint` views. The underlying
178
+ * array can be modified with the [[ArrayModel.push]] and [[ArrayModel.remove]] methods.
179
+ */
180
+ export class ArrayModel<T> extends Model<T> {
181
+ /**
182
+ * @hidden
183
+ */
184
+ #array: Array<T>;
185
+
186
+ /**
187
+ * Creates a new ArrayModel.
188
+ *
189
+ * @param arr
190
+ */
191
+ constructor(arr: Array<T>) {
192
+ super();
193
+ this.#array = arr;
194
+ }
195
+
196
+ /**
197
+ * Returns the number of entries in the array model.
198
+ */
199
+ get length(): number {
200
+ return this.#array.length;
201
+ }
202
+
203
+ /**
204
+ * Returns the number of entries in the array model.
205
+ */
206
+ rowCount() {
207
+ return this.#array.length;
208
+ }
209
+
210
+ /**
211
+ * Returns the data at the specified row.
212
+ * @param row index in range 0..(rowCount() - 1).
213
+ * @returns undefined if row is out of range otherwise the data.
214
+ */
215
+ rowData(row: number) {
216
+ return this.#array[row];
217
+ }
218
+
219
+ /**
220
+ * Stores the given data on the given row index and notifies run-time about the changed row.
221
+ * @param row index in range 0..(rowCount() - 1).
222
+ * @param data new data item to store on the given row index
223
+ */
224
+ setRowData(row: number, data: T) {
225
+ this.#array[row] = data;
226
+ this.notifyRowDataChanged(row);
227
+ }
228
+
229
+ /**
230
+ * Pushes new values to the array that's backing the model and notifies
231
+ * the run-time about the added rows.
232
+ * @param values list of values that will be pushed to the array.
233
+ */
234
+ push(...values: T[]) {
235
+ const size = this.#array.length;
236
+ Array.prototype.push.apply(this.#array, values);
237
+ this.notifyRowAdded(size, arguments.length);
238
+ }
239
+
240
+ /**
241
+ * Removes the last element from the array and returns it.
242
+ *
243
+ * @returns The removed element or undefined if the array is empty.
244
+ */
245
+ pop(): T | undefined {
246
+ const last = this.#array.pop();
247
+ if (last !== undefined) {
248
+ this.notifyRowRemoved(this.#array.length, 1);
249
+ }
250
+ return last;
251
+ }
252
+
253
+ // FIXME: should this be named splice and have the splice api?
254
+ /**
255
+ * Removes the specified number of element from the array that's backing
256
+ * the model, starting at the specified index.
257
+ * @param index index of first row to remove.
258
+ * @param size number of rows to remove.
259
+ */
260
+ remove(index: number, size: number) {
261
+ const r = this.#array.splice(index, size);
262
+ this.notifyRowRemoved(index, size);
263
+ }
264
+
265
+ /**
266
+ * Returns an iterable of values in the array.
267
+ */
268
+ values(): IterableIterator<T> {
269
+ return this.#array.values();
270
+ }
271
+
272
+ /**
273
+ * Returns an iterable of key, value pairs for every entry in the array.
274
+ */
275
+ entries(): IterableIterator<[number, T]> {
276
+ return this.#array.entries();
277
+ }
278
+ }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes