@gtkx/react 0.17.2 → 0.18.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.
Files changed (194) hide show
  1. package/README.md +7 -7
  2. package/dist/factory.d.ts +0 -1
  3. package/dist/factory.js +21 -8
  4. package/dist/generated/internal.d.ts +4 -51
  5. package/dist/generated/internal.js +626 -412
  6. package/dist/generated/jsx.d.ts +453 -958
  7. package/dist/host-config.d.ts +1 -1
  8. package/dist/host-config.js +18 -23
  9. package/dist/index.d.ts +1 -1
  10. package/dist/index.js +1 -1
  11. package/dist/jsx.d.ts +579 -302
  12. package/dist/jsx.js +37 -179
  13. package/dist/metadata.d.ts +3 -0
  14. package/dist/metadata.js +26 -0
  15. package/dist/node.d.ts +20 -12
  16. package/dist/node.js +72 -17
  17. package/dist/nodes/adjustable.d.ts +3 -16
  18. package/dist/nodes/adjustable.js +5 -22
  19. package/dist/nodes/alert-dialog-response.d.ts +14 -1
  20. package/dist/nodes/alert-dialog-response.js +36 -62
  21. package/dist/nodes/animation.d.ts +37 -1
  22. package/dist/nodes/animation.js +162 -105
  23. package/dist/nodes/application.d.ts +11 -1
  24. package/dist/nodes/application.js +17 -38
  25. package/dist/nodes/calendar.d.ts +13 -0
  26. package/dist/nodes/calendar.js +10 -16
  27. package/dist/nodes/color-dialog-button.d.ts +13 -0
  28. package/dist/nodes/color-dialog-button.js +10 -38
  29. package/dist/nodes/column-view-column.d.ts +13 -11
  30. package/dist/nodes/column-view-column.js +27 -23
  31. package/dist/nodes/column-view.d.ts +31 -0
  32. package/dist/nodes/column-view.js +44 -44
  33. package/dist/nodes/container-slot.d.ts +15 -0
  34. package/dist/nodes/container-slot.js +68 -0
  35. package/dist/nodes/dialog.d.ts +6 -8
  36. package/dist/nodes/dialog.js +12 -13
  37. package/dist/nodes/drawing-area.d.ts +12 -0
  38. package/dist/nodes/drawing-area.js +24 -24
  39. package/dist/nodes/drop-down.d.ts +22 -0
  40. package/dist/nodes/drop-down.js +72 -0
  41. package/dist/nodes/event-controller.d.ts +8 -17
  42. package/dist/nodes/event-controller.js +20 -42
  43. package/dist/nodes/fixed-child.d.ts +18 -1
  44. package/dist/nodes/fixed-child.js +52 -36
  45. package/dist/nodes/font-dialog-button.d.ts +13 -0
  46. package/dist/nodes/font-dialog-button.js +12 -35
  47. package/dist/nodes/grid-child.d.ts +17 -1
  48. package/dist/nodes/grid-child.js +57 -37
  49. package/dist/nodes/grid-view.d.ts +24 -0
  50. package/dist/nodes/grid-view.js +73 -0
  51. package/dist/nodes/internal/base-item-renderer.d.ts +7 -9
  52. package/dist/nodes/internal/base-item-renderer.js +15 -18
  53. package/dist/nodes/internal/grid-item-renderer.d.ts +17 -0
  54. package/dist/nodes/internal/grid-item-renderer.js +59 -0
  55. package/dist/nodes/internal/list-item-renderer.d.ts +14 -9
  56. package/dist/nodes/internal/list-item-renderer.js +96 -35
  57. package/dist/nodes/internal/list-store.d.ts +5 -0
  58. package/dist/nodes/internal/list-store.js +39 -9
  59. package/dist/nodes/internal/predicates.d.ts +4 -19
  60. package/dist/nodes/internal/predicates.js +1 -20
  61. package/dist/nodes/internal/props.d.ts +5 -0
  62. package/dist/nodes/internal/props.js +42 -0
  63. package/dist/nodes/internal/{selection-model.d.ts → selection-model-controller.d.ts} +4 -9
  64. package/dist/nodes/internal/{selection-model.js → selection-model-controller.js} +6 -15
  65. package/dist/nodes/internal/signal-store.js +12 -5
  66. package/dist/nodes/internal/simple-list-store.d.ts +5 -0
  67. package/dist/nodes/internal/simple-list-store.js +42 -13
  68. package/dist/nodes/internal/text-buffer-controller.d.ts +4 -12
  69. package/dist/nodes/internal/text-buffer-controller.js +32 -33
  70. package/dist/nodes/internal/tree-store.d.ts +7 -0
  71. package/dist/nodes/internal/tree-store.js +75 -18
  72. package/dist/nodes/internal/widget.d.ts +7 -0
  73. package/dist/nodes/internal/widget.js +68 -0
  74. package/dist/nodes/level-bar.d.ts +10 -0
  75. package/dist/nodes/level-bar.js +11 -22
  76. package/dist/nodes/list-item.d.ts +17 -9
  77. package/dist/nodes/list-item.js +67 -12
  78. package/dist/nodes/list-view.d.ts +23 -0
  79. package/dist/nodes/list-view.js +27 -31
  80. package/dist/nodes/menu.d.ts +2 -4
  81. package/dist/nodes/menu.js +0 -6
  82. package/dist/nodes/models/grid.d.ts +27 -0
  83. package/dist/nodes/models/grid.js +68 -0
  84. package/dist/nodes/models/list.d.ts +15 -13
  85. package/dist/nodes/models/list.js +48 -26
  86. package/dist/nodes/models/menu.d.ts +15 -16
  87. package/dist/nodes/models/menu.js +63 -93
  88. package/dist/nodes/navigation-page.d.ts +16 -10
  89. package/dist/nodes/navigation-page.js +108 -31
  90. package/dist/nodes/navigation-view.d.ts +15 -0
  91. package/dist/nodes/navigation-view.js +15 -65
  92. package/dist/nodes/notebook-page-tab.d.ts +10 -12
  93. package/dist/nodes/notebook-page-tab.js +24 -27
  94. package/dist/nodes/notebook-page.d.ts +19 -16
  95. package/dist/nodes/notebook-page.js +75 -56
  96. package/dist/nodes/notebook.d.ts +10 -1
  97. package/dist/nodes/notebook.js +10 -22
  98. package/dist/nodes/overlay-child.d.ts +17 -1
  99. package/dist/nodes/overlay-child.js +53 -75
  100. package/dist/nodes/popover-menu.d.ts +15 -0
  101. package/dist/nodes/popover-menu.js +13 -26
  102. package/dist/nodes/scale.d.ts +8 -0
  103. package/dist/nodes/scale.js +2 -11
  104. package/dist/nodes/scrolled-window.d.ts +9 -0
  105. package/dist/nodes/scrolled-window.js +5 -11
  106. package/dist/nodes/search-bar.d.ts +9 -0
  107. package/dist/nodes/search-bar.js +8 -33
  108. package/dist/nodes/shortcut-controller.d.ts +9 -1
  109. package/dist/nodes/shortcut-controller.js +12 -25
  110. package/dist/nodes/shortcut.d.ts +11 -33
  111. package/dist/nodes/shortcut.js +19 -15
  112. package/dist/nodes/slot.d.ts +16 -15
  113. package/dist/nodes/slot.js +63 -57
  114. package/dist/nodes/source-view.d.ts +16 -0
  115. package/dist/nodes/source-view.js +44 -44
  116. package/dist/nodes/stack-page.d.ts +21 -1
  117. package/dist/nodes/stack-page.js +68 -17
  118. package/dist/nodes/stack.d.ts +11 -0
  119. package/dist/nodes/stack.js +8 -26
  120. package/dist/nodes/text-anchor.d.ts +11 -30
  121. package/dist/nodes/text-anchor.js +20 -22
  122. package/dist/nodes/text-content.d.ts +1 -0
  123. package/dist/nodes/text-content.js +1 -1
  124. package/dist/nodes/text-paintable.d.ts +10 -15
  125. package/dist/nodes/text-paintable.js +16 -9
  126. package/dist/nodes/text-segment.d.ts +12 -10
  127. package/dist/nodes/text-segment.js +19 -11
  128. package/dist/nodes/text-tag.d.ts +20 -119
  129. package/dist/nodes/text-tag.js +153 -119
  130. package/dist/nodes/text-view.d.ts +13 -18
  131. package/dist/nodes/text-view.js +17 -17
  132. package/dist/nodes/toggle-group.d.ts +9 -0
  133. package/dist/nodes/toggle-group.js +8 -33
  134. package/dist/nodes/toggle.d.ts +15 -1
  135. package/dist/nodes/toggle.js +34 -52
  136. package/dist/nodes/virtual.d.ts +3 -10
  137. package/dist/nodes/virtual.js +1 -14
  138. package/dist/nodes/web-view.d.ts +9 -0
  139. package/dist/nodes/web-view.js +10 -24
  140. package/dist/nodes/widget.d.ts +17 -13
  141. package/dist/nodes/widget.js +185 -112
  142. package/dist/nodes/window.d.ts +20 -21
  143. package/dist/nodes/window.js +54 -35
  144. package/dist/registry.d.ts +17 -6
  145. package/dist/registry.js +104 -5
  146. package/dist/render.d.ts +1 -10
  147. package/dist/render.js +1 -13
  148. package/package.json +6 -6
  149. package/dist/animation/css-builder.d.ts +0 -3
  150. package/dist/animation/css-builder.js +0 -53
  151. package/dist/animation/types.d.ts +0 -120
  152. package/dist/animation/types.js +0 -1
  153. package/dist/nodes/abstract/positional-child.d.ts +0 -9
  154. package/dist/nodes/abstract/positional-child.js +0 -29
  155. package/dist/nodes/abstract/virtual-container.d.ts +0 -21
  156. package/dist/nodes/abstract/virtual-container.js +0 -68
  157. package/dist/nodes/abstract/virtual-single-child.d.ts +0 -18
  158. package/dist/nodes/abstract/virtual-single-child.js +0 -55
  159. package/dist/nodes/action-row-child.d.ts +0 -1
  160. package/dist/nodes/action-row-child.js +0 -30
  161. package/dist/nodes/autowrapped.d.ts +0 -1
  162. package/dist/nodes/autowrapped.js +0 -115
  163. package/dist/nodes/expander-row-child.d.ts +0 -1
  164. package/dist/nodes/expander-row-child.js +0 -30
  165. package/dist/nodes/grid.d.ts +0 -1
  166. package/dist/nodes/grid.js +0 -41
  167. package/dist/nodes/index.d.ts +0 -56
  168. package/dist/nodes/index.js +0 -56
  169. package/dist/nodes/internal/child-attachment.d.ts +0 -26
  170. package/dist/nodes/internal/child-attachment.js +0 -48
  171. package/dist/nodes/internal/deferred-action.d.ts +0 -9
  172. package/dist/nodes/internal/deferred-action.js +0 -22
  173. package/dist/nodes/internal/text-tag-styles.d.ts +0 -43
  174. package/dist/nodes/internal/text-tag-styles.js +0 -52
  175. package/dist/nodes/internal/tree-list-item-renderer.d.ts +0 -26
  176. package/dist/nodes/internal/tree-list-item-renderer.js +0 -134
  177. package/dist/nodes/internal/utils.d.ts +0 -12
  178. package/dist/nodes/internal/utils.js +0 -92
  179. package/dist/nodes/models/tree-list.d.ts +0 -28
  180. package/dist/nodes/models/tree-list.js +0 -113
  181. package/dist/nodes/pack-child.d.ts +0 -1
  182. package/dist/nodes/pack-child.js +0 -30
  183. package/dist/nodes/simple-list-item.d.ts +0 -9
  184. package/dist/nodes/simple-list-item.js +0 -9
  185. package/dist/nodes/simple-list-view.d.ts +0 -1
  186. package/dist/nodes/simple-list-view.js +0 -74
  187. package/dist/nodes/toolbar-child.d.ts +0 -1
  188. package/dist/nodes/toolbar-child.js +0 -30
  189. package/dist/nodes/tree-list-item.d.ts +0 -22
  190. package/dist/nodes/tree-list-item.js +0 -90
  191. package/dist/nodes/tree-list-view.d.ts +0 -1
  192. package/dist/nodes/tree-list-view.js +0 -77
  193. package/dist/scheduler.d.ts +0 -26
  194. package/dist/scheduler.js +0 -42
