@gtkx/react 0.15.0 → 0.16.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 +1 -0
- package/dist/errors.js +3 -0
- package/dist/factory.d.ts +3 -2
- package/dist/factory.js +1 -1
- package/dist/generated/internal.d.ts +28 -1
- package/dist/generated/internal.js +93 -18
- package/dist/generated/jsx.d.ts +1489 -1300
- package/dist/generated/jsx.js +475 -0
- package/dist/host-config.d.ts +3 -1
- package/dist/host-config.js +31 -11
- package/dist/jsx.d.ts +107 -166
- package/dist/jsx.js +58 -69
- package/dist/node.d.ts +3 -1
- package/dist/node.js +5 -3
- package/dist/nodes/abstract/positional-child.d.ts +9 -0
- package/dist/nodes/abstract/positional-child.js +29 -0
- package/dist/nodes/abstract/positional-parent.d.ts +18 -0
- package/dist/nodes/abstract/positional-parent.js +48 -0
- package/dist/nodes/abstract/virtual-container.d.ts +17 -0
- package/dist/nodes/abstract/virtual-container.js +59 -0
- package/dist/nodes/abstract/virtual-single-child.d.ts +18 -0
- package/dist/nodes/abstract/virtual-single-child.js +54 -0
- package/dist/nodes/action-row-child.d.ts +0 -13
- package/dist/nodes/action-row-child.js +14 -12
- package/dist/nodes/action-row.d.ts +6 -1
- package/dist/nodes/action-row.js +4 -37
- package/dist/nodes/adjustable.d.ts +23 -0
- package/dist/nodes/adjustable.js +62 -0
- package/dist/nodes/alert-dialog-response.d.ts +1 -0
- package/dist/nodes/alert-dialog-response.js +86 -0
- package/dist/nodes/animation/animation-controller.d.ts +17 -0
- package/dist/nodes/animation/animation-controller.js +107 -0
- package/dist/nodes/animation/animation-factory.d.ts +15 -0
- package/dist/nodes/animation/animation-factory.js +25 -0
- package/dist/nodes/animation/animation-node.d.ts +9 -0
- package/dist/nodes/animation/animation-node.js +126 -0
- package/dist/nodes/animation/animation-style-sheet.d.ts +16 -0
- package/dist/nodes/animation/animation-style-sheet.js +74 -0
- package/dist/nodes/animation/index.d.ts +4 -0
- package/dist/nodes/animation/index.js +1 -0
- package/dist/nodes/animation/property-mapper.d.ts +11 -0
- package/dist/nodes/animation/property-mapper.js +36 -0
- package/dist/nodes/animation/transform-state.d.ts +11 -0
- package/dist/nodes/animation/transform-state.js +57 -0
- package/dist/nodes/animation/widget-registry.d.ts +5 -0
- package/dist/nodes/animation/widget-registry.js +42 -0
- package/dist/nodes/application.js +17 -7
- package/dist/nodes/autowrapped.js +37 -43
- package/dist/nodes/calendar.js +17 -43
- package/dist/nodes/color-dialog-button.d.ts +1 -0
- package/dist/nodes/color-dialog-button.js +70 -0
- package/dist/nodes/column-view-column.d.ts +3 -3
- package/dist/nodes/column-view-column.js +1 -1
- package/dist/nodes/column-view.js +36 -39
- package/dist/nodes/dialog.d.ts +11 -0
- package/dist/nodes/dialog.js +20 -0
- package/dist/nodes/drawing-area.js +24 -7
- package/dist/nodes/event-controller.d.ts +1 -0
- package/dist/nodes/event-controller.js +96 -0
- package/dist/nodes/expander-row-child.d.ts +0 -14
- package/dist/nodes/expander-row-child.js +14 -12
- package/dist/nodes/expander-row.d.ts +6 -1
- package/dist/nodes/expander-row.js +11 -48
- package/dist/nodes/fixed-child.js +48 -36
- package/dist/nodes/font-dialog-button.d.ts +1 -0
- package/dist/nodes/font-dialog-button.js +90 -0
- package/dist/nodes/grid-child.js +39 -45
- package/dist/nodes/grid.d.ts +1 -0
- package/dist/nodes/grid.js +41 -0
- package/dist/nodes/index.d.ts +17 -9
- package/dist/nodes/index.js +17 -9
- package/dist/nodes/internal/base-item-renderer.d.ts +29 -0
- package/dist/nodes/internal/base-item-renderer.js +88 -0
- package/dist/nodes/internal/base-store.d.ts +9 -0
- package/dist/nodes/internal/base-store.js +20 -0
- package/dist/nodes/internal/child-attachment.d.ts +26 -0
- package/dist/nodes/internal/child-attachment.js +48 -0
- package/dist/nodes/internal/deferred-action.d.ts +8 -0
- package/dist/nodes/internal/deferred-action.js +19 -0
- package/dist/nodes/internal/list-item-renderer.d.ts +14 -15
- package/dist/nodes/internal/list-item-renderer.js +51 -77
- package/dist/nodes/internal/list-store.d.ts +7 -6
- package/dist/nodes/internal/list-store.js +20 -24
- package/dist/nodes/internal/predicates.d.ts +25 -2
- package/dist/nodes/internal/predicates.js +53 -41
- package/dist/nodes/internal/selection-model.d.ts +30 -0
- package/dist/nodes/internal/selection-model.js +91 -0
- package/dist/nodes/internal/signal-store.d.ts +5 -4
- package/dist/nodes/internal/signal-store.js +30 -28
- package/dist/nodes/internal/simple-list-store.js +6 -9
- package/dist/nodes/internal/text-buffer-controller.d.ts +43 -0
- package/dist/nodes/internal/text-buffer-controller.js +287 -0
- package/dist/nodes/internal/text-tag-styles.d.ts +43 -0
- package/dist/nodes/internal/text-tag-styles.js +52 -0
- package/dist/nodes/internal/tree-list-item-renderer.d.ts +15 -14
- package/dist/nodes/internal/tree-list-item-renderer.js +85 -96
- package/dist/nodes/internal/tree-store.d.ts +10 -9
- package/dist/nodes/internal/tree-store.js +31 -35
- package/dist/nodes/internal/utils.d.ts +7 -4
- package/dist/nodes/internal/utils.js +50 -5
- package/dist/nodes/level-bar.js +19 -54
- package/dist/nodes/list-item.d.ts +6 -3
- package/dist/nodes/list-item.js +7 -4
- package/dist/nodes/list-view.js +15 -11
- package/dist/nodes/menu.d.ts +3 -3
- package/dist/nodes/menu.js +3 -3
- package/dist/nodes/models/list.d.ts +11 -13
- package/dist/nodes/models/list.js +16 -73
- package/dist/nodes/models/menu.d.ts +8 -7
- package/dist/nodes/models/menu.js +43 -50
- package/dist/nodes/models/tree-list.d.ts +6 -12
- package/dist/nodes/models/tree-list.js +30 -93
- package/dist/nodes/navigation-page.d.ts +1 -0
- package/dist/nodes/navigation-page.js +27 -32
- package/dist/nodes/navigation-view.js +17 -28
- package/dist/nodes/notebook-page-tab.d.ts +3 -3
- package/dist/nodes/notebook-page-tab.js +11 -14
- package/dist/nodes/notebook-page.d.ts +7 -5
- package/dist/nodes/notebook-page.js +45 -25
- package/dist/nodes/notebook.js +2 -2
- package/dist/nodes/overlay-child.js +90 -30
- package/dist/nodes/pack-child.d.ts +0 -13
- package/dist/nodes/pack-child.js +14 -12
- package/dist/nodes/pack.d.ts +6 -1
- package/dist/nodes/pack.js +4 -37
- package/dist/nodes/popover-menu.js +2 -2
- package/dist/nodes/scale.js +15 -45
- package/dist/nodes/scrolled-window.js +7 -6
- package/dist/nodes/search-bar.d.ts +1 -0
- package/dist/nodes/search-bar.js +40 -0
- package/dist/nodes/shortcut-controller.d.ts +1 -37
- package/dist/nodes/shortcut-controller.js +24 -8
- package/dist/nodes/shortcut.d.ts +5 -4
- package/dist/nodes/shortcut.js +11 -5
- package/dist/nodes/simple-list-view.js +2 -3
- package/dist/nodes/slot.d.ts +6 -9
- package/dist/nodes/slot.js +27 -42
- package/dist/nodes/source-view.js +80 -29
- package/dist/nodes/stack-page.js +20 -22
- package/dist/nodes/stack.js +19 -5
- package/dist/nodes/text-anchor.d.ts +41 -0
- package/dist/nodes/text-anchor.js +59 -0
- package/dist/nodes/text-content.d.ts +10 -0
- package/dist/nodes/text-content.js +1 -0
- package/dist/nodes/text-paintable.d.ts +17 -0
- package/dist/nodes/text-paintable.js +34 -0
- package/dist/nodes/text-segment.d.ts +15 -0
- package/dist/nodes/text-segment.js +29 -0
- package/dist/nodes/text-tag.d.ts +136 -0
- package/dist/nodes/text-tag.js +202 -0
- package/dist/nodes/text-view.d.ts +30 -0
- package/dist/nodes/text-view.js +49 -21
- package/dist/nodes/toggle-group.js +24 -32
- package/dist/nodes/toggle.d.ts +1 -15
- package/dist/nodes/toggle.js +40 -32
- package/dist/nodes/toolbar-child.js +14 -16
- package/dist/nodes/tree-list-item.d.ts +7 -5
- package/dist/nodes/tree-list-item.js +24 -36
- package/dist/nodes/tree-list-view.js +7 -6
- package/dist/nodes/virtual.d.ts +1 -1
- package/dist/nodes/widget.d.ts +2 -16
- package/dist/nodes/widget.js +105 -294
- package/dist/nodes/window.d.ts +9 -3
- package/dist/nodes/window.js +29 -15
- package/dist/registry.d.ts +1 -1
- package/dist/render.js +8 -6
- package/dist/scheduler.d.ts +11 -1
- package/dist/scheduler.js +16 -4
- package/dist/types.d.ts +2 -136
- package/package.json +3 -3
- package/dist/nodes/adjustment.d.ts +0 -48
- package/dist/nodes/adjustment.js +0 -70
- package/dist/nodes/calendar-mark.d.ts +0 -15
- package/dist/nodes/calendar-mark.js +0 -29
- package/dist/nodes/internal/constants.d.ts +0 -1
- package/dist/nodes/internal/constants.js +0 -24
- package/dist/nodes/level-bar-offset.d.ts +0 -13
- package/dist/nodes/level-bar-offset.js +0 -35
- package/dist/nodes/scale-mark.d.ts +0 -17
- package/dist/nodes/scale-mark.js +0 -38
- package/dist/nodes/source-buffer.d.ts +0 -73
- package/dist/nodes/source-buffer.js +0 -149
- package/dist/nodes/text-buffer.d.ts +0 -43
- package/dist/nodes/text-buffer.js +0 -81
- package/dist/nodes/virtual-child.d.ts +0 -18
- package/dist/nodes/virtual-child.js +0 -62
package/dist/nodes/widget.js
CHANGED
|
@@ -1,123 +1,81 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { getNativeObject, isObjectEqual } from "@gtkx/ffi";
|
|
2
|
+
import { ObjectClass, ParamSpecString, Type, TypeInstance, typeClassRef, typeFromName, typeFundamental, typeNameFromInstance, } from "@gtkx/ffi/gobject";
|
|
3
3
|
import * as Gtk from "@gtkx/ffi/gtk";
|
|
4
4
|
import { CONSTRUCTOR_PROPS } from "../generated/internal.js";
|
|
5
5
|
import { Node } from "../node.js";
|
|
6
6
|
import { registerNodeClass } from "../registry.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const
|
|
7
|
+
import { getAttachmentStrategy, attachChild as performAttachment, detachChild as performDetachment, } from "./internal/child-attachment.js";
|
|
8
|
+
import { isAttachable, isEditable, isInsertable, isRemovable, isReorderable, } from "./internal/predicates.js";
|
|
9
|
+
import { filterProps, matchesAnyClass, propNameToSignalName, resolvePropMeta, resolveSignal, } from "./internal/utils.js";
|
|
10
|
+
const EXCLUDED_PROPS = ["children", "widthRequest", "heightRequest", "grabFocus"];
|
|
11
|
+
function findProperty(obj, key) {
|
|
12
|
+
if (!obj.handle)
|
|
13
|
+
return null;
|
|
14
|
+
const propertyName = key.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
15
|
+
const typeInstance = getNativeObject(obj.handle, TypeInstance);
|
|
16
|
+
const typeName = typeNameFromInstance(typeInstance);
|
|
17
|
+
const gtype = typeFromName(typeName);
|
|
18
|
+
const typeClass = typeClassRef(gtype);
|
|
19
|
+
const objectClass = getNativeObject(typeClass.handle, ObjectClass);
|
|
20
|
+
return objectClass.findProperty(propertyName) ?? null;
|
|
21
|
+
}
|
|
15
22
|
export class WidgetNode extends Node {
|
|
16
23
|
static priority = 3;
|
|
17
|
-
motionController;
|
|
18
|
-
clickController;
|
|
19
|
-
keyController;
|
|
20
|
-
scrollController;
|
|
21
|
-
dragSourceController;
|
|
22
|
-
dropTargetController;
|
|
23
|
-
gestureDragController;
|
|
24
|
-
adjustmentChild;
|
|
25
24
|
static matches(_type, containerOrClass) {
|
|
26
|
-
return
|
|
25
|
+
return matchesAnyClass([Gtk.Widget], containerOrClass);
|
|
27
26
|
}
|
|
28
|
-
static createContainer(props, containerClass) {
|
|
27
|
+
static createContainer(props, containerClass, _rootContainer) {
|
|
29
28
|
const WidgetClass = containerClass;
|
|
30
29
|
const typeName = WidgetClass.glibTypeName;
|
|
31
30
|
const args = (CONSTRUCTOR_PROPS[typeName] ?? []).map((name) => props[name]);
|
|
32
31
|
return new WidgetClass(...args);
|
|
33
32
|
}
|
|
34
33
|
appendChild(child) {
|
|
35
|
-
if (child
|
|
36
|
-
child.
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
if (child instanceof SlotNode) {
|
|
40
|
-
child.setParent(this.container);
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
if (child instanceof AdjustmentNode) {
|
|
44
|
-
if (!isAdjustable(this.container)) {
|
|
45
|
-
throw new Error(`Cannot add Adjustment to '${this.typeName}': widget does not support adjustments`);
|
|
46
|
-
}
|
|
47
|
-
if (this.adjustmentChild) {
|
|
48
|
-
throw new Error(`${this.typeName} can only have one Adjustment child`);
|
|
49
|
-
}
|
|
50
|
-
this.adjustmentChild = child;
|
|
51
|
-
child.setWidget(this.container);
|
|
34
|
+
if (isAttachable(child) && child.canBeChildOf(this)) {
|
|
35
|
+
child.attachTo(this);
|
|
52
36
|
return;
|
|
53
37
|
}
|
|
54
38
|
if (!(child instanceof WidgetNode)) {
|
|
55
|
-
throw new Error(`Cannot append '${child.typeName}' to 'Widget': expected
|
|
39
|
+
throw new Error(`Cannot append '${child.typeName}' to 'Widget': expected Widget`);
|
|
56
40
|
}
|
|
57
41
|
if (child.container instanceof Gtk.Window) {
|
|
58
42
|
throw new Error(`Cannot append 'Window' to '${this.typeName}': windows must be top-level containers`);
|
|
59
43
|
}
|
|
60
|
-
|
|
44
|
+
this.attachChild(child);
|
|
61
45
|
}
|
|
62
46
|
removeChild(child) {
|
|
63
|
-
if (child
|
|
64
|
-
child.
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
if (child instanceof SlotNode) {
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
if (child instanceof AdjustmentNode) {
|
|
71
|
-
if (this.adjustmentChild === child) {
|
|
72
|
-
this.adjustmentChild = undefined;
|
|
73
|
-
}
|
|
47
|
+
if (isAttachable(child) && child.canBeChildOf(this)) {
|
|
48
|
+
child.detachFrom(this);
|
|
74
49
|
return;
|
|
75
50
|
}
|
|
76
51
|
if (!(child instanceof WidgetNode)) {
|
|
77
|
-
throw new Error(`Cannot remove '${child.typeName}' from 'Widget': expected
|
|
52
|
+
throw new Error(`Cannot remove '${child.typeName}' from 'Widget': expected Widget`);
|
|
78
53
|
}
|
|
79
54
|
if (child.container instanceof Gtk.Window) {
|
|
80
55
|
throw new Error(`Cannot remove 'Window' from '${this.typeName}': windows must be top-level containers`);
|
|
81
56
|
}
|
|
82
|
-
|
|
57
|
+
this.detachChild(child);
|
|
83
58
|
}
|
|
84
59
|
insertBefore(child, before) {
|
|
85
|
-
if (child
|
|
86
|
-
child.
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
if (child instanceof SlotNode) {
|
|
90
|
-
child.setParent(this.container);
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
if (child instanceof AdjustmentNode) {
|
|
94
|
-
if (!isAdjustable(this.container)) {
|
|
95
|
-
throw new Error(`Cannot add Adjustment to '${this.typeName}': widget does not support adjustments`);
|
|
96
|
-
}
|
|
97
|
-
if (this.adjustmentChild) {
|
|
98
|
-
throw new Error(`${this.typeName} can only have one Adjustment child`);
|
|
99
|
-
}
|
|
100
|
-
this.adjustmentChild = child;
|
|
101
|
-
child.setWidget(this.container);
|
|
60
|
+
if (isAttachable(child) && child.canBeChildOf(this)) {
|
|
61
|
+
child.attachTo(this);
|
|
102
62
|
return;
|
|
103
63
|
}
|
|
104
64
|
if (!(child instanceof WidgetNode) || !(before instanceof WidgetNode)) {
|
|
105
|
-
throw new Error(`Cannot insert '${child.typeName}'
|
|
65
|
+
throw new Error(`Cannot insert '${child.typeName}' into '${this.typeName}': expected Widget`);
|
|
106
66
|
}
|
|
107
67
|
if (child.container instanceof Gtk.Window) {
|
|
108
68
|
throw new Error(`Cannot insert 'Window' into '${this.typeName}': windows must be top-level containers`);
|
|
109
69
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
});
|
|
70
|
+
if (isReorderable(this.container)) {
|
|
71
|
+
this.insertBeforeReorderable(this.container, child, before);
|
|
72
|
+
}
|
|
73
|
+
else if (isInsertable(this.container)) {
|
|
74
|
+
this.insertBeforeInsertable(this.container, child, before);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
this.appendChild(child);
|
|
78
|
+
}
|
|
121
79
|
}
|
|
122
80
|
insertBeforeReorderable(container, child, before) {
|
|
123
81
|
const previousSibling = this.findPreviousSibling(before);
|
|
@@ -137,11 +95,14 @@ export class WidgetNode extends Node {
|
|
|
137
95
|
container.insert(child.container, position);
|
|
138
96
|
}
|
|
139
97
|
updateProps(oldProps, newProps) {
|
|
98
|
+
if (!this.container) {
|
|
99
|
+
throw new Error(`WidgetNode.updateProps: container is undefined for ${this.typeName}`);
|
|
100
|
+
}
|
|
140
101
|
this.updateSizeRequest(oldProps, newProps);
|
|
141
102
|
this.updateGrabFocus(oldProps, newProps);
|
|
142
103
|
const propNames = new Set([
|
|
143
|
-
...Object.keys(filterProps(oldProps ?? {},
|
|
144
|
-
...Object.keys(filterProps(newProps ?? {},
|
|
104
|
+
...Object.keys(filterProps(oldProps ?? {}, EXCLUDED_PROPS)),
|
|
105
|
+
...Object.keys(filterProps(newProps ?? {}, EXCLUDED_PROPS)),
|
|
145
106
|
]);
|
|
146
107
|
const pendingSignals = [];
|
|
147
108
|
const pendingProperties = [];
|
|
@@ -150,40 +111,28 @@ export class WidgetNode extends Node {
|
|
|
150
111
|
const newValue = newProps[name];
|
|
151
112
|
if (oldValue === newValue)
|
|
152
113
|
continue;
|
|
153
|
-
|
|
154
|
-
pendingSignals.push({ name, newValue });
|
|
155
|
-
continue;
|
|
156
|
-
}
|
|
157
|
-
if (name === "onNotify") {
|
|
158
|
-
pendingSignals.push({ name, newValue });
|
|
159
|
-
continue;
|
|
160
|
-
}
|
|
161
|
-
const signalName = this.propNameToSignalName(name);
|
|
114
|
+
const signalName = propNameToSignalName(name);
|
|
162
115
|
if (resolveSignal(this.container, signalName)) {
|
|
163
116
|
pendingSignals.push({ name, newValue });
|
|
164
117
|
}
|
|
165
118
|
else if (newValue !== undefined) {
|
|
166
119
|
pendingProperties.push({ name, oldValue, newValue });
|
|
167
120
|
}
|
|
121
|
+
else if (oldValue !== undefined) {
|
|
122
|
+
const defaultValue = this.getPropertyDefaultValue(name);
|
|
123
|
+
if (defaultValue !== undefined) {
|
|
124
|
+
pendingProperties.push({ name, oldValue, newValue: defaultValue });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
168
127
|
}
|
|
169
128
|
for (const { name, newValue } of pendingSignals) {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
else if (name === "onNotify") {
|
|
174
|
-
this.updateNotifyHandler(newValue ?? null);
|
|
175
|
-
}
|
|
176
|
-
else {
|
|
177
|
-
const signalName = this.propNameToSignalName(name);
|
|
178
|
-
const handler = typeof newValue === "function" ? newValue : undefined;
|
|
179
|
-
signalStore.set(this, this.container, signalName, handler);
|
|
180
|
-
}
|
|
129
|
+
const signalName = propNameToSignalName(name);
|
|
130
|
+
const handler = typeof newValue === "function" ? newValue : undefined;
|
|
131
|
+
this.signalStore.set(this, this.container, signalName, handler);
|
|
181
132
|
}
|
|
182
133
|
for (const { name, oldValue, newValue } of pendingProperties) {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
const currentValue = this.getProperty(name);
|
|
186
|
-
if (oldValue !== currentValue) {
|
|
134
|
+
if (name === "text" && oldValue !== undefined && isEditable(this.container)) {
|
|
135
|
+
if (oldValue !== this.container.getText()) {
|
|
187
136
|
continue;
|
|
188
137
|
}
|
|
189
138
|
}
|
|
@@ -206,157 +155,39 @@ export class WidgetNode extends Node {
|
|
|
206
155
|
this.container.grabFocus();
|
|
207
156
|
}
|
|
208
157
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
? (_self, ...args) => handlerOrValue(...args)
|
|
212
|
-
: undefined;
|
|
213
|
-
switch (propName) {
|
|
214
|
-
case "onEnter":
|
|
215
|
-
case "onLeave":
|
|
216
|
-
case "onMotion": {
|
|
217
|
-
if (!this.motionController) {
|
|
218
|
-
this.motionController = new Gtk.EventControllerMotion();
|
|
219
|
-
this.container.addController(this.motionController);
|
|
220
|
-
}
|
|
221
|
-
const signalName = propName === "onEnter" ? "enter" : propName === "onLeave" ? "leave" : "motion";
|
|
222
|
-
signalStore.set(this, this.motionController, signalName, wrappedHandler);
|
|
223
|
-
break;
|
|
224
|
-
}
|
|
225
|
-
case "onPressed":
|
|
226
|
-
case "onReleased": {
|
|
227
|
-
if (!this.clickController) {
|
|
228
|
-
this.clickController = new Gtk.GestureClick();
|
|
229
|
-
this.container.addController(this.clickController);
|
|
230
|
-
}
|
|
231
|
-
const signalName = propName === "onPressed" ? "pressed" : "released";
|
|
232
|
-
signalStore.set(this, this.clickController, signalName, wrappedHandler);
|
|
233
|
-
break;
|
|
234
|
-
}
|
|
235
|
-
case "onKeyPressed":
|
|
236
|
-
case "onKeyReleased": {
|
|
237
|
-
if (!this.keyController) {
|
|
238
|
-
this.keyController = new Gtk.EventControllerKey();
|
|
239
|
-
this.container.addController(this.keyController);
|
|
240
|
-
}
|
|
241
|
-
const signalName = propName === "onKeyPressed" ? "key-pressed" : "key-released";
|
|
242
|
-
signalStore.set(this, this.keyController, signalName, wrappedHandler);
|
|
243
|
-
break;
|
|
244
|
-
}
|
|
245
|
-
case "onScroll": {
|
|
246
|
-
if (!this.scrollController) {
|
|
247
|
-
this.scrollController = new Gtk.EventControllerScroll(Gtk.EventControllerScrollFlags.BOTH_AXES);
|
|
248
|
-
this.container.addController(this.scrollController);
|
|
249
|
-
}
|
|
250
|
-
signalStore.set(this, this.scrollController, "scroll", wrappedHandler);
|
|
251
|
-
break;
|
|
252
|
-
}
|
|
253
|
-
case "onDragPrepare":
|
|
254
|
-
case "onDragBegin":
|
|
255
|
-
case "onDragEnd":
|
|
256
|
-
case "onDragCancel":
|
|
257
|
-
case "dragActions": {
|
|
258
|
-
const dragSource = this.ensureDragSource();
|
|
259
|
-
if (propName === "dragActions") {
|
|
260
|
-
dragSource.setActions(handlerOrValue ?? Gdk.DragAction.COPY);
|
|
261
|
-
}
|
|
262
|
-
else {
|
|
263
|
-
const signalName = propName === "onDragPrepare"
|
|
264
|
-
? "prepare"
|
|
265
|
-
: propName === "onDragBegin"
|
|
266
|
-
? "drag-begin"
|
|
267
|
-
: propName === "onDragEnd"
|
|
268
|
-
? "drag-end"
|
|
269
|
-
: "drag-cancel";
|
|
270
|
-
signalStore.set(this, dragSource, signalName, wrappedHandler);
|
|
271
|
-
}
|
|
272
|
-
break;
|
|
273
|
-
}
|
|
274
|
-
case "onDrop":
|
|
275
|
-
case "onDropEnter":
|
|
276
|
-
case "onDropLeave":
|
|
277
|
-
case "onDropMotion":
|
|
278
|
-
case "dropActions":
|
|
279
|
-
case "dropTypes": {
|
|
280
|
-
const dropTarget = this.ensureDropTarget();
|
|
281
|
-
if (propName === "dropActions") {
|
|
282
|
-
dropTarget.setActions(handlerOrValue ?? Gdk.DragAction.COPY);
|
|
283
|
-
}
|
|
284
|
-
else if (propName === "dropTypes") {
|
|
285
|
-
const types = handlerOrValue ?? [];
|
|
286
|
-
dropTarget.setGtypes(types.length, types);
|
|
287
|
-
}
|
|
288
|
-
else {
|
|
289
|
-
const signalName = propName === "onDrop"
|
|
290
|
-
? "drop"
|
|
291
|
-
: propName === "onDropEnter"
|
|
292
|
-
? "enter"
|
|
293
|
-
: propName === "onDropLeave"
|
|
294
|
-
? "leave"
|
|
295
|
-
: "motion";
|
|
296
|
-
signalStore.set(this, dropTarget, signalName, wrappedHandler);
|
|
297
|
-
}
|
|
298
|
-
break;
|
|
299
|
-
}
|
|
300
|
-
case "onGestureDragBegin":
|
|
301
|
-
case "onGestureDragUpdate":
|
|
302
|
-
case "onGestureDragEnd": {
|
|
303
|
-
const gestureDrag = this.ensureGestureDrag();
|
|
304
|
-
const signalName = propName === "onGestureDragBegin"
|
|
305
|
-
? "drag-begin"
|
|
306
|
-
: propName === "onGestureDragUpdate"
|
|
307
|
-
? "drag-update"
|
|
308
|
-
: "drag-end";
|
|
309
|
-
signalStore.set(this, gestureDrag, signalName, wrappedHandler);
|
|
310
|
-
break;
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
ensureDragSource() {
|
|
315
|
-
if (!this.dragSourceController) {
|
|
316
|
-
this.dragSourceController = new Gtk.DragSource();
|
|
317
|
-
this.dragSourceController.setActions(Gdk.DragAction.COPY);
|
|
318
|
-
this.container.addController(this.dragSourceController);
|
|
319
|
-
}
|
|
320
|
-
return this.dragSourceController;
|
|
321
|
-
}
|
|
322
|
-
ensureDropTarget() {
|
|
323
|
-
if (!this.dropTargetController) {
|
|
324
|
-
this.dropTargetController = new Gtk.DropTarget(0, Gdk.DragAction.COPY);
|
|
325
|
-
this.container.addController(this.dropTargetController);
|
|
326
|
-
}
|
|
327
|
-
return this.dropTargetController;
|
|
328
|
-
}
|
|
329
|
-
ensureGestureDrag() {
|
|
330
|
-
if (!this.gestureDragController) {
|
|
331
|
-
this.gestureDragController = new Gtk.GestureDrag();
|
|
332
|
-
this.container.addController(this.gestureDragController);
|
|
333
|
-
}
|
|
334
|
-
return this.gestureDragController;
|
|
335
|
-
}
|
|
336
|
-
updateNotifyHandler(handler) {
|
|
337
|
-
const wrappedHandler = handler
|
|
338
|
-
? (obj, pspec) => {
|
|
339
|
-
handler(obj, pspec.getName());
|
|
340
|
-
}
|
|
341
|
-
: undefined;
|
|
342
|
-
signalStore.set(this, this.container, "notify", wrappedHandler);
|
|
343
|
-
}
|
|
344
|
-
propNameToSignalName(name) {
|
|
345
|
-
return name
|
|
346
|
-
.slice(2)
|
|
347
|
-
.replace(/([A-Z])/g, "-$1")
|
|
348
|
-
.toLowerCase()
|
|
349
|
-
.replace(/^-/, "");
|
|
350
|
-
}
|
|
351
|
-
getProperty(key) {
|
|
352
|
-
const propMeta = resolvePropMeta(this.container, key);
|
|
353
|
-
if (!propMeta)
|
|
158
|
+
getPropertyDefaultValue(key) {
|
|
159
|
+
if (!resolvePropMeta(this.container, key))
|
|
354
160
|
return undefined;
|
|
355
|
-
const
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
161
|
+
const pspec = findProperty(this.container, key);
|
|
162
|
+
if (!pspec)
|
|
163
|
+
return undefined;
|
|
164
|
+
const value = pspec.getDefaultValue();
|
|
165
|
+
const gtype = value.getType();
|
|
166
|
+
const fundamental = typeFundamental(gtype);
|
|
167
|
+
if (fundamental === Type.BOOLEAN)
|
|
168
|
+
return value.getBoolean();
|
|
169
|
+
if (fundamental === Type.INT)
|
|
170
|
+
return value.getInt();
|
|
171
|
+
if (fundamental === Type.UINT)
|
|
172
|
+
return value.getUint();
|
|
173
|
+
if (fundamental === Type.LONG)
|
|
174
|
+
return value.getLong();
|
|
175
|
+
if (fundamental === Type.ULONG)
|
|
176
|
+
return value.getUlong();
|
|
177
|
+
if (fundamental === Type.INT64)
|
|
178
|
+
return value.getInt64();
|
|
179
|
+
if (fundamental === Type.UINT64)
|
|
180
|
+
return value.getUint64();
|
|
181
|
+
if (fundamental === Type.FLOAT)
|
|
182
|
+
return value.getFloat();
|
|
183
|
+
if (fundamental === Type.DOUBLE)
|
|
184
|
+
return value.getDouble();
|
|
185
|
+
if (fundamental === Type.STRING)
|
|
186
|
+
return value.getString();
|
|
187
|
+
if (fundamental === Type.ENUM)
|
|
188
|
+
return value.getEnum();
|
|
189
|
+
if (fundamental === Type.FLAGS)
|
|
190
|
+
return value.getFlags();
|
|
360
191
|
return undefined;
|
|
361
192
|
}
|
|
362
193
|
setProperty(key, value) {
|
|
@@ -365,21 +196,17 @@ export class WidgetNode extends Node {
|
|
|
365
196
|
return;
|
|
366
197
|
const [getterName, setterName] = propMeta;
|
|
367
198
|
const setter = this.container[setterName];
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
isObjectEqual(currentValue, value)) {
|
|
377
|
-
return;
|
|
199
|
+
if (!setter || typeof setter !== "function")
|
|
200
|
+
return;
|
|
201
|
+
if (getterName && findProperty(this.container, key) instanceof ParamSpecString) {
|
|
202
|
+
const getter = this.container[getterName];
|
|
203
|
+
if (getter && typeof getter === "function") {
|
|
204
|
+
const currentValue = getter.call(this.container);
|
|
205
|
+
if (currentValue === value)
|
|
206
|
+
return;
|
|
378
207
|
}
|
|
379
208
|
}
|
|
380
|
-
|
|
381
|
-
setter.call(this.container, value);
|
|
382
|
-
}
|
|
209
|
+
setter.call(this.container, value);
|
|
383
210
|
}
|
|
384
211
|
detachChildFromParent(child) {
|
|
385
212
|
const currentParent = child.container.getParent();
|
|
@@ -388,37 +215,21 @@ export class WidgetNode extends Node {
|
|
|
388
215
|
}
|
|
389
216
|
}
|
|
390
217
|
attachChild(child) {
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
this.container.
|
|
218
|
+
const strategy = getAttachmentStrategy(this.container);
|
|
219
|
+
if (!strategy) {
|
|
220
|
+
throw new Error(`Cannot append '${child.typeName}' to '${this.container.constructor.name}': container does not support children`);
|
|
394
221
|
}
|
|
395
|
-
|
|
222
|
+
if (strategy.type === "appendable" || strategy.type === "addable") {
|
|
396
223
|
this.detachChildFromParent(child);
|
|
397
|
-
this.container.add(child.container);
|
|
398
|
-
}
|
|
399
|
-
else if (hasSingleContent(this.container)) {
|
|
400
|
-
this.container.setContent(child.container);
|
|
401
|
-
}
|
|
402
|
-
else if (isSingleChild(this.container)) {
|
|
403
|
-
this.container.setChild(child.container);
|
|
404
|
-
}
|
|
405
|
-
else {
|
|
406
|
-
throw new Error(`Cannot append '${child.typeName}' to '${this.container.constructor.name}': container does not support children`);
|
|
407
224
|
}
|
|
225
|
+
performAttachment(child.container, strategy);
|
|
408
226
|
}
|
|
409
227
|
detachChild(child) {
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
}
|
|
413
|
-
else if (hasSingleContent(this.container)) {
|
|
414
|
-
this.container.setContent(null);
|
|
415
|
-
}
|
|
416
|
-
else if (isSingleChild(this.container)) {
|
|
417
|
-
this.container.setChild(null);
|
|
418
|
-
}
|
|
419
|
-
else {
|
|
228
|
+
const strategy = getAttachmentStrategy(this.container);
|
|
229
|
+
if (!strategy) {
|
|
420
230
|
throw new Error(`Cannot remove '${child.typeName}' from '${this.container.constructor.name}': container does not support child removal`);
|
|
421
231
|
}
|
|
232
|
+
performDetachment(child.container, strategy);
|
|
422
233
|
}
|
|
423
234
|
findPreviousSibling(before) {
|
|
424
235
|
let beforeChild = this.container.getFirstChild();
|
package/dist/nodes/window.d.ts
CHANGED
|
@@ -2,22 +2,28 @@ import * as Gtk from "@gtkx/ffi/gtk";
|
|
|
2
2
|
import type { Node } from "../node.js";
|
|
3
3
|
import type { Container, ContainerClass, Props } from "../types.js";
|
|
4
4
|
import { WidgetNode } from "./widget.js";
|
|
5
|
-
type
|
|
5
|
+
type CreditSection = {
|
|
6
|
+
name: string;
|
|
7
|
+
people: string[];
|
|
8
|
+
};
|
|
9
|
+
export type WindowProps = Props & {
|
|
6
10
|
defaultWidth?: number;
|
|
7
11
|
defaultHeight?: number;
|
|
8
12
|
onClose?: () => void;
|
|
13
|
+
creditSections?: CreditSection[];
|
|
9
14
|
};
|
|
10
15
|
export declare class WindowNode extends WidgetNode<Gtk.Window, WindowProps> {
|
|
11
16
|
static priority: number;
|
|
12
17
|
private menu;
|
|
13
18
|
static matches(_type: string, containerOrClass?: Container | ContainerClass | null): boolean;
|
|
14
|
-
static createContainer(props: Props, containerClass: typeof Gtk.Window, rootContainer
|
|
15
|
-
constructor(typeName: string, props: WindowProps, container: Gtk.Window, rootContainer
|
|
19
|
+
static createContainer(props: Props, containerClass: typeof Gtk.Window, rootContainer: Container | undefined): Gtk.Window;
|
|
20
|
+
constructor(typeName: string, props: WindowProps, container: Gtk.Window, rootContainer: Container);
|
|
16
21
|
appendChild(child: Node): void;
|
|
17
22
|
removeChild(child: Node): void;
|
|
18
23
|
insertBefore(child: Node, before: Node): void;
|
|
19
24
|
mount(): void;
|
|
20
25
|
unmount(): void;
|
|
21
26
|
updateProps(oldProps: WindowProps | null, newProps: WindowProps): void;
|
|
27
|
+
protected applyOwnProps(oldProps: WindowProps | null, newProps: WindowProps): void;
|
|
22
28
|
}
|
|
23
29
|
export {};
|
package/dist/nodes/window.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import * as Adw from "@gtkx/ffi/adw";
|
|
2
2
|
import * as Gtk from "@gtkx/ffi/gtk";
|
|
3
3
|
import { registerNodeClass } from "../registry.js";
|
|
4
|
-
import {
|
|
5
|
-
import { filterProps,
|
|
6
|
-
import {
|
|
4
|
+
import { DialogNode } from "./dialog.js";
|
|
5
|
+
import { filterProps, hasChanged, matchesAnyClass } from "./internal/utils.js";
|
|
6
|
+
import { MenuModel } from "./models/menu.js";
|
|
7
7
|
import { WidgetNode } from "./widget.js";
|
|
8
|
-
const
|
|
8
|
+
const OWN_PROPS = ["defaultWidth", "defaultHeight", "onClose"];
|
|
9
9
|
export class WindowNode extends WidgetNode {
|
|
10
10
|
static priority = 1;
|
|
11
11
|
menu;
|
|
12
12
|
static matches(_type, containerOrClass) {
|
|
13
|
-
return
|
|
13
|
+
return matchesAnyClass([Gtk.Window], containerOrClass);
|
|
14
14
|
}
|
|
15
15
|
static createContainer(props, containerClass, rootContainer) {
|
|
16
16
|
const WindowClass = containerClass;
|
|
17
|
-
if (
|
|
18
|
-
|
|
17
|
+
if (matchesAnyClass([Gtk.ApplicationWindow], WindowClass) ||
|
|
18
|
+
matchesAnyClass([Adw.ApplicationWindow], WindowClass)) {
|
|
19
19
|
if (!(rootContainer instanceof Gtk.Application)) {
|
|
20
20
|
throw new Error("Expected ApplicationWindow to be created within Application");
|
|
21
21
|
}
|
|
22
|
-
if (
|
|
22
|
+
if (matchesAnyClass([Adw.ApplicationWindow], WindowClass)) {
|
|
23
23
|
return new Adw.ApplicationWindow(rootContainer);
|
|
24
24
|
}
|
|
25
25
|
return new Gtk.ApplicationWindow(rootContainer);
|
|
@@ -30,13 +30,22 @@ export class WindowNode extends WidgetNode {
|
|
|
30
30
|
super(typeName, props, container, rootContainer);
|
|
31
31
|
const application = rootContainer instanceof Gtk.Application ? rootContainer : undefined;
|
|
32
32
|
const actionMap = container instanceof Gtk.ApplicationWindow ? container : undefined;
|
|
33
|
-
this.menu = new
|
|
33
|
+
this.menu = new MenuModel("root", {}, rootContainer, actionMap, application);
|
|
34
|
+
if (container instanceof Gtk.AboutDialog && props.creditSections) {
|
|
35
|
+
for (const section of props.creditSections) {
|
|
36
|
+
container.addCreditSection(section.name, section.people);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
34
39
|
}
|
|
35
40
|
appendChild(child) {
|
|
36
41
|
if (child.container instanceof Gtk.Window) {
|
|
37
42
|
child.container.setTransientFor(this.container);
|
|
38
43
|
return;
|
|
39
44
|
}
|
|
45
|
+
if (child instanceof DialogNode) {
|
|
46
|
+
child.parent = this.container;
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
40
49
|
this.menu.appendChild(child);
|
|
41
50
|
super.appendChild(child);
|
|
42
51
|
}
|
|
@@ -45,6 +54,10 @@ export class WindowNode extends WidgetNode {
|
|
|
45
54
|
child.container.setTransientFor(null);
|
|
46
55
|
return;
|
|
47
56
|
}
|
|
57
|
+
if (child instanceof DialogNode) {
|
|
58
|
+
child.parent = null;
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
48
61
|
this.menu.removeChild(child);
|
|
49
62
|
super.removeChild(child);
|
|
50
63
|
}
|
|
@@ -61,14 +74,16 @@ export class WindowNode extends WidgetNode {
|
|
|
61
74
|
super.unmount();
|
|
62
75
|
}
|
|
63
76
|
updateProps(oldProps, newProps) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
77
|
+
super.updateProps(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
|
|
78
|
+
this.applyOwnProps(oldProps, newProps);
|
|
79
|
+
}
|
|
80
|
+
applyOwnProps(oldProps, newProps) {
|
|
81
|
+
if (hasChanged(oldProps, newProps, "defaultWidth") || hasChanged(oldProps, newProps, "defaultHeight")) {
|
|
67
82
|
const width = newProps.defaultWidth ?? -1;
|
|
68
83
|
const height = newProps.defaultHeight ?? -1;
|
|
69
84
|
this.container.setDefaultSize(width, height);
|
|
70
85
|
}
|
|
71
|
-
if (
|
|
86
|
+
if (hasChanged(oldProps, newProps, "onClose")) {
|
|
72
87
|
const userHandler = newProps.onClose;
|
|
73
88
|
const wrappedHandler = userHandler
|
|
74
89
|
? () => {
|
|
@@ -76,9 +91,8 @@ export class WindowNode extends WidgetNode {
|
|
|
76
91
|
return true;
|
|
77
92
|
}
|
|
78
93
|
: undefined;
|
|
79
|
-
signalStore.set(this, this.container, "close-request", wrappedHandler);
|
|
94
|
+
this.signalStore.set(this, this.container, "close-request", wrappedHandler);
|
|
80
95
|
}
|
|
81
|
-
super.updateProps(filterProps(oldProps ?? {}, PROPS), filterProps(newProps, PROPS));
|
|
82
96
|
}
|
|
83
97
|
}
|
|
84
98
|
registerNodeClass(WindowNode);
|
package/dist/registry.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Node } from "./node.js";
|
|
2
2
|
import type { Container, Props } from "./types.js";
|
|
3
3
|
type NodeClass<T = unknown, P = Props> = {
|
|
4
|
-
new (typeName: string, props: P, container: T, rootContainer
|
|
4
|
+
new (typeName: string, props: P, container: T, rootContainer: Container): Node<T, P>;
|
|
5
5
|
} & Omit<typeof Node, "prototype">;
|
|
6
6
|
export declare const NODE_CLASSES: NodeClass[];
|
|
7
7
|
export declare const registerNodeClass: <T, P>(nodeClass: NodeClass<T, P>) => void;
|