@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.
Files changed (172) hide show
  1. package/README.md +1 -0
  2. package/dist/animation/css-builder.d.ts +3 -0
  3. package/dist/animation/css-builder.js +53 -0
  4. package/dist/animation/types.d.ts +120 -0
  5. package/dist/errors.js +3 -0
  6. package/dist/factory.d.ts +3 -2
  7. package/dist/factory.js +1 -1
  8. package/dist/fiber-root.js +1 -1
  9. package/dist/generated/internal.d.ts +28 -1
  10. package/dist/generated/internal.js +93 -18
  11. package/dist/generated/jsx.d.ts +1672 -1483
  12. package/dist/generated/jsx.js +475 -0
  13. package/dist/host-config.d.ts +3 -1
  14. package/dist/host-config.js +26 -11
  15. package/dist/jsx.d.ts +136 -166
  16. package/dist/jsx.js +58 -69
  17. package/dist/node.d.ts +4 -1
  18. package/dist/node.js +14 -3
  19. package/dist/nodes/abstract/positional-child.d.ts +9 -0
  20. package/dist/nodes/abstract/positional-child.js +29 -0
  21. package/dist/nodes/abstract/virtual-container.d.ts +21 -0
  22. package/dist/nodes/abstract/virtual-container.js +68 -0
  23. package/dist/nodes/abstract/virtual-single-child.d.ts +18 -0
  24. package/dist/nodes/abstract/virtual-single-child.js +55 -0
  25. package/dist/nodes/action-row-child.d.ts +0 -13
  26. package/dist/nodes/action-row-child.js +22 -12
  27. package/dist/nodes/adjustable.d.ts +23 -0
  28. package/dist/nodes/adjustable.js +62 -0
  29. package/dist/nodes/alert-dialog-response.js +86 -0
  30. package/dist/nodes/animation.js +252 -0
  31. package/dist/nodes/application.js +17 -7
  32. package/dist/nodes/autowrapped.js +37 -43
  33. package/dist/nodes/calendar.js +17 -43
  34. package/dist/nodes/color-dialog-button.d.ts +1 -0
  35. package/dist/nodes/color-dialog-button.js +70 -0
  36. package/dist/nodes/column-view-column.d.ts +3 -3
  37. package/dist/nodes/column-view-column.js +1 -1
  38. package/dist/nodes/column-view.js +36 -39
  39. package/dist/nodes/dialog.d.ts +11 -0
  40. package/dist/nodes/dialog.js +20 -0
  41. package/dist/nodes/drawing-area.js +24 -7
  42. package/dist/nodes/event-controller.d.ts +22 -0
  43. package/dist/nodes/event-controller.js +96 -0
  44. package/dist/nodes/expander-row-child.d.ts +0 -14
  45. package/dist/nodes/expander-row-child.js +22 -12
  46. package/dist/nodes/fixed-child.js +52 -36
  47. package/dist/nodes/font-dialog-button.d.ts +1 -0
  48. package/dist/nodes/font-dialog-button.js +90 -0
  49. package/dist/nodes/grid-child.js +43 -45
  50. package/dist/nodes/grid.d.ts +1 -0
  51. package/dist/nodes/grid.js +41 -0
  52. package/dist/nodes/index.d.ts +18 -12
  53. package/dist/nodes/index.js +18 -12
  54. package/dist/nodes/internal/base-item-renderer.d.ts +29 -0
  55. package/dist/nodes/internal/base-item-renderer.js +88 -0
  56. package/dist/nodes/internal/child-attachment.d.ts +26 -0
  57. package/dist/nodes/internal/child-attachment.js +48 -0
  58. package/dist/nodes/internal/deferred-action.d.ts +9 -0
  59. package/dist/nodes/internal/deferred-action.js +22 -0
  60. package/dist/nodes/internal/list-item-renderer.d.ts +14 -15
  61. package/dist/nodes/internal/list-item-renderer.js +51 -77
  62. package/dist/nodes/internal/list-store.d.ts +5 -6
  63. package/dist/nodes/internal/list-store.js +29 -38
  64. package/dist/nodes/internal/predicates.d.ts +25 -2
  65. package/dist/nodes/internal/predicates.js +53 -41
  66. package/dist/nodes/internal/selection-model.d.ts +30 -0
  67. package/dist/nodes/internal/selection-model.js +87 -0
  68. package/dist/nodes/internal/signal-store.d.ts +9 -5
  69. package/dist/nodes/internal/signal-store.js +31 -31
  70. package/dist/nodes/internal/simple-list-store.js +6 -9
  71. package/dist/nodes/internal/text-buffer-controller.d.ts +43 -0
  72. package/dist/nodes/internal/text-buffer-controller.js +287 -0
  73. package/dist/nodes/internal/text-tag-styles.d.ts +43 -0
  74. package/dist/nodes/internal/text-tag-styles.js +52 -0
  75. package/dist/nodes/internal/tree-list-item-renderer.d.ts +15 -14
  76. package/dist/nodes/internal/tree-list-item-renderer.js +85 -96
  77. package/dist/nodes/internal/tree-store.d.ts +8 -11
  78. package/dist/nodes/internal/tree-store.js +70 -72
  79. package/dist/nodes/internal/utils.d.ts +7 -4
  80. package/dist/nodes/internal/utils.js +50 -5
  81. package/dist/nodes/level-bar.js +19 -54
  82. package/dist/nodes/list-item.d.ts +6 -3
  83. package/dist/nodes/list-item.js +7 -4
  84. package/dist/nodes/list-view.js +17 -12
  85. package/dist/nodes/menu.d.ts +3 -3
  86. package/dist/nodes/menu.js +3 -3
  87. package/dist/nodes/models/list.d.ts +11 -13
  88. package/dist/nodes/models/list.js +16 -73
  89. package/dist/nodes/models/menu.d.ts +8 -7
  90. package/dist/nodes/models/menu.js +43 -50
  91. package/dist/nodes/models/tree-list.d.ts +6 -12
  92. package/dist/nodes/models/tree-list.js +30 -93
  93. package/dist/nodes/navigation-page.d.ts +1 -0
  94. package/dist/nodes/navigation-page.js +27 -32
  95. package/dist/nodes/navigation-view.js +17 -28
  96. package/dist/nodes/notebook-page-tab.d.ts +3 -3
  97. package/dist/nodes/notebook-page-tab.js +11 -14
  98. package/dist/nodes/notebook-page.d.ts +7 -5
  99. package/dist/nodes/notebook-page.js +45 -25
  100. package/dist/nodes/notebook.js +2 -2
  101. package/dist/nodes/overlay-child.js +90 -30
  102. package/dist/nodes/pack-child.d.ts +0 -13
  103. package/dist/nodes/pack-child.js +22 -12
  104. package/dist/nodes/popover-menu.js +2 -2
  105. package/dist/nodes/scale.js +15 -45
  106. package/dist/nodes/scrolled-window.js +7 -6
  107. package/dist/nodes/search-bar.d.ts +1 -0
  108. package/dist/nodes/search-bar.js +40 -0
  109. package/dist/nodes/shortcut-controller.d.ts +1 -37
  110. package/dist/nodes/shortcut-controller.js +8 -47
  111. package/dist/nodes/shortcut.d.ts +5 -4
  112. package/dist/nodes/shortcut.js +11 -5
  113. package/dist/nodes/simple-list-view.js +2 -3
  114. package/dist/nodes/slot.d.ts +6 -9
  115. package/dist/nodes/slot.js +27 -42
  116. package/dist/nodes/source-view.js +80 -29
  117. package/dist/nodes/stack-page.js +20 -22
  118. package/dist/nodes/stack.js +19 -5
  119. package/dist/nodes/text-anchor.d.ts +41 -0
  120. package/dist/nodes/text-anchor.js +59 -0
  121. package/dist/nodes/text-content.d.ts +10 -0
  122. package/dist/nodes/text-content.js +1 -0
  123. package/dist/nodes/text-paintable.d.ts +17 -0
  124. package/dist/nodes/text-paintable.js +34 -0
  125. package/dist/nodes/text-segment.d.ts +15 -0
  126. package/dist/nodes/text-segment.js +29 -0
  127. package/dist/nodes/text-tag.d.ts +136 -0
  128. package/dist/nodes/text-tag.js +202 -0
  129. package/dist/nodes/text-view.d.ts +30 -0
  130. package/dist/nodes/text-view.js +49 -21
  131. package/dist/nodes/toggle-group.js +24 -32
  132. package/dist/nodes/toggle.d.ts +1 -15
  133. package/dist/nodes/toggle.js +40 -32
  134. package/dist/nodes/toolbar-child.js +22 -31
  135. package/dist/nodes/tree-list-item.d.ts +7 -5
  136. package/dist/nodes/tree-list-item.js +24 -36
  137. package/dist/nodes/tree-list-view.js +9 -7
  138. package/dist/nodes/virtual.d.ts +1 -1
  139. package/dist/nodes/web-view.d.ts +1 -0
  140. package/dist/nodes/web-view.js +29 -0
  141. package/dist/nodes/widget.d.ts +2 -16
  142. package/dist/nodes/widget.js +105 -294
  143. package/dist/nodes/window.d.ts +9 -3
  144. package/dist/nodes/window.js +29 -15
  145. package/dist/registry.d.ts +1 -1
  146. package/dist/render.js +9 -7
  147. package/dist/scheduler.d.ts +11 -1
  148. package/dist/scheduler.js +16 -4
  149. package/dist/types.d.ts +2 -136
  150. package/package.json +4 -4
  151. package/dist/nodes/action-row.js +0 -46
  152. package/dist/nodes/adjustment.d.ts +0 -48
  153. package/dist/nodes/adjustment.js +0 -70
  154. package/dist/nodes/calendar-mark.d.ts +0 -15
  155. package/dist/nodes/calendar-mark.js +0 -29
  156. package/dist/nodes/expander-row.js +0 -55
  157. package/dist/nodes/internal/constants.d.ts +0 -1
  158. package/dist/nodes/internal/constants.js +0 -24
  159. package/dist/nodes/level-bar-offset.d.ts +0 -13
  160. package/dist/nodes/level-bar-offset.js +0 -35
  161. package/dist/nodes/pack.js +0 -46
  162. package/dist/nodes/scale-mark.d.ts +0 -17
  163. package/dist/nodes/scale-mark.js +0 -38
  164. package/dist/nodes/source-buffer.d.ts +0 -73
  165. package/dist/nodes/source-buffer.js +0 -149
  166. package/dist/nodes/text-buffer.d.ts +0 -43
  167. package/dist/nodes/text-buffer.js +0 -81
  168. package/dist/nodes/virtual-child.d.ts +0 -18
  169. package/dist/nodes/virtual-child.js +0 -62
  170. /package/dist/{nodes/action-row.d.ts → animation/types.js} +0 -0
  171. /package/dist/nodes/{expander-row.d.ts → alert-dialog-response.d.ts} +0 -0
  172. /package/dist/nodes/{pack.d.ts → animation.d.ts} +0 -0
