@gtkx/react 0.18.9 → 0.19.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/generated/internal.d.ts +6 -0
- package/dist/generated/internal.d.ts.map +1 -1
- package/dist/generated/internal.js +331 -44
- package/dist/generated/internal.js.map +1 -1
- package/dist/generated/jsx.d.ts +178 -2
- package/dist/generated/jsx.d.ts.map +1 -1
- package/dist/generated/jsx.js.map +1 -1
- package/dist/host-config.d.ts.map +1 -1
- package/dist/host-config.js +46 -10
- package/dist/host-config.js.map +1 -1
- package/dist/jsx.d.ts +133 -13
- package/dist/jsx.d.ts.map +1 -1
- package/dist/jsx.js +41 -2
- 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 +3 -1
- package/dist/metadata.js.map +1 -1
- package/dist/node.d.ts +2 -0
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +22 -6
- package/dist/node.js.map +1 -1
- package/dist/nodes/column-view-column.d.ts +4 -1
- package/dist/nodes/column-view-column.d.ts.map +1 -1
- package/dist/nodes/column-view-column.js +29 -8
- package/dist/nodes/column-view-column.js.map +1 -1
- package/dist/nodes/column-view.d.ts +4 -3
- package/dist/nodes/column-view.d.ts.map +1 -1
- package/dist/nodes/column-view.js +44 -14
- package/dist/nodes/column-view.js.map +1 -1
- package/dist/nodes/drop-down.d.ts +12 -2
- package/dist/nodes/drop-down.d.ts.map +1 -1
- package/dist/nodes/drop-down.js +151 -5
- package/dist/nodes/drop-down.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 +11 -3
- 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/grid-view.d.ts +6 -5
- package/dist/nodes/grid-view.d.ts.map +1 -1
- package/dist/nodes/grid-view.js +23 -18
- package/dist/nodes/grid-view.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/base-item-renderer.d.ts.map +1 -1
- package/dist/nodes/internal/base-item-renderer.js +0 -1
- package/dist/nodes/internal/base-item-renderer.js.map +1 -1
- package/dist/nodes/internal/construct.d.ts +10 -0
- package/dist/nodes/internal/construct.d.ts.map +1 -0
- package/dist/nodes/internal/construct.js +68 -0
- package/dist/nodes/internal/construct.js.map +1 -0
- package/dist/nodes/internal/header-item-renderer.d.ts +23 -0
- package/dist/nodes/internal/header-item-renderer.d.ts.map +1 -0
- package/dist/nodes/internal/header-item-renderer.js +87 -0
- package/dist/nodes/internal/header-item-renderer.js.map +1 -0
- package/dist/nodes/internal/header-renderer-manager.d.ts +13 -0
- package/dist/nodes/internal/header-renderer-manager.d.ts.map +1 -0
- package/dist/nodes/internal/header-renderer-manager.js +20 -0
- package/dist/nodes/internal/header-renderer-manager.js.map +1 -0
- package/dist/nodes/internal/list-store.d.ts +10 -11
- package/dist/nodes/internal/list-store.d.ts.map +1 -1
- package/dist/nodes/internal/list-store.js +28 -29
- package/dist/nodes/internal/list-store.js.map +1 -1
- package/dist/nodes/internal/sectioned-list-store.d.ts +50 -0
- package/dist/nodes/internal/sectioned-list-store.d.ts.map +1 -0
- package/dist/nodes/internal/sectioned-list-store.js +250 -0
- package/dist/nodes/internal/sectioned-list-store.js.map +1 -0
- package/dist/nodes/internal/selection-helpers.d.ts +12 -0
- package/dist/nodes/internal/selection-helpers.d.ts.map +1 -0
- package/dist/nodes/internal/selection-helpers.js +25 -0
- package/dist/nodes/internal/selection-helpers.js.map +1 -0
- package/dist/nodes/internal/selection-model-controller.d.ts.map +1 -1
- package/dist/nodes/internal/selection-model-controller.js +3 -0
- package/dist/nodes/internal/selection-model-controller.js.map +1 -1
- package/dist/nodes/internal/simple-list-store.d.ts +7 -12
- package/dist/nodes/internal/simple-list-store.d.ts.map +1 -1
- package/dist/nodes/internal/simple-list-store.js +58 -35
- package/dist/nodes/internal/simple-list-store.js.map +1 -1
- 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/tree-store.d.ts +3 -0
- package/dist/nodes/internal/tree-store.d.ts.map +1 -1
- package/dist/nodes/internal/tree-store.js +55 -10
- package/dist/nodes/internal/tree-store.js.map +1 -1
- package/dist/nodes/list-section.d.ts +27 -0
- package/dist/nodes/list-section.d.ts.map +1 -0
- package/dist/nodes/list-section.js +43 -0
- package/dist/nodes/list-section.js.map +1 -0
- package/dist/nodes/list-view.d.ts +6 -3
- package/dist/nodes/list-view.d.ts.map +1 -1
- package/dist/nodes/list-view.js +54 -14
- package/dist/nodes/list-view.js.map +1 -1
- package/dist/nodes/models/list.d.ts +13 -5
- package/dist/nodes/models/list.d.ts.map +1 -1
- package/dist/nodes/models/list.js +135 -21
- package/dist/nodes/models/list.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 +44 -61
- package/dist/nodes/widget.js.map +1 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +2 -2
- package/dist/registry.js.map +1 -1
- package/package.json +3 -3
- package/src/generated/internal.ts +333 -44
- package/src/generated/jsx.ts +178 -2
- package/src/host-config.ts +41 -10
- package/src/jsx.ts +166 -15
- package/src/metadata.ts +5 -1
- package/src/node.ts +20 -6
- package/src/nodes/column-view-column.ts +32 -8
- package/src/nodes/column-view.ts +59 -14
- package/src/nodes/drop-down.ts +182 -6
- package/src/nodes/event-controller.ts +11 -3
- package/src/nodes/fixed-child.ts +24 -23
- package/src/nodes/font-dialog-button.ts +10 -0
- package/src/nodes/grid-view.ts +29 -19
- package/src/nodes/internal/accessible.ts +156 -0
- package/src/nodes/internal/base-item-renderer.ts +0 -1
- package/src/nodes/internal/construct.ts +90 -0
- package/src/nodes/internal/header-item-renderer.ts +105 -0
- package/src/nodes/internal/header-renderer-manager.ts +33 -0
- package/src/nodes/internal/list-store.ts +32 -30
- package/src/nodes/internal/sectioned-list-store.ts +287 -0
- package/src/nodes/internal/selection-helpers.ts +35 -0
- package/src/nodes/internal/selection-model-controller.ts +4 -0
- package/src/nodes/internal/simple-list-store.ts +60 -43
- package/src/nodes/internal/text-buffer-controller.ts +51 -8
- package/src/nodes/internal/tree-store.ts +61 -9
- package/src/nodes/list-section.ts +64 -0
- package/src/nodes/list-view.ts +65 -14
- package/src/nodes/models/list.ts +147 -37
- 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 +45 -62
- package/src/registry.ts +4 -2
- 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/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/nodes/models/grid.ts +0 -105
- package/src/nodes/shortcut-controller.ts +0 -27
package/src/nodes/drop-down.ts
CHANGED
|
@@ -1,28 +1,54 @@
|
|
|
1
|
+
import * as Gtk from "@gtkx/ffi/gtk";
|
|
2
|
+
import type { ReactNode } from "react";
|
|
3
|
+
import type Reconciler from "react-reconciler";
|
|
4
|
+
import { createFiberRoot } from "../fiber-root.js";
|
|
1
5
|
import type { AdwComboRowProps, GtkDropDownProps } from "../jsx.js";
|
|
2
6
|
import type { Node } from "../node.js";
|
|
7
|
+
import { reconciler } from "../reconciler.js";
|
|
3
8
|
import type { DropDownWidget } from "../registry.js";
|
|
4
9
|
import type { Container } from "../types.js";
|
|
5
10
|
import { ContainerSlotNode } from "./container-slot.js";
|
|
6
11
|
import { EventControllerNode } from "./event-controller.js";
|
|
12
|
+
import type { HeaderItemRenderer } from "./internal/header-item-renderer.js";
|
|
13
|
+
import { updateHeaderRenderer } from "./internal/header-renderer-manager.js";
|
|
7
14
|
import { filterProps, hasChanged } from "./internal/props.js";
|
|
8
15
|
import { SimpleListStore } from "./internal/simple-list-store.js";
|
|
9
16
|
import { ListItemNode } from "./list-item.js";
|
|
17
|
+
import { ListSectionNode } from "./list-section.js";
|
|
10
18
|
import { SlotNode } from "./slot.js";
|
|
11
19
|
import { WidgetNode } from "./widget.js";
|
|
12
20
|
|
|
13
|
-
const OWN_PROPS = ["selectedId", "onSelectionChanged"] as const;
|
|
21
|
+
const OWN_PROPS = ["selectedId", "onSelectionChanged", "renderItem", "renderListItem", "renderHeader"] as const;
|
|
14
22
|
|
|
15
23
|
type DropDownProps = Pick<GtkDropDownProps | AdwComboRowProps, (typeof OWN_PROPS)[number]>;
|
|
16
24
|
|
|
17
|
-
type DropDownChild = ListItemNode | EventControllerNode | SlotNode | ContainerSlotNode;
|
|
25
|
+
type DropDownChild = ListItemNode | ListSectionNode | EventControllerNode | SlotNode | ContainerSlotNode;
|
|
26
|
+
|
|
27
|
+
type RenderItemFn = (item: string | null) => ReactNode;
|
|
28
|
+
|
|
29
|
+
interface FactoryState {
|
|
30
|
+
factory: Gtk.SignalListItemFactory;
|
|
31
|
+
fiberRoots: Map<object, Reconciler.FiberRoot>;
|
|
32
|
+
tornDown: Set<object>;
|
|
33
|
+
boundLabels: Map<string, object>;
|
|
34
|
+
}
|
|
18
35
|
|
|
19
36
|
export class DropDownNode extends WidgetNode<DropDownWidget, DropDownProps, DropDownChild> {
|
|
20
37
|
private store = new SimpleListStore();
|
|
21
38
|
private initialSelectedId: string | null | undefined;
|
|
22
39
|
|
|
40
|
+
private itemState: FactoryState | null = null;
|
|
41
|
+
private renderItemFn: RenderItemFn | null = null;
|
|
42
|
+
|
|
43
|
+
private listItemState: FactoryState | null = null;
|
|
44
|
+
private renderListItemFn: RenderItemFn | null = null;
|
|
45
|
+
|
|
46
|
+
private headerRenderer: HeaderItemRenderer | null = null;
|
|
47
|
+
|
|
23
48
|
public override isValidChild(child: Node): boolean {
|
|
24
49
|
return (
|
|
25
50
|
child instanceof ListItemNode ||
|
|
51
|
+
child instanceof ListSectionNode ||
|
|
26
52
|
child instanceof EventControllerNode ||
|
|
27
53
|
child instanceof SlotNode ||
|
|
28
54
|
child instanceof ContainerSlotNode
|
|
@@ -33,12 +59,12 @@ export class DropDownNode extends WidgetNode<DropDownWidget, DropDownProps, Drop
|
|
|
33
59
|
super(typeName, props, container, rootContainer);
|
|
34
60
|
this.store.beginBatch();
|
|
35
61
|
this.initialSelectedId = props.selectedId;
|
|
36
|
-
this.container.setModel(this.store.getModel());
|
|
37
62
|
}
|
|
38
63
|
|
|
39
64
|
public override finalizeInitialChildren(props: DropDownProps): boolean {
|
|
40
65
|
super.finalizeInitialChildren(props);
|
|
41
66
|
this.store.flushBatch();
|
|
67
|
+
this.container.setModel(this.store.getModel());
|
|
42
68
|
this.reapplyInitialSelectedId();
|
|
43
69
|
return false;
|
|
44
70
|
}
|
|
@@ -54,7 +80,10 @@ export class DropDownNode extends WidgetNode<DropDownWidget, DropDownProps, Drop
|
|
|
54
80
|
|
|
55
81
|
public override appendChild(child: DropDownChild): void {
|
|
56
82
|
super.appendChild(child);
|
|
57
|
-
if (child instanceof
|
|
83
|
+
if (child instanceof ListSectionNode) {
|
|
84
|
+
this.store.addSection(child.props.id, child.props.value);
|
|
85
|
+
child.setStore(this.store);
|
|
86
|
+
} else if (child instanceof ListItemNode) {
|
|
58
87
|
child.setStore(this.store);
|
|
59
88
|
this.store.addItem(child.props.id, child.props.value as string);
|
|
60
89
|
}
|
|
@@ -62,15 +91,25 @@ export class DropDownNode extends WidgetNode<DropDownWidget, DropDownProps, Drop
|
|
|
62
91
|
|
|
63
92
|
public override insertBefore(child: DropDownChild, before: DropDownChild): void {
|
|
64
93
|
super.insertBefore(child, before);
|
|
65
|
-
if (child instanceof
|
|
94
|
+
if (child instanceof ListSectionNode) {
|
|
95
|
+
this.store.addSection(child.props.id, child.props.value);
|
|
96
|
+
child.setStore(this.store);
|
|
97
|
+
} else if (child instanceof ListItemNode && before instanceof ListItemNode) {
|
|
66
98
|
child.setStore(this.store);
|
|
67
99
|
this.store.insertItemBefore(child.props.id, before.props.id, child.props.value as string);
|
|
100
|
+
} else if (child instanceof ListItemNode) {
|
|
101
|
+
child.setStore(this.store);
|
|
102
|
+
this.store.addItem(child.props.id, child.props.value as string);
|
|
68
103
|
}
|
|
69
104
|
}
|
|
70
105
|
|
|
71
106
|
public override removeChild(child: DropDownChild): void {
|
|
72
|
-
if (child instanceof
|
|
107
|
+
if (child instanceof ListSectionNode) {
|
|
108
|
+
this.store.removeSection(child.props.id);
|
|
109
|
+
child.setStore(null);
|
|
110
|
+
} else if (child instanceof ListItemNode) {
|
|
73
111
|
this.store.removeItem(child.props.id);
|
|
112
|
+
child.setStore(null);
|
|
74
113
|
}
|
|
75
114
|
super.removeChild(child);
|
|
76
115
|
}
|
|
@@ -80,6 +119,15 @@ export class DropDownNode extends WidgetNode<DropDownWidget, DropDownProps, Drop
|
|
|
80
119
|
this.applyOwnProps(oldProps, newProps);
|
|
81
120
|
}
|
|
82
121
|
|
|
122
|
+
public override detachDeletedInstance(): void {
|
|
123
|
+
this.disposeFactory(this.itemState);
|
|
124
|
+
this.itemState = null;
|
|
125
|
+
this.disposeFactory(this.listItemState);
|
|
126
|
+
this.listItemState = null;
|
|
127
|
+
this.headerRenderer?.dispose();
|
|
128
|
+
super.detachDeletedInstance();
|
|
129
|
+
}
|
|
130
|
+
|
|
83
131
|
private applyOwnProps(oldProps: DropDownProps | null, newProps: DropDownProps): void {
|
|
84
132
|
if (hasChanged(oldProps, newProps, "onSelectionChanged")) {
|
|
85
133
|
const onSelectionChanged = newProps.onSelectionChanged;
|
|
@@ -104,5 +152,133 @@ export class DropDownNode extends WidgetNode<DropDownWidget, DropDownProps, Drop
|
|
|
104
152
|
this.container.setSelected(index);
|
|
105
153
|
}
|
|
106
154
|
}
|
|
155
|
+
|
|
156
|
+
if (hasChanged(oldProps, newProps, "renderItem")) {
|
|
157
|
+
if (newProps.renderItem) {
|
|
158
|
+
if (!this.itemState) {
|
|
159
|
+
this.itemState = this.createFactory(
|
|
160
|
+
() => this.renderItemFn,
|
|
161
|
+
(f) => this.container.setFactory(f),
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
this.renderItemFn = newProps.renderItem;
|
|
165
|
+
this.rebindAll(this.itemState, this.renderItemFn);
|
|
166
|
+
} else if (this.itemState) {
|
|
167
|
+
this.disposeFactory(this.itemState);
|
|
168
|
+
this.itemState = null;
|
|
169
|
+
this.container.setFactory(null);
|
|
170
|
+
this.renderItemFn = null;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (hasChanged(oldProps, newProps, "renderListItem")) {
|
|
175
|
+
if (newProps.renderListItem) {
|
|
176
|
+
if (!this.listItemState) {
|
|
177
|
+
this.listItemState = this.createFactory(
|
|
178
|
+
() => this.renderListItemFn,
|
|
179
|
+
(f) => this.container.setListFactory(f),
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
this.renderListItemFn = newProps.renderListItem;
|
|
183
|
+
this.rebindAll(this.listItemState, this.renderListItemFn);
|
|
184
|
+
} else if (this.listItemState) {
|
|
185
|
+
this.disposeFactory(this.listItemState);
|
|
186
|
+
this.listItemState = null;
|
|
187
|
+
this.container.setListFactory(null);
|
|
188
|
+
this.renderListItemFn = null;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (hasChanged(oldProps, newProps, "renderHeader")) {
|
|
193
|
+
this.headerRenderer = updateHeaderRenderer(
|
|
194
|
+
this.headerRenderer,
|
|
195
|
+
{
|
|
196
|
+
signalStore: this.signalStore,
|
|
197
|
+
isEnabled: () => this.store.isSectioned(),
|
|
198
|
+
resolveItem: (label) => this.store.getHeaderValueByLabel(label),
|
|
199
|
+
setFactory: (factory) => this.container.setHeaderFactory(factory),
|
|
200
|
+
},
|
|
201
|
+
newProps.renderHeader,
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
private createFactory(
|
|
207
|
+
getRenderFn: () => RenderItemFn | null,
|
|
208
|
+
applyFactory: (factory: Gtk.SignalListItemFactory) => void,
|
|
209
|
+
): FactoryState {
|
|
210
|
+
const state: FactoryState = {
|
|
211
|
+
factory: new Gtk.SignalListItemFactory(),
|
|
212
|
+
fiberRoots: new Map(),
|
|
213
|
+
tornDown: new Set(),
|
|
214
|
+
boundLabels: new Map(),
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
this.signalStore.set(this, state.factory, "setup", (listItem: Gtk.ListItem) => {
|
|
218
|
+
const box = new Gtk.Box(Gtk.Orientation.HORIZONTAL);
|
|
219
|
+
box.setValign(Gtk.Align.CENTER);
|
|
220
|
+
listItem.setChild(box);
|
|
221
|
+
const fiberRoot = createFiberRoot(box);
|
|
222
|
+
state.fiberRoots.set(listItem, fiberRoot);
|
|
223
|
+
const element = getRenderFn()?.(null);
|
|
224
|
+
reconciler.getInstance().updateContainer(element, fiberRoot, null, () => {});
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
this.signalStore.set(this, state.factory, "bind", (listItem: Gtk.ListItem) => {
|
|
228
|
+
const fiberRoot = state.fiberRoots.get(listItem);
|
|
229
|
+
if (!fiberRoot) return;
|
|
230
|
+
const stringObject = listItem.getItem();
|
|
231
|
+
const label = stringObject instanceof Gtk.StringObject ? stringObject.getString() : null;
|
|
232
|
+
if (label !== null) state.boundLabels.set(label, listItem);
|
|
233
|
+
const element = getRenderFn()?.(label);
|
|
234
|
+
reconciler.getInstance().updateContainer(element, fiberRoot, null, () => {});
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
this.signalStore.set(this, state.factory, "unbind", (listItem: Gtk.ListItem) => {
|
|
238
|
+
const stringObject = listItem.getItem();
|
|
239
|
+
if (stringObject instanceof Gtk.StringObject) {
|
|
240
|
+
state.boundLabels.delete(stringObject.getString());
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
this.signalStore.set(this, state.factory, "teardown", (listItem: Gtk.ListItem) => {
|
|
245
|
+
const fiberRoot = state.fiberRoots.get(listItem);
|
|
246
|
+
if (fiberRoot) {
|
|
247
|
+
state.tornDown.add(listItem);
|
|
248
|
+
reconciler.getInstance().updateContainer(null, fiberRoot, null, () => {});
|
|
249
|
+
queueMicrotask(() => {
|
|
250
|
+
state.fiberRoots.delete(listItem);
|
|
251
|
+
state.tornDown.delete(listItem);
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
applyFactory(state.factory);
|
|
257
|
+
return state;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
private rebindAll(state: FactoryState, renderFn: RenderItemFn): void {
|
|
261
|
+
for (const [label, listItem] of state.boundLabels) {
|
|
262
|
+
const fiberRoot = state.fiberRoots.get(listItem);
|
|
263
|
+
if (!fiberRoot) continue;
|
|
264
|
+
const element = renderFn(label);
|
|
265
|
+
reconciler.getInstance().updateContainer(element, fiberRoot, null, () => {});
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
private disposeFactory(state: FactoryState | null): void {
|
|
270
|
+
if (!state) return;
|
|
271
|
+
this.signalStore.set(this, state.factory, "setup", undefined);
|
|
272
|
+
this.signalStore.set(this, state.factory, "bind", undefined);
|
|
273
|
+
this.signalStore.set(this, state.factory, "unbind", undefined);
|
|
274
|
+
this.signalStore.set(this, state.factory, "teardown", undefined);
|
|
275
|
+
for (const [listItem, fiberRoot] of state.fiberRoots) {
|
|
276
|
+
if (!state.tornDown.has(listItem)) {
|
|
277
|
+
reconciler.getInstance().updateContainer(null, fiberRoot, null, () => {});
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
state.fiberRoots.clear();
|
|
281
|
+
state.tornDown.clear();
|
|
282
|
+
state.boundLabels.clear();
|
|
107
283
|
}
|
|
108
284
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import * as Gtk from "@gtkx/ffi/gtk";
|
|
2
2
|
import { CONSTRUCTOR_PROPS } from "../generated/internal.js";
|
|
3
|
-
import { resolvePropMeta, resolveSignal } from "../metadata.js";
|
|
3
|
+
import { isConstructOnlyProp, resolvePropMeta, resolveSignal } from "../metadata.js";
|
|
4
4
|
import { Node } from "../node.js";
|
|
5
5
|
import type { Props } from "../types.js";
|
|
6
|
+
import { createContainerWithConstructOnly } from "./internal/construct.js";
|
|
6
7
|
import type { SignalHandler } from "./internal/signal-store.js";
|
|
7
8
|
import { WidgetNode } from "./widget.js";
|
|
8
9
|
|
|
@@ -26,8 +27,14 @@ export class EventControllerNode<
|
|
|
26
27
|
|
|
27
28
|
const args = (CONSTRUCTOR_PROPS[typeName] ?? []).map((name) => props[name]);
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
return createContainerWithConstructOnly(containerClass, props, () => {
|
|
31
|
+
// biome-ignore lint/suspicious/noExplicitAny: Dynamic constructor invocation
|
|
32
|
+
return new (containerClass as any)(...args);
|
|
33
|
+
}) as Gtk.EventController;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public override isValidChild(child: Node): boolean {
|
|
37
|
+
return this.container instanceof Gtk.ShortcutController && child.typeName === "Shortcut";
|
|
31
38
|
}
|
|
32
39
|
|
|
33
40
|
public override isValidParent(parent: Node): boolean {
|
|
@@ -63,6 +70,7 @@ export class EventControllerNode<
|
|
|
63
70
|
|
|
64
71
|
for (const name of propNames) {
|
|
65
72
|
if (name === "children") continue;
|
|
73
|
+
if (isConstructOnlyProp(this.container, name)) continue;
|
|
66
74
|
|
|
67
75
|
const oldValue = oldProps?.[name];
|
|
68
76
|
const newValue = newProps[name];
|
package/src/nodes/fixed-child.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as Graphene from "@gtkx/ffi/graphene";
|
|
2
|
+
import * as Gsk from "@gtkx/ffi/gsk";
|
|
1
3
|
import * as Gtk from "@gtkx/ffi/gtk";
|
|
2
4
|
import type { FixedChildProps } from "../jsx.js";
|
|
3
5
|
import type { Node } from "../node.js";
|
|
@@ -23,7 +25,7 @@ export class FixedChildNode extends VirtualNode<FixedChildProps, WidgetNode<Gtk.
|
|
|
23
25
|
|
|
24
26
|
if (parent && this.children[0]) {
|
|
25
27
|
this.attachToParent(parent.container, this.children[0].container);
|
|
26
|
-
this.
|
|
28
|
+
this.applyLayoutTransform();
|
|
27
29
|
}
|
|
28
30
|
}
|
|
29
31
|
|
|
@@ -32,7 +34,7 @@ export class FixedChildNode extends VirtualNode<FixedChildProps, WidgetNode<Gtk.
|
|
|
32
34
|
|
|
33
35
|
if (this.parent) {
|
|
34
36
|
this.attachToParent(this.parent.container, child.container);
|
|
35
|
-
this.
|
|
37
|
+
this.applyLayoutTransform();
|
|
36
38
|
}
|
|
37
39
|
}
|
|
38
40
|
|
|
@@ -51,12 +53,12 @@ export class FixedChildNode extends VirtualNode<FixedChildProps, WidgetNode<Gtk.
|
|
|
51
53
|
return;
|
|
52
54
|
}
|
|
53
55
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
this.
|
|
56
|
+
if (
|
|
57
|
+
hasChanged(oldProps, newProps, "x") ||
|
|
58
|
+
hasChanged(oldProps, newProps, "y") ||
|
|
59
|
+
hasChanged(oldProps, newProps, "transform")
|
|
60
|
+
) {
|
|
61
|
+
this.applyLayoutTransform();
|
|
60
62
|
}
|
|
61
63
|
}
|
|
62
64
|
|
|
@@ -80,29 +82,28 @@ export class FixedChildNode extends VirtualNode<FixedChildProps, WidgetNode<Gtk.
|
|
|
80
82
|
}
|
|
81
83
|
}
|
|
82
84
|
|
|
83
|
-
private
|
|
85
|
+
private applyLayoutTransform(): void {
|
|
84
86
|
if (!this.parent || !this.children[0]) return;
|
|
85
87
|
|
|
88
|
+
const layoutManager = this.parent.container.getLayoutManager();
|
|
89
|
+
if (!layoutManager) return;
|
|
90
|
+
|
|
91
|
+
const layoutChild = layoutManager.getLayoutChild(this.children[0].container) as Gtk.FixedLayoutChild;
|
|
92
|
+
|
|
86
93
|
const x = this.props.x ?? 0;
|
|
87
94
|
const y = this.props.y ?? 0;
|
|
95
|
+
const position = new Graphene.Point();
|
|
96
|
+
position.init(x, y);
|
|
88
97
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
this.applyTransform();
|
|
92
|
-
}
|
|
98
|
+
let transform: Gsk.Transform | null = new Gsk.Transform();
|
|
99
|
+
transform = transform.translate(position);
|
|
93
100
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
return;
|
|
101
|
+
if (this.props.transform && transform) {
|
|
102
|
+
transform = transform.transform(this.props.transform);
|
|
97
103
|
}
|
|
98
104
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
if (!layoutManager) {
|
|
102
|
-
return;
|
|
105
|
+
if (transform) {
|
|
106
|
+
layoutChild.setTransform(transform);
|
|
103
107
|
}
|
|
104
|
-
|
|
105
|
-
const layoutChild = layoutManager.getLayoutChild(this.children[0].container) as Gtk.FixedLayoutChild;
|
|
106
|
-
layoutChild.setTransform(this.props.transform);
|
|
107
108
|
}
|
|
108
109
|
}
|
|
@@ -10,6 +10,8 @@ const OWN_PROPS = [
|
|
|
10
10
|
"title",
|
|
11
11
|
"modal",
|
|
12
12
|
"language",
|
|
13
|
+
"filter",
|
|
14
|
+
"fontMap",
|
|
13
15
|
"useFont",
|
|
14
16
|
"useSize",
|
|
15
17
|
"level",
|
|
@@ -61,6 +63,14 @@ export class FontDialogButtonNode extends WidgetNode<Gtk.FontDialogButton, FontD
|
|
|
61
63
|
this.dialog.setLanguage(newProps.language);
|
|
62
64
|
}
|
|
63
65
|
|
|
66
|
+
if (hasChanged(oldProps, newProps, "filter")) {
|
|
67
|
+
this.dialog.setFilter(newProps.filter);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (hasChanged(oldProps, newProps, "fontMap")) {
|
|
71
|
+
this.dialog.setFontMap(newProps.fontMap);
|
|
72
|
+
}
|
|
73
|
+
|
|
64
74
|
if (hasChanged(oldProps, newProps, "useFont")) {
|
|
65
75
|
this.container.setUseFont(newProps.useFont ?? false);
|
|
66
76
|
}
|
package/src/nodes/grid-view.ts
CHANGED
|
@@ -7,39 +7,43 @@ import { EventControllerNode } from "./event-controller.js";
|
|
|
7
7
|
import { GridItemRenderer } from "./internal/grid-item-renderer.js";
|
|
8
8
|
import { filterProps, hasChanged } from "./internal/props.js";
|
|
9
9
|
import { ListItemNode } from "./list-item.js";
|
|
10
|
-
import {
|
|
10
|
+
import { ListSectionNode } from "./list-section.js";
|
|
11
|
+
import { ListModel, type ListModelProps } from "./models/list.js";
|
|
11
12
|
import { SlotNode } from "./slot.js";
|
|
12
13
|
import { WidgetNode } from "./widget.js";
|
|
13
14
|
|
|
14
|
-
const
|
|
15
|
+
const RENDERER_PROPS = ["renderItem", "estimatedItemHeight"] as const;
|
|
16
|
+
const OWN_PROPS = [...RENDERER_PROPS, "selectionMode", "selected", "onSelectionChanged"] as const;
|
|
15
17
|
|
|
16
|
-
type GridViewProps = Pick<GtkGridViewProps, (typeof
|
|
18
|
+
type GridViewProps = Pick<GtkGridViewProps, (typeof RENDERER_PROPS)[number]> & ListModelProps;
|
|
17
19
|
|
|
18
|
-
type GridViewChild = ListItemNode | EventControllerNode | SlotNode | ContainerSlotNode;
|
|
20
|
+
type GridViewChild = ListItemNode | ListSectionNode | EventControllerNode | SlotNode | ContainerSlotNode;
|
|
19
21
|
|
|
20
22
|
export class GridViewNode extends WidgetNode<Gtk.GridView, GridViewProps, GridViewChild> {
|
|
21
23
|
private itemRenderer: GridItemRenderer;
|
|
22
|
-
private
|
|
24
|
+
private list: ListModel;
|
|
23
25
|
|
|
24
26
|
constructor(typeName: string, props: GridViewProps, container: Gtk.GridView, rootContainer: Container) {
|
|
25
27
|
super(typeName, props, container, rootContainer);
|
|
26
|
-
this.
|
|
28
|
+
this.list = new ListModel(
|
|
27
29
|
{ owner: this, signalStore: this.signalStore },
|
|
28
30
|
{
|
|
29
31
|
selectionMode: props.selectionMode,
|
|
30
32
|
selected: props.selected,
|
|
31
33
|
onSelectionChanged: props.onSelectionChanged,
|
|
32
34
|
},
|
|
35
|
+
true,
|
|
33
36
|
);
|
|
34
37
|
this.itemRenderer = new GridItemRenderer(this.signalStore);
|
|
35
|
-
this.itemRenderer.setStore(this.
|
|
36
|
-
this.
|
|
38
|
+
this.itemRenderer.setStore(this.list.getFlatStore());
|
|
39
|
+
this.list.setOnItemUpdated((id) => this.itemRenderer.rebindItem(id));
|
|
37
40
|
this.container.setFactory(this.itemRenderer.getFactory());
|
|
38
41
|
}
|
|
39
42
|
|
|
40
43
|
public override isValidChild(child: Node): boolean {
|
|
41
44
|
if (child instanceof EventControllerNode || child instanceof SlotNode || child instanceof ContainerSlotNode)
|
|
42
45
|
return true;
|
|
46
|
+
if (child instanceof ListSectionNode) return true;
|
|
43
47
|
if (!(child instanceof ListItemNode)) return false;
|
|
44
48
|
if (child.getChildNodes().length > 0) {
|
|
45
49
|
throw new Error("GtkGridView does not support nested ListItems. Use GtkListView for tree lists.");
|
|
@@ -49,21 +53,24 @@ export class GridViewNode extends WidgetNode<Gtk.GridView, GridViewProps, GridVi
|
|
|
49
53
|
|
|
50
54
|
public override appendChild(child: GridViewChild): void {
|
|
51
55
|
super.appendChild(child);
|
|
52
|
-
if (child instanceof ListItemNode) {
|
|
53
|
-
this.
|
|
56
|
+
if (child instanceof ListItemNode || child instanceof ListSectionNode) {
|
|
57
|
+
this.list.appendChild(child);
|
|
54
58
|
}
|
|
55
59
|
}
|
|
56
60
|
|
|
57
61
|
public override insertBefore(child: GridViewChild, before: GridViewChild): void {
|
|
58
62
|
super.insertBefore(child, before);
|
|
59
|
-
if (
|
|
60
|
-
|
|
63
|
+
if (
|
|
64
|
+
(child instanceof ListItemNode || child instanceof ListSectionNode) &&
|
|
65
|
+
(before instanceof ListItemNode || before instanceof ListSectionNode)
|
|
66
|
+
) {
|
|
67
|
+
this.list.insertBefore(child, before);
|
|
61
68
|
}
|
|
62
69
|
}
|
|
63
70
|
|
|
64
71
|
public override removeChild(child: GridViewChild): void {
|
|
65
|
-
if (child instanceof ListItemNode) {
|
|
66
|
-
this.
|
|
72
|
+
if (child instanceof ListItemNode || child instanceof ListSectionNode) {
|
|
73
|
+
this.list.removeChild(child);
|
|
67
74
|
}
|
|
68
75
|
super.removeChild(child);
|
|
69
76
|
}
|
|
@@ -80,8 +87,8 @@ export class GridViewNode extends WidgetNode<Gtk.GridView, GridViewProps, GridVi
|
|
|
80
87
|
|
|
81
88
|
public override commitMount(): void {
|
|
82
89
|
super.commitMount();
|
|
83
|
-
this.
|
|
84
|
-
this.container.setModel(this.
|
|
90
|
+
this.list.flushBatch();
|
|
91
|
+
this.container.setModel(this.list.getSelectionModel());
|
|
85
92
|
}
|
|
86
93
|
|
|
87
94
|
public override detachDeletedInstance(): void {
|
|
@@ -98,9 +105,12 @@ export class GridViewNode extends WidgetNode<Gtk.GridView, GridViewProps, GridVi
|
|
|
98
105
|
this.itemRenderer.setEstimatedItemHeight(newProps.estimatedItemHeight ?? null);
|
|
99
106
|
}
|
|
100
107
|
|
|
101
|
-
const previousModel = this.
|
|
102
|
-
this.
|
|
103
|
-
|
|
108
|
+
const previousModel = this.list.getSelectionModel();
|
|
109
|
+
this.list.updateProps(
|
|
110
|
+
oldProps ? filterProps(oldProps, RENDERER_PROPS) : null,
|
|
111
|
+
filterProps(newProps, RENDERER_PROPS),
|
|
112
|
+
);
|
|
113
|
+
const currentModel = this.list.getSelectionModel();
|
|
104
114
|
|
|
105
115
|
if (previousModel !== currentModel) {
|
|
106
116
|
this.container.setModel(currentModel);
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import type * as GObject from "@gtkx/ffi/gobject";
|
|
2
|
+
import { Value } from "@gtkx/ffi/gobject";
|
|
3
|
+
import * as Gtk from "@gtkx/ffi/gtk";
|
|
4
|
+
import type { Props } from "../../types.js";
|
|
5
|
+
|
|
6
|
+
type CreateValue = (jsValue: unknown) => Value;
|
|
7
|
+
|
|
8
|
+
type PropertyDef = {
|
|
9
|
+
kind: "property";
|
|
10
|
+
enumValue: Gtk.AccessibleProperty;
|
|
11
|
+
createValue: CreateValue;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type StateDef = {
|
|
15
|
+
kind: "state";
|
|
16
|
+
enumValue: Gtk.AccessibleState;
|
|
17
|
+
createValue: CreateValue;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
type RelationDef = {
|
|
21
|
+
kind: "relation";
|
|
22
|
+
enumValue: Gtk.AccessibleRelation;
|
|
23
|
+
createValue: CreateValue;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
type AccessiblePropDef = PropertyDef | StateDef | RelationDef;
|
|
27
|
+
|
|
28
|
+
const fromString: CreateValue = (val) => Value.newFromString(val as string);
|
|
29
|
+
const fromBoolean: CreateValue = (val) => Value.newFromBoolean(val as boolean);
|
|
30
|
+
const fromInt: CreateValue = (val) => Value.newFromInt(val as number);
|
|
31
|
+
const fromDouble: CreateValue = (val) => Value.newFromDouble(val as number);
|
|
32
|
+
|
|
33
|
+
const fromObject: CreateValue = (val) => Value.newFromObject((val as GObject.Object) ?? null);
|
|
34
|
+
|
|
35
|
+
const fromRefList: CreateValue = (val) => {
|
|
36
|
+
const widgets = val as Gtk.Accessible[];
|
|
37
|
+
const list = Gtk.AccessibleList.newFromList(widgets);
|
|
38
|
+
return Value.newFromBoxed(list);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const prop = (enumValue: Gtk.AccessibleProperty, createValue: CreateValue): PropertyDef => ({
|
|
42
|
+
kind: "property",
|
|
43
|
+
enumValue,
|
|
44
|
+
createValue,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const state = (enumValue: Gtk.AccessibleState, createValue: CreateValue): StateDef => ({
|
|
48
|
+
kind: "state",
|
|
49
|
+
enumValue,
|
|
50
|
+
createValue,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const relation = (enumValue: Gtk.AccessibleRelation, createValue: CreateValue): RelationDef => ({
|
|
54
|
+
kind: "relation",
|
|
55
|
+
enumValue,
|
|
56
|
+
createValue,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const ACCESSIBLE_PROP_MAP: Record<string, AccessiblePropDef> = {
|
|
60
|
+
accessibleAutocomplete: prop(Gtk.AccessibleProperty.AUTOCOMPLETE, fromInt),
|
|
61
|
+
accessibleDescription: prop(Gtk.AccessibleProperty.DESCRIPTION, fromString),
|
|
62
|
+
accessibleHasPopup: prop(Gtk.AccessibleProperty.HAS_POPUP, fromBoolean),
|
|
63
|
+
accessibleKeyShortcuts: prop(Gtk.AccessibleProperty.KEY_SHORTCUTS, fromString),
|
|
64
|
+
accessibleLabel: prop(Gtk.AccessibleProperty.LABEL, fromString),
|
|
65
|
+
accessibleLevel: prop(Gtk.AccessibleProperty.LEVEL, fromInt),
|
|
66
|
+
accessibleModal: prop(Gtk.AccessibleProperty.MODAL, fromBoolean),
|
|
67
|
+
accessibleMultiLine: prop(Gtk.AccessibleProperty.MULTI_LINE, fromBoolean),
|
|
68
|
+
accessibleMultiSelectable: prop(Gtk.AccessibleProperty.MULTI_SELECTABLE, fromBoolean),
|
|
69
|
+
accessibleOrientation: prop(Gtk.AccessibleProperty.ORIENTATION, fromInt),
|
|
70
|
+
accessiblePlaceholder: prop(Gtk.AccessibleProperty.PLACEHOLDER, fromString),
|
|
71
|
+
accessibleReadOnly: prop(Gtk.AccessibleProperty.READ_ONLY, fromBoolean),
|
|
72
|
+
accessibleRequired: prop(Gtk.AccessibleProperty.REQUIRED, fromBoolean),
|
|
73
|
+
accessibleRoleDescription: prop(Gtk.AccessibleProperty.ROLE_DESCRIPTION, fromString),
|
|
74
|
+
accessibleSort: prop(Gtk.AccessibleProperty.SORT, fromInt),
|
|
75
|
+
accessibleValueMax: prop(Gtk.AccessibleProperty.VALUE_MAX, fromDouble),
|
|
76
|
+
accessibleValueMin: prop(Gtk.AccessibleProperty.VALUE_MIN, fromDouble),
|
|
77
|
+
accessibleValueNow: prop(Gtk.AccessibleProperty.VALUE_NOW, fromDouble),
|
|
78
|
+
accessibleValueText: prop(Gtk.AccessibleProperty.VALUE_TEXT, fromString),
|
|
79
|
+
accessibleHelpText: prop(Gtk.AccessibleProperty.HELP_TEXT, fromString),
|
|
80
|
+
|
|
81
|
+
accessibleBusy: state(Gtk.AccessibleState.BUSY, fromBoolean),
|
|
82
|
+
accessibleChecked: state(Gtk.AccessibleState.CHECKED, fromInt),
|
|
83
|
+
accessibleDisabled: state(Gtk.AccessibleState.DISABLED, fromBoolean),
|
|
84
|
+
accessibleExpanded: state(Gtk.AccessibleState.EXPANDED, fromInt),
|
|
85
|
+
accessibleHidden: state(Gtk.AccessibleState.HIDDEN, fromBoolean),
|
|
86
|
+
accessibleInvalid: state(Gtk.AccessibleState.INVALID, fromInt),
|
|
87
|
+
accessiblePressed: state(Gtk.AccessibleState.PRESSED, fromInt),
|
|
88
|
+
accessibleSelected: state(Gtk.AccessibleState.SELECTED, fromInt),
|
|
89
|
+
accessibleVisited: state(Gtk.AccessibleState.VISITED, fromInt),
|
|
90
|
+
|
|
91
|
+
accessibleActiveDescendant: relation(Gtk.AccessibleRelation.ACTIVE_DESCENDANT, fromObject),
|
|
92
|
+
accessibleColCount: relation(Gtk.AccessibleRelation.COL_COUNT, fromInt),
|
|
93
|
+
accessibleColIndex: relation(Gtk.AccessibleRelation.COL_INDEX, fromInt),
|
|
94
|
+
accessibleColIndexText: relation(Gtk.AccessibleRelation.COL_INDEX_TEXT, fromString),
|
|
95
|
+
accessibleColSpan: relation(Gtk.AccessibleRelation.COL_SPAN, fromInt),
|
|
96
|
+
accessibleControls: relation(Gtk.AccessibleRelation.CONTROLS, fromRefList),
|
|
97
|
+
accessibleDescribedBy: relation(Gtk.AccessibleRelation.DESCRIBED_BY, fromRefList),
|
|
98
|
+
accessibleDetails: relation(Gtk.AccessibleRelation.DETAILS, fromRefList),
|
|
99
|
+
accessibleErrorMessage: relation(Gtk.AccessibleRelation.ERROR_MESSAGE, fromRefList),
|
|
100
|
+
accessibleFlowTo: relation(Gtk.AccessibleRelation.FLOW_TO, fromRefList),
|
|
101
|
+
accessibleLabelledBy: relation(Gtk.AccessibleRelation.LABELLED_BY, fromRefList),
|
|
102
|
+
accessibleOwns: relation(Gtk.AccessibleRelation.OWNS, fromRefList),
|
|
103
|
+
accessiblePosInSet: relation(Gtk.AccessibleRelation.POS_IN_SET, fromInt),
|
|
104
|
+
accessibleRowCount: relation(Gtk.AccessibleRelation.ROW_COUNT, fromInt),
|
|
105
|
+
accessibleRowIndex: relation(Gtk.AccessibleRelation.ROW_INDEX, fromInt),
|
|
106
|
+
accessibleRowIndexText: relation(Gtk.AccessibleRelation.ROW_INDEX_TEXT, fromString),
|
|
107
|
+
accessibleRowSpan: relation(Gtk.AccessibleRelation.ROW_SPAN, fromInt),
|
|
108
|
+
accessibleSetSize: relation(Gtk.AccessibleRelation.SET_SIZE, fromInt),
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export const isAccessibleProp = (name: string): boolean => name in ACCESSIBLE_PROP_MAP;
|
|
112
|
+
|
|
113
|
+
function applyDef(widget: Gtk.Widget, def: AccessiblePropDef, newValue: unknown): void {
|
|
114
|
+
const gvalue = def.createValue(newValue);
|
|
115
|
+
|
|
116
|
+
switch (def.kind) {
|
|
117
|
+
case "property":
|
|
118
|
+
widget.updatePropertyValue(1, [def.enumValue], [gvalue]);
|
|
119
|
+
break;
|
|
120
|
+
case "state":
|
|
121
|
+
widget.updateStateValue(1, [def.enumValue], [gvalue]);
|
|
122
|
+
break;
|
|
123
|
+
case "relation":
|
|
124
|
+
widget.updateRelationValue(1, [def.enumValue], [gvalue]);
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function resetDef(widget: Gtk.Widget, def: AccessiblePropDef): void {
|
|
130
|
+
switch (def.kind) {
|
|
131
|
+
case "property":
|
|
132
|
+
widget.resetProperty(def.enumValue);
|
|
133
|
+
break;
|
|
134
|
+
case "state":
|
|
135
|
+
widget.resetState(def.enumValue);
|
|
136
|
+
break;
|
|
137
|
+
case "relation":
|
|
138
|
+
widget.resetRelation(def.enumValue);
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export const applyAccessibleProps = (widget: Gtk.Widget, oldProps: Props | null, newProps: Props): void => {
|
|
144
|
+
for (const [name, def] of Object.entries(ACCESSIBLE_PROP_MAP)) {
|
|
145
|
+
const oldValue = oldProps?.[name];
|
|
146
|
+
const newValue = newProps[name];
|
|
147
|
+
|
|
148
|
+
if (oldValue === newValue) continue;
|
|
149
|
+
|
|
150
|
+
if (newValue === undefined) {
|
|
151
|
+
resetDef(widget, def);
|
|
152
|
+
} else {
|
|
153
|
+
applyDef(widget, def, newValue);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
};
|