@gtkx/react 0.15.0 → 0.17.1
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 +1 -0
- package/dist/animation/css-builder.d.ts +3 -0
- package/dist/animation/css-builder.js +53 -0
- package/dist/animation/types.d.ts +120 -0
- package/dist/errors.js +3 -0
- package/dist/factory.d.ts +3 -2
- package/dist/factory.js +1 -1
- package/dist/fiber-root.js +1 -1
- package/dist/generated/internal.d.ts +28 -1
- package/dist/generated/internal.js +93 -18
- package/dist/generated/jsx.d.ts +1672 -1483
- package/dist/generated/jsx.js +475 -0
- package/dist/host-config.d.ts +3 -1
- package/dist/host-config.js +26 -11
- package/dist/jsx.d.ts +136 -166
- package/dist/jsx.js +58 -69
- package/dist/node.d.ts +4 -1
- package/dist/node.js +14 -3
- package/dist/nodes/abstract/positional-child.d.ts +9 -0
- package/dist/nodes/abstract/positional-child.js +29 -0
- package/dist/nodes/abstract/virtual-container.d.ts +21 -0
- package/dist/nodes/abstract/virtual-container.js +68 -0
- package/dist/nodes/abstract/virtual-single-child.d.ts +18 -0
- package/dist/nodes/abstract/virtual-single-child.js +55 -0
- package/dist/nodes/action-row-child.d.ts +0 -13
- package/dist/nodes/action-row-child.js +22 -12
- package/dist/nodes/adjustable.d.ts +23 -0
- package/dist/nodes/adjustable.js +62 -0
- package/dist/nodes/alert-dialog-response.js +86 -0
- package/dist/nodes/animation.js +252 -0
- package/dist/nodes/application.js +17 -7
- package/dist/nodes/autowrapped.js +37 -43
- package/dist/nodes/calendar.js +17 -43
- package/dist/nodes/color-dialog-button.d.ts +1 -0
- package/dist/nodes/color-dialog-button.js +70 -0
- package/dist/nodes/column-view-column.d.ts +3 -3
- package/dist/nodes/column-view-column.js +1 -1
- package/dist/nodes/column-view.js +36 -39
- package/dist/nodes/dialog.d.ts +11 -0
- package/dist/nodes/dialog.js +20 -0
- package/dist/nodes/drawing-area.js +24 -7
- package/dist/nodes/event-controller.d.ts +22 -0
- package/dist/nodes/event-controller.js +96 -0
- package/dist/nodes/expander-row-child.d.ts +0 -14
- package/dist/nodes/expander-row-child.js +22 -12
- package/dist/nodes/fixed-child.js +52 -36
- package/dist/nodes/font-dialog-button.d.ts +1 -0
- package/dist/nodes/font-dialog-button.js +90 -0
- package/dist/nodes/grid-child.js +43 -45
- package/dist/nodes/grid.d.ts +1 -0
- package/dist/nodes/grid.js +41 -0
- package/dist/nodes/index.d.ts +18 -12
- package/dist/nodes/index.js +18 -12
- package/dist/nodes/internal/base-item-renderer.d.ts +29 -0
- package/dist/nodes/internal/base-item-renderer.js +88 -0
- package/dist/nodes/internal/child-attachment.d.ts +26 -0
- package/dist/nodes/internal/child-attachment.js +48 -0
- package/dist/nodes/internal/deferred-action.d.ts +9 -0
- package/dist/nodes/internal/deferred-action.js +22 -0
- package/dist/nodes/internal/list-item-renderer.d.ts +14 -15
- package/dist/nodes/internal/list-item-renderer.js +51 -77
- package/dist/nodes/internal/list-store.d.ts +5 -6
- package/dist/nodes/internal/list-store.js +29 -38
- package/dist/nodes/internal/predicates.d.ts +25 -2
- package/dist/nodes/internal/predicates.js +53 -41
- package/dist/nodes/internal/selection-model.d.ts +30 -0
- package/dist/nodes/internal/selection-model.js +87 -0
- package/dist/nodes/internal/signal-store.d.ts +9 -5
- package/dist/nodes/internal/signal-store.js +31 -31
- package/dist/nodes/internal/simple-list-store.js +6 -9
- package/dist/nodes/internal/text-buffer-controller.d.ts +43 -0
- package/dist/nodes/internal/text-buffer-controller.js +287 -0
- package/dist/nodes/internal/text-tag-styles.d.ts +43 -0
- package/dist/nodes/internal/text-tag-styles.js +52 -0
- package/dist/nodes/internal/tree-list-item-renderer.d.ts +15 -14
- package/dist/nodes/internal/tree-list-item-renderer.js +85 -96
- package/dist/nodes/internal/tree-store.d.ts +8 -11
- package/dist/nodes/internal/tree-store.js +70 -72
- package/dist/nodes/internal/utils.d.ts +7 -4
- package/dist/nodes/internal/utils.js +50 -5
- package/dist/nodes/level-bar.js +19 -54
- package/dist/nodes/list-item.d.ts +6 -3
- package/dist/nodes/list-item.js +7 -4
- package/dist/nodes/list-view.js +17 -12
- package/dist/nodes/menu.d.ts +3 -3
- package/dist/nodes/menu.js +3 -3
- package/dist/nodes/models/list.d.ts +11 -13
- package/dist/nodes/models/list.js +16 -73
- package/dist/nodes/models/menu.d.ts +8 -7
- package/dist/nodes/models/menu.js +43 -50
- package/dist/nodes/models/tree-list.d.ts +6 -12
- package/dist/nodes/models/tree-list.js +30 -93
- package/dist/nodes/navigation-page.d.ts +1 -0
- package/dist/nodes/navigation-page.js +27 -32
- package/dist/nodes/navigation-view.js +17 -28
- package/dist/nodes/notebook-page-tab.d.ts +3 -3
- package/dist/nodes/notebook-page-tab.js +11 -14
- package/dist/nodes/notebook-page.d.ts +7 -5
- package/dist/nodes/notebook-page.js +45 -25
- package/dist/nodes/notebook.js +2 -2
- package/dist/nodes/overlay-child.js +90 -30
- package/dist/nodes/pack-child.d.ts +0 -13
- package/dist/nodes/pack-child.js +22 -12
- package/dist/nodes/popover-menu.js +2 -2
- package/dist/nodes/scale.js +15 -45
- package/dist/nodes/scrolled-window.js +7 -6
- package/dist/nodes/search-bar.d.ts +1 -0
- package/dist/nodes/search-bar.js +40 -0
- package/dist/nodes/shortcut-controller.d.ts +1 -37
- package/dist/nodes/shortcut-controller.js +8 -47
- package/dist/nodes/shortcut.d.ts +5 -4
- package/dist/nodes/shortcut.js +11 -5
- package/dist/nodes/simple-list-view.js +2 -3
- package/dist/nodes/slot.d.ts +6 -9
- package/dist/nodes/slot.js +27 -42
- package/dist/nodes/source-view.js +80 -29
- package/dist/nodes/stack-page.js +20 -22
- package/dist/nodes/stack.js +19 -5
- package/dist/nodes/text-anchor.d.ts +41 -0
- package/dist/nodes/text-anchor.js +59 -0
- package/dist/nodes/text-content.d.ts +10 -0
- package/dist/nodes/text-content.js +1 -0
- package/dist/nodes/text-paintable.d.ts +17 -0
- package/dist/nodes/text-paintable.js +34 -0
- package/dist/nodes/text-segment.d.ts +15 -0
- package/dist/nodes/text-segment.js +29 -0
- package/dist/nodes/text-tag.d.ts +136 -0
- package/dist/nodes/text-tag.js +202 -0
- package/dist/nodes/text-view.d.ts +30 -0
- package/dist/nodes/text-view.js +49 -21
- package/dist/nodes/toggle-group.js +24 -32
- package/dist/nodes/toggle.d.ts +1 -15
- package/dist/nodes/toggle.js +40 -32
- package/dist/nodes/toolbar-child.js +22 -31
- package/dist/nodes/tree-list-item.d.ts +7 -5
- package/dist/nodes/tree-list-item.js +24 -36
- package/dist/nodes/tree-list-view.js +9 -7
- package/dist/nodes/virtual.d.ts +1 -1
- package/dist/nodes/web-view.d.ts +1 -0
- package/dist/nodes/web-view.js +29 -0
- package/dist/nodes/widget.d.ts +2 -16
- package/dist/nodes/widget.js +105 -294
- package/dist/nodes/window.d.ts +9 -3
- package/dist/nodes/window.js +29 -15
- package/dist/registry.d.ts +1 -1
- package/dist/render.js +9 -7
- package/dist/scheduler.d.ts +11 -1
- package/dist/scheduler.js +16 -4
- package/dist/types.d.ts +2 -136
- package/package.json +4 -4
- package/dist/nodes/action-row.js +0 -46
- package/dist/nodes/adjustment.d.ts +0 -48
- package/dist/nodes/adjustment.js +0 -70
- package/dist/nodes/calendar-mark.d.ts +0 -15
- package/dist/nodes/calendar-mark.js +0 -29
- package/dist/nodes/expander-row.js +0 -55
- package/dist/nodes/internal/constants.d.ts +0 -1
- package/dist/nodes/internal/constants.js +0 -24
- package/dist/nodes/level-bar-offset.d.ts +0 -13
- package/dist/nodes/level-bar-offset.js +0 -35
- package/dist/nodes/pack.js +0 -46
- package/dist/nodes/scale-mark.d.ts +0 -17
- package/dist/nodes/scale-mark.js +0 -38
- package/dist/nodes/source-buffer.d.ts +0 -73
- package/dist/nodes/source-buffer.js +0 -149
- package/dist/nodes/text-buffer.d.ts +0 -43
- package/dist/nodes/text-buffer.js +0 -81
- package/dist/nodes/virtual-child.d.ts +0 -18
- package/dist/nodes/virtual-child.js +0 -62
- /package/dist/{nodes/action-row.d.ts → animation/types.js} +0 -0
- /package/dist/nodes/{expander-row.d.ts → alert-dialog-response.d.ts} +0 -0
- /package/dist/nodes/{pack.d.ts → animation.d.ts} +0 -0
|
@@ -1,122 +1,109 @@
|
|
|
1
|
-
import { getNativeId } from "@gtkx/ffi";
|
|
2
1
|
import * as Gtk from "@gtkx/ffi/gtk";
|
|
3
|
-
import { createFiberRoot } from "../../fiber-root.js";
|
|
4
2
|
import { reconciler } from "../../reconciler.js";
|
|
5
|
-
import {
|
|
6
|
-
export class TreeListItemRenderer {
|
|
7
|
-
factory;
|
|
8
|
-
store;
|
|
9
|
-
fiberRoots = new Map();
|
|
3
|
+
import { BaseItemRenderer } from "./base-item-renderer.js";
|
|
4
|
+
export class TreeListItemRenderer extends BaseItemRenderer {
|
|
10
5
|
expanders = new Map();
|
|
11
6
|
setupComplete = new Set();
|
|
12
7
|
pendingBinds = new Map();
|
|
13
|
-
tornDown = new Set();
|
|
14
8
|
renderFn = () => null;
|
|
15
|
-
|
|
16
|
-
constructor() {
|
|
17
|
-
this.factory = new Gtk.SignalListItemFactory();
|
|
18
|
-
this.initialize();
|
|
19
|
-
}
|
|
20
|
-
getFactory() {
|
|
21
|
-
return this.factory;
|
|
22
|
-
}
|
|
9
|
+
boundItems = new Map();
|
|
23
10
|
setRenderFn(renderFn) {
|
|
24
11
|
this.renderFn = renderFn;
|
|
25
12
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
13
|
+
rebindItem(id) {
|
|
14
|
+
const binding = this.boundItems.get(id);
|
|
15
|
+
if (!binding)
|
|
16
|
+
return;
|
|
17
|
+
const fiberRoot = this.fiberRoots.get(binding.ptr);
|
|
18
|
+
if (!fiberRoot)
|
|
19
|
+
return;
|
|
20
|
+
const expander = this.expanders.get(binding.ptr);
|
|
21
|
+
if (!expander)
|
|
22
|
+
return;
|
|
23
|
+
this.renderBind(binding.ptr, expander, binding.treeListRow, id, fiberRoot);
|
|
31
24
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
throw new Error("Expected tree store to be set on TreeListItemRenderer");
|
|
35
|
-
}
|
|
36
|
-
return this.store;
|
|
25
|
+
getStoreTypeName() {
|
|
26
|
+
return "tree store";
|
|
37
27
|
}
|
|
38
28
|
dispose() {
|
|
39
|
-
|
|
40
|
-
this.fiberRoots.clear();
|
|
29
|
+
super.dispose();
|
|
41
30
|
this.expanders.clear();
|
|
42
31
|
this.setupComplete.clear();
|
|
43
32
|
this.pendingBinds.clear();
|
|
44
|
-
this.
|
|
33
|
+
this.boundItems.clear();
|
|
45
34
|
}
|
|
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
|
-
|
|
35
|
+
renderItem(_ptr) {
|
|
36
|
+
return this.renderFn?.(null, null);
|
|
37
|
+
}
|
|
38
|
+
getItemFromListItem(listItem) {
|
|
39
|
+
const treeListRow = listItem.getItem();
|
|
40
|
+
if (!(treeListRow instanceof Gtk.TreeListRow))
|
|
41
|
+
return null;
|
|
42
|
+
const stringObject = treeListRow.getItem();
|
|
43
|
+
if (!(stringObject instanceof Gtk.StringObject))
|
|
44
|
+
return null;
|
|
45
|
+
return this.getStore().getItem(stringObject.getString());
|
|
46
|
+
}
|
|
47
|
+
onSetup(listItem, ptr) {
|
|
48
|
+
const expander = new Gtk.TreeExpander();
|
|
49
|
+
const box = this.createBox();
|
|
50
|
+
expander.setChild(box);
|
|
51
|
+
listItem.setChild(expander);
|
|
52
|
+
this.expanders.set(ptr, expander);
|
|
53
|
+
return box;
|
|
54
|
+
}
|
|
55
|
+
onSetupComplete(ptr) {
|
|
56
|
+
this.setupComplete.add(ptr);
|
|
57
|
+
this.processPendingBind(ptr);
|
|
58
|
+
}
|
|
59
|
+
onBind(listItem, ptr, fiberRoot) {
|
|
60
|
+
const expander = this.expanders.get(ptr);
|
|
61
|
+
if (!expander)
|
|
62
|
+
return;
|
|
63
|
+
const treeListRow = listItem.getItem();
|
|
64
|
+
if (!(treeListRow instanceof Gtk.TreeListRow))
|
|
65
|
+
return;
|
|
66
|
+
expander.setListRow(treeListRow);
|
|
67
|
+
const stringObject = treeListRow.getItem();
|
|
68
|
+
if (!(stringObject instanceof Gtk.StringObject))
|
|
69
|
+
return;
|
|
70
|
+
const id = stringObject.getString();
|
|
71
|
+
this.boundItems.set(id, { ptr, treeListRow });
|
|
72
|
+
if (!this.setupComplete.has(ptr)) {
|
|
73
|
+
this.pendingBinds.set(ptr, { treeListRow, expander, id });
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
this.renderBind(ptr, expander, treeListRow, id, fiberRoot);
|
|
77
|
+
}
|
|
78
|
+
onUnbind(listItem) {
|
|
79
|
+
const expander = listItem.getChild();
|
|
80
|
+
if (expander instanceof Gtk.TreeExpander) {
|
|
81
|
+
expander.setListRow(null);
|
|
73
82
|
const treeListRow = listItem.getItem();
|
|
74
|
-
if (
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return;
|
|
80
|
-
const id = stringObject.getString();
|
|
81
|
-
if (!this.setupComplete.has(ptr)) {
|
|
82
|
-
this.pendingBinds.set(ptr, { treeListRow, expander, id });
|
|
83
|
-
return;
|
|
83
|
+
if (treeListRow instanceof Gtk.TreeListRow) {
|
|
84
|
+
const stringObject = treeListRow.getItem();
|
|
85
|
+
if (stringObject instanceof Gtk.StringObject) {
|
|
86
|
+
this.boundItems.delete(stringObject.getString());
|
|
87
|
+
}
|
|
84
88
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
signalStore.set(this, this.factory, "teardown", (_self, listItem) => {
|
|
94
|
-
const ptr = getNativeId(listItem.handle);
|
|
95
|
-
const fiberRoot = this.fiberRoots.get(ptr);
|
|
96
|
-
if (fiberRoot) {
|
|
97
|
-
this.tornDown.add(ptr);
|
|
98
|
-
reconciler.getInstance().updateContainer(null, fiberRoot, null, () => { });
|
|
99
|
-
queueMicrotask(() => {
|
|
100
|
-
this.fiberRoots.delete(ptr);
|
|
101
|
-
this.expanders.delete(ptr);
|
|
102
|
-
this.setupComplete.delete(ptr);
|
|
103
|
-
this.pendingBinds.delete(ptr);
|
|
104
|
-
this.tornDown.delete(ptr);
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
onTeardown(_listItem, ptr) {
|
|
92
|
+
this.expanders.delete(ptr);
|
|
93
|
+
this.setupComplete.delete(ptr);
|
|
94
|
+
this.pendingBinds.delete(ptr);
|
|
108
95
|
}
|
|
109
96
|
processPendingBind(ptr) {
|
|
110
97
|
const pending = this.pendingBinds.get(ptr);
|
|
111
98
|
if (!pending)
|
|
112
99
|
return;
|
|
113
100
|
this.pendingBinds.delete(ptr);
|
|
114
|
-
this.renderBind(ptr, pending.expander, pending.treeListRow, pending.id);
|
|
115
|
-
}
|
|
116
|
-
renderBind(ptr, expander, treeListRow, id) {
|
|
117
101
|
const fiberRoot = this.fiberRoots.get(ptr);
|
|
118
|
-
if (
|
|
119
|
-
|
|
102
|
+
if (fiberRoot) {
|
|
103
|
+
this.renderBind(ptr, pending.expander, pending.treeListRow, pending.id, fiberRoot);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
renderBind(ptr, expander, treeListRow, id, fiberRoot) {
|
|
120
107
|
const itemData = this.getStore().getItem(id);
|
|
121
108
|
if (itemData) {
|
|
122
109
|
if (itemData.indentForDepth !== undefined) {
|
|
@@ -133,12 +120,14 @@ export class TreeListItemRenderer {
|
|
|
133
120
|
reconciler.getInstance().updateContainer(element, fiberRoot, null, () => {
|
|
134
121
|
if (this.tornDown.has(ptr))
|
|
135
122
|
return;
|
|
123
|
+
if (this.estimatedItemHeight !== null)
|
|
124
|
+
return;
|
|
136
125
|
const currentExpander = this.expanders.get(ptr);
|
|
137
126
|
if (!currentExpander)
|
|
138
127
|
return;
|
|
139
128
|
const box = currentExpander.getChild();
|
|
140
|
-
if (box
|
|
141
|
-
|
|
129
|
+
if (box) {
|
|
130
|
+
this.clearBoxSizeRequest(box);
|
|
142
131
|
}
|
|
143
132
|
});
|
|
144
133
|
}
|
|
@@ -1,28 +1,25 @@
|
|
|
1
1
|
import * as Gtk from "@gtkx/ffi/gtk";
|
|
2
|
-
export
|
|
2
|
+
export type TreeItemUpdatedCallback = (id: string) => void;
|
|
3
|
+
export type TreeItemData<T = unknown> = {
|
|
3
4
|
value: T;
|
|
4
5
|
indentForDepth?: boolean;
|
|
5
6
|
indentForIcon?: boolean;
|
|
6
7
|
hideExpander?: boolean;
|
|
7
|
-
}
|
|
8
|
+
};
|
|
8
9
|
export declare class TreeStore {
|
|
9
|
-
private items;
|
|
10
10
|
private rootIds;
|
|
11
|
-
private newRootIds;
|
|
12
11
|
private children;
|
|
13
|
-
private newChildren;
|
|
14
12
|
private rootModel;
|
|
15
13
|
private childModels;
|
|
16
|
-
private
|
|
17
|
-
|
|
14
|
+
private items;
|
|
15
|
+
private onItemUpdated;
|
|
16
|
+
setOnItemUpdated(callback: TreeItemUpdatedCallback | null): void;
|
|
17
|
+
updateItem(id: string, item: TreeItemData): void;
|
|
18
18
|
addItem(id: string, data: TreeItemData, parentId?: string): void;
|
|
19
19
|
removeItem(id: string, parentId?: string): void;
|
|
20
20
|
insertItemBefore(id: string, beforeId: string, data: TreeItemData, parentId?: string): void;
|
|
21
|
-
|
|
22
|
-
getItem(id: string): TreeItemData | null;
|
|
21
|
+
getItem(id: string): TreeItemData | undefined;
|
|
23
22
|
getRootModel(): Gtk.StringList;
|
|
24
23
|
getChildrenModel(parentId: string): Gtk.StringList | null;
|
|
25
24
|
hasChildren(parentId: string): boolean;
|
|
26
|
-
private scheduleSync;
|
|
27
|
-
private sync;
|
|
28
25
|
}
|
|
@@ -1,112 +1,138 @@
|
|
|
1
|
-
import { batch } from "@gtkx/ffi";
|
|
2
1
|
import * as Gtk from "@gtkx/ffi/gtk";
|
|
3
|
-
import { CommitPriority, scheduleAfterCommit } from "../../scheduler.js";
|
|
4
2
|
export class TreeStore {
|
|
5
|
-
items = new Map();
|
|
6
3
|
rootIds = [];
|
|
7
|
-
newRootIds = [];
|
|
8
4
|
children = new Map();
|
|
9
|
-
|
|
10
|
-
rootModel;
|
|
5
|
+
rootModel = new Gtk.StringList();
|
|
11
6
|
childModels = new Map();
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
items = new Map();
|
|
8
|
+
onItemUpdated = null;
|
|
9
|
+
setOnItemUpdated(callback) {
|
|
10
|
+
this.onItemUpdated = callback;
|
|
11
|
+
}
|
|
12
|
+
updateItem(id, item) {
|
|
13
|
+
if (this.items.has(id)) {
|
|
14
|
+
this.items.set(id, item);
|
|
15
|
+
this.onItemUpdated?.(id);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
this.addItem(id, item);
|
|
19
|
+
}
|
|
15
20
|
}
|
|
16
21
|
addItem(id, data, parentId) {
|
|
17
22
|
this.items.set(id, data);
|
|
18
23
|
if (parentId === undefined) {
|
|
19
|
-
const existingIndex = this.
|
|
20
|
-
if (existingIndex
|
|
21
|
-
this.
|
|
24
|
+
const existingIndex = this.rootIds.indexOf(id);
|
|
25
|
+
if (existingIndex >= 0) {
|
|
26
|
+
this.rootModel.remove(existingIndex);
|
|
27
|
+
this.rootIds.splice(existingIndex, 1);
|
|
22
28
|
}
|
|
23
|
-
this.
|
|
29
|
+
this.rootIds.push(id);
|
|
30
|
+
this.rootModel.append(id);
|
|
24
31
|
}
|
|
25
32
|
else {
|
|
26
|
-
let siblings = this.
|
|
33
|
+
let siblings = this.children.get(parentId);
|
|
27
34
|
if (!siblings) {
|
|
28
35
|
siblings = [];
|
|
29
|
-
this.
|
|
36
|
+
this.children.set(parentId, siblings);
|
|
30
37
|
}
|
|
31
38
|
const existingIndex = siblings.indexOf(id);
|
|
32
|
-
if (existingIndex
|
|
39
|
+
if (existingIndex >= 0) {
|
|
40
|
+
const model = this.childModels.get(parentId);
|
|
41
|
+
if (model) {
|
|
42
|
+
model.remove(existingIndex);
|
|
43
|
+
}
|
|
33
44
|
siblings.splice(existingIndex, 1);
|
|
34
45
|
}
|
|
35
46
|
siblings.push(id);
|
|
47
|
+
let model = this.childModels.get(parentId);
|
|
48
|
+
if (!model) {
|
|
49
|
+
model = new Gtk.StringList();
|
|
50
|
+
this.childModels.set(parentId, model);
|
|
51
|
+
}
|
|
52
|
+
model.append(id);
|
|
36
53
|
}
|
|
37
|
-
this.scheduleSync();
|
|
38
54
|
}
|
|
39
55
|
removeItem(id, parentId) {
|
|
40
56
|
this.items.delete(id);
|
|
41
|
-
this.
|
|
57
|
+
this.children.delete(id);
|
|
58
|
+
this.childModels.delete(id);
|
|
42
59
|
if (parentId === undefined) {
|
|
43
|
-
const index = this.
|
|
44
|
-
if (index
|
|
45
|
-
this.
|
|
60
|
+
const index = this.rootIds.indexOf(id);
|
|
61
|
+
if (index >= 0) {
|
|
62
|
+
this.rootIds.splice(index, 1);
|
|
63
|
+
this.rootModel.remove(index);
|
|
46
64
|
}
|
|
47
65
|
}
|
|
48
66
|
else {
|
|
49
|
-
const siblings = this.
|
|
67
|
+
const siblings = this.children.get(parentId);
|
|
50
68
|
if (siblings) {
|
|
51
69
|
const index = siblings.indexOf(id);
|
|
52
|
-
if (index
|
|
70
|
+
if (index >= 0) {
|
|
53
71
|
siblings.splice(index, 1);
|
|
72
|
+
const model = this.childModels.get(parentId);
|
|
73
|
+
if (model) {
|
|
74
|
+
model.remove(index);
|
|
75
|
+
}
|
|
54
76
|
}
|
|
55
77
|
if (siblings.length === 0) {
|
|
56
|
-
this.
|
|
78
|
+
this.children.delete(parentId);
|
|
57
79
|
}
|
|
58
80
|
}
|
|
59
81
|
}
|
|
60
|
-
this.scheduleSync();
|
|
61
82
|
}
|
|
62
83
|
insertItemBefore(id, beforeId, data, parentId) {
|
|
63
84
|
this.items.set(id, data);
|
|
64
85
|
if (parentId === undefined) {
|
|
65
|
-
const existingIndex = this.
|
|
66
|
-
if (existingIndex
|
|
67
|
-
this.
|
|
86
|
+
const existingIndex = this.rootIds.indexOf(id);
|
|
87
|
+
if (existingIndex >= 0) {
|
|
88
|
+
this.rootModel.remove(existingIndex);
|
|
89
|
+
this.rootIds.splice(existingIndex, 1);
|
|
68
90
|
}
|
|
69
|
-
const beforeIndex = this.
|
|
70
|
-
if (beforeIndex
|
|
71
|
-
this.
|
|
91
|
+
const beforeIndex = this.rootIds.indexOf(beforeId);
|
|
92
|
+
if (beforeIndex < 0) {
|
|
93
|
+
this.rootIds.push(id);
|
|
94
|
+
this.rootModel.append(id);
|
|
72
95
|
}
|
|
73
96
|
else {
|
|
74
|
-
this.
|
|
97
|
+
this.rootIds.splice(beforeIndex, 0, id);
|
|
98
|
+
this.rootModel.splice(beforeIndex, 0, [id]);
|
|
75
99
|
}
|
|
76
100
|
}
|
|
77
101
|
else {
|
|
78
|
-
let siblings = this.
|
|
102
|
+
let siblings = this.children.get(parentId);
|
|
79
103
|
if (!siblings) {
|
|
80
104
|
siblings = [];
|
|
81
|
-
this.
|
|
105
|
+
this.children.set(parentId, siblings);
|
|
106
|
+
}
|
|
107
|
+
let model = this.childModels.get(parentId);
|
|
108
|
+
if (!model) {
|
|
109
|
+
model = new Gtk.StringList();
|
|
110
|
+
this.childModels.set(parentId, model);
|
|
82
111
|
}
|
|
83
112
|
const existingIndex = siblings.indexOf(id);
|
|
84
|
-
if (existingIndex
|
|
113
|
+
if (existingIndex >= 0) {
|
|
114
|
+
model.remove(existingIndex);
|
|
85
115
|
siblings.splice(existingIndex, 1);
|
|
86
116
|
}
|
|
87
117
|
const beforeIndex = siblings.indexOf(beforeId);
|
|
88
|
-
if (beforeIndex
|
|
118
|
+
if (beforeIndex < 0) {
|
|
89
119
|
siblings.push(id);
|
|
120
|
+
model.append(id);
|
|
90
121
|
}
|
|
91
122
|
else {
|
|
92
123
|
siblings.splice(beforeIndex, 0, id);
|
|
124
|
+
model.splice(beforeIndex, 0, [id]);
|
|
93
125
|
}
|
|
94
126
|
}
|
|
95
|
-
this.scheduleSync();
|
|
96
|
-
}
|
|
97
|
-
updateItem(id, data) {
|
|
98
|
-
if (this.items.has(id)) {
|
|
99
|
-
this.items.set(id, data);
|
|
100
|
-
}
|
|
101
127
|
}
|
|
102
128
|
getItem(id) {
|
|
103
|
-
return this.items.get(id)
|
|
129
|
+
return this.items.get(id);
|
|
104
130
|
}
|
|
105
131
|
getRootModel() {
|
|
106
132
|
return this.rootModel;
|
|
107
133
|
}
|
|
108
134
|
getChildrenModel(parentId) {
|
|
109
|
-
const childIds = this.children.get(parentId)
|
|
135
|
+
const childIds = this.children.get(parentId);
|
|
110
136
|
if (!childIds || childIds.length === 0) {
|
|
111
137
|
return null;
|
|
112
138
|
}
|
|
@@ -121,32 +147,4 @@ export class TreeStore {
|
|
|
121
147
|
const childIds = this.children.get(parentId);
|
|
122
148
|
return childIds !== undefined && childIds.length > 0;
|
|
123
149
|
}
|
|
124
|
-
scheduleSync() {
|
|
125
|
-
if (this.shouldSync) {
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
this.shouldSync = true;
|
|
129
|
-
scheduleAfterCommit(() => this.sync(), CommitPriority.LOW);
|
|
130
|
-
}
|
|
131
|
-
sync() {
|
|
132
|
-
this.shouldSync = false;
|
|
133
|
-
batch(() => {
|
|
134
|
-
const oldRootLength = this.rootIds.length;
|
|
135
|
-
this.rootModel.splice(0, oldRootLength, this.newRootIds.length > 0 ? this.newRootIds : undefined);
|
|
136
|
-
this.rootIds = [...this.newRootIds];
|
|
137
|
-
for (const [parentId, newChildIds] of this.newChildren) {
|
|
138
|
-
const model = this.childModels.get(parentId);
|
|
139
|
-
if (model) {
|
|
140
|
-
const oldLength = model.getNItems();
|
|
141
|
-
model.splice(0, oldLength, newChildIds.length > 0 ? newChildIds : undefined);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
for (const [parentId] of this.children) {
|
|
145
|
-
if (!this.newChildren.has(parentId)) {
|
|
146
|
-
this.childModels.delete(parentId);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
this.children = new Map(this.newChildren);
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
150
|
}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import type { Container, ContainerClass, Props } from "../../types.js";
|
|
2
2
|
type AnyClass = new (...args: any[]) => any;
|
|
3
3
|
export declare const matchesAnyClass: (classes: readonly AnyClass[], containerOrClass?: Container | ContainerClass | null) => boolean;
|
|
4
|
-
export declare const isContainerType: (cls: AnyClass, containerOrClass?: Container | ContainerClass | null) => boolean;
|
|
5
4
|
export declare const matchesInterface: (methods: readonly string[], containerOrClass?: Container | ContainerClass | null) => boolean;
|
|
6
|
-
export declare const filterProps: (props: Props, excludeKeys: string[]) => Props;
|
|
7
|
-
export declare const resolvePropMeta: (
|
|
8
|
-
export declare const resolveSignal: (
|
|
5
|
+
export declare const filterProps: (props: Props, excludeKeys: readonly string[]) => Props;
|
|
6
|
+
export declare const resolvePropMeta: (instance: Container, key: string) => [string | null, string] | null;
|
|
7
|
+
export declare const resolveSignal: (instance: Container, signalName: string) => boolean;
|
|
8
|
+
export declare const propNameToSignalName: (propName: string) => string;
|
|
9
|
+
export declare const hasChanged: <T>(oldProps: T | null, newProps: T, key: keyof T) => boolean;
|
|
10
|
+
export declare const shallowArrayEqual: <T extends Record<string, unknown>>(a: T[], b: T[]) => boolean;
|
|
11
|
+
export declare const primitiveArrayEqual: <T extends string | number | boolean>(a: T[] | null | undefined, b: T[] | null | undefined) => boolean;
|
|
9
12
|
export {};
|
|
@@ -7,7 +7,6 @@ export const matchesAnyClass = (classes, containerOrClass) => {
|
|
|
7
7
|
containerOrClass === cls ||
|
|
8
8
|
Object.prototype.isPrototypeOf.call(cls, containerOrClass));
|
|
9
9
|
};
|
|
10
|
-
export const isContainerType = (cls, containerOrClass) => matchesAnyClass([cls], containerOrClass);
|
|
11
10
|
export const matchesInterface = (methods, containerOrClass) => {
|
|
12
11
|
if (!containerOrClass) {
|
|
13
12
|
return false;
|
|
@@ -24,9 +23,9 @@ export const filterProps = (props, excludeKeys) => {
|
|
|
24
23
|
}
|
|
25
24
|
return result;
|
|
26
25
|
};
|
|
27
|
-
const walkPrototypeChain = (
|
|
26
|
+
const walkPrototypeChain = (instance, lookup) => {
|
|
28
27
|
// biome-ignore lint/complexity/noBannedTypes: Walking prototype chain requires Function type
|
|
29
|
-
let current =
|
|
28
|
+
let current = instance.constructor;
|
|
30
29
|
while (current) {
|
|
31
30
|
const typeName = current.glibTypeName;
|
|
32
31
|
if (typeName) {
|
|
@@ -43,5 +42,51 @@ const walkPrototypeChain = (container, lookup) => {
|
|
|
43
42
|
}
|
|
44
43
|
return null;
|
|
45
44
|
};
|
|
46
|
-
export const resolvePropMeta = (
|
|
47
|
-
export const resolveSignal = (
|
|
45
|
+
export const resolvePropMeta = (instance, key) => walkPrototypeChain(instance, (typeName) => PROPS[typeName]?.[key] ?? null);
|
|
46
|
+
export const resolveSignal = (instance, signalName) => {
|
|
47
|
+
if (signalName === "notify")
|
|
48
|
+
return true;
|
|
49
|
+
return walkPrototypeChain(instance, (typeName) => (SIGNALS[typeName]?.has(signalName) ? true : null)) ?? false;
|
|
50
|
+
};
|
|
51
|
+
export const propNameToSignalName = (propName) => {
|
|
52
|
+
if (!propName.startsWith("on"))
|
|
53
|
+
return propName;
|
|
54
|
+
return propName
|
|
55
|
+
.slice(2)
|
|
56
|
+
.replace(/([A-Z])/g, "-$1")
|
|
57
|
+
.toLowerCase()
|
|
58
|
+
.replace(/^-/, "");
|
|
59
|
+
};
|
|
60
|
+
export const hasChanged = (oldProps, newProps, key) => !oldProps || oldProps[key] !== newProps[key];
|
|
61
|
+
export const shallowArrayEqual = (a, b) => {
|
|
62
|
+
if (a.length !== b.length)
|
|
63
|
+
return false;
|
|
64
|
+
for (let i = 0; i < a.length; i++) {
|
|
65
|
+
const itemA = a[i];
|
|
66
|
+
const itemB = b[i];
|
|
67
|
+
if (!itemA || !itemB)
|
|
68
|
+
return false;
|
|
69
|
+
const keysA = Object.keys(itemA);
|
|
70
|
+
const keysB = Object.keys(itemB);
|
|
71
|
+
if (keysA.length !== keysB.length)
|
|
72
|
+
return false;
|
|
73
|
+
for (const key of keysA) {
|
|
74
|
+
if (itemA[key] !== itemB[key])
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return true;
|
|
79
|
+
};
|
|
80
|
+
export const primitiveArrayEqual = (a, b) => {
|
|
81
|
+
if (a === b)
|
|
82
|
+
return true;
|
|
83
|
+
if (!a || !b)
|
|
84
|
+
return false;
|
|
85
|
+
if (a.length !== b.length)
|
|
86
|
+
return false;
|
|
87
|
+
for (let i = 0; i < a.length; i++) {
|
|
88
|
+
if (a[i] !== b[i])
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
return true;
|
|
92
|
+
};
|
package/dist/nodes/level-bar.js
CHANGED
|
@@ -1,69 +1,34 @@
|
|
|
1
1
|
import * as Gtk from "@gtkx/ffi/gtk";
|
|
2
2
|
import { registerNodeClass } from "../registry.js";
|
|
3
|
-
import {
|
|
4
|
-
import { isContainerType } from "./internal/utils.js";
|
|
5
|
-
import { LevelBarOffsetNode } from "./level-bar-offset.js";
|
|
3
|
+
import { filterProps, matchesAnyClass, shallowArrayEqual } from "./internal/utils.js";
|
|
6
4
|
import { WidgetNode } from "./widget.js";
|
|
5
|
+
const OWN_PROPS = ["offsets"];
|
|
7
6
|
class LevelBarNode extends WidgetNode {
|
|
8
7
|
static priority = 1;
|
|
9
|
-
offsetChildren = [];
|
|
10
8
|
appliedOffsetIds = new Set();
|
|
11
9
|
static matches(_type, containerOrClass) {
|
|
12
|
-
return
|
|
10
|
+
return matchesAnyClass([Gtk.LevelBar], containerOrClass);
|
|
13
11
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
this.offsetChildren.push(child);
|
|
18
|
-
scheduleAfterCommit(() => {
|
|
19
|
-
const id = child.addOffset();
|
|
20
|
-
if (id) {
|
|
21
|
-
this.appliedOffsetIds.add(id);
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
super.appendChild(child);
|
|
12
|
+
updateProps(oldProps, newProps) {
|
|
13
|
+
super.updateProps(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
|
|
14
|
+
this.applyOwnProps(oldProps, newProps);
|
|
27
15
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
child.setLevelBar(this.container, () => this.scheduleRebuildAllOffsets());
|
|
31
|
-
const beforeIndex = this.offsetChildren.indexOf(before);
|
|
32
|
-
if (beforeIndex >= 0) {
|
|
33
|
-
this.offsetChildren.splice(beforeIndex, 0, child);
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
this.offsetChildren.push(child);
|
|
37
|
-
}
|
|
38
|
-
this.scheduleRebuildAllOffsets();
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
super.insertBefore(child, before);
|
|
16
|
+
applyOwnProps(oldProps, newProps) {
|
|
17
|
+
this.applyOffsets(oldProps, newProps);
|
|
42
18
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (index >= 0) {
|
|
47
|
-
this.offsetChildren.splice(index, 1);
|
|
48
|
-
}
|
|
49
|
-
this.scheduleRebuildAllOffsets(CommitPriority.HIGH);
|
|
19
|
+
applyOffsets(oldProps, newProps) {
|
|
20
|
+
const newOffsets = newProps.offsets ?? [];
|
|
21
|
+
if (shallowArrayEqual(oldProps?.offsets ?? [], newOffsets)) {
|
|
50
22
|
return;
|
|
51
23
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
for (const offset of this.offsetChildren) {
|
|
61
|
-
const id = offset.addOffset();
|
|
62
|
-
if (id) {
|
|
63
|
-
this.appliedOffsetIds.add(id);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}, priority);
|
|
24
|
+
for (const id of this.appliedOffsetIds) {
|
|
25
|
+
this.container.removeOffsetValue(id);
|
|
26
|
+
}
|
|
27
|
+
this.appliedOffsetIds.clear();
|
|
28
|
+
for (const offset of newOffsets) {
|
|
29
|
+
this.container.addOffsetValue(offset.id, offset.value);
|
|
30
|
+
this.appliedOffsetIds.add(offset.id);
|
|
31
|
+
}
|
|
67
32
|
}
|
|
68
33
|
}
|
|
69
34
|
registerNodeClass(LevelBarNode);
|