@gtkx/react 0.18.9 → 0.20.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/dist/components/list.d.ts +35 -0
- package/dist/components/list.d.ts.map +1 -0
- package/dist/components/list.js +40 -0
- package/dist/components/list.js.map +1 -0
- package/dist/generated/internal.d.ts +8 -3
- package/dist/generated/internal.d.ts.map +1 -1
- package/dist/generated/internal.js +3553 -53
- package/dist/generated/internal.js.map +1 -1
- package/dist/generated/jsx.d.ts +178 -326
- package/dist/generated/jsx.d.ts.map +1 -1
- package/dist/generated/jsx.js +0 -324
- package/dist/generated/jsx.js.map +1 -1
- package/dist/host-config.d.ts.map +1 -1
- package/dist/host-config.js +48 -10
- package/dist/host-config.js.map +1 -1
- package/dist/jsx.d.ts +111 -54
- package/dist/jsx.d.ts.map +1 -1
- package/dist/jsx.js +3 -28
- package/dist/jsx.js.map +1 -1
- package/dist/metadata.d.ts +1 -0
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js +7 -1
- package/dist/metadata.js.map +1 -1
- package/dist/node.d.ts +0 -2
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +19 -25
- package/dist/node.js.map +1 -1
- package/dist/nodes/application.d.ts.map +1 -1
- package/dist/nodes/application.js +4 -0
- package/dist/nodes/application.js.map +1 -1
- package/dist/nodes/column-view-column.d.ts +19 -16
- package/dist/nodes/column-view-column.d.ts.map +1 -1
- package/dist/nodes/column-view-column.js +129 -97
- package/dist/nodes/column-view-column.js.map +1 -1
- package/dist/nodes/event-controller.d.ts +1 -0
- package/dist/nodes/event-controller.d.ts.map +1 -1
- package/dist/nodes/event-controller.js +9 -7
- package/dist/nodes/event-controller.js.map +1 -1
- package/dist/nodes/fixed-child.d.ts +1 -2
- package/dist/nodes/fixed-child.d.ts.map +1 -1
- package/dist/nodes/fixed-child.js +21 -21
- package/dist/nodes/fixed-child.js.map +1 -1
- package/dist/nodes/font-dialog-button.d.ts +1 -1
- package/dist/nodes/font-dialog-button.d.ts.map +1 -1
- package/dist/nodes/font-dialog-button.js +8 -0
- package/dist/nodes/font-dialog-button.js.map +1 -1
- package/dist/nodes/internal/accessible.d.ts +5 -0
- package/dist/nodes/internal/accessible.d.ts.map +1 -0
- package/dist/nodes/internal/accessible.js +119 -0
- package/dist/nodes/internal/accessible.js.map +1 -0
- package/dist/nodes/internal/bound-item.d.ts +4 -0
- package/dist/nodes/internal/bound-item.d.ts.map +1 -0
- package/dist/nodes/internal/bound-item.js +2 -0
- package/dist/nodes/internal/bound-item.js.map +1 -0
- package/dist/nodes/internal/construct.d.ts +3 -0
- package/dist/nodes/internal/construct.d.ts.map +1 -0
- package/dist/nodes/internal/construct.js +44 -0
- package/dist/nodes/internal/construct.js.map +1 -0
- package/dist/nodes/internal/text-buffer-controller.d.ts +4 -0
- package/dist/nodes/internal/text-buffer-controller.d.ts.map +1 -1
- package/dist/nodes/internal/text-buffer-controller.js +49 -9
- package/dist/nodes/internal/text-buffer-controller.js.map +1 -1
- package/dist/nodes/internal/widget.d.ts.map +1 -1
- package/dist/nodes/internal/widget.js +4 -1
- package/dist/nodes/internal/widget.js.map +1 -1
- package/dist/nodes/list-item-node.d.ts +12 -0
- package/dist/nodes/list-item-node.d.ts.map +1 -0
- package/dist/nodes/list-item-node.js +23 -0
- package/dist/nodes/list-item-node.js.map +1 -0
- package/dist/nodes/list.d.ts +100 -0
- package/dist/nodes/list.d.ts.map +1 -0
- package/dist/nodes/list.js +950 -0
- package/dist/nodes/list.js.map +1 -0
- package/dist/nodes/notebook-page.d.ts.map +1 -1
- package/dist/nodes/notebook-page.js +4 -0
- package/dist/nodes/notebook-page.js.map +1 -1
- package/dist/nodes/shortcut.d.ts +3 -2
- package/dist/nodes/shortcut.d.ts.map +1 -1
- package/dist/nodes/shortcut.js +19 -4
- package/dist/nodes/shortcut.js.map +1 -1
- package/dist/nodes/text-anchor.d.ts.map +1 -1
- package/dist/nodes/text-anchor.js +7 -1
- package/dist/nodes/text-anchor.js.map +1 -1
- package/dist/nodes/text-tag.d.ts.map +1 -1
- package/dist/nodes/text-tag.js +5 -1
- package/dist/nodes/text-tag.js.map +1 -1
- package/dist/nodes/text-view.d.ts +1 -0
- package/dist/nodes/text-view.d.ts.map +1 -1
- package/dist/nodes/text-view.js +4 -0
- package/dist/nodes/text-view.js.map +1 -1
- package/dist/nodes/widget.d.ts +0 -2
- package/dist/nodes/widget.d.ts.map +1 -1
- package/dist/nodes/widget.js +51 -67
- package/dist/nodes/widget.js.map +1 -1
- package/dist/nodes/window.d.ts.map +1 -1
- package/dist/nodes/window.js +2 -2
- package/dist/nodes/window.js.map +1 -1
- package/dist/registry.d.ts +0 -2
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +4 -13
- package/dist/registry.js.map +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -4
- package/src/components/list.tsx +83 -0
- package/src/generated/internal.ts +3559 -49
- package/src/generated/jsx.ts +178 -326
- package/src/host-config.ts +43 -10
- package/src/jsx.ts +121 -62
- package/src/metadata.ts +8 -1
- package/src/node.ts +23 -25
- package/src/nodes/application.ts +5 -0
- package/src/nodes/column-view-column.ts +125 -104
- package/src/nodes/event-controller.ts +8 -8
- package/src/nodes/fixed-child.ts +24 -23
- package/src/nodes/font-dialog-button.ts +10 -0
- package/src/nodes/internal/accessible.ts +155 -0
- package/src/nodes/internal/bound-item.ts +4 -0
- package/src/nodes/internal/construct.ts +60 -0
- package/src/nodes/internal/text-buffer-controller.ts +51 -8
- package/src/nodes/internal/widget.ts +3 -1
- package/src/nodes/list-item-node.ts +29 -0
- package/src/nodes/list.ts +1082 -0
- package/src/nodes/notebook-page.ts +4 -0
- package/src/nodes/shortcut.ts +22 -5
- package/src/nodes/text-anchor.ts +6 -1
- package/src/nodes/text-tag.ts +7 -1
- package/src/nodes/text-view.ts +5 -0
- package/src/nodes/widget.ts +47 -69
- package/src/nodes/window.ts +2 -2
- package/src/registry.ts +11 -17
- package/src/types.ts +7 -2
- package/dist/fiber-root.d.ts +0 -4
- package/dist/fiber-root.d.ts.map +0 -1
- package/dist/fiber-root.js +0 -6
- package/dist/fiber-root.js.map +0 -1
- package/dist/nodes/column-view.d.ts +0 -36
- package/dist/nodes/column-view.d.ts.map +0 -1
- package/dist/nodes/column-view.js +0 -175
- package/dist/nodes/column-view.js.map +0 -1
- package/dist/nodes/drop-down.d.ts +0 -27
- package/dist/nodes/drop-down.d.ts.map +0 -1
- package/dist/nodes/drop-down.js +0 -85
- package/dist/nodes/drop-down.js.map +0 -1
- package/dist/nodes/grid-view.d.ts +0 -29
- package/dist/nodes/grid-view.d.ts.map +0 -1
- package/dist/nodes/grid-view.js +0 -85
- package/dist/nodes/grid-view.js.map +0 -1
- package/dist/nodes/internal/base-item-renderer.d.ts +0 -28
- package/dist/nodes/internal/base-item-renderer.d.ts.map +0 -1
- package/dist/nodes/internal/base-item-renderer.js +0 -86
- package/dist/nodes/internal/base-item-renderer.js.map +0 -1
- package/dist/nodes/internal/grid-item-renderer.d.ts +0 -20
- package/dist/nodes/internal/grid-item-renderer.d.ts.map +0 -1
- package/dist/nodes/internal/grid-item-renderer.js +0 -66
- package/dist/nodes/internal/grid-item-renderer.js.map +0 -1
- package/dist/nodes/internal/list-item-renderer.d.ts +0 -27
- package/dist/nodes/internal/list-item-renderer.d.ts.map +0 -1
- package/dist/nodes/internal/list-item-renderer.js +0 -131
- package/dist/nodes/internal/list-item-renderer.js.map +0 -1
- package/dist/nodes/internal/list-store.d.ts +0 -22
- package/dist/nodes/internal/list-store.d.ts.map +0 -1
- package/dist/nodes/internal/list-store.js +0 -91
- package/dist/nodes/internal/list-store.js.map +0 -1
- package/dist/nodes/internal/selection-model-controller.d.ts +0 -26
- package/dist/nodes/internal/selection-model-controller.d.ts.map +0 -1
- package/dist/nodes/internal/selection-model-controller.js +0 -79
- package/dist/nodes/internal/selection-model-controller.js.map +0 -1
- package/dist/nodes/internal/simple-list-store.d.ts +0 -20
- package/dist/nodes/internal/simple-list-store.d.ts.map +0 -1
- package/dist/nodes/internal/simple-list-store.js +0 -87
- package/dist/nodes/internal/simple-list-store.js.map +0 -1
- package/dist/nodes/internal/tree-store.d.ts +0 -34
- package/dist/nodes/internal/tree-store.d.ts.map +0 -1
- package/dist/nodes/internal/tree-store.js +0 -208
- package/dist/nodes/internal/tree-store.js.map +0 -1
- package/dist/nodes/list-item.d.ts +0 -24
- package/dist/nodes/list-item.d.ts.map +0 -1
- package/dist/nodes/list-item.js +0 -83
- package/dist/nodes/list-item.js.map +0 -1
- package/dist/nodes/list-view.d.ts +0 -29
- package/dist/nodes/list-view.d.ts.map +0 -1
- package/dist/nodes/list-view.js +0 -83
- package/dist/nodes/list-view.js.map +0 -1
- package/dist/nodes/models/grid.d.ts +0 -28
- package/dist/nodes/models/grid.d.ts.map +0 -1
- package/dist/nodes/models/grid.js +0 -69
- package/dist/nodes/models/grid.js.map +0 -1
- package/dist/nodes/models/list.d.ts +0 -31
- package/dist/nodes/models/list.d.ts.map +0 -1
- package/dist/nodes/models/list.js +0 -93
- package/dist/nodes/models/list.js.map +0 -1
- package/dist/nodes/shortcut-controller.d.ts +0 -10
- package/dist/nodes/shortcut-controller.d.ts.map +0 -1
- package/dist/nodes/shortcut-controller.js +0 -23
- package/dist/nodes/shortcut-controller.js.map +0 -1
- package/src/fiber-root.ts +0 -20
- package/src/nodes/column-view.ts +0 -217
- package/src/nodes/drop-down.ts +0 -108
- package/src/nodes/grid-view.ts +0 -109
- package/src/nodes/internal/base-item-renderer.ts +0 -108
- package/src/nodes/internal/grid-item-renderer.ts +0 -78
- package/src/nodes/internal/list-item-renderer.ts +0 -162
- package/src/nodes/internal/list-store.ts +0 -105
- package/src/nodes/internal/selection-model-controller.ts +0 -115
- package/src/nodes/internal/simple-list-store.ts +0 -99
- package/src/nodes/internal/tree-store.ts +0 -237
- package/src/nodes/list-item.ts +0 -107
- package/src/nodes/list-view.ts +0 -113
- package/src/nodes/models/grid.ts +0 -105
- package/src/nodes/models/list.ts +0 -140
- package/src/nodes/shortcut-controller.ts +0 -27
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import * as Gtk from "@gtkx/ffi/gtk";
|
|
2
|
-
import type { ReactNode } from "react";
|
|
3
|
-
import type Reconciler from "react-reconciler";
|
|
4
|
-
import { reconciler } from "../../reconciler.js";
|
|
5
|
-
import { BaseItemRenderer } from "./base-item-renderer.js";
|
|
6
|
-
import type { TreeStore } from "./tree-store.js";
|
|
7
|
-
|
|
8
|
-
type RenderItemFn<T> = (item: T | null, row: Gtk.TreeListRow | null) => ReactNode;
|
|
9
|
-
|
|
10
|
-
type PendingBind = {
|
|
11
|
-
treeListRow: Gtk.TreeListRow;
|
|
12
|
-
expander: Gtk.TreeExpander;
|
|
13
|
-
id: string;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export class ListItemRenderer extends BaseItemRenderer<TreeStore> {
|
|
17
|
-
private expanders = new Map<Gtk.ListItem, Gtk.TreeExpander>();
|
|
18
|
-
private setupComplete = new Set<Gtk.ListItem>();
|
|
19
|
-
private pendingBinds = new Map<Gtk.ListItem, PendingBind>();
|
|
20
|
-
private renderFn: RenderItemFn<unknown> | null = () => null;
|
|
21
|
-
private boundItems = new Map<string, { listItem: Gtk.ListItem; treeListRow: Gtk.TreeListRow }>();
|
|
22
|
-
|
|
23
|
-
public setRenderFn(renderFn: RenderItemFn<unknown> | null): void {
|
|
24
|
-
this.renderFn = renderFn;
|
|
25
|
-
this.rebindAllItems();
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
public rebindAllItems(): void {
|
|
29
|
-
for (const id of this.boundItems.keys()) {
|
|
30
|
-
this.rebindItem(id);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
public rebindItem(id: string): void {
|
|
35
|
-
const binding = this.boundItems.get(id);
|
|
36
|
-
if (!binding) return;
|
|
37
|
-
|
|
38
|
-
const fiberRoot = this.fiberRoots.get(binding.listItem);
|
|
39
|
-
if (!fiberRoot) return;
|
|
40
|
-
|
|
41
|
-
const expander = this.expanders.get(binding.listItem);
|
|
42
|
-
if (!expander) return;
|
|
43
|
-
|
|
44
|
-
this.renderBind(binding.listItem, expander, binding.treeListRow, id, fiberRoot);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
public override dispose(): void {
|
|
48
|
-
super.dispose();
|
|
49
|
-
this.expanders.clear();
|
|
50
|
-
this.setupComplete.clear();
|
|
51
|
-
this.pendingBinds.clear();
|
|
52
|
-
this.boundItems.clear();
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
protected override renderItem(_listItem: Gtk.ListItem): ReactNode {
|
|
56
|
-
return this.renderFn?.(null, null);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
protected override onSetup(listItem: Gtk.ListItem): Gtk.Widget {
|
|
60
|
-
const expander = new Gtk.TreeExpander();
|
|
61
|
-
const box = this.createBox();
|
|
62
|
-
expander.setChild(box);
|
|
63
|
-
listItem.setChild(expander);
|
|
64
|
-
this.expanders.set(listItem, expander);
|
|
65
|
-
return box;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
protected override onSetupComplete(listItem: Gtk.ListItem): void {
|
|
69
|
-
this.setupComplete.add(listItem);
|
|
70
|
-
this.processPendingBind(listItem);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
protected override onBind(listItem: Gtk.ListItem, fiberRoot: Reconciler.FiberRoot): void {
|
|
74
|
-
const expander = this.expanders.get(listItem);
|
|
75
|
-
if (!expander) return;
|
|
76
|
-
|
|
77
|
-
const treeListRow = listItem.getItem();
|
|
78
|
-
if (!(treeListRow instanceof Gtk.TreeListRow)) return;
|
|
79
|
-
|
|
80
|
-
expander.setListRow(treeListRow);
|
|
81
|
-
|
|
82
|
-
const stringObject = treeListRow.getItem();
|
|
83
|
-
if (!(stringObject instanceof Gtk.StringObject)) return;
|
|
84
|
-
|
|
85
|
-
const id = stringObject.getString();
|
|
86
|
-
this.boundItems.set(id, { listItem, treeListRow });
|
|
87
|
-
|
|
88
|
-
if (!this.setupComplete.has(listItem)) {
|
|
89
|
-
this.pendingBinds.set(listItem, { treeListRow, expander, id });
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
this.renderBind(listItem, expander, treeListRow, id, fiberRoot);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
protected override onUnbind(listItem: Gtk.ListItem): void {
|
|
97
|
-
const expander = listItem.getChild();
|
|
98
|
-
if (expander instanceof Gtk.TreeExpander) {
|
|
99
|
-
expander.setListRow(null);
|
|
100
|
-
const treeListRow = listItem.getItem();
|
|
101
|
-
if (treeListRow instanceof Gtk.TreeListRow) {
|
|
102
|
-
const stringObject = treeListRow.getItem();
|
|
103
|
-
if (stringObject instanceof Gtk.StringObject) {
|
|
104
|
-
this.boundItems.delete(stringObject.getString());
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
protected override onTeardown(listItem: Gtk.ListItem): void {
|
|
111
|
-
this.expanders.delete(listItem);
|
|
112
|
-
this.setupComplete.delete(listItem);
|
|
113
|
-
this.pendingBinds.delete(listItem);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
private processPendingBind(listItem: Gtk.ListItem): void {
|
|
117
|
-
const pending = this.pendingBinds.get(listItem);
|
|
118
|
-
if (!pending) return;
|
|
119
|
-
|
|
120
|
-
this.pendingBinds.delete(listItem);
|
|
121
|
-
const fiberRoot = this.fiberRoots.get(listItem);
|
|
122
|
-
if (fiberRoot) {
|
|
123
|
-
this.renderBind(listItem, pending.expander, pending.treeListRow, pending.id, fiberRoot);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
private renderBind(
|
|
128
|
-
listItem: Gtk.ListItem,
|
|
129
|
-
expander: Gtk.TreeExpander,
|
|
130
|
-
treeListRow: Gtk.TreeListRow,
|
|
131
|
-
id: string,
|
|
132
|
-
fiberRoot: Reconciler.FiberRoot,
|
|
133
|
-
): void {
|
|
134
|
-
const itemData = this.getStore().getItem(id);
|
|
135
|
-
|
|
136
|
-
if (itemData) {
|
|
137
|
-
expander.setIndentForDepth(itemData.indentForDepth ?? true);
|
|
138
|
-
expander.setHideExpander(itemData.hideExpander ?? false);
|
|
139
|
-
|
|
140
|
-
if (itemData.indentForIcon !== undefined) {
|
|
141
|
-
expander.setIndentForIcon(itemData.indentForIcon);
|
|
142
|
-
} else {
|
|
143
|
-
expander.setIndentForIcon(treeListRow.isExpandable());
|
|
144
|
-
}
|
|
145
|
-
} else {
|
|
146
|
-
expander.setIndentForIcon(treeListRow.isExpandable());
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
const element = this.renderFn?.(itemData?.value ?? null, treeListRow);
|
|
150
|
-
|
|
151
|
-
reconciler.getInstance().updateContainer(element, fiberRoot, null, () => {
|
|
152
|
-
if (this.tornDown.has(listItem)) return;
|
|
153
|
-
if (this.estimatedItemHeight !== null) return;
|
|
154
|
-
const currentExpander = this.expanders.get(listItem);
|
|
155
|
-
if (!currentExpander) return;
|
|
156
|
-
const box = currentExpander.getChild();
|
|
157
|
-
if (box) {
|
|
158
|
-
this.clearBoxSizeRequest(box);
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
}
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import * as Gtk from "@gtkx/ffi/gtk";
|
|
2
|
-
|
|
3
|
-
type ItemUpdatedCallback = (id: string) => void;
|
|
4
|
-
|
|
5
|
-
export class ListStore {
|
|
6
|
-
private model = new Gtk.StringList();
|
|
7
|
-
private ids: string[] = [];
|
|
8
|
-
private idToIndex = new Map<string, number>();
|
|
9
|
-
private items = new Map<string, unknown>();
|
|
10
|
-
private onItemUpdated: ItemUpdatedCallback | null = null;
|
|
11
|
-
private pendingBatch: string[] | null = null;
|
|
12
|
-
|
|
13
|
-
public setOnItemUpdated(callback: ItemUpdatedCallback | null): void {
|
|
14
|
-
this.onItemUpdated = callback;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
public beginBatch(): void {
|
|
18
|
-
this.pendingBatch = [];
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
public flushBatch(): void {
|
|
22
|
-
const batch = this.pendingBatch;
|
|
23
|
-
this.pendingBatch = null;
|
|
24
|
-
if (batch && batch.length > 0) {
|
|
25
|
-
this.model.splice(0, 0, batch);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
public addItem(id: string, item: unknown): void {
|
|
30
|
-
this.items.set(id, item);
|
|
31
|
-
|
|
32
|
-
const existingIndex = this.idToIndex.get(id);
|
|
33
|
-
if (existingIndex !== undefined) {
|
|
34
|
-
this.model.remove(existingIndex);
|
|
35
|
-
this.ids.splice(existingIndex, 1);
|
|
36
|
-
this.rebuildIndices(existingIndex);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
this.idToIndex.set(id, this.ids.length);
|
|
40
|
-
this.ids.push(id);
|
|
41
|
-
|
|
42
|
-
if (this.pendingBatch) {
|
|
43
|
-
this.pendingBatch.push(id);
|
|
44
|
-
} else {
|
|
45
|
-
this.model.append(id);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
public removeItem(id: string): void {
|
|
50
|
-
const index = this.idToIndex.get(id);
|
|
51
|
-
if (index === undefined) return;
|
|
52
|
-
|
|
53
|
-
this.model.remove(index);
|
|
54
|
-
this.ids.splice(index, 1);
|
|
55
|
-
this.idToIndex.delete(id);
|
|
56
|
-
this.rebuildIndices(index);
|
|
57
|
-
this.items.delete(id);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
public insertItemBefore(id: string, beforeId: string, item: unknown): void {
|
|
61
|
-
this.items.set(id, item);
|
|
62
|
-
|
|
63
|
-
const existingIndex = this.idToIndex.get(id);
|
|
64
|
-
if (existingIndex !== undefined) {
|
|
65
|
-
this.model.remove(existingIndex);
|
|
66
|
-
this.ids.splice(existingIndex, 1);
|
|
67
|
-
this.idToIndex.delete(id);
|
|
68
|
-
this.rebuildIndices(existingIndex);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const beforeIndex = this.idToIndex.get(beforeId);
|
|
72
|
-
if (beforeIndex === undefined) {
|
|
73
|
-
this.idToIndex.set(id, this.ids.length);
|
|
74
|
-
this.ids.push(id);
|
|
75
|
-
this.model.append(id);
|
|
76
|
-
} else {
|
|
77
|
-
this.ids.splice(beforeIndex, 0, id);
|
|
78
|
-
this.rebuildIndices(beforeIndex);
|
|
79
|
-
this.model.splice(beforeIndex, 0, [id]);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
public updateItem(id: string, item: unknown): void {
|
|
84
|
-
if (this.items.has(id)) {
|
|
85
|
-
this.items.set(id, item);
|
|
86
|
-
this.onItemUpdated?.(id);
|
|
87
|
-
} else {
|
|
88
|
-
this.addItem(id, item);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
public getItem(id: string): unknown {
|
|
93
|
-
return this.items.get(id);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
public getModel(): Gtk.StringList {
|
|
97
|
-
return this.model;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
private rebuildIndices(fromIndex: number): void {
|
|
101
|
-
for (let i = fromIndex; i < this.ids.length; i++) {
|
|
102
|
-
this.idToIndex.set(this.ids[i] as string, i);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import type * as Gio from "@gtkx/ffi/gio";
|
|
2
|
-
import * as Gtk from "@gtkx/ffi/gtk";
|
|
3
|
-
import type { GtkListViewProps } from "../../jsx.js";
|
|
4
|
-
import type { SignalStore } from "./signal-store.js";
|
|
5
|
-
|
|
6
|
-
type SelectionModel = Gtk.NoSelection | Gtk.SingleSelection | Gtk.MultiSelection;
|
|
7
|
-
|
|
8
|
-
type SelectionModelConfig = Pick<GtkListViewProps, "selectionMode" | "selected" | "onSelectionChanged"> & {
|
|
9
|
-
owner: object;
|
|
10
|
-
signalStore: SignalStore;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export class SelectionModelController {
|
|
14
|
-
private owner: object;
|
|
15
|
-
private signalStore: SignalStore;
|
|
16
|
-
private selectionModel: SelectionModel;
|
|
17
|
-
private getSelection: () => string[];
|
|
18
|
-
private resolveSelectionIndices: (ids: string[]) => Gtk.Bitset;
|
|
19
|
-
private getItemCount: () => number;
|
|
20
|
-
|
|
21
|
-
constructor(
|
|
22
|
-
config: SelectionModelConfig,
|
|
23
|
-
model: Gio.ListModel,
|
|
24
|
-
getSelection: () => string[],
|
|
25
|
-
resolveSelectionIndices: (ids: string[]) => Gtk.Bitset,
|
|
26
|
-
getItemCount: () => number,
|
|
27
|
-
) {
|
|
28
|
-
this.owner = config.owner;
|
|
29
|
-
this.signalStore = config.signalStore;
|
|
30
|
-
this.selectionModel = this.createSelectionModel(config.selectionMode, model);
|
|
31
|
-
this.selectionModel.setModel(model);
|
|
32
|
-
this.getSelection = getSelection;
|
|
33
|
-
this.resolveSelectionIndices = resolveSelectionIndices;
|
|
34
|
-
this.getItemCount = getItemCount;
|
|
35
|
-
this.initSelectionHandler(config.onSelectionChanged);
|
|
36
|
-
this.setSelection(config.selected);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
public getSelectionModel(): SelectionModel {
|
|
40
|
-
return this.selectionModel;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
public update(
|
|
44
|
-
oldProps: SelectionModelConfig | null,
|
|
45
|
-
newProps: SelectionModelConfig,
|
|
46
|
-
model: Gio.ListModel,
|
|
47
|
-
): SelectionModel {
|
|
48
|
-
if (oldProps && oldProps.selectionMode !== newProps.selectionMode) {
|
|
49
|
-
this.signalStore.set(this.owner, this.selectionModel, "selection-changed", null);
|
|
50
|
-
this.selectionModel = this.createSelectionModel(newProps.selectionMode, model);
|
|
51
|
-
this.selectionModel.setModel(model);
|
|
52
|
-
this.initSelectionHandler(newProps.onSelectionChanged);
|
|
53
|
-
this.setSelection(newProps.selected);
|
|
54
|
-
return this.selectionModel;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (!oldProps || oldProps.onSelectionChanged !== newProps.onSelectionChanged) {
|
|
58
|
-
this.initSelectionHandler(newProps.onSelectionChanged);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (!oldProps || oldProps.selected !== newProps.selected) {
|
|
62
|
-
this.setSelection(newProps.selected);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return this.selectionModel;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
private initSelectionHandler(onSelectionChanged?: ((ids: string[]) => void) | null): void {
|
|
69
|
-
if (!onSelectionChanged) {
|
|
70
|
-
this.signalStore.set(this.owner, this.selectionModel, "selection-changed", null);
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const handler = () => {
|
|
75
|
-
onSelectionChanged(this.getSelection());
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
this.signalStore.set(this.owner, this.selectionModel, "selection-changed", handler);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
private createSelectionModel(mode: Gtk.SelectionMode | null | undefined, model: Gio.ListModel): SelectionModel {
|
|
82
|
-
const selectionMode = mode ?? Gtk.SelectionMode.SINGLE;
|
|
83
|
-
|
|
84
|
-
if (selectionMode === Gtk.SelectionMode.NONE) {
|
|
85
|
-
return new Gtk.NoSelection(model);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (selectionMode === Gtk.SelectionMode.MULTIPLE) {
|
|
89
|
-
return new Gtk.MultiSelection(model);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const selectionModel = new Gtk.SingleSelection(model);
|
|
93
|
-
selectionModel.setAutoselect(selectionMode === Gtk.SelectionMode.BROWSE);
|
|
94
|
-
selectionModel.setCanUnselect(selectionMode !== Gtk.SelectionMode.BROWSE);
|
|
95
|
-
|
|
96
|
-
return selectionModel;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
public reapplySelection(ids?: string[] | null): void {
|
|
100
|
-
this.setSelection(ids);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
private setSelection(ids?: string[] | null): void {
|
|
104
|
-
const nItems = this.getItemCount();
|
|
105
|
-
const selected = ids ? this.resolveSelectionIndices(ids) : new Gtk.Bitset();
|
|
106
|
-
const mask = Gtk.Bitset.newRange(0, nItems);
|
|
107
|
-
|
|
108
|
-
if (this.selectionModel instanceof Gtk.SingleSelection) {
|
|
109
|
-
const position = selected.getSize() > 0 ? selected.getNth(0) : Gtk.INVALID_LIST_POSITION;
|
|
110
|
-
this.selectionModel.setSelected(position);
|
|
111
|
-
} else {
|
|
112
|
-
this.selectionModel.setSelection(selected, mask);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import * as Gtk from "@gtkx/ffi/gtk";
|
|
2
|
-
|
|
3
|
-
export class SimpleListStore {
|
|
4
|
-
private ids: string[] = [];
|
|
5
|
-
private idToIndex = new Map<string, number>();
|
|
6
|
-
private model = new Gtk.StringList();
|
|
7
|
-
private pendingBatch: string[] | null = null;
|
|
8
|
-
|
|
9
|
-
public beginBatch(): void {
|
|
10
|
-
this.pendingBatch = [];
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
public flushBatch(): void {
|
|
14
|
-
const batch = this.pendingBatch;
|
|
15
|
-
this.pendingBatch = null;
|
|
16
|
-
if (batch && batch.length > 0) {
|
|
17
|
-
this.model.splice(0, 0, batch);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
public addItem(id: string, label: string): void {
|
|
22
|
-
this.idToIndex.set(id, this.ids.length);
|
|
23
|
-
this.ids.push(id);
|
|
24
|
-
|
|
25
|
-
if (this.pendingBatch) {
|
|
26
|
-
this.pendingBatch.push(label);
|
|
27
|
-
} else {
|
|
28
|
-
this.model.append(label);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
public appendItem(id: string, label: string): void {
|
|
33
|
-
const existingIndex = this.idToIndex.get(id);
|
|
34
|
-
|
|
35
|
-
if (existingIndex !== undefined) {
|
|
36
|
-
this.model.remove(existingIndex);
|
|
37
|
-
this.ids.splice(existingIndex, 1);
|
|
38
|
-
this.rebuildIndices(existingIndex);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
this.idToIndex.set(id, this.ids.length);
|
|
42
|
-
this.ids.push(id);
|
|
43
|
-
this.model.append(label);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
public removeItem(id: string): void {
|
|
47
|
-
const index = this.idToIndex.get(id);
|
|
48
|
-
if (index === undefined) return;
|
|
49
|
-
|
|
50
|
-
this.model.remove(index);
|
|
51
|
-
this.ids.splice(index, 1);
|
|
52
|
-
this.idToIndex.delete(id);
|
|
53
|
-
this.rebuildIndices(index);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
public insertItemBefore(id: string, beforeId: string, label: string): void {
|
|
57
|
-
const beforeIndex = this.idToIndex.get(beforeId);
|
|
58
|
-
if (beforeIndex === undefined) {
|
|
59
|
-
this.addItem(id, label);
|
|
60
|
-
} else {
|
|
61
|
-
this.ids.splice(beforeIndex, 0, id);
|
|
62
|
-
this.rebuildIndices(beforeIndex);
|
|
63
|
-
this.model.splice(beforeIndex, 0, [label]);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
public updateItem(id: string, label: string): void {
|
|
68
|
-
const index = this.idToIndex.get(id);
|
|
69
|
-
if (index === undefined) {
|
|
70
|
-
this.addItem(id, label);
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
this.model.splice(index, 1, [label]);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
public getItem(id: string) {
|
|
77
|
-
const index = this.idToIndex.get(id);
|
|
78
|
-
if (index === undefined) return null;
|
|
79
|
-
return this.model.getString(index);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
public getIdAtIndex(index: number): string | null {
|
|
83
|
-
return this.ids[index] ?? null;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
public getIndexById(id: string): number | null {
|
|
87
|
-
return this.idToIndex.get(id) ?? null;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
public getModel(): Gtk.StringList {
|
|
91
|
-
return this.model;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
private rebuildIndices(fromIndex: number): void {
|
|
95
|
-
for (let i = fromIndex; i < this.ids.length; i++) {
|
|
96
|
-
this.idToIndex.set(this.ids[i] as string, i);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|