@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,10 @@
1
+ import type * as WebKit from "@gtkx/ffi/webkit";
2
+ import type { WebKitWebViewProps } from "../jsx.js";
3
+ import { WidgetNode } from "./widget.js";
4
+ declare const OWN_PROPS: readonly ["onLoadChanged"];
5
+ type WebViewProps = Pick<WebKitWebViewProps, (typeof OWN_PROPS)[number]>;
6
+ export declare class WebViewNode extends WidgetNode<WebKit.WebView, WebViewProps> {
7
+ commitUpdate(oldProps: WebViewProps | null, newProps: WebViewProps): void;
8
+ private applyOwnProps;
9
+ }
1
10
  export {};
@@ -1,29 +1,15 @@
1
- import * as WebKit from "@gtkx/ffi/webkit";
2
- import { registerNodeClass } from "../registry.js";
3
- import { filterProps, hasChanged, matchesAnyClass, propNameToSignalName, resolveSignal } from "./internal/utils.js";
1
+ import { filterProps, hasChanged } from "./internal/props.js";
4
2
  import { WidgetNode } from "./widget.js";
5
- const NON_BLOCKABLE_SIGNALS = ["load-changed"];
6
- class WebViewNode extends WidgetNode {
7
- static priority = 1;
8
- static matches(_type, containerOrClass) {
9
- return matchesAnyClass([WebKit.WebView], containerOrClass);
3
+ const OWN_PROPS = ["onLoadChanged"];
4
+ export class WebViewNode extends WidgetNode {
5
+ commitUpdate(oldProps, newProps) {
6
+ super.commitUpdate(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
7
+ this.applyOwnProps(oldProps, newProps);
10
8
  }
11
- updateProps(oldProps, newProps) {
12
- super.updateProps(oldProps ? filterProps(oldProps, NON_BLOCKABLE_SIGNALS) : null, filterProps(newProps, NON_BLOCKABLE_SIGNALS));
13
- this.applyNonBlockableSignals(oldProps, newProps);
14
- }
15
- applyNonBlockableSignals(oldProps, newProps) {
16
- for (const propName of NON_BLOCKABLE_SIGNALS) {
17
- const camelCaseName = `on${propName.charAt(0).toUpperCase()}${propName.slice(1).replace(/-([a-z])/g, (_, c) => c.toUpperCase())}`;
18
- if (hasChanged(oldProps, newProps, camelCaseName)) {
19
- const signalName = propNameToSignalName(camelCaseName);
20
- if (resolveSignal(this.container, signalName)) {
21
- const newValue = newProps[camelCaseName];
22
- const handler = typeof newValue === "function" ? newValue : undefined;
23
- this.signalStore.set(this, this.container, signalName, handler, { blockable: false });
24
- }
25
- }
9
+ applyOwnProps(oldProps, newProps) {
10
+ if (hasChanged(oldProps, newProps, "onLoadChanged")) {
11
+ const callback = newProps.onLoadChanged;
12
+ this.signalStore.set(this, this.container, "load-changed", callback ?? undefined, { blockable: false });
26
13
  }
27
14
  }
28
15
  }
29
- registerNodeClass(WebViewNode);
@@ -1,23 +1,27 @@
1
1
  import * as Gtk from "@gtkx/ffi/gtk";
2
2
  import { Node } from "../node.js";
3
- import type { Container, ContainerClass, Props } from "../types.js";
4
- export declare class WidgetNode<T extends Gtk.Widget = Gtk.Widget, P extends Props = Props> extends Node<T, P> {
5
- static priority: number;
6
- static matches(_type: string, containerOrClass?: Container | ContainerClass | null): boolean;
3
+ import type { Container, Props } from "../types.js";
4
+ export declare class WidgetNode<T extends Gtk.Widget = Gtk.Widget, P extends Props = Props, TChild extends Node = any, TParent extends Node = Node> extends Node<T, P, TParent, TChild> {
7
5
  static createContainer(props: Props, containerClass: typeof Gtk.Widget, _rootContainer?: Container): Container | null;
8
- appendChild(child: Node): void;
9
- removeChild(child: Node): void;
10
- insertBefore(child: Node, before: Node): void;
11
- private insertBeforeReorderable;
12
- private insertBeforeInsertable;
13
- updateProps(oldProps: P | null, newProps: P): void;
6
+ isValidChild(_child: Node): boolean;
7
+ protected shouldAttachToParent(): boolean;
8
+ appendChild(child: TChild): void;
9
+ removeChild(child: TChild): void;
10
+ insertBefore(child: TChild, before: TChild): void;
11
+ commitUpdate(oldProps: P | null, newProps: P): void;
12
+ private appendWidgetChild;
13
+ private isChildAutowrapped;
14
+ private detachAutowrappedChild;
15
+ private insertBeforeAutowrapping;
16
+ private findAutowrappedPosition;
17
+ private unwrapGtkChild;
18
+ private reinsertAllChildren;
14
19
  private updateSizeRequest;
15
20
  private updateGrabFocus;
16
21
  private getPropertyDefaultValue;
17
22
  private setProperty;
18
- private detachChildFromParent;
19
- private attachChild;
20
- private detachChild;
23
+ private insertBeforeReorderable;
24
+ private insertBeforeInsertable;
21
25
  private findPreviousSibling;
22
26
  private findInsertPosition;
23
27
  }
@@ -1,16 +1,14 @@
1
- import { getNativeObject, isObjectEqual } from "@gtkx/ffi";
1
+ import { getNativeObject } from "@gtkx/ffi";
2
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
+ import { resolvePropMeta, resolveSignal } from "../metadata.js";
5
6
  import { Node } from "../node.js";
6
- import { registerNodeClass } from "../registry.js";
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";
7
+ import { isAddable, isAppendable, isEditable, isInsertable, isRemovable, isReorderable, isSingleChild, } from "./internal/predicates.js";
8
+ import { filterProps } from "./internal/props.js";
9
+ import { attachChild, detachChild } from "./internal/widget.js";
10
10
  const EXCLUDED_PROPS = ["children", "widthRequest", "heightRequest", "grabFocus"];
11
11
  function findProperty(obj, key) {
12
- if (!obj.handle)
13
- return null;
14
12
  const propertyName = key.replace(/([A-Z])/g, "-$1").toLowerCase();
15
13
  const typeInstance = getNativeObject(obj.handle, TypeInstance);
16
14
  const typeName = typeNameFromInstance(typeInstance);
@@ -20,123 +18,199 @@ function findProperty(obj, key) {
20
18
  return objectClass.findProperty(propertyName) ?? null;
21
19
  }
22
20
  export class WidgetNode extends Node {
23
- static priority = 3;
24
- static matches(_type, containerOrClass) {
25
- return matchesAnyClass([Gtk.Widget], containerOrClass);
26
- }
27
21
  static createContainer(props, containerClass, _rootContainer) {
28
22
  const WidgetClass = containerClass;
29
23
  const typeName = WidgetClass.glibTypeName;
30
24
  const args = (CONSTRUCTOR_PROPS[typeName] ?? []).map((name) => props[name]);
31
25
  return new WidgetClass(...args);
32
26
  }
27
+ isValidChild(_child) {
28
+ return true;
29
+ }
30
+ shouldAttachToParent() {
31
+ return true;
32
+ }
33
33
  appendChild(child) {
34
- if (isAttachable(child) && child.canBeChildOf(this)) {
35
- child.attachTo(this);
36
- return;
34
+ super.appendChild(child);
35
+ if (child instanceof WidgetNode && child.shouldAttachToParent()) {
36
+ this.appendWidgetChild(child);
37
37
  }
38
- if (!(child instanceof WidgetNode)) {
39
- throw new Error(`Cannot append '${child.typeName}' to 'Widget': expected Widget`);
40
- }
41
- if (child.container instanceof Gtk.Window) {
42
- throw new Error(`Cannot append 'Window' to '${this.typeName}': windows must be top-level containers`);
43
- }
44
- this.attachChild(child);
45
38
  }
46
39
  removeChild(child) {
47
- if (isAttachable(child) && child.canBeChildOf(this)) {
48
- child.detachFrom(this);
49
- return;
50
- }
51
- if (!(child instanceof WidgetNode)) {
52
- throw new Error(`Cannot remove '${child.typeName}' from 'Widget': expected Widget`);
53
- }
54
- if (child.container instanceof Gtk.Window) {
55
- throw new Error(`Cannot remove 'Window' from '${this.typeName}': windows must be top-level containers`);
40
+ if (child instanceof WidgetNode && child.shouldAttachToParent()) {
41
+ if (this.isChildAutowrapped(child)) {
42
+ const wrapper = child.container.getParent();
43
+ if (wrapper && isSingleChild(wrapper)) {
44
+ wrapper.setChild(null);
45
+ if (isRemovable(this.container)) {
46
+ this.container.remove(wrapper);
47
+ }
48
+ }
49
+ }
50
+ else {
51
+ detachChild(child.container, this.container);
52
+ }
56
53
  }
57
- this.detachChild(child);
54
+ super.removeChild(child);
58
55
  }
59
56
  insertBefore(child, before) {
60
- if (isAttachable(child) && child.canBeChildOf(this)) {
61
- child.attachTo(this);
57
+ super.insertBefore(child, before);
58
+ if (!(child instanceof WidgetNode) || !child.shouldAttachToParent())
59
+ return;
60
+ if (!(before instanceof WidgetNode)) {
61
+ this.appendWidgetChild(child);
62
62
  return;
63
63
  }
64
- if (!(child instanceof WidgetNode) || !(before instanceof WidgetNode)) {
65
- throw new Error(`Cannot insert '${child.typeName}' into '${this.typeName}': expected Widget`);
66
- }
67
- if (child.container instanceof Gtk.Window) {
68
- throw new Error(`Cannot insert 'Window' into '${this.typeName}': windows must be top-level containers`);
64
+ if (this.container instanceof Gtk.ListBox || this.container instanceof Gtk.FlowBox) {
65
+ this.insertBeforeAutowrapping(child, before);
69
66
  }
70
- if (isReorderable(this.container)) {
67
+ else if (isReorderable(this.container)) {
71
68
  this.insertBeforeReorderable(this.container, child, before);
72
69
  }
73
70
  else if (isInsertable(this.container)) {
74
71
  this.insertBeforeInsertable(this.container, child, before);
75
72
  }
76
73
  else {
77
- this.appendChild(child);
74
+ this.reinsertAllChildren();
78
75
  }
79
76
  }
80
- insertBeforeReorderable(container, child, before) {
81
- const previousSibling = this.findPreviousSibling(before);
82
- const currentParent = child.container.getParent();
83
- const isChildOfThisContainer = currentParent && isObjectEqual(currentParent, container);
84
- if (isChildOfThisContainer) {
85
- container.reorderChildAfter(child.container, previousSibling);
77
+ commitUpdate(oldProps, newProps) {
78
+ super.commitUpdate(oldProps, newProps);
79
+ if (!this.container) {
80
+ throw new Error(`Container is undefined for '${this.typeName}'`);
86
81
  }
87
- else {
88
- this.detachChildFromParent(child);
89
- container.insertChildAfter(child.container, previousSibling);
82
+ this.signalStore.blockAll();
83
+ try {
84
+ this.updateSizeRequest(oldProps, newProps);
85
+ this.updateGrabFocus(oldProps, newProps);
86
+ const propNames = new Set([
87
+ ...Object.keys(filterProps(oldProps ?? {}, EXCLUDED_PROPS)),
88
+ ...Object.keys(filterProps(newProps ?? {}, EXCLUDED_PROPS)),
89
+ ]);
90
+ const pendingSignals = [];
91
+ const pendingProperties = [];
92
+ for (const name of propNames) {
93
+ const oldValue = oldProps?.[name];
94
+ const newValue = newProps[name];
95
+ if (oldValue === newValue)
96
+ continue;
97
+ const signalName = resolveSignal(this.container, name);
98
+ if (signalName) {
99
+ pendingSignals.push({ name, newValue });
100
+ }
101
+ else if (newValue !== undefined) {
102
+ pendingProperties.push({ name, oldValue, newValue });
103
+ }
104
+ else if (oldValue !== undefined) {
105
+ const defaultValue = this.getPropertyDefaultValue(name);
106
+ if (defaultValue !== undefined) {
107
+ pendingProperties.push({ name, oldValue, newValue: defaultValue });
108
+ }
109
+ }
110
+ }
111
+ for (const { name, newValue } of pendingSignals) {
112
+ const signalName = resolveSignal(this.container, name);
113
+ if (!signalName)
114
+ continue;
115
+ const handler = typeof newValue === "function" ? newValue : undefined;
116
+ this.signalStore.set(this, this.container, signalName, handler);
117
+ }
118
+ for (const { name, oldValue, newValue } of pendingProperties) {
119
+ if (name === "text" && oldValue !== undefined && isEditable(this.container)) {
120
+ if (oldValue !== this.container.getText()) {
121
+ continue;
122
+ }
123
+ }
124
+ this.setProperty(name, newValue);
125
+ }
126
+ }
127
+ finally {
128
+ this.signalStore.unblockAll();
90
129
  }
91
130
  }
92
- insertBeforeInsertable(container, child, before) {
93
- this.detachChildFromParent(child);
94
- const position = this.findInsertPosition(before);
95
- container.insert(child.container, position);
131
+ appendWidgetChild(child) {
132
+ if (isAppendable(this.container) || isAddable(this.container)) {
133
+ if (this.isChildAutowrapped(child)) {
134
+ this.detachAutowrappedChild(child);
135
+ }
136
+ else {
137
+ detachChildFromParent(child);
138
+ }
139
+ }
140
+ attachChild(child.container, this.container);
96
141
  }
97
- updateProps(oldProps, newProps) {
98
- if (!this.container) {
99
- throw new Error(`WidgetNode.updateProps: container is undefined for ${this.typeName}`);
142
+ isChildAutowrapped(child) {
143
+ return ((this.container instanceof Gtk.ListBox || this.container instanceof Gtk.FlowBox) &&
144
+ !(child.container instanceof Gtk.ListBoxRow || child.container instanceof Gtk.FlowBoxChild));
145
+ }
146
+ detachAutowrappedChild(child) {
147
+ const wrapper = child.container.getParent();
148
+ if (wrapper && isSingleChild(wrapper)) {
149
+ wrapper.setChild(null);
150
+ const wrapperParent = wrapper.getParent();
151
+ if (wrapperParent && isRemovable(wrapperParent)) {
152
+ wrapperParent.remove(wrapper);
153
+ }
100
154
  }
101
- this.updateSizeRequest(oldProps, newProps);
102
- this.updateGrabFocus(oldProps, newProps);
103
- const propNames = new Set([
104
- ...Object.keys(filterProps(oldProps ?? {}, EXCLUDED_PROPS)),
105
- ...Object.keys(filterProps(newProps ?? {}, EXCLUDED_PROPS)),
106
- ]);
107
- const pendingSignals = [];
108
- const pendingProperties = [];
109
- for (const name of propNames) {
110
- const oldValue = oldProps?.[name];
111
- const newValue = newProps[name];
112
- if (oldValue === newValue)
113
- continue;
114
- const signalName = propNameToSignalName(name);
115
- if (resolveSignal(this.container, signalName)) {
116
- pendingSignals.push({ name, newValue });
155
+ }
156
+ insertBeforeAutowrapping(child, before) {
157
+ const currentParent = child.container.getParent();
158
+ if (currentParent !== null) {
159
+ if (child.container instanceof Gtk.ListBoxRow || child.container instanceof Gtk.FlowBoxChild) {
160
+ if (isRemovable(currentParent)) {
161
+ currentParent.remove(child.container);
162
+ }
117
163
  }
118
- else if (newValue !== undefined) {
119
- pendingProperties.push({ name, oldValue, newValue });
164
+ else {
165
+ this.detachAutowrappedChild(child);
120
166
  }
121
- else if (oldValue !== undefined) {
122
- const defaultValue = this.getPropertyDefaultValue(name);
123
- if (defaultValue !== undefined) {
124
- pendingProperties.push({ name, oldValue, newValue: defaultValue });
125
- }
167
+ }
168
+ else if (!(child.container instanceof Gtk.ListBoxRow || child.container instanceof Gtk.FlowBoxChild)) {
169
+ this.detachAutowrappedChild(child);
170
+ }
171
+ const container = this.container;
172
+ if (!(container instanceof Gtk.ListBox) && !(container instanceof Gtk.FlowBox))
173
+ return;
174
+ const position = this.findAutowrappedPosition(before);
175
+ if (position !== null) {
176
+ container.insert(child.container, position);
177
+ }
178
+ else {
179
+ container.append(child.container);
180
+ }
181
+ }
182
+ findAutowrappedPosition(before) {
183
+ let position = 0;
184
+ let currentChild = this.container.getFirstChild();
185
+ const beforeIsRow = before.container instanceof Gtk.ListBoxRow || before.container instanceof Gtk.FlowBoxChild;
186
+ while (currentChild) {
187
+ const widgetToCompare = beforeIsRow ? currentChild : this.unwrapGtkChild(currentChild);
188
+ if (widgetToCompare && widgetToCompare === before.container) {
189
+ return position;
126
190
  }
191
+ position++;
192
+ currentChild = currentChild.getNextSibling();
127
193
  }
128
- for (const { name, newValue } of pendingSignals) {
129
- const signalName = propNameToSignalName(name);
130
- const handler = typeof newValue === "function" ? newValue : undefined;
131
- this.signalStore.set(this, this.container, signalName, handler);
194
+ return null;
195
+ }
196
+ unwrapGtkChild(child) {
197
+ if ("getChild" in child && typeof child.getChild === "function") {
198
+ return child.getChild();
132
199
  }
133
- for (const { name, oldValue, newValue } of pendingProperties) {
134
- if (name === "text" && oldValue !== undefined && isEditable(this.container)) {
135
- if (oldValue !== this.container.getText()) {
136
- continue;
137
- }
200
+ return child;
201
+ }
202
+ reinsertAllChildren() {
203
+ const widgetChildren = [];
204
+ for (const child of this.children) {
205
+ if (child instanceof WidgetNode && child.shouldAttachToParent()) {
206
+ widgetChildren.push(child);
138
207
  }
139
- this.setProperty(name, newValue);
208
+ }
209
+ for (const child of widgetChildren) {
210
+ detachChild(child.container, this.container);
211
+ }
212
+ for (const child of widgetChildren) {
213
+ attachChild(child.container, this.container);
140
214
  }
141
215
  }
142
216
  updateSizeRequest(oldProps, newProps) {
@@ -208,50 +282,49 @@ export class WidgetNode extends Node {
208
282
  }
209
283
  setter.call(this.container, value);
210
284
  }
211
- detachChildFromParent(child) {
285
+ insertBeforeReorderable(container, child, before) {
286
+ const previousSibling = this.findPreviousSibling(before);
212
287
  const currentParent = child.container.getParent();
213
- if (currentParent !== null && isRemovable(currentParent)) {
214
- currentParent.remove(child.container);
215
- }
216
- }
217
- attachChild(child) {
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`);
288
+ const isChildOfThisContainer = currentParent && currentParent === container;
289
+ if (isChildOfThisContainer) {
290
+ container.reorderChildAfter(child.container, previousSibling);
221
291
  }
222
- if (strategy.type === "appendable" || strategy.type === "addable") {
223
- this.detachChildFromParent(child);
292
+ else {
293
+ detachChildFromParent(child);
294
+ container.insertChildAfter(child.container, previousSibling);
224
295
  }
225
- performAttachment(child.container, strategy);
226
296
  }
227
- detachChild(child) {
228
- const strategy = getAttachmentStrategy(this.container);
229
- if (!strategy) {
230
- throw new Error(`Cannot remove '${child.typeName}' from '${this.container.constructor.name}': container does not support child removal`);
231
- }
232
- performDetachment(child.container, strategy);
297
+ insertBeforeInsertable(container, child, before) {
298
+ detachChildFromParent(child);
299
+ const position = this.findInsertPosition(before);
300
+ container.insert(child.container, position);
233
301
  }
234
302
  findPreviousSibling(before) {
235
303
  let beforeChild = this.container.getFirstChild();
236
304
  while (beforeChild) {
237
- if (isObjectEqual(beforeChild, before.container)) {
305
+ if (beforeChild === before.container) {
238
306
  return beforeChild.getPrevSibling() ?? undefined;
239
307
  }
240
308
  beforeChild = beforeChild.getNextSibling();
241
309
  }
242
- throw new Error(`Cannot find 'before' child in container`);
310
+ throw new Error(`Cannot find 'before' sibling in '${this.typeName}'`);
243
311
  }
244
312
  findInsertPosition(before) {
245
313
  let position = 0;
246
314
  let currentChild = this.container.getFirstChild();
247
315
  while (currentChild) {
248
- if (isObjectEqual(currentChild, before.container)) {
316
+ if (currentChild === before.container) {
249
317
  return position;
250
318
  }
251
319
  position++;
252
320
  currentChild = currentChild.getNextSibling();
253
321
  }
254
- throw new Error(`Cannot find 'before' child in container`);
322
+ throw new Error(`Cannot find 'before' child position in '${this.typeName}'`);
323
+ }
324
+ }
325
+ function detachChildFromParent(child) {
326
+ const currentParent = child.container.getParent();
327
+ if (currentParent !== null && isRemovable(currentParent)) {
328
+ currentParent.remove(child.container);
255
329
  }
256
330
  }
257
- registerNodeClass(WidgetNode);
@@ -1,29 +1,28 @@
1
1
  import * as Gtk from "@gtkx/ffi/gtk";
2
+ import type { GtkAboutDialogProps, GtkWindowProps } from "../jsx.js";
2
3
  import type { Node } from "../node.js";
3
- import type { Container, ContainerClass, Props } from "../types.js";
4
+ import type { Container, Props } from "../types.js";
5
+ import { AnimationNode } from "./animation.js";
6
+ import type { DialogNode } from "./dialog.js";
7
+ import { MenuNode } from "./menu.js";
8
+ import { NavigationPageNode } from "./navigation-page.js";
9
+ import { SlotNode } from "./slot.js";
4
10
  import { WidgetNode } from "./widget.js";
5
- type CreditSection = {
6
- name: string;
7
- people: string[];
8
- };
9
- export type WindowProps = Props & {
10
- defaultWidth?: number;
11
- defaultHeight?: number;
12
- onClose?: () => void;
13
- creditSections?: CreditSection[];
14
- };
15
- export declare class WindowNode extends WidgetNode<Gtk.Window, WindowProps> {
16
- static priority: number;
11
+ export type WindowProps = Pick<GtkWindowProps, "onClose"> & Pick<GtkAboutDialogProps, "creditSections">;
12
+ type WindowChild = WindowNode | DialogNode | MenuNode | SlotNode | AnimationNode | NavigationPageNode | WidgetNode;
13
+ export declare class WindowNode extends WidgetNode<Gtk.Window, WindowProps, WindowChild> {
17
14
  private menu;
18
- static matches(_type: string, containerOrClass?: Container | ContainerClass | null): boolean;
19
15
  static createContainer(props: Props, containerClass: typeof Gtk.Window, rootContainer: Container | undefined): Gtk.Window;
20
16
  constructor(typeName: string, props: WindowProps, container: Gtk.Window, rootContainer: Container);
21
- appendChild(child: Node): void;
22
- removeChild(child: Node): void;
23
- insertBefore(child: Node, before: Node): void;
24
- mount(): void;
25
- unmount(): void;
26
- updateProps(oldProps: WindowProps | null, newProps: WindowProps): void;
27
- protected applyOwnProps(oldProps: WindowProps | null, newProps: WindowProps): void;
17
+ protected shouldAttachToParent(): boolean;
18
+ isValidChild(child: Node): boolean;
19
+ appendChild(child: WindowChild): void;
20
+ removeChild(child: WindowChild): void;
21
+ insertBefore(child: WindowChild, before: WindowChild): void;
22
+ finalizeInitialChildren(props: WindowProps): boolean;
23
+ commitUpdate(oldProps: WindowProps | null, newProps: WindowProps): void;
24
+ commitMount(): void;
25
+ detachDeletedInstance(): void;
26
+ private applyOwnProps;
28
27
  }
29
28
  export {};