@@ -1 +1,37 @@
1
- export {};
1
+ import type { AnimationProps } from "../jsx.js";
2
+ import type { Node } from "../node.js";
3
+ import type { Container } from "../types.js";
4
+ import { VirtualNode } from "./virtual.js";
5
+ import { WidgetNode } from "./widget.js";
6
+ export declare class AnimationNode extends VirtualNode<AnimationProps, WidgetNode, WidgetNode> {
7
+ private className;
8
+ private provider;
9
+ private display;
10
+ private currentAnimation;
11
+ private currentValues;
12
+ private isExiting;
13
+ private detachedParentWidget;
14
+ constructor(typeName: string, props: AnimationProps, container: undefined, rootContainer: Container);
15
+ isValidChild(child: Node): boolean;
16
+ isValidParent(parent: Node): boolean;
17
+ setParent(parent: WidgetNode | null): void;
18
+ appendChild(child: WidgetNode): void;
19
+ removeChild(child: WidgetNode): void;
20
+ finalizeInitialChildren(props: AnimationProps): boolean;
21
+ commitMount(): void;
22
+ commitUpdate(oldProps: AnimationProps | null, newProps: AnimationProps): void;
23
+ detachDeletedInstance(): void;
24
+ private onChildChange;
25
+ private detachChildFromParentWidget;
26
+ private setupCssProvider;
27
+ private cleanup;
28
+ private animateTo;
29
+ private createAnimation;
30
+ private createTimedAnimation;
31
+ private createSpringAnimation;
32
+ private applyValues;
33
+ private getDefaultValue;
34
+ private interpolate;
35
+ private buildCss;
36
+ private areAnimatedPropsEqual;
37
+ }
@@ -1,129 +1,133 @@
1
- import { isObjectEqual } from "@gtkx/ffi";
2
1
  import * as Adw from "@gtkx/ffi/adw";
