@gtkx/react 0.19.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -62
- package/dist/components/compound.d.ts +40 -0
- package/dist/components/compound.d.ts.map +1 -0
- package/dist/components/compound.js +46 -0
- package/dist/components/compound.js.map +1 -0
- package/dist/components/list.d.ts +75 -0
- package/dist/components/list.d.ts.map +1 -0
- package/dist/components/list.js +81 -0
- package/dist/components/list.js.map +1 -0
- package/dist/components/slot-widget.d.ts +15 -0
- package/dist/components/slot-widget.d.ts.map +1 -0
- package/dist/components/slot-widget.js +37 -0
- package/dist/components/slot-widget.js.map +1 -0
- package/dist/errors.d.ts +6 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +8 -6
- package/dist/errors.js.map +1 -1
- package/dist/generated/compounds.d.ts +2672 -0
- package/dist/generated/compounds.d.ts.map +1 -0
- package/dist/generated/compounds.js +2624 -0
- package/dist/generated/compounds.js.map +1 -0
- package/dist/generated/internal.d.ts +6 -7
- package/dist/generated/internal.d.ts.map +1 -1
- package/dist/generated/internal.js +3054 -1838
- package/dist/generated/internal.js.map +1 -1
- package/dist/generated/jsx.d.ts +2096 -4970
- package/dist/generated/jsx.d.ts.map +1 -1
- package/dist/generated/jsx.js +979 -3862
- package/dist/generated/jsx.js.map +1 -1
- package/dist/generated/registry.d.ts +1 -0
- package/dist/generated/registry.d.ts.map +1 -1
- package/dist/generated/registry.js +0 -1
- package/dist/generated/registry.js.map +1 -1
- package/dist/host-config.d.ts.map +1 -1
- package/dist/host-config.js +2 -0
- package/dist/host-config.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/jsx.d.ts +157 -518
- package/dist/jsx.d.ts.map +1 -1
- package/dist/jsx.js +6 -393
- package/dist/jsx.js.map +1 -1
- package/dist/metadata.d.ts +1 -1
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js +7 -3
- package/dist/metadata.js.map +1 -1
- package/dist/node.d.ts +0 -4
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +19 -41
- package/dist/node.js.map +1 -1
- package/dist/nodes/alert-dialog.d.ts +14 -0
- package/dist/nodes/alert-dialog.d.ts.map +1 -0
- package/dist/nodes/alert-dialog.js +41 -0
- package/dist/nodes/alert-dialog.js.map +1 -0
- package/dist/nodes/animation.d.ts +5 -4
- package/dist/nodes/animation.d.ts.map +1 -1
- package/dist/nodes/animation.js +65 -49
- package/dist/nodes/animation.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 -19
- package/dist/nodes/column-view-column.d.ts.map +1 -1
- package/dist/nodes/column-view-column.js +130 -119
- package/dist/nodes/column-view-column.js.map +1 -1
- package/dist/nodes/container-slot.d.ts +3 -1
- package/dist/nodes/container-slot.d.ts.map +1 -1
- package/dist/nodes/container-slot.js +28 -16
- package/dist/nodes/container-slot.js.map +1 -1
- package/dist/nodes/drawing-area.d.ts +3 -1
- package/dist/nodes/drawing-area.d.ts.map +1 -1
- package/dist/nodes/drawing-area.js +20 -22
- package/dist/nodes/drawing-area.js.map +1 -1
- package/dist/nodes/event-controller.d.ts.map +1 -1
- package/dist/nodes/event-controller.js +6 -16
- package/dist/nodes/event-controller.js.map +1 -1
- package/dist/nodes/fixed-child.d.ts +1 -0
- package/dist/nodes/fixed-child.d.ts.map +1 -1
- package/dist/nodes/fixed-child.js +13 -0
- package/dist/nodes/fixed-child.js.map +1 -1
- package/dist/nodes/grid-child.d.ts +1 -0
- package/dist/nodes/grid-child.d.ts.map +1 -1
- package/dist/nodes/grid-child.js +13 -0
- package/dist/nodes/grid-child.js.map +1 -1
- package/dist/nodes/internal/accessible.d.ts.map +1 -1
- package/dist/nodes/internal/accessible.js.map +1 -1
- 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 +1 -8
- package/dist/nodes/internal/construct.d.ts.map +1 -1
- package/dist/nodes/internal/construct.js +30 -54
- package/dist/nodes/internal/construct.js.map +1 -1
- package/dist/nodes/internal/widget.d.ts.map +1 -1
- package/dist/nodes/internal/widget.js +9 -10
- 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 +45 -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 +6 -2
- package/dist/nodes/notebook-page.js.map +1 -1
- package/dist/nodes/overlay-child.d.ts +2 -0
- package/dist/nodes/overlay-child.d.ts.map +1 -1
- package/dist/nodes/overlay-child.js +29 -8
- package/dist/nodes/overlay-child.js.map +1 -1
- package/dist/nodes/spin-row.d.ts +14 -0
- package/dist/nodes/spin-row.d.ts.map +1 -0
- package/dist/nodes/spin-row.js +46 -0
- package/dist/nodes/spin-row.js.map +1 -0
- package/dist/nodes/switch-row.d.ts +11 -0
- package/dist/nodes/switch-row.d.ts.map +1 -0
- package/dist/nodes/switch-row.js +15 -0
- package/dist/nodes/switch-row.js.map +1 -0
- package/dist/nodes/text-anchor.d.ts.map +1 -1
- package/dist/nodes/text-anchor.js +10 -0
- 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 +45 -39
- package/dist/nodes/text-tag.js.map +1 -1
- package/dist/nodes/toggle-group.d.ts +12 -6
- package/dist/nodes/toggle-group.d.ts.map +1 -1
- package/dist/nodes/toggle-group.js +53 -4
- package/dist/nodes/toggle-group.js.map +1 -1
- package/dist/nodes/widget.d.ts.map +1 -1
- package/dist/nodes/widget.js +16 -22
- 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 +11 -18
- package/dist/registry.js.map +1 -1
- package/dist/types.d.ts +3 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/use-property.d.ts +29 -0
- package/dist/use-property.d.ts.map +1 -0
- package/dist/use-property.js +44 -0
- package/dist/use-property.js.map +1 -0
- package/dist/use-setting.d.ts +36 -0
- package/dist/use-setting.d.ts.map +1 -0
- package/dist/use-setting.js +68 -0
- package/dist/use-setting.js.map +1 -0
- package/package.json +5 -4
- package/src/components/compound.tsx +57 -0
- package/src/components/list.tsx +140 -0
- package/src/components/slot-widget.tsx +46 -0
- package/src/errors.ts +8 -7
- package/src/generated/compounds.ts +2741 -0
- package/src/generated/internal.ts +3059 -1840
- package/src/generated/jsx.ts +2509 -5350
- package/src/generated/registry.ts +2 -1
- package/src/host-config.ts +2 -0
- package/src/index.ts +2 -0
- package/src/jsx.ts +167 -581
- package/src/metadata.ts +7 -4
- package/src/node.ts +23 -39
- package/src/nodes/alert-dialog.ts +55 -0
- package/src/nodes/animation.ts +67 -60
- package/src/nodes/application.ts +5 -0
- package/src/nodes/column-view-column.ts +125 -128
- package/src/nodes/container-slot.ts +30 -17
- package/src/nodes/drawing-area.ts +23 -32
- package/src/nodes/event-controller.ts +6 -18
- package/src/nodes/fixed-child.ts +13 -0
- package/src/nodes/grid-child.ts +13 -0
- package/src/nodes/internal/accessible.ts +0 -1
- package/src/nodes/internal/bound-item.ts +4 -0
- package/src/nodes/internal/construct.ts +38 -68
- package/src/nodes/internal/widget.ts +9 -13
- package/src/nodes/list-item-node.ts +53 -0
- package/src/nodes/list.ts +1082 -0
- package/src/nodes/notebook-page.ts +6 -2
- package/src/nodes/overlay-child.ts +30 -9
- package/src/nodes/spin-row.ts +72 -0
- package/src/nodes/switch-row.ts +26 -0
- package/src/nodes/text-anchor.ts +9 -0
- package/src/nodes/text-tag.ts +45 -40
- package/src/nodes/toggle-group.ts +63 -9
- package/src/nodes/widget.ts +14 -26
- package/src/nodes/window.ts +2 -2
- package/src/registry.ts +18 -24
- package/src/types.ts +8 -2
- package/src/use-property.ts +58 -0
- package/src/use-setting.ts +96 -0
- 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 -37
- package/dist/nodes/column-view.d.ts.map +0 -1
- package/dist/nodes/column-view.js +0 -205
- package/dist/nodes/column-view.js.map +0 -1
- package/dist/nodes/drop-down.d.ts +0 -37
- package/dist/nodes/drop-down.d.ts.map +0 -1
- package/dist/nodes/drop-down.js +0 -231
- package/dist/nodes/drop-down.js.map +0 -1
- package/dist/nodes/grid-view.d.ts +0 -30
- package/dist/nodes/grid-view.d.ts.map +0 -1
- package/dist/nodes/grid-view.js +0 -90
- 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 -85
- 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/header-item-renderer.d.ts +0 -23
- package/dist/nodes/internal/header-item-renderer.d.ts.map +0 -1
- package/dist/nodes/internal/header-item-renderer.js +0 -87
- package/dist/nodes/internal/header-item-renderer.js.map +0 -1
- package/dist/nodes/internal/header-renderer-manager.d.ts +0 -13
- package/dist/nodes/internal/header-renderer-manager.d.ts.map +0 -1
- package/dist/nodes/internal/header-renderer-manager.js +0 -20
- package/dist/nodes/internal/header-renderer-manager.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 -21
- package/dist/nodes/internal/list-store.d.ts.map +0 -1
- package/dist/nodes/internal/list-store.js +0 -90
- package/dist/nodes/internal/list-store.js.map +0 -1
- package/dist/nodes/internal/sectioned-list-store.d.ts +0 -50
- package/dist/nodes/internal/sectioned-list-store.d.ts.map +0 -1
- package/dist/nodes/internal/sectioned-list-store.js +0 -250
- package/dist/nodes/internal/sectioned-list-store.js.map +0 -1
- package/dist/nodes/internal/selection-helpers.d.ts +0 -12
- package/dist/nodes/internal/selection-helpers.d.ts.map +0 -1
- package/dist/nodes/internal/selection-helpers.js +0 -25
- package/dist/nodes/internal/selection-helpers.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 -82
- package/dist/nodes/internal/selection-model-controller.js.map +0 -1
- package/dist/nodes/internal/simple-list-store.d.ts +0 -15
- package/dist/nodes/internal/simple-list-store.d.ts.map +0 -1
- package/dist/nodes/internal/simple-list-store.js +0 -110
- package/dist/nodes/internal/simple-list-store.js.map +0 -1
- package/dist/nodes/internal/tree-store.d.ts +0 -37
- package/dist/nodes/internal/tree-store.d.ts.map +0 -1
- package/dist/nodes/internal/tree-store.js +0 -253
- 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-section.d.ts +0 -27
- package/dist/nodes/list-section.d.ts.map +0 -1
- package/dist/nodes/list-section.js +0 -43
- package/dist/nodes/list-section.js.map +0 -1
- package/dist/nodes/list-view.d.ts +0 -32
- package/dist/nodes/list-view.d.ts.map +0 -1
- package/dist/nodes/list-view.js +0 -123
- package/dist/nodes/list-view.js.map +0 -1
- package/dist/nodes/models/list.d.ts +0 -39
- package/dist/nodes/models/list.d.ts.map +0 -1
- package/dist/nodes/models/list.js +0 -207
- package/dist/nodes/models/list.js.map +0 -1
- package/src/fiber-root.ts +0 -20
- package/src/nodes/column-view.ts +0 -262
- package/src/nodes/drop-down.ts +0 -284
- package/src/nodes/grid-view.ts +0 -119
- package/src/nodes/internal/base-item-renderer.ts +0 -107
- package/src/nodes/internal/grid-item-renderer.ts +0 -78
- package/src/nodes/internal/header-item-renderer.ts +0 -105
- package/src/nodes/internal/header-renderer-manager.ts +0 -33
- package/src/nodes/internal/list-item-renderer.ts +0 -162
- package/src/nodes/internal/list-store.ts +0 -107
- package/src/nodes/internal/sectioned-list-store.ts +0 -287
- package/src/nodes/internal/selection-helpers.ts +0 -35
- package/src/nodes/internal/selection-model-controller.ts +0 -119
- package/src/nodes/internal/simple-list-store.ts +0 -116
- package/src/nodes/internal/tree-store.ts +0 -289
- package/src/nodes/list-item.ts +0 -107
- package/src/nodes/list-section.ts +0 -64
- package/src/nodes/list-view.ts +0 -164
- package/src/nodes/models/list.ts +0 -250
package/src/nodes/drop-down.ts
DELETED
|
@@ -1,284 +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 { createFiberRoot } from "../fiber-root.js";
|
|
5
|
-
import type { AdwComboRowProps, GtkDropDownProps } from "../jsx.js";
|
|
6
|
-
import type { Node } from "../node.js";
|
|
7
|
-
import { reconciler } from "../reconciler.js";
|
|
8
|
-
import type { DropDownWidget } from "../registry.js";
|
|
9
|
-
import type { Container } from "../types.js";
|
|
10
|
-
import { ContainerSlotNode } from "./container-slot.js";
|
|
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";
|
|
14
|
-
import { filterProps, hasChanged } from "./internal/props.js";
|
|
15
|
-
import { SimpleListStore } from "./internal/simple-list-store.js";
|
|
16
|
-
import { ListItemNode } from "./list-item.js";
|
|
17
|
-
import { ListSectionNode } from "./list-section.js";
|
|
18
|
-
import { SlotNode } from "./slot.js";
|
|
19
|
-
import { WidgetNode } from "./widget.js";
|
|
20
|
-
|
|
21
|
-
const OWN_PROPS = ["selectedId", "onSelectionChanged", "renderItem", "renderListItem", "renderHeader"] as const;
|
|
22
|
-
|
|
23
|
-
type DropDownProps = Pick<GtkDropDownProps | AdwComboRowProps, (typeof OWN_PROPS)[number]>;
|
|
24
|
-
|
|
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
|
-
}
|
|
35
|
-
|
|
36
|
-
export class DropDownNode extends WidgetNode<DropDownWidget, DropDownProps, DropDownChild> {
|
|
37
|
-
private store = new SimpleListStore();
|
|
38
|
-
private initialSelectedId: string | null | undefined;
|
|
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
|
-
|
|
48
|
-
public override isValidChild(child: Node): boolean {
|
|
49
|
-
return (
|
|
50
|
-
child instanceof ListItemNode ||
|
|
51
|
-
child instanceof ListSectionNode ||
|
|
52
|
-
child instanceof EventControllerNode ||
|
|
53
|
-
child instanceof SlotNode ||
|
|
54
|
-
child instanceof ContainerSlotNode
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
constructor(typeName: string, props: DropDownProps, container: DropDownWidget, rootContainer: Container) {
|
|
59
|
-
super(typeName, props, container, rootContainer);
|
|
60
|
-
this.store.beginBatch();
|
|
61
|
-
this.initialSelectedId = props.selectedId;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
public override finalizeInitialChildren(props: DropDownProps): boolean {
|
|
65
|
-
super.finalizeInitialChildren(props);
|
|
66
|
-
this.store.flushBatch();
|
|
67
|
-
this.container.setModel(this.store.getModel());
|
|
68
|
-
this.reapplyInitialSelectedId();
|
|
69
|
-
return false;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
private reapplyInitialSelectedId(): void {
|
|
73
|
-
if (this.initialSelectedId == null) return;
|
|
74
|
-
const index = this.store.getIndexById(this.initialSelectedId);
|
|
75
|
-
this.initialSelectedId = undefined;
|
|
76
|
-
if (index !== null) {
|
|
77
|
-
this.container.setSelected(index);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
public override appendChild(child: DropDownChild): void {
|
|
82
|
-
super.appendChild(child);
|
|
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) {
|
|
87
|
-
child.setStore(this.store);
|
|
88
|
-
this.store.addItem(child.props.id, child.props.value as string);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
public override insertBefore(child: DropDownChild, before: DropDownChild): void {
|
|
93
|
-
super.insertBefore(child, before);
|
|
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) {
|
|
98
|
-
child.setStore(this.store);
|
|
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);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
public override removeChild(child: DropDownChild): void {
|
|
107
|
-
if (child instanceof ListSectionNode) {
|
|
108
|
-
this.store.removeSection(child.props.id);
|
|
109
|
-
child.setStore(null);
|
|
110
|
-
} else if (child instanceof ListItemNode) {
|
|
111
|
-
this.store.removeItem(child.props.id);
|
|
112
|
-
child.setStore(null);
|
|
113
|
-
}
|
|
114
|
-
super.removeChild(child);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
public override commitUpdate(oldProps: DropDownProps | null, newProps: DropDownProps): void {
|
|
118
|
-
super.commitUpdate(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
|
|
119
|
-
this.applyOwnProps(oldProps, newProps);
|
|
120
|
-
}
|
|
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
|
-
|
|
131
|
-
private applyOwnProps(oldProps: DropDownProps | null, newProps: DropDownProps): void {
|
|
132
|
-
if (hasChanged(oldProps, newProps, "onSelectionChanged")) {
|
|
133
|
-
const onSelectionChanged = newProps.onSelectionChanged;
|
|
134
|
-
|
|
135
|
-
const handleSelectionChange = onSelectionChanged
|
|
136
|
-
? () => {
|
|
137
|
-
const selectedIndex = this.container.getSelected();
|
|
138
|
-
const id = this.store.getIdAtIndex(selectedIndex);
|
|
139
|
-
if (id !== null) {
|
|
140
|
-
onSelectionChanged(id);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
: undefined;
|
|
144
|
-
|
|
145
|
-
this.signalStore.set(this, this.container, "notify::selected", handleSelectionChange);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
if (hasChanged(oldProps, newProps, "selectedId")) {
|
|
149
|
-
const index = newProps.selectedId != null ? this.store.getIndexById(newProps.selectedId) : null;
|
|
150
|
-
|
|
151
|
-
if (index !== null) {
|
|
152
|
-
this.container.setSelected(index);
|
|
153
|
-
}
|
|
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();
|
|
283
|
-
}
|
|
284
|
-
}
|
package/src/nodes/grid-view.ts
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import type * as Gtk from "@gtkx/ffi/gtk";
|
|
2
|
-
import type { GtkGridViewProps } from "../jsx.js";
|
|
3
|
-
import type { Node } from "../node.js";
|
|
4
|
-
import type { Container } from "../types.js";
|
|
5
|
-
import { ContainerSlotNode } from "./container-slot.js";
|
|
6
|
-
import { EventControllerNode } from "./event-controller.js";
|
|
7
|
-
import { GridItemRenderer } from "./internal/grid-item-renderer.js";
|
|
8
|
-
import { filterProps, hasChanged } from "./internal/props.js";
|
|
9
|
-
import { ListItemNode } from "./list-item.js";
|
|
10
|
-
import { ListSectionNode } from "./list-section.js";
|
|
11
|
-
import { ListModel, type ListModelProps } from "./models/list.js";
|
|
12
|
-
import { SlotNode } from "./slot.js";
|
|
13
|
-
import { WidgetNode } from "./widget.js";
|
|
14
|
-
|
|
15
|
-
const RENDERER_PROPS = ["renderItem", "estimatedItemHeight"] as const;
|
|
16
|
-
const OWN_PROPS = [...RENDERER_PROPS, "selectionMode", "selected", "onSelectionChanged"] as const;
|
|
17
|
-
|
|
18
|
-
type GridViewProps = Pick<GtkGridViewProps, (typeof RENDERER_PROPS)[number]> & ListModelProps;
|
|
19
|
-
|
|
20
|
-
type GridViewChild = ListItemNode | ListSectionNode | EventControllerNode | SlotNode | ContainerSlotNode;
|
|
21
|
-
|
|
22
|
-
export class GridViewNode extends WidgetNode<Gtk.GridView, GridViewProps, GridViewChild> {
|
|
23
|
-
private itemRenderer: GridItemRenderer;
|
|
24
|
-
private list: ListModel;
|
|
25
|
-
|
|
26
|
-
constructor(typeName: string, props: GridViewProps, container: Gtk.GridView, rootContainer: Container) {
|
|
27
|
-
super(typeName, props, container, rootContainer);
|
|
28
|
-
this.list = new ListModel(
|
|
29
|
-
{ owner: this, signalStore: this.signalStore },
|
|
30
|
-
{
|
|
31
|
-
selectionMode: props.selectionMode,
|
|
32
|
-
selected: props.selected,
|
|
33
|
-
onSelectionChanged: props.onSelectionChanged,
|
|
34
|
-
},
|
|
35
|
-
true,
|
|
36
|
-
);
|
|
37
|
-
this.itemRenderer = new GridItemRenderer(this.signalStore);
|
|
38
|
-
this.itemRenderer.setStore(this.list.getFlatStore());
|
|
39
|
-
this.list.setOnItemUpdated((id) => this.itemRenderer.rebindItem(id));
|
|
40
|
-
this.container.setFactory(this.itemRenderer.getFactory());
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
public override isValidChild(child: Node): boolean {
|
|
44
|
-
if (child instanceof EventControllerNode || child instanceof SlotNode || child instanceof ContainerSlotNode)
|
|
45
|
-
return true;
|
|
46
|
-
if (child instanceof ListSectionNode) return true;
|
|
47
|
-
if (!(child instanceof ListItemNode)) return false;
|
|
48
|
-
if (child.getChildNodes().length > 0) {
|
|
49
|
-
throw new Error("GtkGridView does not support nested ListItems. Use GtkListView for tree lists.");
|
|
50
|
-
}
|
|
51
|
-
return true;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
public override appendChild(child: GridViewChild): void {
|
|
55
|
-
super.appendChild(child);
|
|
56
|
-
if (child instanceof ListItemNode || child instanceof ListSectionNode) {
|
|
57
|
-
this.list.appendChild(child);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
public override insertBefore(child: GridViewChild, before: GridViewChild): void {
|
|
62
|
-
super.insertBefore(child, before);
|
|
63
|
-
if (
|
|
64
|
-
(child instanceof ListItemNode || child instanceof ListSectionNode) &&
|
|
65
|
-
(before instanceof ListItemNode || before instanceof ListSectionNode)
|
|
66
|
-
) {
|
|
67
|
-
this.list.insertBefore(child, before);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
public override removeChild(child: GridViewChild): void {
|
|
72
|
-
if (child instanceof ListItemNode || child instanceof ListSectionNode) {
|
|
73
|
-
this.list.removeChild(child);
|
|
74
|
-
}
|
|
75
|
-
super.removeChild(child);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
public override finalizeInitialChildren(props: GridViewProps): boolean {
|
|
79
|
-
super.finalizeInitialChildren(props);
|
|
80
|
-
return true;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
public override commitUpdate(oldProps: GridViewProps | null, newProps: GridViewProps): void {
|
|
84
|
-
super.commitUpdate(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
|
|
85
|
-
this.applyOwnProps(oldProps, newProps);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
public override commitMount(): void {
|
|
89
|
-
super.commitMount();
|
|
90
|
-
this.list.flushBatch();
|
|
91
|
-
this.container.setModel(this.list.getSelectionModel());
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
public override detachDeletedInstance(): void {
|
|
95
|
-
this.itemRenderer.dispose();
|
|
96
|
-
super.detachDeletedInstance();
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
private applyOwnProps(oldProps: GridViewProps | null, newProps: GridViewProps): void {
|
|
100
|
-
if (hasChanged(oldProps, newProps, "renderItem")) {
|
|
101
|
-
this.itemRenderer.setRenderFn(newProps.renderItem ?? null);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
if (hasChanged(oldProps, newProps, "estimatedItemHeight")) {
|
|
105
|
-
this.itemRenderer.setEstimatedItemHeight(newProps.estimatedItemHeight ?? null);
|
|
106
|
-
}
|
|
107
|
-
|
|
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();
|
|
114
|
-
|
|
115
|
-
if (previousModel !== currentModel) {
|
|
116
|
-
this.container.setModel(currentModel);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
@@ -1,107 +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 { createFiberRoot } from "../../fiber-root.js";
|
|
5
|
-
import { reconciler } from "../../reconciler.js";
|
|
6
|
-
import type { SignalStore } from "./signal-store.js";
|
|
7
|
-
|
|
8
|
-
export abstract class BaseItemRenderer<TStore = unknown> {
|
|
9
|
-
protected factory: Gtk.SignalListItemFactory;
|
|
10
|
-
protected fiberRoots = new Map<Gtk.ListItem, Reconciler.FiberRoot>();
|
|
11
|
-
protected tornDown = new Set<Gtk.ListItem>();
|
|
12
|
-
protected estimatedItemHeight: number | null = null;
|
|
13
|
-
private store: TStore | null = null;
|
|
14
|
-
protected signalStore: SignalStore;
|
|
15
|
-
|
|
16
|
-
constructor(signalStore: SignalStore) {
|
|
17
|
-
this.signalStore = signalStore;
|
|
18
|
-
this.factory = new Gtk.SignalListItemFactory();
|
|
19
|
-
this.initializeFactory();
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
public getFactory(): Gtk.SignalListItemFactory {
|
|
23
|
-
return this.factory;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
public setEstimatedItemHeight(height: number | null): void {
|
|
27
|
-
this.estimatedItemHeight = height;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
public setStore(store: TStore | null): void {
|
|
31
|
-
this.store = store;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
protected getStore(): TStore {
|
|
35
|
-
if (!this.store) {
|
|
36
|
-
throw new Error(`Expected store to be set on ${this.constructor.name}`);
|
|
37
|
-
}
|
|
38
|
-
return this.store;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
public dispose(): void {
|
|
42
|
-
this.signalStore.clear(this);
|
|
43
|
-
this.fiberRoots.clear();
|
|
44
|
-
this.tornDown.clear();
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
protected abstract renderItem(listItem: Gtk.ListItem): ReactNode;
|
|
48
|
-
protected abstract onSetup(listItem: Gtk.ListItem): Gtk.Widget;
|
|
49
|
-
protected abstract onBind(listItem: Gtk.ListItem, fiberRoot: Reconciler.FiberRoot): void;
|
|
50
|
-
protected abstract onUnbind(listItem: Gtk.ListItem): void;
|
|
51
|
-
|
|
52
|
-
protected onSetupComplete(_listItem: Gtk.ListItem): void {}
|
|
53
|
-
protected onTeardown(_listItem: Gtk.ListItem): void {}
|
|
54
|
-
|
|
55
|
-
protected createBox(): Gtk.Box {
|
|
56
|
-
const box = new Gtk.Box(Gtk.Orientation.HORIZONTAL);
|
|
57
|
-
|
|
58
|
-
if (this.estimatedItemHeight !== null) {
|
|
59
|
-
box.setSizeRequest(-1, this.estimatedItemHeight);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return box;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
protected clearBoxSizeRequest(box: Gtk.Widget): void {
|
|
66
|
-
if (box instanceof Gtk.Box) {
|
|
67
|
-
box.setSizeRequest(-1, -1);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
private initializeFactory(): void {
|
|
72
|
-
this.signalStore.set(this, this.factory, "setup", (listItem: Gtk.ListItem) => {
|
|
73
|
-
const container = this.onSetup(listItem);
|
|
74
|
-
const fiberRoot = createFiberRoot(container);
|
|
75
|
-
this.fiberRoots.set(listItem, fiberRoot);
|
|
76
|
-
const element = this.renderItem(listItem);
|
|
77
|
-
reconciler.getInstance().updateContainer(element, fiberRoot, null, () => {
|
|
78
|
-
if (this.tornDown.has(listItem)) return;
|
|
79
|
-
this.onSetupComplete(listItem);
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
this.signalStore.set(this, this.factory, "bind", (listItem: Gtk.ListItem) => {
|
|
84
|
-
const fiberRoot = this.fiberRoots.get(listItem);
|
|
85
|
-
if (!fiberRoot) return;
|
|
86
|
-
this.onBind(listItem, fiberRoot);
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
this.signalStore.set(this, this.factory, "unbind", (listItem: Gtk.ListItem) => {
|
|
90
|
-
this.onUnbind(listItem);
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
this.signalStore.set(this, this.factory, "teardown", (listItem: Gtk.ListItem) => {
|
|
94
|
-
const fiberRoot = this.fiberRoots.get(listItem);
|
|
95
|
-
|
|
96
|
-
if (fiberRoot) {
|
|
97
|
-
this.tornDown.add(listItem);
|
|
98
|
-
this.onTeardown(listItem);
|
|
99
|
-
reconciler.getInstance().updateContainer(null, fiberRoot, null, () => {});
|
|
100
|
-
queueMicrotask(() => {
|
|
101
|
-
this.fiberRoots.delete(listItem);
|
|
102
|
-
this.tornDown.delete(listItem);
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
}
|
|
@@ -1,78 +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 { ListStore } from "./list-store.js";
|
|
7
|
-
|
|
8
|
-
type GridRenderItemFn<T> = (item: T | null) => ReactNode;
|
|
9
|
-
|
|
10
|
-
export class GridItemRenderer extends BaseItemRenderer<ListStore> {
|
|
11
|
-
private renderFn: GridRenderItemFn<unknown> | null = () => null;
|
|
12
|
-
private boundItems = new Map<string, Gtk.ListItem>();
|
|
13
|
-
|
|
14
|
-
public setRenderFn(renderFn: GridRenderItemFn<unknown> | null): void {
|
|
15
|
-
this.renderFn = renderFn;
|
|
16
|
-
this.rebindAllItems();
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
public rebindAllItems(): void {
|
|
20
|
-
for (const id of this.boundItems.keys()) {
|
|
21
|
-
this.rebindItem(id);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
public rebindItem(id: string): void {
|
|
26
|
-
const listItem = this.boundItems.get(id);
|
|
27
|
-
if (!listItem) return;
|
|
28
|
-
|
|
29
|
-
const fiberRoot = this.fiberRoots.get(listItem);
|
|
30
|
-
if (!fiberRoot) return;
|
|
31
|
-
|
|
32
|
-
const item = this.getStore().getItem(id);
|
|
33
|
-
const element = this.renderFn?.(item);
|
|
34
|
-
|
|
35
|
-
reconciler.getInstance().updateContainer(element, fiberRoot, null, () => {});
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
protected override renderItem(_listItem: Gtk.ListItem): ReactNode {
|
|
39
|
-
return this.renderFn?.(null);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
private getItemFromListItem(listItem: Gtk.ListItem): string | null {
|
|
43
|
-
const stringObject = listItem.getItem();
|
|
44
|
-
if (!(stringObject instanceof Gtk.StringObject)) return null;
|
|
45
|
-
return stringObject.getString();
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
protected override onSetup(listItem: Gtk.ListItem): Gtk.Widget {
|
|
49
|
-
const box = this.createBox();
|
|
50
|
-
listItem.setChild(box);
|
|
51
|
-
return box;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
protected override onBind(listItem: Gtk.ListItem, fiberRoot: Reconciler.FiberRoot): void {
|
|
55
|
-
const id = this.getItemFromListItem(listItem);
|
|
56
|
-
if (id !== null) {
|
|
57
|
-
this.boundItems.set(id, listItem);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const item = id !== null ? this.getStore().getItem(id) : null;
|
|
61
|
-
const element = this.renderFn?.(item);
|
|
62
|
-
|
|
63
|
-
reconciler.getInstance().updateContainer(element, fiberRoot, null, () => {
|
|
64
|
-
if (this.tornDown.has(listItem)) return;
|
|
65
|
-
if (this.estimatedItemHeight !== null) return;
|
|
66
|
-
const currentFiberRoot = this.fiberRoots.get(listItem);
|
|
67
|
-
if (!currentFiberRoot) return;
|
|
68
|
-
this.clearBoxSizeRequest(currentFiberRoot.containerInfo);
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
protected override onUnbind(listItem: Gtk.ListItem): void {
|
|
73
|
-
const id = this.getItemFromListItem(listItem);
|
|
74
|
-
if (id !== null) {
|
|
75
|
-
this.boundItems.delete(id);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
@@ -1,105 +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 { createFiberRoot } from "../../fiber-root.js";
|
|
5
|
-
import { reconciler } from "../../reconciler.js";
|
|
6
|
-
import type { SignalStore } from "./signal-store.js";
|
|
7
|
-
|
|
8
|
-
type RenderHeaderFn = (item: unknown) => ReactNode;
|
|
9
|
-
|
|
10
|
-
type ItemResolver = (id: string) => unknown;
|
|
11
|
-
|
|
12
|
-
export class HeaderItemRenderer {
|
|
13
|
-
private factory: Gtk.SignalListItemFactory;
|
|
14
|
-
private fiberRoots = new Map<object, Reconciler.FiberRoot>();
|
|
15
|
-
private tornDown = new Set<object>();
|
|
16
|
-
private renderFn: RenderHeaderFn | null = () => null;
|
|
17
|
-
private boundHeaders = new Map<string, object>();
|
|
18
|
-
private signalStore: SignalStore;
|
|
19
|
-
private resolveItem: ItemResolver | null = null;
|
|
20
|
-
|
|
21
|
-
constructor(signalStore: SignalStore) {
|
|
22
|
-
this.signalStore = signalStore;
|
|
23
|
-
this.factory = new Gtk.SignalListItemFactory();
|
|
24
|
-
this.initializeFactory();
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
public getFactory(): Gtk.SignalListItemFactory {
|
|
28
|
-
return this.factory;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
public setResolveItem(resolver: ItemResolver | null): void {
|
|
32
|
-
this.resolveItem = resolver;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
public setRenderFn(renderFn: RenderHeaderFn | null): void {
|
|
36
|
-
this.renderFn = renderFn;
|
|
37
|
-
this.rebindAllHeaders();
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
public dispose(): void {
|
|
41
|
-
this.signalStore.clear(this);
|
|
42
|
-
this.fiberRoots.clear();
|
|
43
|
-
this.tornDown.clear();
|
|
44
|
-
this.boundHeaders.clear();
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
private rebindAllHeaders(): void {
|
|
48
|
-
for (const [id, header] of this.boundHeaders) {
|
|
49
|
-
const fiberRoot = this.fiberRoots.get(header);
|
|
50
|
-
if (!fiberRoot) continue;
|
|
51
|
-
const item = this.resolveItem?.(id) ?? null;
|
|
52
|
-
const element = this.renderFn?.(item);
|
|
53
|
-
reconciler.getInstance().updateContainer(element, fiberRoot, null, () => {});
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
private initializeFactory(): void {
|
|
58
|
-
this.signalStore.set(this, this.factory, "setup", (listHeader: Gtk.ListHeader) => {
|
|
59
|
-
const box = new Gtk.Box(Gtk.Orientation.HORIZONTAL);
|
|
60
|
-
listHeader.setChild(box);
|
|
61
|
-
const fiberRoot = createFiberRoot(box);
|
|
62
|
-
this.fiberRoots.set(listHeader, fiberRoot);
|
|
63
|
-
const element = this.renderFn?.(null);
|
|
64
|
-
reconciler.getInstance().updateContainer(element, fiberRoot, null, () => {});
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
this.signalStore.set(this, this.factory, "bind", (listHeader: Gtk.ListHeader) => {
|
|
68
|
-
const fiberRoot = this.fiberRoots.get(listHeader);
|
|
69
|
-
if (!fiberRoot) return;
|
|
70
|
-
|
|
71
|
-
const stringObject = listHeader.getItem();
|
|
72
|
-
let id: string | null = null;
|
|
73
|
-
if (stringObject instanceof Gtk.StringObject) {
|
|
74
|
-
id = stringObject.getString();
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
if (id !== null) {
|
|
78
|
-
this.boundHeaders.set(id, listHeader);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const item = id !== null && this.resolveItem ? this.resolveItem(id) : null;
|
|
82
|
-
const element = this.renderFn?.(item);
|
|
83
|
-
reconciler.getInstance().updateContainer(element, fiberRoot, null, () => {});
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
this.signalStore.set(this, this.factory, "unbind", (listHeader: Gtk.ListHeader) => {
|
|
87
|
-
const stringObject = listHeader.getItem();
|
|
88
|
-
if (stringObject instanceof Gtk.StringObject) {
|
|
89
|
-
this.boundHeaders.delete(stringObject.getString());
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
this.signalStore.set(this, this.factory, "teardown", (listHeader: Gtk.ListHeader) => {
|
|
94
|
-
const fiberRoot = this.fiberRoots.get(listHeader);
|
|
95
|
-
if (fiberRoot) {
|
|
96
|
-
this.tornDown.add(listHeader);
|
|
97
|
-
reconciler.getInstance().updateContainer(null, fiberRoot, null, () => {});
|
|
98
|
-
queueMicrotask(() => {
|
|
99
|
-
this.fiberRoots.delete(listHeader);
|
|
100
|
-
this.tornDown.delete(listHeader);
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
}
|