@gtkx/react 0.15.0 → 0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/animation/css-builder.d.ts +3 -0
- package/dist/animation/css-builder.js +53 -0
- package/dist/animation/types.d.ts +120 -0
- package/dist/errors.js +3 -0
- package/dist/factory.d.ts +3 -2
- package/dist/factory.js +1 -1
- package/dist/fiber-root.js +1 -1
- package/dist/generated/internal.d.ts +28 -1
- package/dist/generated/internal.js +93 -18
- package/dist/generated/jsx.d.ts +1672 -1483
- package/dist/generated/jsx.js +475 -0
- package/dist/host-config.d.ts +3 -1
- package/dist/host-config.js +26 -11
- package/dist/jsx.d.ts +136 -166
- package/dist/jsx.js +58 -69
- package/dist/node.d.ts +4 -1
- package/dist/node.js +14 -3
- package/dist/nodes/abstract/positional-child.d.ts +9 -0
- package/dist/nodes/abstract/positional-child.js +29 -0
- package/dist/nodes/abstract/virtual-container.d.ts +21 -0
- package/dist/nodes/abstract/virtual-container.js +68 -0
- package/dist/nodes/abstract/virtual-single-child.d.ts +18 -0
- package/dist/nodes/abstract/virtual-single-child.js +55 -0
- package/dist/nodes/action-row-child.d.ts +0 -13
- package/dist/nodes/action-row-child.js +22 -12
- package/dist/nodes/adjustable.d.ts +23 -0
- package/dist/nodes/adjustable.js +62 -0
- package/dist/nodes/alert-dialog-response.js +86 -0
- package/dist/nodes/animation.js +252 -0
- package/dist/nodes/application.js +17 -7
- package/dist/nodes/autowrapped.js +37 -43
- package/dist/nodes/calendar.js +17 -43
- package/dist/nodes/color-dialog-button.d.ts +1 -0
- package/dist/nodes/color-dialog-button.js +70 -0
- package/dist/nodes/column-view-column.d.ts +3 -3
- package/dist/nodes/column-view-column.js +1 -1
- package/dist/nodes/column-view.js +36 -39
- package/dist/nodes/dialog.d.ts +11 -0
- package/dist/nodes/dialog.js +20 -0
- package/dist/nodes/drawing-area.js +24 -7
- package/dist/nodes/event-controller.d.ts +22 -0
- package/dist/nodes/event-controller.js +96 -0
- package/dist/nodes/expander-row-child.d.ts +0 -14
- package/dist/nodes/expander-row-child.js +22 -12
- package/dist/nodes/fixed-child.js +52 -36
- package/dist/nodes/font-dialog-button.d.ts +1 -0
- package/dist/nodes/font-dialog-button.js +90 -0
- package/dist/nodes/grid-child.js +43 -45
- package/dist/nodes/grid.d.ts +1 -0
- package/dist/nodes/grid.js +41 -0
- package/dist/nodes/index.d.ts +18 -12
- package/dist/nodes/index.js +18 -12
- package/dist/nodes/internal/base-item-renderer.d.ts +29 -0
- package/dist/nodes/internal/base-item-renderer.js +88 -0
- package/dist/nodes/internal/child-attachment.d.ts +26 -0
- package/dist/nodes/internal/child-attachment.js +48 -0
- package/dist/nodes/internal/deferred-action.d.ts +9 -0
- package/dist/nodes/internal/deferred-action.js +22 -0
- package/dist/nodes/internal/list-item-renderer.d.ts +14 -15
- package/dist/nodes/internal/list-item-renderer.js +51 -77
- package/dist/nodes/internal/list-store.d.ts +5 -6
- package/dist/nodes/internal/list-store.js +29 -38
- package/dist/nodes/internal/predicates.d.ts +25 -2
- package/dist/nodes/internal/predicates.js +53 -41
- package/dist/nodes/internal/selection-model.d.ts +30 -0
- package/dist/nodes/internal/selection-model.js +87 -0
- package/dist/nodes/internal/signal-store.d.ts +9 -5
- package/dist/nodes/internal/signal-store.js +31 -31
- package/dist/nodes/internal/simple-list-store.js +6 -9
- package/dist/nodes/internal/text-buffer-controller.d.ts +43 -0
- package/dist/nodes/internal/text-buffer-controller.js +287 -0
- package/dist/nodes/internal/text-tag-styles.d.ts +43 -0
- package/dist/nodes/internal/text-tag-styles.js +52 -0
- package/dist/nodes/internal/tree-list-item-renderer.d.ts +15 -14
- package/dist/nodes/internal/tree-list-item-renderer.js +85 -96
- package/dist/nodes/internal/tree-store.d.ts +8 -11
- package/dist/nodes/internal/tree-store.js +70 -72
- package/dist/nodes/internal/utils.d.ts +7 -4
- package/dist/nodes/internal/utils.js +50 -5
- package/dist/nodes/level-bar.js +19 -54
- package/dist/nodes/list-item.d.ts +6 -3
- package/dist/nodes/list-item.js +7 -4
- package/dist/nodes/list-view.js +17 -12
- package/dist/nodes/menu.d.ts +3 -3
- package/dist/nodes/menu.js +3 -3
- package/dist/nodes/models/list.d.ts +11 -13
- package/dist/nodes/models/list.js +16 -73
- package/dist/nodes/models/menu.d.ts +8 -7
- package/dist/nodes/models/menu.js +43 -50
- package/dist/nodes/models/tree-list.d.ts +6 -12
- package/dist/nodes/models/tree-list.js +30 -93
- package/dist/nodes/navigation-page.d.ts +1 -0
- package/dist/nodes/navigation-page.js +27 -32
- package/dist/nodes/navigation-view.js +17 -28
- package/dist/nodes/notebook-page-tab.d.ts +3 -3
- package/dist/nodes/notebook-page-tab.js +11 -14
- package/dist/nodes/notebook-page.d.ts +7 -5
- package/dist/nodes/notebook-page.js +45 -25
- package/dist/nodes/notebook.js +2 -2
- package/dist/nodes/overlay-child.js +90 -30
- package/dist/nodes/pack-child.d.ts +0 -13
- package/dist/nodes/pack-child.js +22 -12
- package/dist/nodes/popover-menu.js +2 -2
- package/dist/nodes/scale.js +15 -45
- package/dist/nodes/scrolled-window.js +7 -6
- package/dist/nodes/search-bar.d.ts +1 -0
- package/dist/nodes/search-bar.js +40 -0
- package/dist/nodes/shortcut-controller.d.ts +1 -37
- package/dist/nodes/shortcut-controller.js +8 -47
- package/dist/nodes/shortcut.d.ts +5 -4
- package/dist/nodes/shortcut.js +11 -5
- package/dist/nodes/simple-list-view.js +2 -3
- package/dist/nodes/slot.d.ts +6 -9
- package/dist/nodes/slot.js +27 -42
- package/dist/nodes/source-view.js +80 -29
- package/dist/nodes/stack-page.js +20 -22
- package/dist/nodes/stack.js +19 -5
- package/dist/nodes/text-anchor.d.ts +41 -0
- package/dist/nodes/text-anchor.js +59 -0
- package/dist/nodes/text-content.d.ts +10 -0
- package/dist/nodes/text-content.js +1 -0
- package/dist/nodes/text-paintable.d.ts +17 -0
- package/dist/nodes/text-paintable.js +34 -0
- package/dist/nodes/text-segment.d.ts +15 -0
- package/dist/nodes/text-segment.js +29 -0
- package/dist/nodes/text-tag.d.ts +136 -0
- package/dist/nodes/text-tag.js +202 -0
- package/dist/nodes/text-view.d.ts +30 -0
- package/dist/nodes/text-view.js +49 -21
- package/dist/nodes/toggle-group.js +24 -32
- package/dist/nodes/toggle.d.ts +1 -15
- package/dist/nodes/toggle.js +40 -32
- package/dist/nodes/toolbar-child.js +22 -31
- package/dist/nodes/tree-list-item.d.ts +7 -5
- package/dist/nodes/tree-list-item.js +24 -36
- package/dist/nodes/tree-list-view.js +9 -7
- package/dist/nodes/virtual.d.ts +1 -1
- package/dist/nodes/web-view.d.ts +1 -0
- package/dist/nodes/web-view.js +29 -0
- package/dist/nodes/widget.d.ts +2 -16
- package/dist/nodes/widget.js +105 -294
- package/dist/nodes/window.d.ts +9 -3
- package/dist/nodes/window.js +29 -15
- package/dist/registry.d.ts +1 -1
- package/dist/render.js +9 -7
- package/dist/scheduler.d.ts +11 -1
- package/dist/scheduler.js +16 -4
- package/dist/types.d.ts +2 -136
- package/package.json +4 -4
- package/dist/nodes/action-row.js +0 -46
- package/dist/nodes/adjustment.d.ts +0 -48
- package/dist/nodes/adjustment.js +0 -70
- package/dist/nodes/calendar-mark.d.ts +0 -15
- package/dist/nodes/calendar-mark.js +0 -29
- package/dist/nodes/expander-row.js +0 -55
- package/dist/nodes/internal/constants.d.ts +0 -1
- package/dist/nodes/internal/constants.js +0 -24
- package/dist/nodes/level-bar-offset.d.ts +0 -13
- package/dist/nodes/level-bar-offset.js +0 -35
- package/dist/nodes/pack.js +0 -46
- package/dist/nodes/scale-mark.d.ts +0 -17
- package/dist/nodes/scale-mark.js +0 -38
- package/dist/nodes/source-buffer.d.ts +0 -73
- package/dist/nodes/source-buffer.js +0 -149
- package/dist/nodes/text-buffer.d.ts +0 -43
- package/dist/nodes/text-buffer.js +0 -81
- package/dist/nodes/virtual-child.d.ts +0 -18
- package/dist/nodes/virtual-child.js +0 -62
- /package/dist/{nodes/action-row.d.ts → animation/types.js} +0 -0
- /package/dist/nodes/{expander-row.d.ts → alert-dialog-response.d.ts} +0 -0
- /package/dist/nodes/{pack.d.ts → animation.d.ts} +0 -0
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { isObjectEqual } from "@gtkx/ffi";
|
|
2
|
+
import * as Adw from "@gtkx/ffi/adw";
|
|
3
|
+
import * as Gdk from "@gtkx/ffi/gdk";
|
|
4
|
+
import * as Gtk from "@gtkx/ffi/gtk";
|
|
5
|
+
import { buildCss, interpolate } from "../animation/css-builder.js";
|
|
6
|
+
import { registerNodeClass } from "../registry.js";
|
|
7
|
+
import { CommitPriority, scheduleAfterCommit } from "../scheduler.js";
|
|
8
|
+
import { VirtualSingleChildNode } from "./abstract/virtual-single-child.js";
|
|
9
|
+
import { attachChild, detachChild, getAttachmentStrategy } from "./internal/child-attachment.js";
|
|
10
|
+
import { isRemovable } from "./internal/predicates.js";
|
|
11
|
+
let animationCounter = 0;
|
|
12
|
+
const DEFAULT_TIMED_DURATION = 300;
|
|
13
|
+
const DEFAULT_SPRING_DAMPING = 1;
|
|
14
|
+
const DEFAULT_SPRING_MASS = 1;
|
|
15
|
+
const DEFAULT_SPRING_STIFFNESS = 100;
|
|
16
|
+
class AnimationNode extends VirtualSingleChildNode {
|
|
17
|
+
static priority = 2;
|
|
18
|
+
static matches(type) {
|
|
19
|
+
return type === "Animation";
|
|
20
|
+
}
|
|
21
|
+
className;
|
|
22
|
+
provider = null;
|
|
23
|
+
display = null;
|
|
24
|
+
currentAnimation = null;
|
|
25
|
+
currentValues = {};
|
|
26
|
+
isExiting = false;
|
|
27
|
+
constructor(typeName, props, container, rootContainer) {
|
|
28
|
+
super(typeName, props, container, rootContainer);
|
|
29
|
+
this.className = `gtkx-anim-${animationCounter++}`;
|
|
30
|
+
}
|
|
31
|
+
updateProps(oldProps, newProps) {
|
|
32
|
+
super.updateProps(oldProps, newProps);
|
|
33
|
+
if (this.isExiting) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (oldProps && newProps.animate && !this.arePropsEqual(oldProps.animate, newProps.animate)) {
|
|
37
|
+
const target = newProps.animate;
|
|
38
|
+
scheduleAfterCommit(() => {
|
|
39
|
+
if (this.child && !this.isExiting) {
|
|
40
|
+
this.animateTo(target);
|
|
41
|
+
}
|
|
42
|
+
}, CommitPriority.LOW);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
onChildChange(oldChild) {
|
|
46
|
+
if (oldChild && this.provider) {
|
|
47
|
+
oldChild.removeCssClass(this.className);
|
|
48
|
+
}
|
|
49
|
+
if (oldChild && this.parent && this.isWidgetAttachedTo(oldChild, this.parent)) {
|
|
50
|
+
const strategy = getAttachmentStrategy(this.parent);
|
|
51
|
+
if (strategy) {
|
|
52
|
+
detachChild(oldChild, strategy);
|
|
53
|
+
}
|
|
54
|
+
else if (isRemovable(this.parent)) {
|
|
55
|
+
this.parent.remove(oldChild);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (this.child && this.parent) {
|
|
59
|
+
const strategy = getAttachmentStrategy(this.parent);
|
|
60
|
+
if (strategy) {
|
|
61
|
+
attachChild(this.child, strategy);
|
|
62
|
+
}
|
|
63
|
+
this.setupCssProvider();
|
|
64
|
+
this.child.addCssClass(this.className);
|
|
65
|
+
scheduleAfterCommit(() => {
|
|
66
|
+
if (!this.child)
|
|
67
|
+
return;
|
|
68
|
+
const initial = this.props.initial;
|
|
69
|
+
const animate = this.props.animate;
|
|
70
|
+
if (initial === false || !this.props.animateOnMount) {
|
|
71
|
+
if (animate) {
|
|
72
|
+
this.currentValues = { ...animate };
|
|
73
|
+
this.applyValues(this.currentValues);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
const initialValues = initial ?? animate ?? {};
|
|
78
|
+
this.currentValues = { ...initialValues };
|
|
79
|
+
this.applyValues(this.currentValues);
|
|
80
|
+
if (this.props.animateOnMount && animate) {
|
|
81
|
+
this.animateTo(animate);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}, CommitPriority.LOW);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
unmount() {
|
|
88
|
+
if (this.isExiting) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (this.props.exit && this.child) {
|
|
92
|
+
this.isExiting = true;
|
|
93
|
+
this.animateTo(this.props.exit, () => {
|
|
94
|
+
this.detachChildFromParent();
|
|
95
|
+
this.cleanup();
|
|
96
|
+
super.unmount();
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
this.detachChildFromParent();
|
|
101
|
+
this.cleanup();
|
|
102
|
+
super.unmount();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
detachChildFromParent() {
|
|
106
|
+
if (this.child && this.parent && this.isChildAttachedToParent()) {
|
|
107
|
+
const strategy = getAttachmentStrategy(this.parent);
|
|
108
|
+
if (strategy) {
|
|
109
|
+
detachChild(this.child, strategy);
|
|
110
|
+
}
|
|
111
|
+
else if (isRemovable(this.parent)) {
|
|
112
|
+
this.parent.remove(this.child);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
isChildAttachedToParent() {
|
|
117
|
+
return this.isWidgetAttachedTo(this.child, this.parent);
|
|
118
|
+
}
|
|
119
|
+
isWidgetAttachedTo(child, parent) {
|
|
120
|
+
if (!child || !parent)
|
|
121
|
+
return false;
|
|
122
|
+
const childParent = child.getParent();
|
|
123
|
+
return childParent !== null && isObjectEqual(childParent, parent);
|
|
124
|
+
}
|
|
125
|
+
setupCssProvider() {
|
|
126
|
+
if (this.provider || !this.child)
|
|
127
|
+
return;
|
|
128
|
+
this.provider = new Gtk.CssProvider();
|
|
129
|
+
this.display = Gdk.DisplayManager.get().getDefaultDisplay();
|
|
130
|
+
if (this.display) {
|
|
131
|
+
Gtk.StyleContext.addProviderForDisplay(this.display, this.provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
cleanup() {
|
|
135
|
+
if (this.currentAnimation) {
|
|
136
|
+
this.currentAnimation.skip();
|
|
137
|
+
this.currentAnimation = null;
|
|
138
|
+
}
|
|
139
|
+
if (this.provider && this.display) {
|
|
140
|
+
Gtk.StyleContext.removeProviderForDisplay(this.display, this.provider);
|
|
141
|
+
}
|
|
142
|
+
if (this.child) {
|
|
143
|
+
this.child.removeCssClass(this.className);
|
|
144
|
+
}
|
|
145
|
+
this.provider = null;
|
|
146
|
+
this.display = null;
|
|
147
|
+
}
|
|
148
|
+
animateTo(target, onComplete) {
|
|
149
|
+
if (!this.child)
|
|
150
|
+
return;
|
|
151
|
+
if (this.currentAnimation) {
|
|
152
|
+
this.currentAnimation.skip();
|
|
153
|
+
this.currentAnimation = null;
|
|
154
|
+
}
|
|
155
|
+
const from = { ...this.currentValues };
|
|
156
|
+
const to = { ...target };
|
|
157
|
+
this.props.onAnimationStart?.();
|
|
158
|
+
const callback = new Adw.CallbackAnimationTarget((progress) => {
|
|
159
|
+
const interpolated = interpolate(from, to, progress);
|
|
160
|
+
this.currentValues = interpolated;
|
|
161
|
+
this.applyValues(interpolated);
|
|
162
|
+
});
|
|
163
|
+
const animation = this.createAnimation(this.child, callback);
|
|
164
|
+
animation.connect("done", () => {
|
|
165
|
+
this.currentValues = { ...to };
|
|
166
|
+
this.currentAnimation = null;
|
|
167
|
+
this.props.onAnimationComplete?.();
|
|
168
|
+
onComplete?.();
|
|
169
|
+
});
|
|
170
|
+
this.currentAnimation = animation;
|
|
171
|
+
const transition = this.props.transition;
|
|
172
|
+
const delay = transition?.delay ?? 0;
|
|
173
|
+
if (delay > 0) {
|
|
174
|
+
setTimeout(() => {
|
|
175
|
+
if (this.currentAnimation === animation) {
|
|
176
|
+
animation.play();
|
|
177
|
+
}
|
|
178
|
+
}, delay);
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
animation.play();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
createAnimation(widget, target) {
|
|
185
|
+
const mode = this.props.mode;
|
|
186
|
+
if (mode === "spring") {
|
|
187
|
+
return this.createSpringAnimation(widget, target);
|
|
188
|
+
}
|
|
189
|
+
return this.createTimedAnimation(widget, target);
|
|
190
|
+
}
|
|
191
|
+
createTimedAnimation(widget, target) {
|
|
192
|
+
const transition = this.props.transition;
|
|
193
|
+
const duration = transition?.duration ?? DEFAULT_TIMED_DURATION;
|
|
194
|
+
const animation = new Adw.TimedAnimation(widget, 0, 1, duration, target);
|
|
195
|
+
if (transition?.easing !== undefined) {
|
|
196
|
+
animation.setEasing(transition.easing);
|
|
197
|
+
}
|
|
198
|
+
if (transition?.repeat !== undefined) {
|
|
199
|
+
animation.setRepeatCount(transition.repeat);
|
|
200
|
+
}
|
|
201
|
+
if (transition?.reverse !== undefined) {
|
|
202
|
+
animation.setReverse(transition.reverse);
|
|
203
|
+
}
|
|
204
|
+
if (transition?.alternate !== undefined) {
|
|
205
|
+
animation.setAlternate(transition.alternate);
|
|
206
|
+
}
|
|
207
|
+
return animation;
|
|
208
|
+
}
|
|
209
|
+
createSpringAnimation(widget, target) {
|
|
210
|
+
const transition = this.props.transition;
|
|
211
|
+
const damping = transition?.damping ?? DEFAULT_SPRING_DAMPING;
|
|
212
|
+
const mass = transition?.mass ?? DEFAULT_SPRING_MASS;
|
|
213
|
+
const stiffness = transition?.stiffness ?? DEFAULT_SPRING_STIFFNESS;
|
|
214
|
+
const springParams = new Adw.SpringParams(damping, mass, stiffness);
|
|
215
|
+
const animation = new Adw.SpringAnimation(widget, 0, 1, springParams, target);
|
|
216
|
+
if (transition?.initialVelocity !== undefined) {
|
|
217
|
+
animation.setInitialVelocity(transition.initialVelocity);
|
|
218
|
+
}
|
|
219
|
+
if (transition?.clamp !== undefined) {
|
|
220
|
+
animation.setClamp(transition.clamp);
|
|
221
|
+
}
|
|
222
|
+
return animation;
|
|
223
|
+
}
|
|
224
|
+
applyValues(values) {
|
|
225
|
+
if (!this.provider) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
if (this.child && !this.child.getCssClasses()?.includes(this.className)) {
|
|
229
|
+
this.child.addCssClass(this.className);
|
|
230
|
+
}
|
|
231
|
+
const css = buildCss(this.className, values);
|
|
232
|
+
if (css) {
|
|
233
|
+
this.provider.loadFromString(css);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
arePropsEqual(a, b) {
|
|
237
|
+
if (a === b)
|
|
238
|
+
return true;
|
|
239
|
+
if (!a || !b)
|
|
240
|
+
return false;
|
|
241
|
+
const keysA = Object.keys(a);
|
|
242
|
+
const keysB = Object.keys(b);
|
|
243
|
+
if (keysA.length !== keysB.length)
|
|
244
|
+
return false;
|
|
245
|
+
for (const key of keysA) {
|
|
246
|
+
if (a[key] !== b[key])
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
return true;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
registerNodeClass(AnimationNode);
|
|
@@ -2,20 +2,21 @@ import * as Gtk from "@gtkx/ffi/gtk";
|
|
|
2
2
|
import { Node } from "../node.js";
|
|
3
3
|
import { registerNodeClass } from "../registry.js";
|
|
4
4
|
import { CommitPriority, scheduleAfterCommit } from "../scheduler.js";
|
|
5
|
-
import {
|
|
5
|
+
import { DialogNode } from "./dialog.js";
|
|
6
|
+
import { matchesAnyClass } from "./internal/utils.js";
|
|
6
7
|
import { MenuNode } from "./menu.js";
|
|
7
|
-
import {
|
|
8
|
+
import { MenuModel } from "./models/menu.js";
|
|
8
9
|
import { WindowNode } from "./window.js";
|
|
9
10
|
class ApplicationNode extends Node {
|
|
10
11
|
static priority = 0;
|
|
11
12
|
menu;
|
|
12
13
|
static matches(_type, containerOrClass) {
|
|
13
|
-
return
|
|
14
|
+
return matchesAnyClass([Gtk.Application], containerOrClass);
|
|
14
15
|
}
|
|
15
16
|
constructor(typeName, props, container, rootContainer) {
|
|
16
17
|
super(typeName, props, container, rootContainer);
|
|
17
18
|
const application = rootContainer instanceof Gtk.Application ? rootContainer : undefined;
|
|
18
|
-
this.menu = new
|
|
19
|
+
this.menu = new MenuModel("root", {}, rootContainer, container, application);
|
|
19
20
|
}
|
|
20
21
|
appendChild(child) {
|
|
21
22
|
if (child instanceof MenuNode) {
|
|
@@ -26,7 +27,10 @@ class ApplicationNode extends Node {
|
|
|
26
27
|
if (child instanceof WindowNode && child.container instanceof Gtk.ApplicationWindow) {
|
|
27
28
|
return;
|
|
28
29
|
}
|
|
29
|
-
|
|
30
|
+
if (child instanceof DialogNode) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
throw new Error(`Cannot append '${child.typeName}' to 'Application': expected ApplicationWindow, Dialog, or MenuItem`);
|
|
30
34
|
}
|
|
31
35
|
insertBefore(child, before) {
|
|
32
36
|
if (child instanceof MenuNode) {
|
|
@@ -36,7 +40,10 @@ class ApplicationNode extends Node {
|
|
|
36
40
|
if (child instanceof WindowNode && child.container instanceof Gtk.ApplicationWindow) {
|
|
37
41
|
return;
|
|
38
42
|
}
|
|
39
|
-
|
|
43
|
+
if (child instanceof DialogNode) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
throw new Error(`Cannot insert '${child.typeName}' into 'Application': expected ApplicationWindow, Dialog, or MenuItem`);
|
|
40
47
|
}
|
|
41
48
|
removeChild(child) {
|
|
42
49
|
if (child instanceof MenuNode) {
|
|
@@ -51,7 +58,10 @@ class ApplicationNode extends Node {
|
|
|
51
58
|
if (child instanceof WindowNode && child.container instanceof Gtk.ApplicationWindow) {
|
|
52
59
|
return;
|
|
53
60
|
}
|
|
54
|
-
|
|
61
|
+
if (child instanceof DialogNode) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
throw new Error(`Cannot remove '${child.typeName}' from 'Application': expected ApplicationWindow, Dialog, or MenuItem`);
|
|
55
65
|
}
|
|
56
66
|
}
|
|
57
67
|
registerNodeClass(ApplicationNode);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isObjectEqual } from "@gtkx/ffi";
|
|
2
2
|
import * as Gtk from "@gtkx/ffi/gtk";
|
|
3
3
|
import { AUTOWRAP_CLASSES } from "../generated/internal.js";
|
|
4
4
|
import { registerNodeClass } from "../registry.js";
|
|
@@ -10,7 +10,7 @@ const isAutowrappedChild = (obj) => {
|
|
|
10
10
|
return obj instanceof Gtk.ListBoxRow || obj instanceof Gtk.FlowBoxChild;
|
|
11
11
|
};
|
|
12
12
|
class AutowrappedNode extends WidgetNode {
|
|
13
|
-
static priority =
|
|
13
|
+
static priority = 1;
|
|
14
14
|
static matches(_type, containerOrClass) {
|
|
15
15
|
return matchesAnyClass(AUTOWRAP_CLASSES, containerOrClass);
|
|
16
16
|
}
|
|
@@ -22,18 +22,16 @@ class AutowrappedNode extends WidgetNode {
|
|
|
22
22
|
if (!(child instanceof WidgetNode)) {
|
|
23
23
|
throw new Error(`Cannot append '${child.typeName}' to 'ListBox/FlowBox': expected Widget`);
|
|
24
24
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
currentParent.remove(child.container);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
this.removeExistingWrapper(child.container);
|
|
25
|
+
if (isAutowrappedChild(child.container)) {
|
|
26
|
+
const currentParent = child.container.getParent();
|
|
27
|
+
if (currentParent !== null && isRemovable(currentParent)) {
|
|
28
|
+
currentParent.remove(child.container);
|
|
34
29
|
}
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
this.removeExistingWrapper(child.container);
|
|
33
|
+
}
|
|
34
|
+
this.container.append(child.container);
|
|
37
35
|
}
|
|
38
36
|
removeChild(child) {
|
|
39
37
|
if (child instanceof SlotNode) {
|
|
@@ -43,17 +41,15 @@ class AutowrappedNode extends WidgetNode {
|
|
|
43
41
|
if (!(child instanceof WidgetNode)) {
|
|
44
42
|
throw new Error(`Cannot remove '${child.typeName}' from 'ListBox/FlowBox': expected Widget`);
|
|
45
43
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
44
|
+
if (!isAutowrappedChild(child.container)) {
|
|
45
|
+
const wrapper = child.container.getParent();
|
|
46
|
+
if (wrapper && isSingleChild(wrapper)) {
|
|
47
|
+
wrapper.setChild(null);
|
|
48
|
+
this.container.remove(wrapper);
|
|
49
|
+
return;
|
|
54
50
|
}
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
}
|
|
52
|
+
this.container.remove(child.container);
|
|
57
53
|
}
|
|
58
54
|
insertBefore(child, before) {
|
|
59
55
|
if (child instanceof SlotNode) {
|
|
@@ -61,31 +57,29 @@ class AutowrappedNode extends WidgetNode {
|
|
|
61
57
|
return;
|
|
62
58
|
}
|
|
63
59
|
if (!(child instanceof WidgetNode) || !(before instanceof WidgetNode)) {
|
|
64
|
-
throw new Error(`Cannot insert '${child.typeName}'
|
|
60
|
+
throw new Error(`Cannot insert '${child.typeName}' into 'ListBox/FlowBox': expected Widget`);
|
|
65
61
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
if (
|
|
69
|
-
if (
|
|
70
|
-
|
|
71
|
-
currentParent.remove(child.container);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
this.removeExistingWrapper(child.container);
|
|
62
|
+
const currentParent = child.container.getParent();
|
|
63
|
+
if (currentParent !== null) {
|
|
64
|
+
if (isAutowrappedChild(child.container)) {
|
|
65
|
+
if (isRemovable(currentParent)) {
|
|
66
|
+
currentParent.remove(child.container);
|
|
76
67
|
}
|
|
77
68
|
}
|
|
78
|
-
else if (!isAutowrappedChild(child.container)) {
|
|
79
|
-
this.removeExistingWrapper(child.container);
|
|
80
|
-
}
|
|
81
|
-
const position = this.findChildPosition(before);
|
|
82
|
-
if (position !== null) {
|
|
83
|
-
this.container.insert(child.container, position);
|
|
84
|
-
}
|
|
85
69
|
else {
|
|
86
|
-
this.
|
|
70
|
+
this.removeExistingWrapper(child.container);
|
|
87
71
|
}
|
|
88
|
-
}
|
|
72
|
+
}
|
|
73
|
+
else if (!isAutowrappedChild(child.container)) {
|
|
74
|
+
this.removeExistingWrapper(child.container);
|
|
75
|
+
}
|
|
76
|
+
const position = this.findChildPosition(before);
|
|
77
|
+
if (position !== null) {
|
|
78
|
+
this.container.insert(child.container, position);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
this.container.append(child.container);
|
|
82
|
+
}
|
|
89
83
|
}
|
|
90
84
|
removeExistingWrapper(childWidget) {
|
|
91
85
|
const existingWrapper = childWidget.getParent();
|
package/dist/nodes/calendar.js
CHANGED
|
@@ -1,57 +1,31 @@
|
|
|
1
1
|
import * as Gtk from "@gtkx/ffi/gtk";
|
|
2
2
|
import { registerNodeClass } from "../registry.js";
|
|
3
|
-
import {
|
|
4
|
-
import { CalendarMarkNode } from "./calendar-mark.js";
|
|
5
|
-
import { isContainerType } from "./internal/utils.js";
|
|
3
|
+
import { filterProps, matchesAnyClass, primitiveArrayEqual } from "./internal/utils.js";
|
|
6
4
|
import { WidgetNode } from "./widget.js";
|
|
5
|
+
const OWN_PROPS = ["markedDays"];
|
|
7
6
|
class CalendarNode extends WidgetNode {
|
|
8
7
|
static priority = 1;
|
|
9
|
-
|
|
8
|
+
appliedMarks = [];
|
|
10
9
|
static matches(_type, containerOrClass) {
|
|
11
|
-
return
|
|
10
|
+
return matchesAnyClass([Gtk.Calendar], containerOrClass);
|
|
12
11
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
this.markChildren.push(child);
|
|
17
|
-
scheduleAfterCommit(() => child.addMark());
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
super.appendChild(child);
|
|
12
|
+
updateProps(oldProps, newProps) {
|
|
13
|
+
super.updateProps(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
|
|
14
|
+
this.applyOwnProps(oldProps, newProps);
|
|
21
15
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
child.setCalendar(this.container, () => this.scheduleRebuildAllMarks());
|
|
25
|
-
const beforeIndex = this.markChildren.indexOf(before);
|
|
26
|
-
if (beforeIndex >= 0) {
|
|
27
|
-
this.markChildren.splice(beforeIndex, 0, child);
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
30
|
-
this.markChildren.push(child);
|
|
31
|
-
}
|
|
32
|
-
this.scheduleRebuildAllMarks();
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
super.insertBefore(child, before);
|
|
16
|
+
applyOwnProps(_oldProps, newProps) {
|
|
17
|
+
this.applyMarkedDays(newProps);
|
|
36
18
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (index >= 0) {
|
|
41
|
-
this.markChildren.splice(index, 1);
|
|
42
|
-
}
|
|
43
|
-
this.scheduleRebuildAllMarks(CommitPriority.HIGH);
|
|
19
|
+
applyMarkedDays(newProps) {
|
|
20
|
+
const newMarkedDays = newProps.markedDays ?? [];
|
|
21
|
+
if (primitiveArrayEqual(this.appliedMarks, newMarkedDays)) {
|
|
44
22
|
return;
|
|
45
23
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
for (const mark of this.markChildren) {
|
|
52
|
-
mark.addMark();
|
|
53
|
-
}
|
|
54
|
-
}, priority);
|
|
24
|
+
this.container.clearMarks();
|
|
25
|
+
for (const day of newMarkedDays) {
|
|
26
|
+
this.container.markDay(day);
|
|
27
|
+
}
|
|
28
|
+
this.appliedMarks = [...newMarkedDays];
|
|
55
29
|
}
|
|
56
30
|
}
|
|
57
31
|
registerNodeClass(CalendarNode);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import * as Gtk from "@gtkx/ffi/gtk";
|
|
2
|
+
import { registerNodeClass } from "../registry.js";
|
|
3
|
+
import { filterProps, hasChanged, matchesAnyClass } from "./internal/utils.js";
|
|
4
|
+
import { WidgetNode } from "./widget.js";
|
|
5
|
+
const OWN_PROPS = ["rgba", "onRgbaChanged", "title", "modal", "withAlpha"];
|
|
6
|
+
class ColorDialogButtonNode extends WidgetNode {
|
|
7
|
+
static priority = 1;
|
|
8
|
+
dialog;
|
|
9
|
+
notifyHandler = null;
|
|
10
|
+
static matches(_type, containerOrClass) {
|
|
11
|
+
return matchesAnyClass([Gtk.ColorDialogButton], containerOrClass);
|
|
12
|
+
}
|
|
13
|
+
static createContainer(_props, containerClass) {
|
|
14
|
+
const dialog = new Gtk.ColorDialog();
|
|
15
|
+
const button = new containerClass(dialog);
|
|
16
|
+
return button;
|
|
17
|
+
}
|
|
18
|
+
constructor(type, props, container, rootContainer) {
|
|
19
|
+
super(type, props, container, rootContainer);
|
|
20
|
+
const dialog = container.getDialog();
|
|
21
|
+
if (!dialog) {
|
|
22
|
+
throw new Error("ColorDialogButton must have a dialog");
|
|
23
|
+
}
|
|
24
|
+
this.dialog = dialog;
|
|
25
|
+
}
|
|
26
|
+
updateProps(oldProps, newProps) {
|
|
27
|
+
super.updateProps(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
|
|
28
|
+
this.applyOwnProps(oldProps, newProps);
|
|
29
|
+
}
|
|
30
|
+
applyOwnProps(oldProps, newProps) {
|
|
31
|
+
if (hasChanged(oldProps, newProps, "title") && newProps.title !== undefined) {
|
|
32
|
+
this.dialog.setTitle(newProps.title);
|
|
33
|
+
}
|
|
34
|
+
if (hasChanged(oldProps, newProps, "modal")) {
|
|
35
|
+
this.dialog.setModal(newProps.modal ?? true);
|
|
36
|
+
}
|
|
37
|
+
if (hasChanged(oldProps, newProps, "withAlpha")) {
|
|
38
|
+
this.dialog.setWithAlpha(newProps.withAlpha ?? true);
|
|
39
|
+
}
|
|
40
|
+
if (hasChanged(oldProps, newProps, "rgba") && newProps.rgba) {
|
|
41
|
+
this.container.setRgba(newProps.rgba);
|
|
42
|
+
}
|
|
43
|
+
if (hasChanged(oldProps, newProps, "onRgbaChanged")) {
|
|
44
|
+
this.setupNotifyHandler(newProps.onRgbaChanged);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
setupNotifyHandler(callback) {
|
|
48
|
+
if (this.notifyHandler) {
|
|
49
|
+
this.signalStore.set(this, this.container, "notify", undefined);
|
|
50
|
+
this.notifyHandler = null;
|
|
51
|
+
}
|
|
52
|
+
if (callback) {
|
|
53
|
+
this.notifyHandler = (_button, pspec) => {
|
|
54
|
+
if (pspec.getName() === "rgba") {
|
|
55
|
+
const rgba = this.container.getRgba();
|
|
56
|
+
callback(rgba);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
this.signalStore.set(this, this.container, "notify", this.notifyHandler);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
unmount() {
|
|
63
|
+
if (this.notifyHandler) {
|
|
64
|
+
this.signalStore.set(this, this.container, "notify", undefined);
|
|
65
|
+
this.notifyHandler = null;
|
|
66
|
+
}
|
|
67
|
+
super.unmount();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
registerNodeClass(ColorDialogButtonNode);
|
|
@@ -9,10 +9,10 @@ export declare class ColumnViewColumnNode extends VirtualNode<Props> {
|
|
|
9
9
|
static matches(type: string): boolean;
|
|
10
10
|
column: Gtk.ColumnViewColumn;
|
|
11
11
|
private itemRenderer;
|
|
12
|
-
constructor(typeName: string, props: Props, container: undefined, rootContainer
|
|
12
|
+
constructor(typeName: string, props: Props, container: undefined, rootContainer: Container);
|
|
13
13
|
unmount(): void;
|
|
14
|
-
setStore(model
|
|
15
|
-
setEstimatedRowHeight(height
|
|
14
|
+
setStore(model: ListStore | null): void;
|
|
15
|
+
setEstimatedRowHeight(height: number | null): void;
|
|
16
16
|
updateProps(oldProps: Props | null, newProps: Props): void;
|
|
17
17
|
}
|
|
18
18
|
export {};
|
|
@@ -11,7 +11,7 @@ export class ColumnViewColumnNode extends VirtualNode {
|
|
|
11
11
|
itemRenderer;
|
|
12
12
|
constructor(typeName, props, container, rootContainer) {
|
|
13
13
|
super(typeName, props, container, rootContainer);
|
|
14
|
-
this.itemRenderer = new ListItemRenderer();
|
|
14
|
+
this.itemRenderer = new ListItemRenderer(this.signalStore);
|
|
15
15
|
this.column = new Gtk.ColumnViewColumn();
|
|
16
16
|
this.column.setFactory(this.itemRenderer.getFactory());
|
|
17
17
|
}
|