3
2
  import * as Gdk from "@gtkx/ffi/gdk";
4
3
  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";
4
+ import { attachChild, detachChild, isAttachedTo } from "./internal/widget.js";
5
+ import { VirtualNode } from "./virtual.js";
6
+ import { WidgetNode } from "./widget.js";
11
7
  let animationCounter = 0;
12
8
  const DEFAULT_TIMED_DURATION = 300;
13
9
  const DEFAULT_SPRING_DAMPING = 1;
14
10
  const DEFAULT_SPRING_MASS = 1;
15
11
  const DEFAULT_SPRING_STIFFNESS = 100;
16
- class AnimationNode extends VirtualSingleChildNode {
17
- static priority = 2;
18
- static matches(type) {
19
- return type === "Animation";
20
- }
12
+ export class AnimationNode extends VirtualNode {
21
13
  className;
22
14
  provider = null;
23
15
  display = null;
24
16
  currentAnimation = null;
25
17
  currentValues = {};
26
18
  isExiting = false;
19
+ detachedParentWidget = null;
27
20
  constructor(typeName, props, container, rootContainer) {
28
21
  super(typeName, props, container, rootContainer);
29
22
  this.className = `gtkx-anim-${animationCounter++}`;
30
23
  }
31
- updateProps(oldProps, newProps) {
32
- super.updateProps(oldProps, newProps);
33
- if (this.isExiting) {
34
- return;
24
+ isValidChild(child) {
25
+ return child instanceof WidgetNode;
26
+ }
27
+ isValidParent(parent) {
28
+ return parent instanceof WidgetNode;
29
+ }
30
+ setParent(parent) {
31
+ if (!parent && this.parent) {
32
+ this.detachedParentWidget = this.parent.container;
35
33
  }
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);
34
+ super.setParent(parent);
35
+ if (parent && this.children[0]) {
36
+ this.onChildChange(null);
43
37
  }
44
38
  }
45
- onChildChange(oldChild) {
46
- if (oldChild && this.provider) {
47
- oldChild.removeCssClass(this.className);
39
+ appendChild(child) {
40
+ const oldChildWidget = this.children[0]?.container ?? null;
41
+ super.appendChild(child);
42
+ if (this.parent) {
43
+ this.onChildChange(oldChildWidget);
48
44
  }
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
- }
45
+ }
46
+ removeChild(child) {
47
+ const oldChildWidget = child.container;
48
+ super.removeChild(child);
49
+ if (this.parent && oldChildWidget) {
50
+ this.onChildChange(oldChildWidget);
57
51
  }
58
- if (this.child && this.parent) {
59
- const strategy = getAttachmentStrategy(this.parent);
60
- if (strategy) {
61
- attachChild(this.child, strategy);
52
+ }
53
+ finalizeInitialChildren(props) {
54
+ this.commitUpdate(null, props);
55
+ return !!props.animateOnMount;
56
+ }
57
+ commitMount() {
58
+ const animate = this.props.animate;
59
+ if (this.props.animateOnMount && animate) {
60
+ this.animateTo(animate);
61
+ }
62
+ }
63
+ commitUpdate(oldProps, newProps) {
64
+ super.commitUpdate(oldProps, newProps);
65
+ if (this.isExiting) {
66
+ return;
67
+ }
68
+ if (oldProps && newProps.animate && !this.areAnimatedPropsEqual(oldProps.animate, newProps.animate)) {
69
+ const target = newProps.animate;
70
+ if (this.children[0] && !this.isExiting) {
71
+ this.animateTo(target);
62
72
  }
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
73
  }
86
74
  }
87
- unmount() {
75
+ detachDeletedInstance() {
88
76
  if (this.isExiting) {
89
77
  return;
90
78
  }
91
- if (this.props.exit && this.child) {
79
+ if (this.props.exit && this.children[0]) {
92
80
  this.isExiting = true;
93
81
  this.animateTo(this.props.exit, () => {
94
- this.detachChildFromParent();
82
+ this.detachChildFromParentWidget();
95
83
  this.cleanup();
96
- super.unmount();
84
+ super.detachDeletedInstance();
97
85
  });
98
86
  }
99
87
  else {
100
- this.detachChildFromParent();
88
+ this.detachChildFromParentWidget();
101
89
  this.cleanup();
102
- super.unmount();
90
+ super.detachDeletedInstance();
103
91
  }
104
92
  }
105
- detachChildFromParent() {
106
- if (this.child && this.parent && this.isChildAttachedToParent()) {
107
- const strategy = getAttachmentStrategy(this.parent);
108
- if (strategy) {
109
- detachChild(this.child, strategy);
93
+ onChildChange(oldChild) {
94
+ const parentWidget = this.parent?.container ?? null;
95
+ const childWidget = this.children[0]?.container ?? null;
96
+ if (oldChild && this.provider) {
97
+ oldChild.removeCssClass(this.className);
98
+ }
99
+ if (oldChild && parentWidget && isAttachedTo(oldChild, parentWidget)) {
100
+ detachChild(oldChild, parentWidget);
101
+ }
102
+ if (childWidget && parentWidget) {
103
+ attachChild(childWidget, parentWidget);
104
+ this.setupCssProvider();
105
+ childWidget.addCssClass(this.className);
106
+ const initial = this.props.initial;
107
+ const animate = this.props.animate;
108
+ if (initial === false || !this.props.animateOnMount) {
109
+ if (animate) {
110
+ this.currentValues = { ...animate };
111
+ this.applyValues(this.currentValues);
112
+ }
110
113
  }
111
- else if (isRemovable(this.parent)) {
112
- this.parent.remove(this.child);
114
+ else {
115
+ const initialValues = initial ?? animate ?? {};
116
+ this.currentValues = { ...initialValues };
117
+ this.applyValues(this.currentValues);
113
118
  }
114
119
  }
115
120
  }
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);
121
+ detachChildFromParentWidget() {
122
+ const parentWidget = this.parent?.container ?? this.detachedParentWidget;
123
+ const childWidget = this.children[0]?.container ?? null;
124
+ if (childWidget && parentWidget && isAttachedTo(childWidget, parentWidget)) {
125
+ detachChild(childWidget, parentWidget);
126
+ }
124
127
  }
125
128
  setupCssProvider() {
126
- if (this.provider || !this.child)
129
+ const childWidget = this.children[0]?.container ?? null;
130
+ if (this.provider || !childWidget)
127
131
  return;
128
132
  this.provider = new Gtk.CssProvider();
129
133
  this.display = Gdk.DisplayManager.get().getDefaultDisplay();
@@ -132,6 +136,7 @@ class AnimationNode extends VirtualSingleChildNode {
132
136
  }
133
137
  }
134
138
  cleanup() {
139
+ const childWidget = this.children[0]?.container ?? null;
135
140
  if (this.currentAnimation) {
136
141
  this.currentAnimation.skip();
137
142
  this.currentAnimation = null;
@@ -139,14 +144,15 @@ class AnimationNode extends VirtualSingleChildNode {
139
144
  if (this.provider && this.display) {
140
145
  Gtk.StyleContext.removeProviderForDisplay(this.display, this.provider);
141
146
  }
142
- if (this.child) {
143
- this.child.removeCssClass(this.className);
147
+ if (childWidget) {
148
+ childWidget.removeCssClass(this.className);
144
149
  }
145
150
  this.provider = null;
146
151
  this.display = null;
147
152
  }
148
153
  animateTo(target, onComplete) {
149
- if (!this.child)
154
+ const childWidget = this.children[0]?.container ?? null;
155
+ if (!childWidget)
150
156
  return;
151
157
  if (this.currentAnimation) {
152
158
  this.currentAnimation.skip();
@@ -156,11 +162,11 @@ class AnimationNode extends VirtualSingleChildNode {
156
162
  const to = { ...target };
157
163
  this.props.onAnimationStart?.();
158
164
  const callback = new Adw.CallbackAnimationTarget((progress) => {
159
- const interpolated = interpolate(from, to, progress);
165
+ const interpolated = this.interpolate(from, to, progress);
160
166
  this.currentValues = interpolated;
161
167
  this.applyValues(interpolated);
162
168
  });
163
- const animation = this.createAnimation(this.child, callback);
169
+ const animation = this.createAnimation(childWidget, callback);
164
170
  animation.connect("done", () => {
165
171
  this.currentValues = { ...to };
166
172
  this.currentAnimation = null;
@@ -182,14 +188,13 @@ class AnimationNode extends VirtualSingleChildNode {
182
188
  }
183
189
  }
184
190
  createAnimation(widget, target) {
185
- const mode = this.props.mode;
186
- if (mode === "spring") {
187
- return this.createSpringAnimation(widget, target);
191
+ const transition = this.props.transition;
192
+ if (transition?.mode === "spring") {
193
+ return this.createSpringAnimation(widget, target, transition);
188
194
  }
189
- return this.createTimedAnimation(widget, target);
195
+ return this.createTimedAnimation(widget, target, transition);
190
196
  }
191
- createTimedAnimation(widget, target) {
192
- const transition = this.props.transition;
197
+ createTimedAnimation(widget, target, transition) {
193
198
  const duration = transition?.duration ?? DEFAULT_TIMED_DURATION;
194
199
  const animation = new Adw.TimedAnimation(widget, 0, 1, duration, target);
195
200
  if (transition?.easing !== undefined) {
@@ -206,17 +211,16 @@ class AnimationNode extends VirtualSingleChildNode {
206
211
  }
207
212
  return animation;
208
213
  }
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
+ createSpringAnimation(widget, target, transition) {
215
+ const damping = transition.damping ?? DEFAULT_SPRING_DAMPING;
216
+ const mass = transition.mass ?? DEFAULT_SPRING_MASS;
217
+ const stiffness = transition.stiffness ?? DEFAULT_SPRING_STIFFNESS;
214
218
  const springParams = new Adw.SpringParams(damping, mass, stiffness);
215
219
  const animation = new Adw.SpringAnimation(widget, 0, 1, springParams, target);
216
- if (transition?.initialVelocity !== undefined) {
220
+ if (transition.initialVelocity !== undefined) {
217
221
  animation.setInitialVelocity(transition.initialVelocity);
218
222
  }
219
- if (transition?.clamp !== undefined) {
223
+ if (transition.clamp !== undefined) {
220
224
  animation.setClamp(transition.clamp);
221
225
  }
222
226
  return animation;
@@ -225,15 +229,69 @@ class AnimationNode extends VirtualSingleChildNode {
225
229
  if (!this.provider) {
226
230
  return;
227
231
  }
228
- if (this.child && !this.child.getCssClasses()?.includes(this.className)) {
229
- this.child.addCssClass(this.className);
232
+ const childWidget = this.children[0]?.container ?? null;
233
+ if (childWidget && !childWidget.getCssClasses()?.includes(this.className)) {
234
+ childWidget.addCssClass(this.className);
230
235
  }
231
- const css = buildCss(this.className, values);
236
+ const css = this.buildCss(this.className, values);
232
237
  if (css) {
233
238
  this.provider.loadFromString(css);
234
239
  }
235
240
  }
236
- arePropsEqual(a, b) {
241
+ getDefaultValue(property) {
242
+ switch (property) {
243
+ case "opacity":
244
+ case "scale":
245
+ case "scaleX":
246
+ case "scaleY":
247
+ return 1;
248
+ default:
249
+ return 0;
250
+ }
251
+ }
252
+ interpolate(from, to, progress) {
253
+ const result = {};
254
+ const allKeys = new Set([...Object.keys(from), ...Object.keys(to)]);
255
+ for (const key of allKeys) {
256
+ const fromVal = from[key] ?? this.getDefaultValue(key);
257
+ const toVal = to[key] ?? this.getDefaultValue(key);
258
+ result[key] = fromVal + (toVal - fromVal) * progress;
259
+ }
260
+ return result;
261
+ }
262
+ buildCss(className, props) {
263
+ const parts = [];
264
+ const transforms = [];
265
+ if (props.opacity !== undefined) {
266
+ parts.push(`opacity: ${props.opacity}`);
267
+ }
268
+ if (props.translateX !== undefined || props.translateY !== undefined) {
269
+ transforms.push(`translate(${props.translateX ?? 0}px, ${props.translateY ?? 0}px)`);
270
+ }
271
+ if (props.scale !== undefined) {
272
+ transforms.push(`scale(${props.scale})`);
273
+ }
274
+ else if (props.scaleX !== undefined || props.scaleY !== undefined) {
275
+ transforms.push(`scale(${props.scaleX ?? 1}, ${props.scaleY ?? 1})`);
276
+ }
277
+ if (props.rotate !== undefined) {
278
+ transforms.push(`rotate(${props.rotate}deg)`);
279
+ }
280
+ if (props.skewX !== undefined) {
281
+ transforms.push(`skewX(${props.skewX}deg)`);
282
+ }
283
+ if (props.skewY !== undefined) {
284
+ transforms.push(`skewY(${props.skewY}deg)`);
285
+ }
286
+ if (transforms.length > 0) {
287
+ parts.push(`transform: ${transforms.join(" ")}`);
288
+ }
289
+ if (parts.length === 0) {
290
+ return "";
291
+ }
292
+ return `.${className} { ${parts.join("; ")}; }`;
293
+ }
294
+ areAnimatedPropsEqual(a, b) {
237
295
  if (a === b)
238
296
  return true;
239
297
  if (!a || !b)
@@ -249,4 +307,3 @@ class AnimationNode extends VirtualSingleChildNode {
249
307
  return true;
250
308
  }
251
309
  }
252
- registerNodeClass(AnimationNode);
@@ -1 +1,11 @@
1
- export {};
1
+ import * as Gtk from "@gtkx/ffi/gtk";
2
+ import { Node } from "../node.js";
3
+ import type { Container, Props } from "../types.js";
4
+ export declare class ApplicationNode extends Node<Gtk.Application, Props, Node, Node> {
5
+ private menu;
6
+ constructor(typeName: string, props: Props, container: Gtk.Application, rootContainer: Container);
7
+ isValidChild(): boolean;
8
+ appendChild(child: Node): void;
9
+ insertBefore(child: Node, before: Node): void;
10
+ removeChild(child: Node): void;
11
+ }
@@ -1,67 +1,46 @@
1
1
  import * as Gtk from "@gtkx/ffi/gtk";
2
2
  import { Node } from "../node.js";
3
- import { registerNodeClass } from "../registry.js";
4
- import { CommitPriority, scheduleAfterCommit } from "../scheduler.js";
5
- import { DialogNode } from "./dialog.js";
6
- import { matchesAnyClass } from "./internal/utils.js";
7
3
  import { MenuNode } from "./menu.js";
8
4
  import { MenuModel } from "./models/menu.js";
9
- import { WindowNode } from "./window.js";
10
- class ApplicationNode extends Node {
11
- static priority = 0;
5
+ export class ApplicationNode extends Node {
12
6
  menu;
13
- static matches(_type, containerOrClass) {
14
- return matchesAnyClass([Gtk.Application], containerOrClass);
15
- }
16
7
  constructor(typeName, props, container, rootContainer) {
17
8
  super(typeName, props, container, rootContainer);
18
9
  const application = rootContainer instanceof Gtk.Application ? rootContainer : undefined;
19
10
  this.menu = new MenuModel("root", {}, rootContainer, container, application);
20
11
  }
12
+ isValidChild() {
13
+ return true;
14
+ }
21
15
  appendChild(child) {
22
16
  if (child instanceof MenuNode) {
23
17
  this.menu.appendChild(child);
24
18
  this.container.setMenubar(this.menu.getMenu());
25
19
  return;
26
20
  }
27
- if (child instanceof WindowNode && child.container instanceof Gtk.ApplicationWindow) {
28
- return;
29
- }
30
- if (child instanceof DialogNode) {
31
- return;
32
- }
33
- throw new Error(`Cannot append '${child.typeName}' to 'Application': expected ApplicationWindow, Dialog, or MenuItem`);
21
+ super.appendChild(child);
34
22
  }
35
23
  insertBefore(child, before) {
36
24
  if (child instanceof MenuNode) {
37
- this.menu.insertBefore(child, before);
38
- return;
39
- }
40
- if (child instanceof WindowNode && child.container instanceof Gtk.ApplicationWindow) {
41
- return;
42
- }
43
- if (child instanceof DialogNode) {
25
+ if (before instanceof MenuNode) {
26
+ this.menu.insertBefore(child, before);
27
+ }
28
+ else {
29
+ this.menu.appendChild(child);
30
+ }
31
+ this.container.setMenubar(this.menu.getMenu());
44
32
  return;
45
33
  }
46
- throw new Error(`Cannot insert '${child.typeName}' into 'Application': expected ApplicationWindow, Dialog, or MenuItem`);
34
+ super.insertBefore(child, before);
47
35
  }
48
36
  removeChild(child) {
49
37
  if (child instanceof MenuNode) {
50
38
  this.menu.removeChild(child);
51
- scheduleAfterCommit(() => {
52
- if (this.menu.getMenu().getNItems() === 0) {
53
- this.container.setMenubar(null);
54
- }
55
- }, CommitPriority.LOW);
56
- return;
57
- }
58
- if (child instanceof WindowNode && child.container instanceof Gtk.ApplicationWindow) {
59
- return;
60
- }
61
- if (child instanceof DialogNode) {
39
+ if (this.menu.getMenu().getNItems() === 0) {
40
+ this.container.setMenubar(null);
41
+ }
62
42
  return;
63
43
  }
64
- throw new Error(`Cannot remove '${child.typeName}' from 'Application': expected ApplicationWindow, Dialog, or MenuItem`);
44
+ super.removeChild(child);
65
45
  }
66
46
  }
67
- registerNodeClass(ApplicationNode);
@@ -1 +1,14 @@
1
+ import type * as Gtk from "@gtkx/ffi/gtk";
2
+ import type { GtkCalendarProps } from "../jsx.js";
3
+ import type { Node } from "../node.js";
4
+ import { EventControllerNode } from "./event-controller.js";
5
+ import { WidgetNode } from "./widget.js";
6
+ declare const OWN_PROPS: readonly ["markedDays"];
7
+ type CalendarProps = Pick<GtkCalendarProps, (typeof OWN_PROPS)[number]>;
8
+ export declare class CalendarNode extends WidgetNode<Gtk.Calendar, CalendarProps, EventControllerNode> {
9
+ isValidChild(child: Node): boolean;
10
+ private appliedMarks;
11
+ commitUpdate(oldProps: CalendarProps | null, newProps: CalendarProps): void;
12
+ private applyOwnProps;
13
+ }
1
14
  export {};
@@ -1,22 +1,17 @@
1
- import * as Gtk from "@gtkx/ffi/gtk";
2
- import { registerNodeClass } from "../registry.js";
3
- import { filterProps, matchesAnyClass, primitiveArrayEqual } from "./internal/utils.js";
1
+ import { EventControllerNode } from "./event-controller.js";
2
+ import { filterProps, primitiveArrayEqual } from "./internal/props.js";
4
3
  import { WidgetNode } from "./widget.js";
5
4
  const OWN_PROPS = ["markedDays"];
6
- class CalendarNode extends WidgetNode {
7
- static priority = 1;
8
- appliedMarks = [];
9
- static matches(_type, containerOrClass) {
10
- return matchesAnyClass([Gtk.Calendar], containerOrClass);
11
- }
12
- updateProps(oldProps, newProps) {
13
- super.updateProps(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
14
- this.applyOwnProps(oldProps, newProps);
5
+ export class CalendarNode extends WidgetNode {
6
+ isValidChild(child) {
7
+ return child instanceof EventControllerNode;
15
8
  }
16
- applyOwnProps(_oldProps, newProps) {
17
- this.applyMarkedDays(newProps);
9
+ appliedMarks = [];
10
+ commitUpdate(oldProps, newProps) {
11
+ super.commitUpdate(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
12
+ this.applyOwnProps(newProps);
18
13
  }
19
- applyMarkedDays(newProps) {
14
+ applyOwnProps(newProps) {
20
15
  const newMarkedDays = newProps.markedDays ?? [];
21
16
  if (primitiveArrayEqual(this.appliedMarks, newMarkedDays)) {
22
17
  return;
@@ -28,4 +23,3 @@ class CalendarNode extends WidgetNode {
28
23
  this.appliedMarks = [...newMarkedDays];
29
24
  }
30
25
  }
31
- registerNodeClass(CalendarNode);
@@ -1 +1,14 @@
1
+ import * as Gtk from "@gtkx/ffi/gtk";
2
+ import type { GtkColorDialogButtonProps } from "../jsx.js";
3
+ import type { Container } from "../types.js";
4
+ import { WidgetNode } from "./widget.js";
5
+ declare const OWN_PROPS: readonly ["rgba", "onRgbaChanged", "title", "modal", "withAlpha"];
6
+ type ColorDialogButtonProps = Pick<GtkColorDialogButtonProps, (typeof OWN_PROPS)[number]>;
7
+ export declare class ColorDialogButtonNode extends WidgetNode<Gtk.ColorDialogButton, ColorDialogButtonProps> {
8
+ private dialog;
9
+ static createContainer(_props: ColorDialogButtonProps, containerClass: typeof Gtk.Widget): Container | null;
10
+ constructor(typeName: string, props: ColorDialogButtonProps, container: Gtk.ColorDialogButton, rootContainer: Container);
11
+ commitUpdate(oldProps: ColorDialogButtonProps | null, newProps: ColorDialogButtonProps): void;
12
+ private applyOwnProps;
13
+ }
1
14
  export {};
@@ -1,35 +1,29 @@
1
1
  import * as Gtk from "@gtkx/ffi/gtk";
2
- import { registerNodeClass } from "../registry.js";
3
- import { filterProps, hasChanged, matchesAnyClass } from "./internal/utils.js";
2
+ import { filterProps, hasChanged } from "./internal/props.js";
4
3
  import { WidgetNode } from "./widget.js";
5
4
  const OWN_PROPS = ["rgba", "onRgbaChanged", "title", "modal", "withAlpha"];
6
- class ColorDialogButtonNode extends WidgetNode {
7
- static priority = 1;
5
+ export class ColorDialogButtonNode extends WidgetNode {
8
6
  dialog;
9
- notifyHandler = null;
10
- static matches(_type, containerOrClass) {
11
- return matchesAnyClass([Gtk.ColorDialogButton], containerOrClass);
12
- }
13
7
  static createContainer(_props, containerClass) {
14
8
  const dialog = new Gtk.ColorDialog();
15
9
  const button = new containerClass(dialog);
16
10
  return button;
17
11
  }
18
- constructor(type, props, container, rootContainer) {
19
- super(type, props, container, rootContainer);
12
+ constructor(typeName, props, container, rootContainer) {
13
+ super(typeName, props, container, rootContainer);
20
14
  const dialog = container.getDialog();
21
15
  if (!dialog) {
22
16
  throw new Error("ColorDialogButton must have a dialog");
23
17
  }
24
18
  this.dialog = dialog;
25
19
  }
26
- updateProps(oldProps, newProps) {
27
- super.updateProps(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
20
+ commitUpdate(oldProps, newProps) {
21
+ super.commitUpdate(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
28
22
  this.applyOwnProps(oldProps, newProps);
29
23
  }
30
24
  applyOwnProps(oldProps, newProps) {
31
- if (hasChanged(oldProps, newProps, "title") && newProps.title !== undefined) {
32
- this.dialog.setTitle(newProps.title);
25
+ if (hasChanged(oldProps, newProps, "title")) {
26
+ this.dialog.setTitle(newProps.title ?? "");
33
27
  }
34
28
  if (hasChanged(oldProps, newProps, "modal")) {
35
29
  this.dialog.setModal(newProps.modal ?? true);
@@ -41,30 +35,8 @@ class ColorDialogButtonNode extends WidgetNode {
41
35
  this.container.setRgba(newProps.rgba);
42
36
  }
43
37
  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;
38
+ const callback = newProps.onRgbaChanged;
39
+ this.signalStore.set(this, this.container, "notify::rgba", callback ? () => callback(this.container.getRgba()) : undefined);
66
40
  }
67
- super.unmount();
68
41
  }
69
42
  }
70
- registerNodeClass(ColorDialogButtonNode);