@@ -1,49 +1,109 @@
1
- import { batch, isObjectEqual } from "@gtkx/ffi";
1
+ import { getNativeId, isObjectEqual } from "@gtkx/ffi";
2
2
  import { registerNodeClass } from "../registry.js";
3
- import { SlotNode } from "./slot.js";
4
- class OverlayChildNode extends SlotNode {
3
+ import { CommitPriority, scheduleAfterCommit } from "../scheduler.js";
4
+ import { VirtualNode } from "./virtual.js";
5
+ import { WidgetNode } from "./widget.js";
6
+ class OverlayChildNode extends VirtualNode {
5
7
  static priority = 1;
6
8
  static matches(type) {
7
9
  return type === "OverlayChild";
8
10
  }
9
- getOverlay() {
10
- if (!this.parent) {
11
- throw new Error("Expected parent widget to be set on OverlayChildNode");
11
+ parent = null;
12
+ children = new Map();
13
+ canBeChildOf(parent) {
14
+ return parent instanceof WidgetNode;
15
+ }
16
+ attachTo(parent) {
17
+ if (parent instanceof WidgetNode) {
18
+ this.parent = parent.container;
12
19
  }
13
- return this.parent;
14
20
  }
15
- updateProps(oldProps, newProps) {
16
- super.updateProps(oldProps, newProps);
17
- if (!this.parent || !this.child) {
18
- return;
21
+ detachFrom(_parent) { }
22
+ unmount() {
23
+ if (this.parent && this.children.size > 0) {
24
+ const parent = this.parent;
25
+ const children = [...this.children.values()];
26
+ this.children.clear();
27
+ for (const child of children) {
28
+ const currentParent = child.getParent();
29
+ if (currentParent && isObjectEqual(currentParent, parent)) {
30
+ parent.removeOverlay(child);
31
+ }
32
+ }
19
33
  }
20
- const overlay = this.getOverlay();
21
- if (!oldProps || oldProps.measure !== newProps.measure) {
22
- overlay.setMeasureOverlay(this.child, newProps.measure ?? false);
34
+ this.parent = null;
35
+ super.unmount();
36
+ }
37
+ appendChild(child) {
38
+ if (!(child instanceof WidgetNode)) {
39
+ throw new Error(`Cannot append '${child.typeName}' to '${this.typeName}': expected Widget`);
23
40
  }
24
- if (!oldProps || oldProps.clipOverlay !== newProps.clipOverlay) {
25
- overlay.setClipOverlay(this.child, newProps.clipOverlay ?? false);
41
+ const widget = child.container;
42
+ this.children.set(getNativeId(widget.handle), widget);
43
+ scheduleAfterCommit(() => {
44
+ if (this.parent) {
45
+ this.attachChild(widget);
46
+ }
47
+ }, CommitPriority.NORMAL);
48
+ }
49
+ insertBefore(child, _before) {
50
+ if (!(child instanceof WidgetNode)) {
51
+ throw new Error(`Cannot insert '${child.typeName}' into '${this.typeName}': expected Widget`);
26
52
  }
53
+ const widget = child.container;
54
+ this.children.set(getNativeId(widget.handle), widget);
55
+ scheduleAfterCommit(() => {
56
+ if (this.parent) {
57
+ this.attachChild(widget);
58
+ }
59
+ }, CommitPriority.NORMAL);
27
60
  }
28
- onChildChange(oldChild) {
29
- const overlay = this.getOverlay();
30
- batch(() => {
31
- if (oldChild) {
32
- const parent = oldChild.getParent();
33
- if (parent && isObjectEqual(parent, overlay)) {
34
- overlay.removeOverlay(oldChild);
61
+ removeChild(child) {
62
+ if (!(child instanceof WidgetNode)) {
63
+ throw new Error(`Cannot remove '${child.typeName}' from '${this.typeName}': expected Widget`);
64
+ }
65
+ const widget = child.container;
66
+ const parent = this.parent;
67
+ this.children.delete(getNativeId(widget.handle));
68
+ scheduleAfterCommit(() => {
69
+ if (parent) {
70
+ const currentParent = widget.getParent();
71
+ if (currentParent && isObjectEqual(currentParent, parent)) {
72
+ parent.removeOverlay(widget);
35
73
  }
36
74
  }
37
- if (this.child) {
38
- overlay.addOverlay(this.child);
39
- if (this.props.measure !== undefined) {
40
- overlay.setMeasureOverlay(this.child, this.props.measure);
75
+ }, CommitPriority.HIGH);
76
+ }
77
+ updateProps(oldProps, newProps) {
78
+ super.updateProps(oldProps, newProps);
79
+ if (!this.parent) {
80
+ return;
81
+ }
82
+ const measureChanged = oldProps?.measure !== newProps.measure;
83
+ const clipOverlayChanged = oldProps?.clipOverlay !== newProps.clipOverlay;
84
+ if (measureChanged || clipOverlayChanged) {
85
+ const parent = this.parent;
86
+ for (const child of this.children.values()) {
87
+ if (measureChanged) {
88
+ parent.setMeasureOverlay(child, newProps.measure ?? false);
41
89
  }
42
- if (this.props.clipOverlay !== undefined) {
43
- overlay.setClipOverlay(this.child, this.props.clipOverlay);
90
+ if (clipOverlayChanged) {
91
+ parent.setClipOverlay(child, newProps.clipOverlay ?? false);
44
92
  }
45
93
  }
46
- });
94
+ }
95
+ }
96
+ attachChild(widget) {
97
+ if (!this.parent) {
98
+ return;
99
+ }
100
+ this.parent.addOverlay(widget);
101
+ if (this.props.measure !== undefined) {
102
+ this.parent.setMeasureOverlay(widget, this.props.measure);
103
+ }
104
+ if (this.props.clipOverlay !== undefined) {
105
+ this.parent.setClipOverlay(widget, this.props.clipOverlay);
106
+ }
47
107
  }
48
108
  }
49
109
  registerNodeClass(OverlayChildNode);
@@ -1,14 +1 @@
1
- import type * as Gtk from "@gtkx/ffi/gtk";
2
- import { VirtualChildNode } from "./virtual-child.js";
3
- type PackableWidget = Gtk.Widget & {
4
- packStart(child: Gtk.Widget): void;
5
- packEnd(child: Gtk.Widget): void;
6
- remove(child: Gtk.Widget): void;
7
- };
8
- export declare class PackChild extends VirtualChildNode<PackableWidget> {
9
- static priority: number;
10
- static matches(type: string): boolean;
11
- protected getPositionLabel(): string;
12
- protected attachChild(parent: PackableWidget, widget: Gtk.Widget): void;
13
- }
14
1
  export {};
@@ -1,20 +1,30 @@
1
+ import { PACK_INTERFACE_METHODS } from "../generated/internal.js";
1
2
  import { registerNodeClass } from "../registry.js";
2
- import { VirtualChildNode } from "./virtual-child.js";
3
- export class PackChild extends VirtualChildNode {
3
+ import { VirtualContainerNode } from "./abstract/virtual-container.js";
4
+ import { matchesInterface } from "./internal/utils.js";
5
+ class PackStartNode extends VirtualContainerNode {
4
6
  static priority = 1;
5
7
  static matches(type) {
6
- return type === "PackStart" || type === "PackEnd";
8
+ return type === "PackStart";
7
9
  }
8
- getPositionLabel() {
9
- return this.typeName === "PackStart" ? "start" : "end";
10
+ canBeChildOf(parent) {
11
+ return matchesInterface(PACK_INTERFACE_METHODS, parent.container);
10
12
  }
11
13
  attachChild(parent, widget) {
12
- if (this.getPositionLabel() === "start") {
13
- parent.packStart(widget);
14
- }
15
- else {
16
- parent.packEnd(widget);
17
- }
14
+ parent.packStart(widget);
18
15
  }
19
16
  }
20
- registerNodeClass(PackChild);
17
+ class PackEndNode extends VirtualContainerNode {
18
+ static priority = 1;
19
+ static matches(type) {
20
+ return type === "PackEnd";
21
+ }
22
+ canBeChildOf(parent) {
23
+ return matchesInterface(PACK_INTERFACE_METHODS, parent.container);
24
+ }
25
+ attachChild(parent, widget) {
26
+ parent.packEnd(widget);
27
+ }
28
+ }
29
+ registerNodeClass(PackStartNode);
30
+ registerNodeClass(PackEndNode);
@@ -4,7 +4,7 @@ import { POPOVER_MENU_CLASSES } from "../generated/internal.js";
4
4
  import { registerNodeClass } from "../registry.js";
5
5
  import { matchesAnyClass } from "./internal/utils.js";
6
6
  import { MenuNode } from "./menu.js";
7
- import { Menu } from "./models/menu.js";
7
+ import { MenuModel } from "./models/menu.js";
8
8
  import { SlotNode } from "./slot.js";
9
9
  import { WidgetNode } from "./widget.js";
10
10
  const ACTION_PREFIX = "menu";
@@ -20,7 +20,7 @@ class PopoverMenuNode extends WidgetNode {
20
20
  const actionGroup = new Gio.SimpleActionGroup();
21
21
  const prefix = application ? "app" : ACTION_PREFIX;
22
22
  this.container.insertActionGroup(prefix, actionGroup);
23
- this.menu = new Menu("root", {}, actionGroup, application);
23
+ this.menu = new MenuModel("root", {}, rootContainer, actionGroup, application);
24
24
  this.container.setMenuModel(this.menu.getMenu());
25
25
  }
26
26
  appendChild(child) {
@@ -1,57 +1,27 @@
1
1
  import * as Gtk from "@gtkx/ffi/gtk";
2
2
  import { registerNodeClass } from "../registry.js";
3
- import { CommitPriority, scheduleAfterCommit } from "../scheduler.js";
4
- import { isContainerType } from "./internal/utils.js";
5
- import { ScaleMarkNode } from "./scale-mark.js";
6
- import { WidgetNode } from "./widget.js";
7
- class ScaleNode extends WidgetNode {
3
+ import { AdjustableNode } from "./adjustable.js";
4
+ import { matchesAnyClass, shallowArrayEqual } from "./internal/utils.js";
5
+ class ScaleNode extends AdjustableNode {
8
6
  static priority = 1;
9
- markChildren = [];
7
+ appliedMarks = [];
10
8
  static matches(_type, containerOrClass) {
11
- return isContainerType(Gtk.Scale, containerOrClass);
9
+ return matchesAnyClass([Gtk.Scale], containerOrClass);
12
10
  }
13
- appendChild(child) {
14
- if (child instanceof ScaleMarkNode) {
15
- child.setScale(this.container, () => this.scheduleRebuildAllMarks());
16
- this.markChildren.push(child);
17
- scheduleAfterCommit(() => child.addMark());
18
- return;
19
- }
20
- super.appendChild(child);
11
+ applyOwnProps(oldProps, newProps) {
12
+ super.applyOwnProps(oldProps, newProps);
13
+ this.applyMarks(newProps);
21
14
  }
22
- insertBefore(child, before) {
23
- if (child instanceof ScaleMarkNode) {
24
- child.setScale(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();
15
+ applyMarks(newProps) {
16
+ const newMarks = newProps.marks ?? [];
17
+ if (shallowArrayEqual(this.appliedMarks, newMarks)) {
33
18
  return;
34
19
  }
35
- super.insertBefore(child, before);
36
- }
37
- removeChild(child) {
38
- if (child instanceof ScaleMarkNode) {
39
- const index = this.markChildren.indexOf(child);
40
- if (index >= 0) {
41
- this.markChildren.splice(index, 1);
42
- }
43
- this.scheduleRebuildAllMarks(CommitPriority.HIGH);
44
- return;
20
+ this.container.clearMarks();
21
+ for (const mark of newMarks) {
22
+ this.container.addMark(mark.value, mark.position ?? Gtk.PositionType.BOTTOM, mark.label);
45
23
  }
46
- super.removeChild(child);
47
- }
48
- scheduleRebuildAllMarks(priority = CommitPriority.NORMAL) {
49
- scheduleAfterCommit(() => {
50
- this.container.clearMarks();
51
- for (const mark of this.markChildren) {
52
- mark.addMark();
53
- }
54
- }, priority);
24
+ this.appliedMarks = [...newMarks];
55
25
  }
56
26
  }
57
27
  registerNodeClass(ScaleNode);
@@ -1,22 +1,23 @@
1
1
  import * as Gtk from "@gtkx/ffi/gtk";
2
2
  import { registerNodeClass } from "../registry.js";
3
- import { filterProps, isContainerType } from "./internal/utils.js";
3
+ import { filterProps, hasChanged, matchesAnyClass } from "./internal/utils.js";
4
4
  import { WidgetNode } from "./widget.js";
5
5
  const PROPS = ["hscrollbarPolicy", "vscrollbarPolicy"];
6
6
  class ScrolledWindowNode extends WidgetNode {
7
7
  static priority = 2;
8
8
  static matches(_type, containerOrClass) {
9
- return isContainerType(Gtk.ScrolledWindow, containerOrClass);
9
+ return matchesAnyClass([Gtk.ScrolledWindow], containerOrClass);
10
10
  }
11
11
  updateProps(oldProps, newProps) {
12
- if (!oldProps ||
13
- oldProps.hscrollbarPolicy !== newProps.hscrollbarPolicy ||
14
- oldProps.vscrollbarPolicy !== newProps.vscrollbarPolicy) {
12
+ super.updateProps(oldProps ? filterProps(oldProps, PROPS) : null, filterProps(newProps, PROPS));
13
+ this.applyOwnProps(oldProps, newProps);
14
+ }
15
+ applyOwnProps(oldProps, newProps) {
16
+ if (hasChanged(oldProps, newProps, "hscrollbarPolicy") || hasChanged(oldProps, newProps, "vscrollbarPolicy")) {
15
17
  const hPolicy = newProps.hscrollbarPolicy ?? Gtk.PolicyType.AUTOMATIC;
16
18
  const vPolicy = newProps.vscrollbarPolicy ?? Gtk.PolicyType.AUTOMATIC;
17
19
  this.container.setPolicy(hPolicy, vPolicy);
18
20
  }
19
- super.updateProps(filterProps(oldProps ?? {}, PROPS), filterProps(newProps, PROPS));
20
21
  }
21
22
  }
22
23
  registerNodeClass(ScrolledWindowNode);
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,40 @@
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 = ["onSearchModeChanged"];
6
+ class SearchBarNode extends WidgetNode {
7
+ static priority = 1;
8
+ notifyHandler = null;
9
+ static matches(_type, containerOrClass) {
10
+ return matchesAnyClass([Gtk.SearchBar], containerOrClass);
11
+ }
12
+ updateProps(oldProps, newProps) {
13
+ super.updateProps(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
14
+ if (hasChanged(oldProps, newProps, "onSearchModeChanged")) {
15
+ this.setupNotifyHandler(newProps.onSearchModeChanged);
16
+ }
17
+ }
18
+ setupNotifyHandler(callback) {
19
+ if (this.notifyHandler) {
20
+ this.signalStore.set(this, this.container, "notify", undefined);
21
+ this.notifyHandler = null;
22
+ }
23
+ if (callback) {
24
+ this.notifyHandler = (_searchBar, pspec) => {
25
+ if (pspec.getName() === "search-mode-enabled") {
26
+ callback(this.container.getSearchMode());
27
+ }
28
+ };
29
+ this.signalStore.set(this, this.container, "notify", this.notifyHandler);
30
+ }
31
+ }
32
+ unmount() {
33
+ if (this.notifyHandler) {
34
+ this.signalStore.set(this, this.container, "notify", undefined);
35
+ this.notifyHandler = null;
36
+ }
37
+ super.unmount();
38
+ }
39
+ }
40
+ registerNodeClass(SearchBarNode);
@@ -1,37 +1 @@
1
- import * as Gtk from "@gtkx/ffi/gtk";
2
- import type { Node } from "../node.js";
3
- import type { Props } from "../types.js";
4
- import { VirtualNode } from "./virtual.js";
5
- /**
6
- * Props for the ShortcutController virtual element.
7
- *
8
- * Attaches keyboard shortcuts to a widget. Must contain `x.Shortcut` children.
9
- *
10
- * @example
11
- * ```tsx
12
- * <GtkBox>
13
- * <x.ShortcutController scope={Gtk.ShortcutScope.GLOBAL}>
14
- * <x.Shortcut trigger="<Control>f" onActivate={toggleSearch} />
15
- * <x.Shortcut trigger="<Control>q" onActivate={quit} />
16
- * </x.ShortcutController>
17
- * </GtkBox>
18
- * ```
19
- */
20
- export interface ShortcutControllerProps extends Props {
21
- /** The scope for shortcuts (LOCAL, MANAGED, or GLOBAL) */
22
- scope?: Gtk.ShortcutScope;
23
- }
24
- export declare class ShortcutControllerNode extends VirtualNode<ShortcutControllerProps> {
25
- static priority: number;
26
- static matches(type: string): boolean;
27
- private controller?;
28
- private parentWidget?;
29
- private shortcuts;
30
- setParent(widget?: Gtk.Widget): void;
31
- appendChild(child: Node): void;
32
- removeChild(child: Node): void;
33
- updateProps(oldProps: ShortcutControllerProps | null, newProps: ShortcutControllerProps): void;
34
- unmount(): void;
35
- private applyScope;
36
- private addShortcutToController;
37
- }
1
+ export {};
@@ -1,40 +1,18 @@
1
- import * as Gtk from "@gtkx/ffi/gtk";
2
1
  import { registerNodeClass } from "../registry.js";
2
+ import { EventControllerNode } from "./event-controller.js";
3
3
  import { ShortcutNode } from "./shortcut.js";
4
- import { VirtualNode } from "./virtual.js";
5
- export class ShortcutControllerNode extends VirtualNode {
6
- static priority = 1;
4
+ class ShortcutControllerNode extends EventControllerNode {
5
+ static priority = 0;
7
6
  static matches(type) {
8
- return type === "ShortcutController";
7
+ return type === "GtkShortcutController";
9
8
  }
10
- controller;
11
- parentWidget;
12
9
  shortcuts = [];
13
- setParent(widget) {
14
- if (this.parentWidget && this.controller) {
15
- this.parentWidget.removeController(this.controller);
16
- }
17
- this.parentWidget = widget;
18
- if (widget) {
19
- this.controller = new Gtk.ShortcutController();
20
- this.applyScope();
21
- widget.addController(this.controller);
22
- for (const shortcut of this.shortcuts) {
23
- this.addShortcutToController(shortcut);
24
- }
25
- }
26
- else {
27
- this.controller = undefined;
28
- }
29
- }
30
10
  appendChild(child) {
31
11
  if (!(child instanceof ShortcutNode)) {
32
12
  throw new Error(`ShortcutController only accepts Shortcut children, got '${child.typeName}'`);
33
13
  }
34
14
  this.shortcuts.push(child);
35
- if (this.controller) {
36
- this.addShortcutToController(child);
37
- }
15
+ this.addShortcutToController(child);
38
16
  }
39
17
  removeChild(child) {
40
18
  if (!(child instanceof ShortcutNode))
@@ -42,32 +20,15 @@ export class ShortcutControllerNode extends VirtualNode {
42
20
  const index = this.shortcuts.indexOf(child);
43
21
  if (index !== -1) {
44
22
  this.shortcuts.splice(index, 1);
45
- if (this.controller && child.shortcut) {
46
- this.controller.removeShortcut(child.shortcut);
23
+ if (child.shortcut) {
24
+ this.container.removeShortcut(child.shortcut);
47
25
  }
48
26
  }
49
27
  }
50
- updateProps(oldProps, newProps) {
51
- super.updateProps(oldProps, newProps);
52
- if (!oldProps || oldProps.scope !== newProps.scope) {
53
- this.applyScope();
54
- }
55
- }
56
- unmount() {
57
- this.setParent(undefined);
58
- super.unmount();
59
- }
60
- applyScope() {
61
- if (!this.controller)
62
- return;
63
- this.controller.setScope(this.props.scope ?? Gtk.ShortcutScope.LOCAL);
64
- }
65
28
  addShortcutToController(node) {
66
- if (!this.controller)
67
- return;
68
29
  node.createShortcut();
69
30
  if (node.shortcut) {
70
- this.controller.addShortcut(node.shortcut);
31
+ this.container.addShortcut(node.shortcut);
71
32
  }
72
33
  }
73
34
  }
@@ -15,7 +15,7 @@ import { VirtualNode } from "./virtual.js";
15
15
  * </x.ShortcutController>
16
16
  * ```
17
17
  */
18
- export interface ShortcutProps extends Props {
18
+ export type ShortcutProps = Props & {
19
19
  /** The trigger string(s) using GTK accelerator format (e.g., "\<Control\>s", "F1") */
20
20
  trigger: string | string[];
21
21
  /**
@@ -25,14 +25,15 @@ export interface ShortcutProps extends Props {
25
25
  onActivate: () => boolean | void;
26
26
  /** Whether the shortcut is disabled */
27
27
  disabled?: boolean;
28
- }
28
+ };
29
29
  export declare class ShortcutNode extends VirtualNode<ShortcutProps> {
30
30
  static priority: number;
31
31
  static matches(type: string): boolean;
32
- shortcut?: Gtk.Shortcut;
33
- private action?;
32
+ shortcut: Gtk.Shortcut | null;
33
+ private action;
34
34
  createShortcut(): void;
35
35
  updateProps(oldProps: ShortcutProps | null, newProps: ShortcutProps): void;
36
+ protected applyOwnProps(oldProps: ShortcutProps | null, newProps: ShortcutProps): void;
36
37
  unmount(): void;
37
38
  private createTrigger;
38
39
  }
@@ -1,13 +1,14 @@
1
1
  import * as Gtk from "@gtkx/ffi/gtk";
2
2
  import { registerNodeClass } from "../registry.js";
3
+ import { hasChanged } from "./internal/utils.js";
3
4
  import { VirtualNode } from "./virtual.js";
4
5
  export class ShortcutNode extends VirtualNode {
5
6
  static priority = 1;
6
7
  static matches(type) {
7
8
  return type === "Shortcut";
8
9
  }
9
- shortcut;
10
- action;
10
+ shortcut = null;
11
+ action = null;
11
12
  createShortcut() {
12
13
  const trigger = this.createTrigger();
13
14
  this.action = new Gtk.CallbackAction(() => {
@@ -18,13 +19,18 @@ export class ShortcutNode extends VirtualNode {
18
19
  }
19
20
  updateProps(oldProps, newProps) {
20
21
  super.updateProps(oldProps, newProps);
21
- if (this.shortcut && (oldProps?.trigger !== newProps.trigger || oldProps?.disabled !== newProps.disabled)) {
22
+ this.applyOwnProps(oldProps, newProps);
23
+ }
24
+ applyOwnProps(oldProps, newProps) {
25
+ if (!this.shortcut)
26
+ return;
27
+ if (hasChanged(oldProps, newProps, "trigger") || hasChanged(oldProps, newProps, "disabled")) {
22
28
  this.shortcut.setTrigger(this.createTrigger());
23
29
  }
24
30
  }
25
31
  unmount() {
26
- this.shortcut = undefined;
27
- this.action = undefined;
32
+ this.shortcut = null;
33
+ this.action = null;
28
34
  super.unmount();
29
35
  }
30
36
  createTrigger() {
@@ -1,6 +1,5 @@
1
1
  import { DROP_DOWN_CLASSES } from "../generated/internal.js";
2
2
  import { registerNodeClass } from "../registry.js";
3
- import { signalStore } from "./internal/signal-store.js";
4
3
  import { SimpleListStore } from "./internal/simple-list-store.js";
5
4
  import { filterProps, matchesAnyClass } from "./internal/utils.js";
6
5
  import { SimpleListItemNode } from "./simple-list-item.js";
@@ -28,7 +27,7 @@ class SimpleListViewNode extends WidgetNode {
28
27
  }
29
28
  }
30
29
  : undefined;
31
- signalStore.set(this, this.container, "notify::selected", handleSelectionChange);
30
+ this.signalStore.set(this, this.container, "notify::selected", handleSelectionChange);
32
31
  }
33
32
  if (!oldProps || oldProps.selectedId !== newProps.selectedId) {
34
33
  const index = newProps.selectedId !== undefined ? this.store.getIndexById(newProps.selectedId) : null;
@@ -36,7 +35,7 @@ class SimpleListViewNode extends WidgetNode {
36
35
  this.container.setSelected(index);
37
36
  }
38
37
  }
39
- super.updateProps(filterProps(oldProps ?? {}, PROP_NAMES), filterProps(newProps, PROP_NAMES));
38
+ super.updateProps(oldProps ? filterProps(oldProps, PROP_NAMES) : null, filterProps(newProps, PROP_NAMES));
40
39
  }
41
40
  appendChild(child) {
42
41
  if (!(child instanceof SimpleListItemNode)) {
@@ -1,21 +1,18 @@
1
1
  import type * as Gtk from "@gtkx/ffi/gtk";
2
2
  import type { SlotProps } from "../jsx.js";
3
- import type { Node } from "../node.js";
4
3
  import type { Props } from "../types.js";
5
- import { VirtualNode } from "./virtual.js";
4
+ import { VirtualSingleChildNode } from "./abstract/virtual-single-child.js";
6
5
  type SlotNodeProps = Omit<SlotProps, "children">;
7
- export declare class SlotNode<P extends Props = SlotNodeProps> extends VirtualNode<P> {
6
+ export declare class SlotNode<P extends Props = SlotNodeProps> extends VirtualSingleChildNode<P> {
8
7
  static priority: number;
9
8
  static matches(type: string): boolean;
10
- parent?: Gtk.Widget;
11
- child?: Gtk.Widget;
12
- setParent(parent?: Gtk.Widget): void;
9
+ private cachedSetter;
10
+ setParent(parent: Gtk.Widget | null): void;
13
11
  unmount(): void;
12
+ getChild(): Gtk.Widget;
14
13
  protected getId(): string;
15
14
  protected getParent(): Gtk.Widget;
16
- getChild(): Gtk.Widget;
17
- appendChild(child: Node): void;
18
- removeChild(): void;
15
+ protected ensureChildSetter(): (child: Gtk.Widget | null) => void;
19
16
  protected onChildChange(oldChild: Gtk.Widget | null): void;
20
17
  private isDescendantOf;
21
18
  }