@gtkx/components 1.0.0-rc.3 → 1.0.0
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.
- package/README.md +8 -9
- package/dist/adw/combo-row.d.ts +1 -0
- package/dist/adw/combo-row.d.ts.map +1 -1
- package/dist/adw/combo-row.js.map +1 -1
- package/dist/adw/types.d.ts +2 -1
- package/dist/adw/types.d.ts.map +1 -1
- package/dist/adw/types.js.map +1 -1
- package/dist/column-view.d.ts +2 -2
- package/dist/column-view.d.ts.map +1 -1
- package/dist/column-view.js +15 -13
- package/dist/column-view.js.map +1 -1
- package/dist/drop-down.d.ts +1 -0
- package/dist/drop-down.d.ts.map +1 -1
- package/dist/drop-down.js.map +1 -1
- package/dist/grid-view.js +2 -2
- package/dist/grid-view.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/cells.d.ts +32 -24
- package/dist/internal/cells.d.ts.map +1 -1
- package/dist/internal/cells.js +168 -77
- package/dist/internal/cells.js.map +1 -1
- package/dist/internal/collection-index.d.ts +9 -13
- package/dist/internal/collection-index.d.ts.map +1 -1
- package/dist/internal/collection-index.js +33 -70
- package/dist/internal/collection-index.js.map +1 -1
- package/dist/internal/collection-model.d.ts +23 -2
- package/dist/internal/collection-model.d.ts.map +1 -1
- package/dist/internal/collection-model.js +210 -98
- package/dist/internal/collection-model.js.map +1 -1
- package/dist/internal/collection.d.ts +9 -12
- package/dist/internal/collection.d.ts.map +1 -1
- package/dist/internal/collection.js +38 -49
- package/dist/internal/collection.js.map +1 -1
- package/dist/internal/controlled-sync.d.ts +11 -0
- package/dist/internal/controlled-sync.d.ts.map +1 -0
- package/dist/internal/controlled-sync.js +19 -0
- package/dist/internal/controlled-sync.js.map +1 -0
- package/dist/internal/drop-down.d.ts.map +1 -1
- package/dist/internal/drop-down.js +27 -15
- package/dist/internal/drop-down.js.map +1 -1
- package/dist/internal/expansion.d.ts +3 -2
- package/dist/internal/expansion.d.ts.map +1 -1
- package/dist/internal/expansion.js +80 -47
- package/dist/internal/expansion.js.map +1 -1
- package/dist/internal/keys.d.ts +5 -0
- package/dist/internal/keys.d.ts.map +1 -0
- package/dist/internal/keys.js +13 -0
- package/dist/internal/keys.js.map +1 -0
- package/dist/internal/selection.d.ts +3 -2
- package/dist/internal/selection.d.ts.map +1 -1
- package/dist/internal/selection.js +68 -35
- package/dist/internal/selection.js.map +1 -1
- package/dist/internal/slots.d.ts +10 -0
- package/dist/internal/slots.d.ts.map +1 -0
- package/dist/internal/slots.js +43 -0
- package/dist/internal/slots.js.map +1 -0
- package/dist/internal/tree-expansion.d.ts +20 -0
- package/dist/internal/tree-expansion.d.ts.map +1 -0
- package/dist/internal/tree-expansion.js +68 -0
- package/dist/internal/tree-expansion.js.map +1 -0
- package/dist/internal/tree-order.d.ts +27 -0
- package/dist/internal/tree-order.d.ts.map +1 -0
- package/dist/internal/tree-order.js +71 -0
- package/dist/internal/tree-order.js.map +1 -0
- package/dist/internal/use-collection.d.ts +5 -5
- package/dist/internal/use-collection.d.ts.map +1 -1
- package/dist/internal/use-collection.js +6 -6
- package/dist/internal/use-collection.js.map +1 -1
- package/dist/list-view.d.ts.map +1 -1
- package/dist/list-view.js +6 -6
- package/dist/list-view.js.map +1 -1
- package/dist/types.d.ts +127 -54
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +7 -7
- package/src/adw/combo-row.tsx +1 -0
- package/src/adw/types.ts +2 -1
- package/src/column-view.tsx +38 -35
- package/src/drop-down.tsx +1 -0
- package/src/grid-view.tsx +2 -2
- package/src/index.ts +10 -11
- package/src/internal/cells.tsx +345 -123
- package/src/internal/collection-index.ts +51 -99
- package/src/internal/collection-model.ts +259 -110
- package/src/internal/collection.ts +46 -68
- package/src/internal/controlled-sync.ts +34 -0
- package/src/internal/drop-down.tsx +44 -23
- package/src/internal/expansion.ts +104 -67
- package/src/internal/keys.ts +18 -0
- package/src/internal/selection.tsx +100 -51
- package/src/internal/slots.ts +67 -0
- package/src/internal/tree-expansion.ts +110 -0
- package/src/internal/tree-order.ts +138 -0
- package/src/internal/use-collection.tsx +11 -11
- package/src/list-view.tsx +14 -10
- package/src/types.ts +140 -65
- package/dist/size-group.d.ts +0 -12
- package/dist/size-group.d.ts.map +0 -1
- package/dist/size-group.js +0 -41
- package/dist/size-group.js.map +0 -1
- package/src/size-group.tsx +0 -77
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection-index.js","sourceRoot":"","sources":["../../src/internal/collection-index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"collection-index.js","sourceRoot":"","sources":["../../src/internal/collection-index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ListItem, ListSection } from \"../types.js\";\nimport { encodePart } from \"./keys.js\";\n\ntype Level = {\n path: string;\n items: ListItem[];\n expandableFlags: boolean[];\n};\n\ntype CollectionIndex = {\n isTree: boolean;\n groups: Level[];\n children: Map<string, Level>;\n itemAt: (levelPath: string, slot: number) => ListItem | undefined;\n sectionFor: (levelPath: string) => unknown;\n expandablePathsFor: (id: string) => string[];\n};\n\ntype IndexState = {\n isTree: boolean;\n groups: Level[];\n children: Map<string, Level>;\n levels: Map<string, Level>;\n expandablePaths: Map<string, string[]>;\n sectionValues: Map<string, unknown>;\n};\n\nconst NO_PATHS: string[] = [];\n\nconst hasChildren = (item: ListItem): boolean => item.children !== undefined && item.children.length > 0;\n\nfunction pushPath(table: Map<string, string[]>, id: string, path: string): void {\n const existing = table.get(id);\n\n if (existing === undefined) {\n table.set(id, [path]);\n\n return;\n }\n\n existing.push(path);\n}\n\nfunction collectChildren(state: IndexState, level: Level, slotPath: string, item: ListItem): void {\n const canExpand = hasChildren(item);\n level.expandableFlags.push(canExpand);\n\n if (!canExpand) {\n return;\n }\n\n pushPath(state.expandablePaths, item.id, slotPath);\n state.children.set(slotPath, collectLevel(state, slotPath, item.children ?? []));\n}\n\nfunction collectLevel(state: IndexState, path: string, items: ListItem[]): Level {\n const level: Level = { path, items, expandableFlags: [] };\n state.levels.set(path, level);\n\n if (!state.isTree) {\n return level;\n }\n\n for (const [slot, item] of items.entries()) {\n collectChildren(state, level, path + encodePart(String(slot)), item);\n }\n\n return level;\n}\n\nfunction buildGroups(state: IndexState, source: ListItem[], sections: ListSection[] | undefined): Level[] {\n if (sections === undefined) {\n return [collectLevel(state, encodePart(\"0\"), source)];\n }\n\n return sections.map((section, group) => {\n const path = encodePart(String(group));\n state.sectionValues.set(path, section.value);\n\n return collectLevel(state, path, section.data);\n });\n}\n\nfunction isTreeSource(source: ListItem[], sections: ListSection[] | undefined, isFlat: boolean): boolean {\n if (sections !== undefined || isFlat) {\n return false;\n }\n\n return source.some((item) => hasChildren(item));\n}\n\nfunction createCollectionIndex(\n items: ListItem[] | undefined,\n sections: ListSection[] | undefined,\n isFlat: boolean,\n): CollectionIndex {\n const source = items ?? [];\n\n const state: IndexState = {\n isTree: isTreeSource(source, sections, isFlat),\n groups: [],\n children: new Map(),\n levels: new Map(),\n expandablePaths: new Map(),\n sectionValues: new Map(),\n };\n\n state.groups = buildGroups(state, source, sections);\n\n return {\n isTree: state.isTree,\n groups: state.groups,\n children: state.children,\n itemAt: (levelPath, slot) => state.levels.get(levelPath)?.items[slot],\n sectionFor: (levelPath) => state.sectionValues.get(levelPath),\n expandablePathsFor: (id) => state.expandablePaths.get(id) ?? NO_PATHS,\n };\n}\n\nexport { createCollectionIndex, type CollectionIndex, type Level };\n"]}
|
|
@@ -1,12 +1,33 @@
|
|
|
1
|
+
import * as Gio from "@gtkx/gi/gio";
|
|
1
2
|
import * as GObject from "@gtkx/gi/gobject";
|
|
2
3
|
import * as Gtk from "@gtkx/gi/gtk";
|
|
3
4
|
import type { CollectionIndex } from "./collection-index.js";
|
|
5
|
+
import type { TreeExpansion } from "./tree-expansion.js";
|
|
6
|
+
type LevelStore = Gio.ListModel & LazyLevelStore;
|
|
7
|
+
type SlotRef = {
|
|
8
|
+
store: LevelStore;
|
|
9
|
+
slot: number;
|
|
10
|
+
};
|
|
4
11
|
type CollectionModel = {
|
|
5
12
|
model: Gtk.FlattenListModel;
|
|
13
|
+
expansion: TreeExpansion;
|
|
6
14
|
treeModel: () => Gtk.TreeListModel | null;
|
|
7
15
|
sync: (index: CollectionIndex) => void;
|
|
8
16
|
};
|
|
9
|
-
declare function
|
|
17
|
+
declare function slotRefFor(value: GObject.Object | null): SlotRef | null;
|
|
18
|
+
declare function slotPathAt(store: LevelStore, slot: number): string;
|
|
10
19
|
declare function createCollectionModel(): CollectionModel;
|
|
11
|
-
|
|
20
|
+
declare class LazyLevelStore extends GObject.Object implements Gio.ListModelImpl {
|
|
21
|
+
itemsChanged: Gio.ListModel["itemsChanged"];
|
|
22
|
+
path: string;
|
|
23
|
+
refs: SlotRef[];
|
|
24
|
+
objects: (Gtk.StringObject | null)[];
|
|
25
|
+
childStores: (LevelStore | null)[];
|
|
26
|
+
expandableFlags: boolean[];
|
|
27
|
+
private createItem;
|
|
28
|
+
vfuncGetItemType(): bigint;
|
|
29
|
+
vfuncGetNItems(): number;
|
|
30
|
+
vfuncGetItem(position: number): GObject.Object | null;
|
|
31
|
+
}
|
|
32
|
+
export { createCollectionModel, slotPathAt, slotRefFor, type CollectionModel, type SlotRef };
|
|
12
33
|
//# sourceMappingURL=collection-model.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection-model.d.ts","sourceRoot":"","sources":["../../src/internal/collection-model.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"collection-model.d.ts","sourceRoot":"","sources":["../../src/internal/collection-model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AACpC,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AAEpC,OAAO,KAAK,EAAE,eAAe,EAAS,MAAM,uBAAuB,CAAC;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAKzD,KAAK,UAAU,GAAG,GAAG,CAAC,SAAS,GAAG,cAAc,CAAC;AAEjD,KAAK,OAAO,GAAG;IACX,KAAK,EAAE,UAAU,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CAChB,CAAC;AAsBF,KAAK,eAAe,GAAG;IACnB,KAAK,EAAE,GAAG,CAAC,gBAAgB,CAAC;IAC5B,SAAS,EAAE,aAAa,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC;IAC1C,IAAI,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;CAC1C,CAAC;AAmCF,iBAAS,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,OAAO,GAAG,IAAI,CAUhE;AAED,iBAAS,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3D;AAoPD,iBAAS,qBAAqB,IAAI,eAAe,CAsBhD;AAED,cAAM,cAAe,SAAQ,OAAO,CAAC,MAAO,YAAW,GAAG,CAAC,aAAa;IAC5D,YAAY,EAAE,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IACpD,IAAI,SAAM;IACV,IAAI,EAAE,OAAO,EAAE,CAAM;IACrB,OAAO,EAAE,CAAC,GAAG,CAAC,YAAY,GAAG,IAAI,CAAC,EAAE,CAAM;IAC1C,WAAW,EAAE,CAAC,UAAU,GAAG,IAAI,CAAC,EAAE,CAAM;IACxC,eAAe,EAAE,OAAO,EAAE,CAAM;IAEhC,OAAO,CAAC,UAAU;IAQlB,gBAAgB,IAAI,MAAM;IAI1B,cAAc,IAAI,MAAM;IAIxB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI;CASxD;AAED,OAAO,EAAE,qBAAqB,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,KAAK,OAAO,EAAE,CAAC"}
|
|
@@ -1,112 +1,186 @@
|
|
|
1
1
|
import * as Gio from "@gtkx/gi/gio";
|
|
2
2
|
import * as GObject from "@gtkx/gi/gobject";
|
|
3
3
|
import * as Gtk from "@gtkx/gi/gtk";
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
4
|
+
import { registerClass } from "@gtkx/runtime";
|
|
5
|
+
import { createCollectionIndex } from "./collection-index.js";
|
|
6
|
+
import { encodePart } from "./keys.js";
|
|
7
|
+
import { adoptIndex, createTreeExpansion, pruneSlots, resetExpansion } from "./tree-expansion.js";
|
|
8
|
+
const STORE_CLASS_KEY = Symbol.for("gtkx.components.lazy-level-store");
|
|
9
|
+
const SLOTS_KEY = Symbol.for("gtkx.components.lazy-level-store.slots");
|
|
10
|
+
const EMPTY_INDEX = createCollectionIndex(undefined, undefined, true);
|
|
11
|
+
const SLOTS = sharedSlots();
|
|
12
|
+
const newRootStore = () => new Gio.ListStore({ itemType: GObject.TYPE_OBJECT });
|
|
13
|
+
function sharedSlots() {
|
|
14
|
+
const cached = Reflect.get(globalThis, SLOTS_KEY);
|
|
15
|
+
if (cached instanceof WeakMap) {
|
|
16
|
+
return cached;
|
|
15
17
|
}
|
|
16
|
-
const created =
|
|
17
|
-
|
|
18
|
+
const created = new WeakMap();
|
|
19
|
+
Reflect.set(globalThis, SLOTS_KEY, created);
|
|
18
20
|
return created;
|
|
19
21
|
}
|
|
20
|
-
function
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
function registeredStoreClass() {
|
|
23
|
+
const cached = Reflect.get(globalThis, STORE_CLASS_KEY);
|
|
24
|
+
if (typeof cached === "function") {
|
|
25
|
+
return cached;
|
|
24
26
|
}
|
|
25
|
-
|
|
27
|
+
registerClass(LazyLevelStore, { typeName: "GtkxLazyLevelStore", implements: [Gio.ListModel] });
|
|
28
|
+
Reflect.set(globalThis, STORE_CLASS_KEY, LazyLevelStore);
|
|
29
|
+
return LazyLevelStore;
|
|
26
30
|
}
|
|
27
|
-
function
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
function slotRefFor(value) {
|
|
32
|
+
const item = value instanceof Gtk.TreeListRow ? value.getItem() : value;
|
|
33
|
+
if (item === null) {
|
|
34
|
+
return null;
|
|
31
35
|
}
|
|
32
|
-
|
|
36
|
+
const ref = SLOTS.get(item);
|
|
37
|
+
return ref === undefined || ref.slot === -1 ? null : ref;
|
|
38
|
+
}
|
|
39
|
+
function slotPathAt(store, slot) {
|
|
40
|
+
return store.path + encodePart(String(slot));
|
|
33
41
|
}
|
|
34
|
-
function
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
42
|
+
function newLevelStore(path) {
|
|
43
|
+
const store = new (registeredStoreClass())();
|
|
44
|
+
store.path = path;
|
|
45
|
+
return store;
|
|
46
|
+
}
|
|
47
|
+
function buildChildStore(context, path) {
|
|
48
|
+
const level = context.index.children.get(path);
|
|
49
|
+
if (level === undefined) {
|
|
38
50
|
return null;
|
|
39
51
|
}
|
|
40
|
-
const
|
|
41
|
-
|
|
52
|
+
const store = newLevelStore(path);
|
|
53
|
+
growStore(context, store, level);
|
|
54
|
+
return store;
|
|
55
|
+
}
|
|
56
|
+
function pushSlot(context, store, level, slot) {
|
|
57
|
+
const canExpand = level.expandableFlags[slot] ?? false;
|
|
58
|
+
store.refs.push({ store, slot });
|
|
59
|
+
store.objects.push(null);
|
|
60
|
+
store.expandableFlags.push(canExpand);
|
|
61
|
+
store.childStores.push(canExpand ? buildChildStore(context, slotPathAt(store, slot)) : null);
|
|
42
62
|
}
|
|
43
|
-
function
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return existing;
|
|
63
|
+
function growStore(context, store, level) {
|
|
64
|
+
for (let slot = store.refs.length; slot < level.items.length; slot++) {
|
|
65
|
+
pushSlot(context, store, level, slot);
|
|
47
66
|
}
|
|
48
|
-
const created = { store: newStore(), ids: [], canExpand: new Map() };
|
|
49
|
-
state.levels.set(key, created);
|
|
50
|
-
return created;
|
|
51
67
|
}
|
|
52
|
-
function
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
68
|
+
function flipSlot(context, store, slot) {
|
|
69
|
+
const canExpand = !(store.expandableFlags[slot] ?? false);
|
|
70
|
+
store.expandableFlags[slot] = canExpand;
|
|
71
|
+
store.childStores[slot] = canExpand ? buildChildStore(context, slotPathAt(store, slot)) : null;
|
|
72
|
+
}
|
|
73
|
+
function collectFlips(store, level) {
|
|
74
|
+
const overlap = Math.min(store.refs.length, level.items.length);
|
|
75
|
+
const flipped = new Set();
|
|
76
|
+
for (let slot = 0; slot < overlap; slot++) {
|
|
77
|
+
if ((store.expandableFlags[slot] ?? false) !== (level.expandableFlags[slot] ?? false)) {
|
|
78
|
+
flipped.add(slot);
|
|
60
79
|
}
|
|
61
80
|
}
|
|
62
|
-
|
|
81
|
+
return flipped;
|
|
63
82
|
}
|
|
64
|
-
function
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
83
|
+
function syncOverlap(context, store, level) {
|
|
84
|
+
const flipped = collectFlips(store, level);
|
|
85
|
+
if (flipped.size === 0) {
|
|
86
|
+
return flipped;
|
|
87
|
+
}
|
|
88
|
+
pruneSlots(context.expansion, store.path, (slot) => flipped.has(slot));
|
|
89
|
+
for (const slot of flipped) {
|
|
90
|
+
flipSlot(context, store, slot);
|
|
69
91
|
}
|
|
70
|
-
|
|
71
|
-
current.ids = [...level.ids];
|
|
72
|
-
return true;
|
|
92
|
+
return flipped;
|
|
73
93
|
}
|
|
74
|
-
function
|
|
75
|
-
for (
|
|
76
|
-
|
|
77
|
-
|
|
94
|
+
function detachRefs(store, nextLength) {
|
|
95
|
+
for (let slot = nextLength; slot < store.refs.length; slot++) {
|
|
96
|
+
const ref = store.refs[slot];
|
|
97
|
+
if (ref !== undefined) {
|
|
98
|
+
ref.slot = -1;
|
|
78
99
|
}
|
|
79
100
|
}
|
|
80
101
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
// grow the list many times per keystroke, so the cache is only swept once it passes an absolute bound.
|
|
84
|
-
function pruneObjects(state, index) {
|
|
85
|
-
if (state.objects.size <= OBJECT_CACHE_MAX) {
|
|
102
|
+
function shrinkStore(context, store, nextLength) {
|
|
103
|
+
if (store.refs.length <= nextLength) {
|
|
86
104
|
return;
|
|
87
105
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
106
|
+
detachRefs(store, nextLength);
|
|
107
|
+
pruneSlots(context.expansion, store.path, (slot) => slot >= nextLength);
|
|
108
|
+
store.refs.length = nextLength;
|
|
109
|
+
store.objects.length = nextLength;
|
|
110
|
+
store.childStores.length = nextLength;
|
|
111
|
+
store.expandableFlags.length = nextLength;
|
|
112
|
+
}
|
|
113
|
+
function emitTailSplice(store, previousLength, nextLength) {
|
|
114
|
+
if (nextLength < previousLength) {
|
|
115
|
+
store.itemsChanged(nextLength, previousLength - nextLength, 0);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (nextLength > previousLength) {
|
|
119
|
+
store.itemsChanged(previousLength, 0, nextLength - previousLength);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function extendRuns(runs, slot) {
|
|
123
|
+
const last = runs.at(-1);
|
|
124
|
+
if (last !== undefined && last.start + last.length === slot) {
|
|
125
|
+
last.length += 1;
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
runs.push({ start: slot, length: 1 });
|
|
129
|
+
}
|
|
130
|
+
function collectFlipRuns(flipped) {
|
|
131
|
+
const runs = [];
|
|
132
|
+
for (const slot of flipped) {
|
|
133
|
+
extendRuns(runs, slot);
|
|
134
|
+
}
|
|
135
|
+
return runs;
|
|
136
|
+
}
|
|
137
|
+
function emitFlips(store, flipped) {
|
|
138
|
+
for (const run of collectFlipRuns(flipped)) {
|
|
139
|
+
store.itemsChanged(run.start, run.length, run.length);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function stepChildStore(context, store, slot, flipped) {
|
|
143
|
+
const child = store.childStores[slot];
|
|
144
|
+
if (child == null || flipped.has(slot)) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const level = context.index.children.get(slotPathAt(store, slot));
|
|
148
|
+
if (level !== undefined) {
|
|
149
|
+
syncLevel(context, child, level);
|
|
92
150
|
}
|
|
93
151
|
}
|
|
94
|
-
function
|
|
95
|
-
const
|
|
96
|
-
|
|
152
|
+
function syncLevel(context, store, level) {
|
|
153
|
+
const previousLength = store.refs.length;
|
|
154
|
+
const overlap = Math.min(previousLength, level.items.length);
|
|
155
|
+
const flipped = syncOverlap(context, store, level);
|
|
156
|
+
shrinkStore(context, store, level.items.length);
|
|
157
|
+
growStore(context, store, level);
|
|
158
|
+
emitTailSplice(store, previousLength, level.items.length);
|
|
159
|
+
emitFlips(store, flipped);
|
|
160
|
+
for (let slot = 0; slot < overlap; slot++) {
|
|
161
|
+
stepChildStore(context, store, slot, flipped);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
function childStoreFor(object) {
|
|
165
|
+
const ref = slotRefFor(object);
|
|
166
|
+
if (ref === null) {
|
|
97
167
|
return null;
|
|
98
168
|
}
|
|
99
|
-
return
|
|
169
|
+
return ref.store.childStores[ref.slot] ?? null;
|
|
100
170
|
}
|
|
101
|
-
function ensureTree(state) {
|
|
102
|
-
state.tree
|
|
171
|
+
function ensureTree(state, first) {
|
|
172
|
+
if (state.tree === null || state.treeRoot !== first) {
|
|
173
|
+
state.tree = Gtk.TreeListModel.new(first, false, false, (object) => childStoreFor(object));
|
|
174
|
+
state.treeRoot = first;
|
|
175
|
+
}
|
|
103
176
|
return state.tree;
|
|
104
177
|
}
|
|
105
178
|
function desiredRootModels(state, index) {
|
|
106
|
-
|
|
107
|
-
|
|
179
|
+
const [first] = state.groupStores;
|
|
180
|
+
if (first !== undefined && index.isTree) {
|
|
181
|
+
return [ensureTree(state, first)];
|
|
108
182
|
}
|
|
109
|
-
return
|
|
183
|
+
return [...state.groupStores];
|
|
110
184
|
}
|
|
111
185
|
function hasSameModels(previous, next) {
|
|
112
186
|
return previous.length === next.length && next.every((model, index) => previous[index] === model);
|
|
@@ -118,47 +192,85 @@ function syncRoot(state, index) {
|
|
|
118
192
|
}
|
|
119
193
|
state.root.splice(0, state.rootModels.length, next);
|
|
120
194
|
state.rootModels = next;
|
|
195
|
+
resetExpansion(state.expansion);
|
|
196
|
+
}
|
|
197
|
+
function adjustGroupStores(state, context) {
|
|
198
|
+
const { groups } = context.index;
|
|
199
|
+
state.groupStores.length = Math.min(state.groupStores.length, groups.length);
|
|
200
|
+
for (const level of groups.slice(state.groupStores.length)) {
|
|
201
|
+
const store = newLevelStore(level.path);
|
|
202
|
+
growStore(context, store, level);
|
|
203
|
+
state.groupStores.push(store);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
function stepGroupStores(state, context, surviving) {
|
|
207
|
+
for (const [group, level] of context.index.groups.entries()) {
|
|
208
|
+
const store = state.groupStores[group];
|
|
209
|
+
if (store !== undefined && group < surviving) {
|
|
210
|
+
syncLevel(context, store, level);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
121
213
|
}
|
|
122
214
|
function syncModel(state, index) {
|
|
123
|
-
const
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (didChange || visited.size !== state.levels.size) {
|
|
131
|
-
dropUnvisited(state, visited);
|
|
132
|
-
pruneObjects(state, index);
|
|
133
|
-
}
|
|
134
|
-
syncRoot(state, index);
|
|
135
|
-
refreshExpandableLevels(state, index, levels);
|
|
136
|
-
}
|
|
137
|
-
function refreshExpandableLevels(state, index, levels) {
|
|
138
|
-
if (!index.isTree) {
|
|
139
|
-
return;
|
|
215
|
+
const context = { index, expansion: state.expansion };
|
|
216
|
+
const surviving = Math.min(state.groupStores.length, index.groups.length);
|
|
217
|
+
state.expansion.isSyncing = true;
|
|
218
|
+
try {
|
|
219
|
+
adjustGroupStores(state, context);
|
|
220
|
+
syncRoot(state, index);
|
|
221
|
+
stepGroupStores(state, context, surviving);
|
|
140
222
|
}
|
|
141
|
-
|
|
142
|
-
|
|
223
|
+
finally {
|
|
224
|
+
state.expansion.isSyncing = false;
|
|
143
225
|
}
|
|
226
|
+
adoptIndex(state.expansion, index);
|
|
144
227
|
}
|
|
145
228
|
function createCollectionModel() {
|
|
146
|
-
|
|
229
|
+
registeredStoreClass();
|
|
230
|
+
const root = newRootStore();
|
|
147
231
|
const state = {
|
|
148
232
|
root,
|
|
149
233
|
rootModels: [],
|
|
150
234
|
model: Gtk.FlattenListModel.new(root),
|
|
151
|
-
|
|
152
|
-
levels: new Map(),
|
|
235
|
+
groupStores: [],
|
|
153
236
|
tree: null,
|
|
237
|
+
treeRoot: null,
|
|
238
|
+
expansion: createTreeExpansion(EMPTY_INDEX),
|
|
154
239
|
};
|
|
155
240
|
return {
|
|
156
241
|
model: state.model,
|
|
242
|
+
expansion: state.expansion,
|
|
157
243
|
treeModel: () => state.tree,
|
|
158
244
|
sync: (index) => {
|
|
159
245
|
syncModel(state, index);
|
|
160
246
|
},
|
|
161
247
|
};
|
|
162
248
|
}
|
|
163
|
-
|
|
249
|
+
class LazyLevelStore extends GObject.Object {
|
|
250
|
+
path = "";
|
|
251
|
+
refs = [];
|
|
252
|
+
objects = [];
|
|
253
|
+
childStores = [];
|
|
254
|
+
expandableFlags = [];
|
|
255
|
+
createItem(position, ref) {
|
|
256
|
+
const created = Gtk.StringObject.new("");
|
|
257
|
+
this.objects[position] = created;
|
|
258
|
+
SLOTS.set(created, ref);
|
|
259
|
+
return created;
|
|
260
|
+
}
|
|
261
|
+
vfuncGetItemType() {
|
|
262
|
+
return GObject.TYPE_OBJECT;
|
|
263
|
+
}
|
|
264
|
+
vfuncGetNItems() {
|
|
265
|
+
return this.refs.length;
|
|
266
|
+
}
|
|
267
|
+
vfuncGetItem(position) {
|
|
268
|
+
const ref = this.refs[position];
|
|
269
|
+
if (ref === undefined) {
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
return this.objects[position] ?? this.createItem(position, ref);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
export { createCollectionModel, slotPathAt, slotRefFor };
|
|
164
276
|
//# sourceMappingURL=collection-model.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection-model.js","sourceRoot":"","sources":["../../src/internal/collection-model.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Gio from \"@gtkx/gi/gio\";\nimport * as GObject from \"@gtkx/gi/gobject\";\nimport * as Gtk from \"@gtkx/gi/gtk\";\nimport type { CollectionIndex, Level } from \"./collection-index.js\";\nimport { childLevelKey, ROOT_LEVEL_KEY } from \"./collection-index.js\";\n\ntype LevelState = {\n store: Gio.ListStore;\n ids: string[];\n canExpand: Map<string, boolean>;\n};\n\ntype SpliceRange = {\n start: number;\n removed: number;\n added: string[];\n};\n\ntype ModelState = {\n root: Gio.ListStore;\n rootModels: GObject.Object[];\n model: Gtk.FlattenListModel;\n objects: Map<string, Gtk.StringObject>;\n levels: Map<string, LevelState>;\n tree: Gtk.TreeListModel | null;\n};\n\ntype CollectionModel = {\n model: Gtk.FlattenListModel;\n treeModel: () => Gtk.TreeListModel | null;\n sync: (index: CollectionIndex) => void;\n};\n\nconst OBJECT_CACHE_MAX = 1 << 20;\n\nconst newStore = (): Gio.ListStore => new Gio.ListStore({ itemType: GObject.TYPE_OBJECT });\n\nfunction getId(value: GObject.Object | null): string | null {\n const item = value instanceof Gtk.TreeListRow ? value.getItem() : value;\n\n return item instanceof Gtk.StringObject ? item.getString() : null;\n}\n\nfunction objectFor(state: ModelState, id: string): Gtk.StringObject {\n const existing = state.objects.get(id);\n\n if (existing !== undefined) {\n return existing;\n }\n\n const created = Gtk.StringObject.new(id);\n state.objects.set(id, created);\n\n return created;\n}\n\nfunction commonPrefix(previous: string[], next: string[], max: number): number {\n let count = 0;\n\n while (count < max && previous[count] === next[count]) {\n count += 1;\n }\n\n return count;\n}\n\nfunction commonSuffix(previous: string[], next: string[], max: number): number {\n let count = 0;\n\n while (count < max && previous[previous.length - 1 - count] === next[next.length - 1 - count]) {\n count += 1;\n }\n\n return count;\n}\n\nfunction spliceRange(previous: string[], next: string[]): SpliceRange | null {\n const shared = Math.min(previous.length, next.length);\n const start = commonPrefix(previous, next, shared);\n\n if (start === previous.length && start === next.length) {\n return null;\n }\n\n const tail = commonSuffix(previous, next, shared - start);\n\n return { start, removed: previous.length - start - tail, added: next.slice(start, next.length - tail) };\n}\n\nfunction levelFor(state: ModelState, key: string): LevelState {\n const existing = state.levels.get(key);\n\n if (existing !== undefined) {\n return existing;\n }\n\n const created: LevelState = { store: newStore(), ids: [], canExpand: new Map() };\n state.levels.set(key, created);\n\n return created;\n}\n\nfunction refreshExpandable(current: LevelState, level: Level): void {\n const next: Map<string, boolean> = new Map();\n\n for (const [index, id] of level.ids.entries()) {\n const isWanted = level.isExpandable[index] ?? false;\n const previous = current.canExpand.get(id);\n next.set(id, isWanted);\n\n if (previous !== undefined && previous !== isWanted) {\n current.store.itemsChanged(index, 1, 1);\n }\n }\n\n current.canExpand = next;\n}\n\nfunction didSpliceLevel(state: ModelState, level: Level): boolean {\n const current = levelFor(state, level.key);\n const range = spliceRange(current.ids, level.ids);\n\n if (range === null) {\n return false;\n }\n\n current.store.splice(range.start, range.removed, range.added.map((id) => objectFor(state, id)));\n current.ids = [...level.ids];\n\n return true;\n}\n\nfunction dropUnvisited(state: ModelState, visited: Set<string>): void {\n for (const key of state.levels.keys()) {\n if (!visited.has(key)) {\n state.levels.delete(key);\n }\n }\n}\n\n// Items keep their identity by id, so a collection that shrinks keeps its objects cached: filtering a long\n// list down and back up reuses them instead of rebuilding one GObject per row. Incremental filters shrink and\n// grow the list many times per keystroke, so the cache is only swept once it passes an absolute bound.\nfunction pruneObjects(state: ModelState, index: CollectionIndex): void {\n if (state.objects.size <= OBJECT_CACHE_MAX) {\n return;\n }\n\n for (const id of state.objects.keys()) {\n if (!index.has(id)) {\n state.objects.delete(id);\n }\n }\n}\n\nfunction childStoreFor(state: ModelState, object: GObject.Object): Gio.ListStore | null {\n const id = getId(object);\n\n if (id === null) {\n return null;\n }\n\n return state.levels.get(childLevelKey(id))?.store ?? null;\n}\n\nfunction ensureTree(state: ModelState): Gtk.TreeListModel {\n state.tree ??= Gtk.TreeListModel.new(levelFor(state, ROOT_LEVEL_KEY).store, false, false, (object) =>\n childStoreFor(state, object));\n\n return state.tree;\n}\n\nfunction desiredRootModels(state: ModelState, index: CollectionIndex): GObject.Object[] {\n if (index.isTree) {\n return [ensureTree(state)];\n }\n\n return index.groups.map((level) => levelFor(state, level.key).store);\n}\n\nfunction hasSameModels(previous: GObject.Object[], next: GObject.Object[]): boolean {\n return previous.length === next.length && next.every((model, index) => previous[index] === model);\n}\n\nfunction syncRoot(state: ModelState, index: CollectionIndex): void {\n const next = desiredRootModels(state, index);\n\n if (hasSameModels(state.rootModels, next)) {\n return;\n }\n\n state.root.splice(0, state.rootModels.length, next);\n state.rootModels = next;\n}\n\nfunction syncModel(state: ModelState, index: CollectionIndex): void {\n const levels = [...index.groups, ...index.children.values()];\n const visited: Set<string> = new Set();\n let didChange = false;\n\n for (const level of levels) {\n didChange = didSpliceLevel(state, level) || didChange;\n visited.add(level.key);\n }\n\n if (didChange || visited.size !== state.levels.size) {\n dropUnvisited(state, visited);\n pruneObjects(state, index);\n }\n\n syncRoot(state, index);\n refreshExpandableLevels(state, index, levels);\n}\n\nfunction refreshExpandableLevels(state: ModelState, index: CollectionIndex, levels: Level[]): void {\n if (!index.isTree) {\n return;\n }\n\n for (const level of levels) {\n refreshExpandable(levelFor(state, level.key), level);\n }\n}\n\nfunction createCollectionModel(): CollectionModel {\n const root = newStore();\n\n const state: ModelState = {\n root,\n rootModels: [],\n model: Gtk.FlattenListModel.new(root),\n objects: new Map(),\n levels: new Map(),\n tree: null,\n };\n\n return {\n model: state.model,\n treeModel: () => state.tree,\n sync: (index) => {\n syncModel(state, index);\n },\n };\n}\n\nexport { createCollectionModel, getId, type CollectionModel };\n"]}
|
|
1
|
+
{"version":3,"file":"collection-model.js","sourceRoot":"","sources":["../../src/internal/collection-model.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Gio from \"@gtkx/gi/gio\";\nimport * as GObject from \"@gtkx/gi/gobject\";\nimport * as Gtk from \"@gtkx/gi/gtk\";\nimport { registerClass } from \"@gtkx/runtime\";\nimport type { CollectionIndex, Level } from \"./collection-index.js\";\nimport type { TreeExpansion } from \"./tree-expansion.js\";\nimport { createCollectionIndex } from \"./collection-index.js\";\nimport { encodePart } from \"./keys.js\";\nimport { adoptIndex, createTreeExpansion, pruneSlots, resetExpansion } from \"./tree-expansion.js\";\n\ntype LevelStore = Gio.ListModel & LazyLevelStore;\n\ntype SlotRef = {\n store: LevelStore;\n slot: number;\n};\n\ntype SyncContext = {\n index: CollectionIndex;\n expansion: TreeExpansion;\n};\n\ntype SlotRun = {\n start: number;\n length: number;\n};\n\ntype ModelState = {\n root: Gio.ListStore;\n rootModels: GObject.Object[];\n model: Gtk.FlattenListModel;\n groupStores: LevelStore[];\n tree: Gtk.TreeListModel | null;\n treeRoot: LevelStore | null;\n expansion: TreeExpansion;\n};\n\ntype CollectionModel = {\n model: Gtk.FlattenListModel;\n expansion: TreeExpansion;\n treeModel: () => Gtk.TreeListModel | null;\n sync: (index: CollectionIndex) => void;\n};\n\nconst STORE_CLASS_KEY = Symbol.for(\"gtkx.components.lazy-level-store\");\nconst SLOTS_KEY = Symbol.for(\"gtkx.components.lazy-level-store.slots\");\nconst EMPTY_INDEX = createCollectionIndex(undefined, undefined, true);\nconst SLOTS = sharedSlots();\n\nconst newRootStore = (): Gio.ListStore => new Gio.ListStore({ itemType: GObject.TYPE_OBJECT });\n\nfunction sharedSlots(): WeakMap<GObject.Object, SlotRef> {\n const cached: unknown = Reflect.get(globalThis, SLOTS_KEY);\n\n if (cached instanceof WeakMap) {\n return cached as WeakMap<GObject.Object, SlotRef>;\n }\n\n const created: WeakMap<GObject.Object, SlotRef> = new WeakMap();\n Reflect.set(globalThis, SLOTS_KEY, created);\n\n return created;\n}\n\nfunction registeredStoreClass(): typeof LazyLevelStore {\n const cached: unknown = Reflect.get(globalThis, STORE_CLASS_KEY);\n\n if (typeof cached === \"function\") {\n return cached as typeof LazyLevelStore;\n }\n\n registerClass(LazyLevelStore, { typeName: \"GtkxLazyLevelStore\", implements: [Gio.ListModel] });\n Reflect.set(globalThis, STORE_CLASS_KEY, LazyLevelStore);\n\n return LazyLevelStore;\n}\n\nfunction slotRefFor(value: GObject.Object | null): SlotRef | null {\n const item = value instanceof Gtk.TreeListRow ? value.getItem() : value;\n\n if (item === null) {\n return null;\n }\n\n const ref = SLOTS.get(item);\n\n return ref === undefined || ref.slot === -1 ? null : ref;\n}\n\nfunction slotPathAt(store: LevelStore, slot: number): string {\n return store.path + encodePart(String(slot));\n}\n\nfunction newLevelStore(path: string): LevelStore {\n const store = new (registeredStoreClass())() as LevelStore;\n store.path = path;\n\n return store;\n}\n\nfunction buildChildStore(context: SyncContext, path: string): LevelStore | null {\n const level = context.index.children.get(path);\n\n if (level === undefined) {\n return null;\n }\n\n const store = newLevelStore(path);\n growStore(context, store, level);\n\n return store;\n}\n\nfunction pushSlot(context: SyncContext, store: LevelStore, level: Level, slot: number): void {\n const canExpand = level.expandableFlags[slot] ?? false;\n store.refs.push({ store, slot });\n store.objects.push(null);\n store.expandableFlags.push(canExpand);\n store.childStores.push(canExpand ? buildChildStore(context, slotPathAt(store, slot)) : null);\n}\n\nfunction growStore(context: SyncContext, store: LevelStore, level: Level): void {\n for (let slot = store.refs.length; slot < level.items.length; slot++) {\n pushSlot(context, store, level, slot);\n }\n}\n\nfunction flipSlot(context: SyncContext, store: LevelStore, slot: number): void {\n const canExpand = !(store.expandableFlags[slot] ?? false);\n store.expandableFlags[slot] = canExpand;\n store.childStores[slot] = canExpand ? buildChildStore(context, slotPathAt(store, slot)) : null;\n}\n\nfunction collectFlips(store: LevelStore, level: Level): Set<number> {\n const overlap = Math.min(store.refs.length, level.items.length);\n const flipped: Set<number> = new Set();\n\n for (let slot = 0; slot < overlap; slot++) {\n if ((store.expandableFlags[slot] ?? false) !== (level.expandableFlags[slot] ?? false)) {\n flipped.add(slot);\n }\n }\n\n return flipped;\n}\n\nfunction syncOverlap(context: SyncContext, store: LevelStore, level: Level): Set<number> {\n const flipped = collectFlips(store, level);\n\n if (flipped.size === 0) {\n return flipped;\n }\n\n pruneSlots(context.expansion, store.path, (slot) => flipped.has(slot));\n\n for (const slot of flipped) {\n flipSlot(context, store, slot);\n }\n\n return flipped;\n}\n\nfunction detachRefs(store: LevelStore, nextLength: number): void {\n for (let slot = nextLength; slot < store.refs.length; slot++) {\n const ref = store.refs[slot];\n\n if (ref !== undefined) {\n ref.slot = -1;\n }\n }\n}\n\nfunction shrinkStore(context: SyncContext, store: LevelStore, nextLength: number): void {\n if (store.refs.length <= nextLength) {\n return;\n }\n\n detachRefs(store, nextLength);\n pruneSlots(context.expansion, store.path, (slot) => slot >= nextLength);\n store.refs.length = nextLength;\n store.objects.length = nextLength;\n store.childStores.length = nextLength;\n store.expandableFlags.length = nextLength;\n}\n\nfunction emitTailSplice(store: LevelStore, previousLength: number, nextLength: number): void {\n if (nextLength < previousLength) {\n store.itemsChanged(nextLength, previousLength - nextLength, 0);\n\n return;\n }\n\n if (nextLength > previousLength) {\n store.itemsChanged(previousLength, 0, nextLength - previousLength);\n }\n}\n\nfunction extendRuns(runs: SlotRun[], slot: number): void {\n const last = runs.at(-1);\n\n if (last !== undefined && last.start + last.length === slot) {\n last.length += 1;\n\n return;\n }\n\n runs.push({ start: slot, length: 1 });\n}\n\nfunction collectFlipRuns(flipped: Set<number>): SlotRun[] {\n const runs: SlotRun[] = [];\n\n for (const slot of flipped) {\n extendRuns(runs, slot);\n }\n\n return runs;\n}\n\nfunction emitFlips(store: LevelStore, flipped: Set<number>): void {\n for (const run of collectFlipRuns(flipped)) {\n store.itemsChanged(run.start, run.length, run.length);\n }\n}\n\nfunction stepChildStore(context: SyncContext, store: LevelStore, slot: number, flipped: Set<number>): void {\n const child = store.childStores[slot];\n\n if (child == null || flipped.has(slot)) {\n return;\n }\n\n const level = context.index.children.get(slotPathAt(store, slot));\n\n if (level !== undefined) {\n syncLevel(context, child, level);\n }\n}\n\nfunction syncLevel(context: SyncContext, store: LevelStore, level: Level): void {\n const previousLength = store.refs.length;\n const overlap = Math.min(previousLength, level.items.length);\n const flipped = syncOverlap(context, store, level);\n shrinkStore(context, store, level.items.length);\n growStore(context, store, level);\n emitTailSplice(store, previousLength, level.items.length);\n emitFlips(store, flipped);\n\n for (let slot = 0; slot < overlap; slot++) {\n stepChildStore(context, store, slot, flipped);\n }\n}\n\nfunction childStoreFor(object: GObject.Object): Gio.ListModel | null {\n const ref = slotRefFor(object);\n\n if (ref === null) {\n return null;\n }\n\n return ref.store.childStores[ref.slot] ?? null;\n}\n\nfunction ensureTree(state: ModelState, first: LevelStore): Gtk.TreeListModel {\n if (state.tree === null || state.treeRoot !== first) {\n state.tree = Gtk.TreeListModel.new(first, false, false, (object) => childStoreFor(object));\n state.treeRoot = first;\n }\n\n return state.tree;\n}\n\nfunction desiredRootModels(state: ModelState, index: CollectionIndex): GObject.Object[] {\n const [first] = state.groupStores;\n\n if (first !== undefined && index.isTree) {\n return [ensureTree(state, first)];\n }\n\n return [...state.groupStores];\n}\n\nfunction hasSameModels(previous: GObject.Object[], next: GObject.Object[]): boolean {\n return previous.length === next.length && next.every((model, index) => previous[index] === model);\n}\n\nfunction syncRoot(state: ModelState, index: CollectionIndex): void {\n const next = desiredRootModels(state, index);\n\n if (hasSameModels(state.rootModels, next)) {\n return;\n }\n\n state.root.splice(0, state.rootModels.length, next);\n state.rootModels = next;\n resetExpansion(state.expansion);\n}\n\nfunction adjustGroupStores(state: ModelState, context: SyncContext): void {\n const { groups } = context.index;\n state.groupStores.length = Math.min(state.groupStores.length, groups.length);\n\n for (const level of groups.slice(state.groupStores.length)) {\n const store = newLevelStore(level.path);\n growStore(context, store, level);\n state.groupStores.push(store);\n }\n}\n\nfunction stepGroupStores(state: ModelState, context: SyncContext, surviving: number): void {\n for (const [group, level] of context.index.groups.entries()) {\n const store = state.groupStores[group];\n\n if (store !== undefined && group < surviving) {\n syncLevel(context, store, level);\n }\n }\n}\n\nfunction syncModel(state: ModelState, index: CollectionIndex): void {\n const context: SyncContext = { index, expansion: state.expansion };\n const surviving = Math.min(state.groupStores.length, index.groups.length);\n state.expansion.isSyncing = true;\n\n try {\n adjustGroupStores(state, context);\n syncRoot(state, index);\n stepGroupStores(state, context, surviving);\n } finally {\n state.expansion.isSyncing = false;\n }\n\n adoptIndex(state.expansion, index);\n}\n\nfunction createCollectionModel(): CollectionModel {\n registeredStoreClass();\n const root = newRootStore();\n\n const state: ModelState = {\n root,\n rootModels: [],\n model: Gtk.FlattenListModel.new(root),\n groupStores: [],\n tree: null,\n treeRoot: null,\n expansion: createTreeExpansion(EMPTY_INDEX),\n };\n\n return {\n model: state.model,\n expansion: state.expansion,\n treeModel: () => state.tree,\n sync: (index) => {\n syncModel(state, index);\n },\n };\n}\n\nclass LazyLevelStore extends GObject.Object implements Gio.ListModelImpl {\n declare itemsChanged: Gio.ListModel[\"itemsChanged\"];\n path = \"\";\n refs: SlotRef[] = [];\n objects: (Gtk.StringObject | null)[] = [];\n childStores: (LevelStore | null)[] = [];\n expandableFlags: boolean[] = [];\n\n private createItem(position: number, ref: SlotRef): Gtk.StringObject {\n const created = Gtk.StringObject.new(\"\");\n this.objects[position] = created;\n SLOTS.set(created, ref);\n\n return created;\n }\n\n vfuncGetItemType(): bigint {\n return GObject.TYPE_OBJECT;\n }\n\n vfuncGetNItems(): number {\n return this.refs.length;\n }\n\n vfuncGetItem(position: number): GObject.Object | null {\n const ref = this.refs[position];\n\n if (ref === undefined) {\n return null;\n }\n\n return this.objects[position] ?? this.createItem(position, ref);\n }\n}\n\nexport { createCollectionModel, slotPathAt, slotRefFor, type CollectionModel, type SlotRef };\n"]}
|
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import type { Item } from "../types.js";
|
|
1
|
+
import type { ListItem } from "../types.js";
|
|
3
2
|
import type { CollectionIndex } from "./collection-index.js";
|
|
4
|
-
import type { CollectionModel } from "./collection-model.js";
|
|
5
|
-
type Collection = {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
treeModel: () => Gtk.TreeListModel | null;
|
|
9
|
-
itemFor: (id: string) => Item | undefined;
|
|
10
|
-
sectionFor: (id: string) => unknown;
|
|
3
|
+
import type { CollectionModel, SlotRef } from "./collection-model.js";
|
|
4
|
+
type Collection = Pick<CollectionModel, "model" | "expansion" | "treeModel"> & {
|
|
5
|
+
itemAt: (ref: SlotRef) => ListItem | undefined;
|
|
6
|
+
sectionFor: (levelPath: string) => unknown;
|
|
11
7
|
idAt: (position: number) => string | null;
|
|
8
|
+
pathAt: (position: number) => string | null;
|
|
12
9
|
positionFor: (id: string) => number;
|
|
13
10
|
positionsFor: (ids: string[]) => number[];
|
|
14
11
|
};
|
|
15
|
-
declare function
|
|
16
|
-
declare function createCollection(
|
|
17
|
-
export { createCollection,
|
|
12
|
+
declare function isCollectionIdle(collection: Collection): boolean;
|
|
13
|
+
declare function createCollection(collectionModel: CollectionModel, index: CollectionIndex): Collection;
|
|
14
|
+
export { createCollection, isCollectionIdle, type Collection };
|
|
18
15
|
//# sourceMappingURL=collection.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../../src/internal/collection.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../../src/internal/collection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAItE,KAAK,UAAU,GAAG,IAAI,CAAC,eAAe,EAAE,OAAO,GAAG,WAAW,GAAG,WAAW,CAAC,GAAG;IAC3E,MAAM,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,QAAQ,GAAG,SAAS,CAAC;IAC/C,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;IAC3C,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAC1C,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAC5C,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC;IACpC,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;CAC7C,CAAC;AAgDF,iBAAS,gBAAgB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAIzD;AAED,iBAAS,gBAAgB,CAAC,eAAe,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,GAAG,UAAU,CAY9F;AAED,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,KAAK,UAAU,EAAE,CAAC"}
|