@gtkx/react 0.9.4 → 0.10.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 +55 -67
- package/dist/errors.d.ts +3 -3
- package/dist/errors.js +8 -8
- package/dist/factory.d.ts +3 -5
- package/dist/factory.js +18 -71
- package/dist/fiber-root.d.ts +1 -1
- package/dist/fiber-root.js +1 -2
- package/dist/generated/internal.d.ts +3 -6
- package/dist/generated/internal.js +10386 -13577
- package/dist/generated/jsx.d.ts +914 -808
- package/dist/generated/jsx.js +123 -358
- package/dist/generated/registry.d.ts +4 -0
- package/dist/generated/registry.js +13 -0
- package/dist/host-config.d.ts +7 -4
- package/dist/host-config.js +53 -18
- package/dist/index.d.ts +2 -22
- package/dist/index.js +2 -40
- package/dist/jsx.d.ts +719 -0
- package/dist/jsx.js +392 -0
- package/dist/node.d.ts +15 -32
- package/dist/node.js +20 -240
- package/dist/nodes/action-row-child.d.ts +21 -0
- package/dist/nodes/action-row-child.js +69 -0
- package/dist/nodes/action-row.js +33 -0
- package/dist/nodes/application.d.ts +1 -0
- package/dist/nodes/application.js +38 -0
- package/dist/nodes/autowrapped.d.ts +1 -0
- package/dist/nodes/autowrapped.js +109 -0
- package/dist/nodes/column-view-column.d.ts +16 -0
- package/dist/nodes/column-view-column.js +54 -0
- package/dist/nodes/column-view.d.ts +0 -59
- package/dist/nodes/column-view.js +107 -226
- package/dist/nodes/fixed-child.d.ts +1 -0
- package/dist/nodes/fixed-child.js +45 -0
- package/dist/nodes/grid-child.d.ts +1 -0
- package/dist/nodes/grid-child.js +54 -0
- package/dist/nodes/index.d.ts +34 -0
- package/dist/nodes/index.js +34 -0
- package/dist/nodes/internal/list-item-renderer.d.ts +18 -0
- package/dist/nodes/internal/list-item-renderer.js +67 -0
- package/dist/nodes/internal/list-store.d.ts +16 -0
- package/dist/nodes/internal/list-store.js +69 -0
- package/dist/nodes/internal/predicates.d.ts +26 -0
- package/dist/nodes/internal/predicates.js +36 -0
- package/dist/nodes/internal/signal-store.d.ts +9 -0
- package/dist/nodes/internal/signal-store.js +54 -0
- package/dist/nodes/internal/simple-list-store.d.ts +14 -0
- package/dist/nodes/internal/simple-list-store.js +60 -0
- package/dist/nodes/internal/tree-list-item-renderer.d.ts +18 -0
- package/dist/nodes/internal/tree-list-item-renderer.js +90 -0
- package/dist/nodes/internal/tree-store.d.ts +28 -0
- package/dist/nodes/internal/tree-store.js +153 -0
- package/dist/nodes/internal/utils.d.ts +3 -0
- package/dist/nodes/internal/utils.js +20 -0
- package/dist/nodes/list-item.d.ts +12 -0
- package/dist/nodes/list-item.js +24 -0
- package/dist/nodes/list-view.d.ts +0 -22
- package/dist/nodes/list-view.js +45 -38
- package/dist/nodes/menu.d.ts +6 -106
- package/dist/nodes/menu.js +16 -268
- package/dist/nodes/models/list.d.ts +24 -0
- package/dist/nodes/models/list.js +102 -0
- package/dist/nodes/models/menu.d.ts +45 -0
- package/dist/nodes/models/menu.js +265 -0
- package/dist/nodes/models/tree-list.d.ts +28 -0
- package/dist/nodes/models/tree-list.js +141 -0
- package/dist/nodes/navigation-page.d.ts +21 -0
- package/dist/nodes/navigation-page.js +95 -0
- package/dist/nodes/navigation-view.d.ts +1 -0
- package/dist/nodes/navigation-view.js +29 -0
- package/dist/nodes/notebook-page-tab.d.ts +15 -0
- package/dist/nodes/notebook-page-tab.js +42 -0
- package/dist/nodes/notebook-page.d.ts +23 -0
- package/dist/nodes/notebook-page.js +106 -0
- package/dist/nodes/notebook.d.ts +0 -32
- package/dist/nodes/notebook.js +20 -113
- package/dist/nodes/overlay-child.d.ts +1 -0
- package/dist/nodes/overlay-child.js +30 -0
- package/dist/nodes/pack-child.d.ts +21 -0
- package/dist/nodes/pack-child.js +68 -0
- package/dist/nodes/pack.d.ts +1 -0
- package/dist/nodes/pack.js +33 -0
- package/dist/nodes/popover-menu.d.ts +1 -0
- package/dist/nodes/popover-menu.js +58 -0
- package/dist/nodes/simple-list-item.d.ts +9 -0
- package/dist/nodes/simple-list-item.js +9 -0
- package/dist/nodes/simple-list-view.d.ts +1 -0
- package/dist/nodes/simple-list-view.js +75 -0
- package/dist/nodes/slot.d.ts +18 -10
- package/dist/nodes/slot.js +83 -51
- package/dist/nodes/stack-page.d.ts +1 -0
- package/dist/nodes/stack-page.js +80 -0
- package/dist/nodes/stack.d.ts +1 -22
- package/dist/nodes/stack.js +21 -60
- package/dist/nodes/toast-overlay.d.ts +1 -0
- package/dist/nodes/toast-overlay.js +35 -0
- package/dist/nodes/toast.d.ts +17 -0
- package/dist/nodes/toast.js +77 -0
- package/dist/nodes/toolbar-child.d.ts +9 -0
- package/dist/nodes/toolbar-child.js +33 -0
- package/dist/nodes/toolbar.d.ts +1 -0
- package/dist/nodes/toolbar.js +42 -0
- package/dist/nodes/tree-list-item.d.ts +20 -0
- package/dist/nodes/tree-list-item.js +102 -0
- package/dist/nodes/tree-list-view.d.ts +1 -0
- package/dist/nodes/tree-list-view.js +57 -0
- package/dist/nodes/virtual.d.ts +13 -0
- package/dist/nodes/virtual.js +21 -0
- package/dist/nodes/widget.d.ts +17 -3
- package/dist/nodes/widget.js +258 -2
- package/dist/nodes/window.d.ts +1 -12
- package/dist/nodes/window.js +66 -27
- package/dist/portal.d.ts +18 -13
- package/dist/portal.js +17 -14
- package/dist/reconciler.d.ts +0 -4
- package/dist/reconciler.js +1 -9
- package/dist/registry.d.ts +8 -0
- package/dist/registry.js +5 -0
- package/dist/render.d.ts +108 -12
- package/dist/render.js +140 -16
- package/dist/scheduler.d.ts +4 -0
- package/dist/scheduler.js +10 -0
- package/dist/types.d.ts +3 -136
- package/package.json +6 -6
- package/dist/batch.d.ts +0 -5
- package/dist/batch.js +0 -31
- package/dist/codegen/jsx-generator.d.ts +0 -56
- package/dist/codegen/jsx-generator.js +0 -959
- package/dist/containers.d.ts +0 -58
- package/dist/nodes/about-dialog.d.ts +0 -8
- package/dist/nodes/about-dialog.js +0 -16
- package/dist/nodes/action-bar.d.ts +0 -5
- package/dist/nodes/action-bar.js +0 -6
- package/dist/nodes/combo-row.d.ts +0 -5
- package/dist/nodes/combo-row.js +0 -6
- package/dist/nodes/drop-down.d.ts +0 -9
- package/dist/nodes/drop-down.js +0 -12
- package/dist/nodes/flow-box.d.ts +0 -10
- package/dist/nodes/flow-box.js +0 -41
- package/dist/nodes/grid.d.ts +0 -30
- package/dist/nodes/grid.js +0 -84
- package/dist/nodes/header-bar.d.ts +0 -43
- package/dist/nodes/header-bar.js +0 -116
- package/dist/nodes/indexed-child-container.d.ts +0 -16
- package/dist/nodes/indexed-child-container.js +0 -22
- package/dist/nodes/list-box.d.ts +0 -10
- package/dist/nodes/list-box.js +0 -48
- package/dist/nodes/list-item-factory.d.ts +0 -19
- package/dist/nodes/list-item-factory.js +0 -58
- package/dist/nodes/overlay.d.ts +0 -11
- package/dist/nodes/overlay.js +0 -50
- package/dist/nodes/paged-stack.d.ts +0 -31
- package/dist/nodes/paged-stack.js +0 -95
- package/dist/nodes/root.d.ts +0 -8
- package/dist/nodes/root.js +0 -13
- package/dist/nodes/selectable-list.d.ts +0 -45
- package/dist/nodes/selectable-list.js +0 -260
- package/dist/nodes/stack-page-props.d.ts +0 -11
- package/dist/nodes/stack-page-props.js +0 -23
- package/dist/nodes/string-list-container.d.ts +0 -34
- package/dist/nodes/string-list-container.js +0 -118
- package/dist/nodes/string-list-item.d.ts +0 -19
- package/dist/nodes/string-list-item.js +0 -50
- package/dist/nodes/string-list-store.d.ts +0 -13
- package/dist/nodes/string-list-store.js +0 -44
- package/dist/nodes/text-view.d.ts +0 -8
- package/dist/nodes/text-view.js +0 -16
- package/dist/nodes/toggle-button.d.ts +0 -14
- package/dist/nodes/toggle-button.js +0 -39
- package/dist/nodes/toolbar-view.d.ts +0 -14
- package/dist/nodes/toolbar-view.js +0 -78
- package/dist/nodes/view-stack.d.ts +0 -9
- package/dist/nodes/view-stack.js +0 -28
- package/dist/nodes/virtual-item.d.ts +0 -19
- package/dist/nodes/virtual-item.js +0 -48
- package/dist/nodes/virtual-slot.d.ts +0 -25
- package/dist/nodes/virtual-slot.js +0 -57
- package/dist/predicates.d.ts +0 -29
- package/dist/predicates.js +0 -37
- package/dist/props.d.ts +0 -7
- package/dist/props.js +0 -12
- /package/dist/{containers.js → nodes/action-row.d.ts} +0 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { registerNodeClass } from "../registry.js";
|
|
2
|
+
import { scheduleAfterCommit } from "../scheduler.js";
|
|
3
|
+
import { VirtualNode } from "./virtual.js";
|
|
4
|
+
export class TreeListItemNode extends VirtualNode {
|
|
5
|
+
static priority = 1;
|
|
6
|
+
store;
|
|
7
|
+
parentItemId;
|
|
8
|
+
childNodes = [];
|
|
9
|
+
static matches(type) {
|
|
10
|
+
return type === "TreeListItem";
|
|
11
|
+
}
|
|
12
|
+
setStore(store) {
|
|
13
|
+
this.store = store;
|
|
14
|
+
for (const child of this.childNodes) {
|
|
15
|
+
child.setStore(store);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
setParentItemId(parentId) {
|
|
19
|
+
this.parentItemId = parentId;
|
|
20
|
+
}
|
|
21
|
+
getParentItemId() {
|
|
22
|
+
return this.parentItemId;
|
|
23
|
+
}
|
|
24
|
+
appendChild(child) {
|
|
25
|
+
if (!(child instanceof TreeListItemNode)) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
child.setStore(this.store);
|
|
29
|
+
child.setParentItemId(this.props.id);
|
|
30
|
+
this.childNodes.push(child);
|
|
31
|
+
scheduleAfterCommit(() => {
|
|
32
|
+
if (this.store && child.props.id !== undefined) {
|
|
33
|
+
this.store.addItem(child.props.id, {
|
|
34
|
+
value: child.props.value,
|
|
35
|
+
indentForDepth: child.props.indentForDepth,
|
|
36
|
+
indentForIcon: child.props.indentForIcon,
|
|
37
|
+
hideExpander: child.props.hideExpander,
|
|
38
|
+
}, this.props.id);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
insertBefore(child, before) {
|
|
43
|
+
if (!(child instanceof TreeListItemNode) || !(before instanceof TreeListItemNode)) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
child.setStore(this.store);
|
|
47
|
+
child.setParentItemId(this.props.id);
|
|
48
|
+
const beforeIndex = this.childNodes.indexOf(before);
|
|
49
|
+
if (beforeIndex === -1) {
|
|
50
|
+
this.childNodes.push(child);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
this.childNodes.splice(beforeIndex, 0, child);
|
|
54
|
+
}
|
|
55
|
+
scheduleAfterCommit(() => {
|
|
56
|
+
if (this.store && child.props.id !== undefined && before.props.id !== undefined) {
|
|
57
|
+
this.store.insertItemBefore(child.props.id, before.props.id, {
|
|
58
|
+
value: child.props.value,
|
|
59
|
+
indentForDepth: child.props.indentForDepth,
|
|
60
|
+
indentForIcon: child.props.indentForIcon,
|
|
61
|
+
hideExpander: child.props.hideExpander,
|
|
62
|
+
}, this.props.id);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
removeChild(child) {
|
|
67
|
+
if (!(child instanceof TreeListItemNode)) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const index = this.childNodes.indexOf(child);
|
|
71
|
+
if (index !== -1) {
|
|
72
|
+
this.childNodes.splice(index, 1);
|
|
73
|
+
}
|
|
74
|
+
if (this.store && child.props.id !== undefined) {
|
|
75
|
+
this.store.removeItem(child.props.id, this.props.id);
|
|
76
|
+
}
|
|
77
|
+
child.setStore(undefined);
|
|
78
|
+
child.setParentItemId(undefined);
|
|
79
|
+
}
|
|
80
|
+
updateProps(oldProps, newProps) {
|
|
81
|
+
super.updateProps(oldProps, newProps);
|
|
82
|
+
if (!this.store) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (!oldProps ||
|
|
86
|
+
oldProps.id !== newProps.id ||
|
|
87
|
+
oldProps.value !== newProps.value ||
|
|
88
|
+
oldProps.indentForDepth !== newProps.indentForDepth ||
|
|
89
|
+
oldProps.indentForIcon !== newProps.indentForIcon ||
|
|
90
|
+
oldProps.hideExpander !== newProps.hideExpander) {
|
|
91
|
+
if (newProps.id !== undefined) {
|
|
92
|
+
this.store.updateItem(newProps.id, {
|
|
93
|
+
value: newProps.value,
|
|
94
|
+
indentForDepth: newProps.indentForDepth,
|
|
95
|
+
indentForIcon: newProps.indentForIcon,
|
|
96
|
+
hideExpander: newProps.hideExpander,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
registerNodeClass(TreeListItemNode);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import * as Gtk from "@gtkx/ffi/gtk";
|
|
2
|
+
import { registerNodeClass } from "../registry.js";
|
|
3
|
+
import { TreeListItemRenderer } from "./internal/tree-list-item-renderer.js";
|
|
4
|
+
import { filterProps } from "./internal/utils.js";
|
|
5
|
+
import { TreeList } from "./models/tree-list.js";
|
|
6
|
+
import { TreeListItemNode } from "./tree-list-item.js";
|
|
7
|
+
import { WidgetNode } from "./widget.js";
|
|
8
|
+
const PROP_NAMES = ["renderItem", "autoexpand", "selectionMode", "selected", "onSelectionChanged"];
|
|
9
|
+
class TreeListViewNode extends WidgetNode {
|
|
10
|
+
static priority = 1;
|
|
11
|
+
itemRenderer;
|
|
12
|
+
treeList;
|
|
13
|
+
static matches(type) {
|
|
14
|
+
return type === "TreeListView";
|
|
15
|
+
}
|
|
16
|
+
static createContainer() {
|
|
17
|
+
return new Gtk.ListView();
|
|
18
|
+
}
|
|
19
|
+
constructor(typeName, props, container, rootContainer) {
|
|
20
|
+
const listView = container ?? new Gtk.ListView();
|
|
21
|
+
super(typeName, props, listView, rootContainer);
|
|
22
|
+
this.treeList = new TreeList(props.autoexpand, props.selectionMode);
|
|
23
|
+
this.itemRenderer = new TreeListItemRenderer(this.signalStore);
|
|
24
|
+
this.itemRenderer.setStore(this.treeList.getStore());
|
|
25
|
+
this.container.setFactory(this.itemRenderer.getFactory());
|
|
26
|
+
}
|
|
27
|
+
mount() {
|
|
28
|
+
super.mount();
|
|
29
|
+
this.container.setModel(this.treeList.getSelectionModel());
|
|
30
|
+
}
|
|
31
|
+
appendChild(child) {
|
|
32
|
+
if (!(child instanceof TreeListItemNode)) {
|
|
33
|
+
throw new Error(`Cannot append '${child.typeName}' to 'TreeListView': expected TreeListItem`);
|
|
34
|
+
}
|
|
35
|
+
this.treeList.appendChild(child);
|
|
36
|
+
}
|
|
37
|
+
insertBefore(child, before) {
|
|
38
|
+
if (!(child instanceof TreeListItemNode) || !(before instanceof TreeListItemNode)) {
|
|
39
|
+
throw new Error(`Cannot insert '${child.typeName}' to 'TreeListView': expected TreeListItem`);
|
|
40
|
+
}
|
|
41
|
+
this.treeList.insertBefore(child, before);
|
|
42
|
+
}
|
|
43
|
+
removeChild(child) {
|
|
44
|
+
if (!(child instanceof TreeListItemNode)) {
|
|
45
|
+
throw new Error(`Cannot remove '${child.typeName}' from 'TreeListView': expected TreeListItem`);
|
|
46
|
+
}
|
|
47
|
+
this.treeList.removeChild(child);
|
|
48
|
+
}
|
|
49
|
+
updateProps(oldProps, newProps) {
|
|
50
|
+
if (!oldProps || oldProps.renderItem !== newProps.renderItem) {
|
|
51
|
+
this.itemRenderer.setRenderFn(newProps.renderItem);
|
|
52
|
+
}
|
|
53
|
+
this.treeList.updateProps(filterProps(oldProps ?? {}, ["renderItem"]), filterProps(newProps, ["renderItem"]));
|
|
54
|
+
super.updateProps(filterProps(oldProps ?? {}, PROP_NAMES), filterProps(newProps, PROP_NAMES));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
registerNodeClass(TreeListViewNode);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Node } from "../node.js";
|
|
2
|
+
import type { Container, Props } from "../types.js";
|
|
3
|
+
export declare class VirtualNode<P = Props> extends Node<undefined, P> {
|
|
4
|
+
static priority: number;
|
|
5
|
+
static matches(_type: string): boolean;
|
|
6
|
+
static createContainer(): void;
|
|
7
|
+
props: P;
|
|
8
|
+
constructor(typeName: string, props: P | undefined, container: undefined, rootContainer?: Container);
|
|
9
|
+
appendChild(_child: Node): void;
|
|
10
|
+
removeChild(_child: Node): void;
|
|
11
|
+
insertBefore(_child: Node, _before: Node): void;
|
|
12
|
+
updateProps(_oldProps: P | null, newProps: P): void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Node } from "../node.js";
|
|
2
|
+
import { registerNodeClass } from "../registry.js";
|
|
3
|
+
export class VirtualNode extends Node {
|
|
4
|
+
static priority = 1;
|
|
5
|
+
static matches(_type) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
static createContainer() { }
|
|
9
|
+
props;
|
|
10
|
+
constructor(typeName, props = {}, container, rootContainer) {
|
|
11
|
+
super(typeName, props, container, rootContainer);
|
|
12
|
+
this.props = props;
|
|
13
|
+
}
|
|
14
|
+
appendChild(_child) { }
|
|
15
|
+
removeChild(_child) { }
|
|
16
|
+
insertBefore(_child, _before) { }
|
|
17
|
+
updateProps(_oldProps, newProps) {
|
|
18
|
+
this.props = newProps;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
registerNodeClass(VirtualNode);
|
package/dist/nodes/widget.d.ts
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as Gtk from "@gtkx/ffi/gtk";
|
|
2
2
|
import { Node } from "../node.js";
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import type { Container, ContainerClass, Props } from "../types.js";
|
|
4
|
+
export declare class WidgetNode<T extends Gtk.Widget = Gtk.Widget, P extends Props = Props> extends Node<T, P> {
|
|
5
|
+
static priority: number;
|
|
6
|
+
private motionController?;
|
|
7
|
+
private clickController?;
|
|
8
|
+
private keyController?;
|
|
9
|
+
private scrollController?;
|
|
10
|
+
static matches(_type: string, containerOrClass?: Container | ContainerClass): boolean;
|
|
11
|
+
static createContainer(props: Props, containerClass: typeof Gtk.Widget): Container | undefined;
|
|
12
|
+
appendChild(child: Node): void;
|
|
13
|
+
removeChild(child: Node): void;
|
|
14
|
+
insertBefore(child: Node, before: Node): void;
|
|
15
|
+
updateProps(oldProps: P | null, newProps: P): void;
|
|
16
|
+
private updateEventControllerProp;
|
|
17
|
+
private propNameToSignalName;
|
|
18
|
+
private setProperty;
|
|
5
19
|
}
|
package/dist/nodes/widget.js
CHANGED
|
@@ -1,6 +1,262 @@
|
|
|
1
|
+
import { batch, NativeObject } from "@gtkx/ffi";
|
|
2
|
+
import * as Gtk from "@gtkx/ffi/gtk";
|
|
3
|
+
import { CONSTRUCTOR_PROPS, PROPS, SIGNALS } from "../generated/internal.js";
|
|
1
4
|
import { Node } from "../node.js";
|
|
5
|
+
import { registerNodeClass } from "../registry.js";
|
|
6
|
+
import { isAddable, isAppendable, isEditable, isInsertable, isRemovable, isReorderable, isSingleChild, } from "./internal/predicates.js";
|
|
7
|
+
import { filterProps, isContainerType } from "./internal/utils.js";
|
|
8
|
+
import { SlotNode } from "./slot.js";
|
|
9
|
+
const EVENT_CONTROLLER_PROPS = new Set([
|
|
10
|
+
"onEnter",
|
|
11
|
+
"onLeave",
|
|
12
|
+
"onMotion",
|
|
13
|
+
"onPressed",
|
|
14
|
+
"onReleased",
|
|
15
|
+
"onKeyPressed",
|
|
16
|
+
"onKeyReleased",
|
|
17
|
+
"onScroll",
|
|
18
|
+
"onNotify",
|
|
19
|
+
]);
|
|
2
20
|
export class WidgetNode extends Node {
|
|
3
|
-
static
|
|
4
|
-
|
|
21
|
+
static priority = 3;
|
|
22
|
+
motionController;
|
|
23
|
+
clickController;
|
|
24
|
+
keyController;
|
|
25
|
+
scrollController;
|
|
26
|
+
static matches(_type, containerOrClass) {
|
|
27
|
+
return isContainerType(Gtk.Widget, containerOrClass);
|
|
28
|
+
}
|
|
29
|
+
static createContainer(props, containerClass) {
|
|
30
|
+
const WidgetClass = containerClass;
|
|
31
|
+
const typeName = WidgetClass.glibTypeName;
|
|
32
|
+
const args = (CONSTRUCTOR_PROPS[typeName] ?? []).map((name) => props[name]);
|
|
33
|
+
return new WidgetClass(...args);
|
|
34
|
+
}
|
|
35
|
+
appendChild(child) {
|
|
36
|
+
if (child instanceof SlotNode) {
|
|
37
|
+
child.setParent(this.container);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (!(child instanceof WidgetNode)) {
|
|
41
|
+
throw new Error(`Cannot append '${child.typeName}' to 'Widget': expected WidgetNode child`);
|
|
42
|
+
}
|
|
43
|
+
if (child.container instanceof Gtk.Window) {
|
|
44
|
+
throw new Error(`Cannot append 'Window' to '${this.typeName}': windows must be top-level containers`);
|
|
45
|
+
}
|
|
46
|
+
batch(() => {
|
|
47
|
+
if (isAppendable(this.container)) {
|
|
48
|
+
const currentParent = child.container.getParent();
|
|
49
|
+
if (currentParent !== null && isRemovable(currentParent)) {
|
|
50
|
+
currentParent.remove(child.container);
|
|
51
|
+
}
|
|
52
|
+
this.container.append(child.container);
|
|
53
|
+
}
|
|
54
|
+
else if (isAddable(this.container)) {
|
|
55
|
+
const currentParent = child.container.getParent();
|
|
56
|
+
if (currentParent !== null && isRemovable(currentParent)) {
|
|
57
|
+
currentParent.remove(child.container);
|
|
58
|
+
}
|
|
59
|
+
this.container.add(child.container);
|
|
60
|
+
}
|
|
61
|
+
else if (isSingleChild(this.container)) {
|
|
62
|
+
this.container.setChild(child.container);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
throw new Error(`Cannot append '${child.typeName}' to '${this.container.constructor.name}': container does not support children`);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
removeChild(child) {
|
|
70
|
+
if (child instanceof SlotNode) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (!(child instanceof WidgetNode)) {
|
|
74
|
+
throw new Error(`Cannot remove '${child.typeName}' from 'Widget': expected WidgetNode child`);
|
|
75
|
+
}
|
|
76
|
+
if (child.container instanceof Gtk.Window) {
|
|
77
|
+
throw new Error(`Cannot remove 'Window' from '${this.typeName}': windows must be top-level containers`);
|
|
78
|
+
}
|
|
79
|
+
batch(() => {
|
|
80
|
+
if (isRemovable(this.container)) {
|
|
81
|
+
this.container.remove(child.container);
|
|
82
|
+
}
|
|
83
|
+
else if (isSingleChild(this.container)) {
|
|
84
|
+
this.container.setChild(null);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
throw new Error(`Cannot remove '${child.typeName}' from '${this.container.constructor.name}': container does not support child removal`);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
insertBefore(child, before) {
|
|
92
|
+
if (child instanceof SlotNode) {
|
|
93
|
+
child.setParent(this.container);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (!(child instanceof WidgetNode) || !(before instanceof WidgetNode)) {
|
|
97
|
+
throw new Error(`Cannot insert '${child.typeName}' before '${before.typeName}': expected WidgetNode children`);
|
|
98
|
+
}
|
|
99
|
+
if (child.container instanceof Gtk.Window) {
|
|
100
|
+
throw new Error(`Cannot insert 'Window' into '${this.typeName}': windows must be top-level containers`);
|
|
101
|
+
}
|
|
102
|
+
batch(() => {
|
|
103
|
+
if (isReorderable(this.container)) {
|
|
104
|
+
let beforeChild = this.container.getFirstChild();
|
|
105
|
+
while (beforeChild) {
|
|
106
|
+
if (beforeChild.equals(before.container)) {
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
beforeChild = beforeChild.getNextSibling();
|
|
110
|
+
}
|
|
111
|
+
if (!beforeChild) {
|
|
112
|
+
throw new Error(`Cannot insert '${child.typeName}': 'before' child not found in container`);
|
|
113
|
+
}
|
|
114
|
+
const previousSibling = beforeChild.getPrevSibling() ?? undefined;
|
|
115
|
+
const currentParent = child.container.getParent();
|
|
116
|
+
const isChildOfThisContainer = currentParent?.equals(this.container);
|
|
117
|
+
if (isChildOfThisContainer) {
|
|
118
|
+
this.container.reorderChildAfter(child.container, previousSibling);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
if (currentParent !== null && isRemovable(currentParent)) {
|
|
122
|
+
currentParent.remove(child.container);
|
|
123
|
+
}
|
|
124
|
+
this.container.insertChildAfter(child.container, previousSibling);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
else if (isInsertable(this.container)) {
|
|
128
|
+
const currentParent = child.container.getParent();
|
|
129
|
+
if (currentParent !== null && isRemovable(currentParent)) {
|
|
130
|
+
currentParent.remove(child.container);
|
|
131
|
+
}
|
|
132
|
+
let position = 0;
|
|
133
|
+
let currentChild = this.container.getFirstChild();
|
|
134
|
+
while (currentChild) {
|
|
135
|
+
if (currentChild.equals(before.container)) {
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
position++;
|
|
139
|
+
currentChild = currentChild.getNextSibling();
|
|
140
|
+
}
|
|
141
|
+
if (!currentChild) {
|
|
142
|
+
throw new Error(`Cannot insert '${child.typeName}': 'before' child not found in container`);
|
|
143
|
+
}
|
|
144
|
+
this.container.insert(child.container, position);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
this.appendChild(child);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
updateProps(oldProps, newProps) {
|
|
152
|
+
const propNames = new Set([
|
|
153
|
+
...Object.keys(filterProps(oldProps ?? {}, ["children"])),
|
|
154
|
+
...Object.keys(filterProps(newProps ?? {}, ["children"])),
|
|
155
|
+
]);
|
|
156
|
+
const WidgetClass = this.container.constructor;
|
|
157
|
+
const signals = SIGNALS[WidgetClass.glibTypeName] || new Set();
|
|
158
|
+
for (const name of propNames) {
|
|
159
|
+
const oldValue = oldProps?.[name];
|
|
160
|
+
const newValue = newProps[name];
|
|
161
|
+
if (oldValue === newValue)
|
|
162
|
+
continue;
|
|
163
|
+
if (EVENT_CONTROLLER_PROPS.has(name)) {
|
|
164
|
+
this.updateEventControllerProp(name, newValue);
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
const signalName = this.propNameToSignalName(name);
|
|
168
|
+
if (signals.has(signalName)) {
|
|
169
|
+
const handler = typeof newValue === "function" ? newValue : undefined;
|
|
170
|
+
this.signalStore.set(this.container, signalName, handler);
|
|
171
|
+
}
|
|
172
|
+
else if (newValue !== undefined) {
|
|
173
|
+
this.setProperty(name, newValue);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
updateEventControllerProp(propName, handler) {
|
|
178
|
+
switch (propName) {
|
|
179
|
+
case "onEnter":
|
|
180
|
+
case "onLeave":
|
|
181
|
+
case "onMotion": {
|
|
182
|
+
if (!this.motionController) {
|
|
183
|
+
this.motionController = new Gtk.EventControllerMotion();
|
|
184
|
+
this.container.addController(this.motionController);
|
|
185
|
+
}
|
|
186
|
+
const signalName = propName === "onEnter" ? "enter" : propName === "onLeave" ? "leave" : "motion";
|
|
187
|
+
this.signalStore.set(this.motionController, signalName, handler);
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
case "onPressed":
|
|
191
|
+
case "onReleased": {
|
|
192
|
+
if (!this.clickController) {
|
|
193
|
+
this.clickController = new Gtk.GestureClick();
|
|
194
|
+
this.container.addController(this.clickController);
|
|
195
|
+
}
|
|
196
|
+
const signalName = propName === "onPressed" ? "pressed" : "released";
|
|
197
|
+
this.signalStore.set(this.clickController, signalName, handler);
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
case "onKeyPressed":
|
|
201
|
+
case "onKeyReleased": {
|
|
202
|
+
if (!this.keyController) {
|
|
203
|
+
this.keyController = new Gtk.EventControllerKey();
|
|
204
|
+
this.container.addController(this.keyController);
|
|
205
|
+
}
|
|
206
|
+
const signalName = propName === "onKeyPressed" ? "key-pressed" : "key-released";
|
|
207
|
+
this.signalStore.set(this.keyController, signalName, handler);
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
case "onScroll": {
|
|
211
|
+
if (!this.scrollController) {
|
|
212
|
+
this.scrollController = new Gtk.EventControllerScroll(Gtk.EventControllerScrollFlags.BOTH_AXES);
|
|
213
|
+
this.container.addController(this.scrollController);
|
|
214
|
+
}
|
|
215
|
+
this.signalStore.set(this.scrollController, "scroll", handler);
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
case "onNotify": {
|
|
219
|
+
const wrappedHandler = handler
|
|
220
|
+
? (_obj, pspec) => {
|
|
221
|
+
handler(pspec.getName());
|
|
222
|
+
}
|
|
223
|
+
: undefined;
|
|
224
|
+
this.signalStore.set(this.container, "notify", wrappedHandler);
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
propNameToSignalName(name) {
|
|
230
|
+
return name
|
|
231
|
+
.slice(2)
|
|
232
|
+
.replace(/([A-Z])/g, "-$1")
|
|
233
|
+
.toLowerCase()
|
|
234
|
+
.replace(/^-/, "");
|
|
235
|
+
}
|
|
236
|
+
setProperty(key, value) {
|
|
237
|
+
const WidgetClass = this.container.constructor;
|
|
238
|
+
const [getterName, setterName] = PROPS[WidgetClass.glibTypeName]?.[key] || [];
|
|
239
|
+
const setter = this.container[setterName];
|
|
240
|
+
const getter = this.container[getterName];
|
|
241
|
+
if (getter && typeof getter === "function") {
|
|
242
|
+
const currentValue = getter.call(this.container);
|
|
243
|
+
if (currentValue === value) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
if (currentValue instanceof NativeObject && currentValue.equals(value)) {
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
if (setter && typeof setter === "function") {
|
|
251
|
+
const editable = isEditable(this.container) ? this.container : null;
|
|
252
|
+
const shouldPreserveCursor = key === "text" && editable !== null;
|
|
253
|
+
const cursorPosition = shouldPreserveCursor ? editable.getPosition() : 0;
|
|
254
|
+
setter.call(this.container, value);
|
|
255
|
+
if (shouldPreserveCursor && editable !== null) {
|
|
256
|
+
const textLength = editable.getText().length;
|
|
257
|
+
editable.setPosition(Math.min(cursorPosition, textLength));
|
|
258
|
+
}
|
|
259
|
+
}
|
|
5
260
|
}
|
|
6
261
|
}
|
|
262
|
+
registerNodeClass(WidgetNode);
|
package/dist/nodes/window.d.ts
CHANGED
|
@@ -1,12 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import type { Props } from "../factory.js";
|
|
3
|
-
import { Node } from "../node.js";
|
|
4
|
-
export declare class WindowNode extends Node<Gtk.Window> {
|
|
5
|
-
static consumedPropNames: string[];
|
|
6
|
-
static matches(type: string): boolean;
|
|
7
|
-
protected isStandalone(): boolean;
|
|
8
|
-
protected createWidget(type: string, _props: Props): Gtk.Window;
|
|
9
|
-
mount(): void;
|
|
10
|
-
unmount(): void;
|
|
11
|
-
updateProps(oldProps: Props, newProps: Props): void;
|
|
12
|
-
}
|
|
1
|
+
export {};
|
package/dist/nodes/window.js
CHANGED
|
@@ -1,44 +1,83 @@
|
|
|
1
|
-
import { getApplication } from "@gtkx/ffi";
|
|
2
1
|
import * as Adw from "@gtkx/ffi/adw";
|
|
3
2
|
import * as Gtk from "@gtkx/ffi/gtk";
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
3
|
+
import { registerNodeClass } from "../registry.js";
|
|
4
|
+
import { filterProps, isContainerType } from "./internal/utils.js";
|
|
5
|
+
import { Menu } from "./models/menu.js";
|
|
6
|
+
import { WidgetNode } from "./widget.js";
|
|
7
|
+
const PROPS = ["defaultWidth", "defaultHeight"];
|
|
8
|
+
class WindowNode extends WidgetNode {
|
|
9
|
+
static priority = 1;
|
|
10
|
+
menu;
|
|
11
|
+
static matches(_type, containerOrClass) {
|
|
12
|
+
return isContainerType(Gtk.Window, containerOrClass);
|
|
13
|
+
}
|
|
14
|
+
static createContainer(props, containerClass, rootContainer) {
|
|
15
|
+
const WindowClass = containerClass;
|
|
16
|
+
if (isContainerType(Gtk.ApplicationWindow, WindowClass) ||
|
|
17
|
+
isContainerType(Adw.ApplicationWindow, WindowClass)) {
|
|
18
|
+
if (!(rootContainer instanceof Gtk.Application)) {
|
|
19
|
+
throw new Error("Expected ApplicationWindow to be created within Application");
|
|
20
|
+
}
|
|
21
|
+
if (isContainerType(Adw.ApplicationWindow, WindowClass)) {
|
|
22
|
+
return new Adw.ApplicationWindow(rootContainer);
|
|
23
|
+
}
|
|
24
|
+
return new Gtk.ApplicationWindow(rootContainer);
|
|
18
25
|
}
|
|
19
|
-
|
|
20
|
-
|
|
26
|
+
return WidgetNode.createContainer(props, containerClass);
|
|
27
|
+
}
|
|
28
|
+
constructor(typeName, props, container, rootContainer) {
|
|
29
|
+
super(typeName, props, container, rootContainer);
|
|
30
|
+
const application = rootContainer instanceof Gtk.Application ? rootContainer : undefined;
|
|
31
|
+
const actionMap = container instanceof Gtk.ApplicationWindow ? container : undefined;
|
|
32
|
+
this.menu = new Menu("root", {}, actionMap, application);
|
|
33
|
+
}
|
|
34
|
+
appendChild(child) {
|
|
35
|
+
if (child.container instanceof Gtk.Window) {
|
|
36
|
+
child.container.setTransientFor(this.container);
|
|
37
|
+
return;
|
|
21
38
|
}
|
|
22
|
-
|
|
23
|
-
|
|
39
|
+
this.menu.appendChild(child);
|
|
40
|
+
if (child instanceof WidgetNode &&
|
|
41
|
+
(this.container instanceof Adw.ApplicationWindow || this.container instanceof Adw.Window)) {
|
|
42
|
+
this.container.setContent(child.container);
|
|
43
|
+
return;
|
|
24
44
|
}
|
|
25
|
-
|
|
45
|
+
super.appendChild(child);
|
|
46
|
+
}
|
|
47
|
+
removeChild(child) {
|
|
48
|
+
if (child.container instanceof Gtk.Window) {
|
|
49
|
+
child.container.setTransientFor(undefined);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
this.menu.removeChild(child);
|
|
53
|
+
if (child instanceof WidgetNode &&
|
|
54
|
+
(this.container instanceof Adw.ApplicationWindow || this.container instanceof Adw.Window)) {
|
|
55
|
+
this.container.setContent(undefined);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
super.removeChild(child);
|
|
59
|
+
}
|
|
60
|
+
insertBefore(child, before) {
|
|
61
|
+
this.menu.insertBefore(child, before);
|
|
62
|
+
this.appendChild(child);
|
|
26
63
|
}
|
|
27
64
|
mount() {
|
|
28
|
-
this.
|
|
65
|
+
this.container.present();
|
|
66
|
+
super.mount();
|
|
29
67
|
}
|
|
30
68
|
unmount() {
|
|
31
|
-
this.
|
|
69
|
+
this.container.destroy();
|
|
32
70
|
super.unmount();
|
|
33
71
|
}
|
|
34
72
|
updateProps(oldProps, newProps) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
73
|
+
if (!oldProps ||
|
|
74
|
+
oldProps.defaultWidth !== newProps.defaultWidth ||
|
|
75
|
+
oldProps.defaultHeight !== newProps.defaultHeight) {
|
|
38
76
|
const width = newProps.defaultWidth ?? -1;
|
|
39
77
|
const height = newProps.defaultHeight ?? -1;
|
|
40
|
-
this.
|
|
78
|
+
this.container.setDefaultSize(width, height);
|
|
41
79
|
}
|
|
42
|
-
super.updateProps(oldProps, newProps);
|
|
80
|
+
super.updateProps(filterProps(oldProps ?? {}, PROPS), filterProps(newProps, PROPS));
|
|
43
81
|
}
|
|
44
82
|
}
|
|
83
|
+
registerNodeClass(WindowNode);
|
package/dist/portal.d.ts
CHANGED
|
@@ -1,23 +1,28 @@
|
|
|
1
1
|
import type { ReactNode, ReactPortal } from "react";
|
|
2
|
+
import type { Container } from "./types.js";
|
|
2
3
|
/**
|
|
3
|
-
* Creates a portal
|
|
4
|
+
* Creates a React portal for rendering children into a different part of the widget tree.
|
|
4
5
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
6
|
+
* Portals are useful for rendering dialogs, tooltips, or other floating content
|
|
7
|
+
* that should visually appear outside its parent component's boundaries.
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* the internal representation required by custom reconcilers.
|
|
9
|
+
* @param children - The React elements to render in the portal
|
|
10
|
+
* @param container - The target container widget to render into
|
|
11
|
+
* @param key - Optional key for the portal element
|
|
12
|
+
* @returns A ReactPortal element
|
|
13
13
|
*
|
|
14
14
|
* @example
|
|
15
15
|
* ```tsx
|
|
16
|
-
*
|
|
17
|
-
* {createPortal(<AboutDialog programName="My App" />)}
|
|
16
|
+
* import { createPortal } from "@gtkx/react";
|
|
18
17
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* const Modal = ({ container, children }) => {
|
|
19
|
+
* return createPortal(
|
|
20
|
+
* <GtkWindow modal>
|
|
21
|
+
* {children}
|
|
22
|
+
* </GtkWindow>,
|
|
23
|
+
* container
|
|
24
|
+
* );
|
|
25
|
+
* };
|
|
21
26
|
* ```
|
|
22
27
|
*/
|
|
23
|
-
export declare const createPortal: (children: ReactNode, container
|
|
28
|
+
export declare const createPortal: (children: ReactNode, container: Container, key?: string | null) => ReactPortal;
|