@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
@@ -0,0 +1,136 @@
1
+ import * as Gtk from "@gtkx/ffi/gtk";
2
+ import type * as Pango from "@gtkx/ffi/pango";
3
+ import type { ReactNode } from "react";
4
+ import type { Node } from "../node.js";
5
+ import type { TextContentChild, TextContentParent } from "./text-content.js";
6
+ import { TextSegmentNode } from "./text-segment.js";
7
+ import { VirtualNode } from "./virtual.js";
8
+ /**
9
+ * Props for the TextTag virtual element.
10
+ *
11
+ * Used to declaratively define and apply text formatting to content within a TextBuffer.
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * <GtkTextView>
16
+ * <x.TextBuffer>
17
+ * Hello <x.TextTag id="bold" weight={Pango.Weight.BOLD}>bold</x.TextTag> world
18
+ * </x.TextBuffer>
19
+ * </GtkTextView>
20
+ * ```
21
+ */
22
+ export type TextTagProps = {
23
+ /** Unique identifier for this tag in the tag table */
24
+ id: string;
25
+ /** Priority of this tag (higher wins when multiple tags affect same property) */
26
+ priority?: number;
27
+ /** Background color as a string (e.g., "red", "#ff0000") */
28
+ background?: string;
29
+ /** Whether the background fills the entire line height */
30
+ backgroundFullHeight?: boolean;
31
+ /** Foreground (text) color as a string */
32
+ foreground?: string;
33
+ /** Font family name (e.g., "Sans", "Monospace") */
34
+ family?: string;
35
+ /** Font description string (e.g., "Sans Italic 12") */
36
+ font?: string;
37
+ /** Font size in points */
38
+ sizePoints?: number;
39
+ /** Font size in Pango units */
40
+ size?: number;
41
+ /** Font size scale factor relative to default */
42
+ scale?: number;
43
+ /** Font weight (use Pango.Weight constants) */
44
+ weight?: Pango.Weight | number;
45
+ /** Font style (use Pango.Style constants) */
46
+ style?: Pango.Style;
47
+ /** Font stretch (use Pango.Stretch constants) */
48
+ stretch?: Pango.Stretch;
49
+ /** Font variant (use Pango.Variant constants) */
50
+ variant?: Pango.Variant;
51
+ /** Whether to strike through the text */
52
+ strikethrough?: boolean;
53
+ /** Underline style (use Pango.Underline constants) */
54
+ underline?: Pango.Underline;
55
+ /** Overline style (use Pango.Overline constants) */
56
+ overline?: Pango.Overline;
57
+ /** Offset of text above baseline in Pango units (negative = below) */
58
+ rise?: number;
59
+ /** Extra spacing between characters in Pango units */
60
+ letterSpacing?: number;
61
+ /** Factor to scale line height by */
62
+ lineHeight?: number;
63
+ /** Left margin in pixels */
64
+ leftMargin?: number;
65
+ /** Right margin in pixels */
66
+ rightMargin?: number;
67
+ /** Paragraph indent in pixels (negative = hanging) */
68
+ indent?: number;
69
+ /** Pixels of blank space above paragraphs */
70
+ pixelsAboveLines?: number;
71
+ /** Pixels of blank space below paragraphs */
72
+ pixelsBelowLines?: number;
73
+ /** Pixels of blank space between wrapped lines */
74
+ pixelsInsideWrap?: number;
75
+ /** Text justification */
76
+ justification?: Gtk.Justification;
77
+ /** Text direction */
78
+ direction?: Gtk.TextDirection;
79
+ /** Wrap mode for line breaks */
80
+ wrapMode?: Gtk.WrapMode;
81
+ /** Whether the text can be modified */
82
+ editable?: boolean;
83
+ /** Whether the text is invisible/hidden */
84
+ invisible?: boolean;
85
+ /** Whether breaks are allowed */
86
+ allowBreaks?: boolean;
87
+ /** Whether to insert hyphens at breaks */
88
+ insertHyphens?: boolean;
89
+ /** Whether font fallback is enabled */
90
+ fallback?: boolean;
91
+ /** Whether margins accumulate */
92
+ accumulativeMargin?: boolean;
93
+ /** Paragraph background color as a string */
94
+ paragraphBackground?: string;
95
+ /** How to render invisible characters */
96
+ showSpaces?: Pango.ShowFlags;
97
+ /** How to transform text for display */
98
+ textTransform?: Pango.TextTransform;
99
+ /** OpenType font features as a string */
100
+ fontFeatures?: string;
101
+ /** Language code (e.g., "en-US") */
102
+ language?: string;
103
+ /** Text content and nested TextTag children */
104
+ children?: ReactNode;
105
+ };
106
+ export declare class TextTagNode extends VirtualNode<TextTagProps> implements TextContentParent {
107
+ static priority: number;
108
+ private buffer;
109
+ private tag;
110
+ private children;
111
+ private parent;
112
+ bufferOffset: number;
113
+ static matches(type: string): boolean;
114
+ setParent(parent: TextContentParent): void;
115
+ setBuffer(buffer: Gtk.TextBuffer): void;
116
+ hasBuffer(): boolean;
117
+ private setupTag;
118
+ private applyStyleProps;
119
+ getText(): string;
120
+ getLength(): number;
121
+ getChildren(): TextContentChild[];
122
+ private applyTagToRange;
123
+ private removeTagFromBuffer;
124
+ reapplyTag(): void;
125
+ private updateChildOffsets;
126
+ onChildInserted(child: TextContentChild): void;
127
+ onChildRemoved(child: TextContentChild): void;
128
+ onChildTextChanged(child: TextSegmentNode, oldLength: number, newLength: number): void;
129
+ appendChild(child: Node): void;
130
+ removeChild(child: Node): void;
131
+ insertBefore(child: Node, before: Node): void;
132
+ private isTextContentChild;
133
+ private setChildParent;
134
+ updateProps(oldProps: TextTagProps | null, newProps: TextTagProps): void;
135
+ unmount(): void;
136
+ }
@@ -0,0 +1,202 @@
1
+ import * as Gtk from "@gtkx/ffi/gtk";
2
+ import { registerNodeClass } from "../registry.js";
3
+ import { applyStyleChanges } from "./internal/text-tag-styles.js";
4
+ import { hasChanged } from "./internal/utils.js";
5
+ import { TextAnchorNode } from "./text-anchor.js";
6
+ import { TextSegmentNode } from "./text-segment.js";
7
+ import { VirtualNode } from "./virtual.js";
8
+ export class TextTagNode extends VirtualNode {
9
+ static priority = 1;
10
+ buffer = null;
11
+ tag = null;
12
+ children = [];
13
+ parent = null;
14
+ bufferOffset = 0;
15
+ static matches(type) {
16
+ return type === "TextTag";
17
+ }
18
+ setParent(parent) {
19
+ this.parent = parent;
20
+ }
21
+ setBuffer(buffer) {
22
+ this.buffer = buffer;
23
+ this.updateChildOffsets(0);
24
+ this.setupTag();
25
+ for (const child of this.children) {
26
+ if (child instanceof TextTagNode) {
27
+ child.setBuffer(buffer);
28
+ }
29
+ }
30
+ }
31
+ hasBuffer() {
32
+ return this.buffer !== null;
33
+ }
34
+ setupTag() {
35
+ if (!this.buffer)
36
+ return;
37
+ const tagTable = this.buffer.getTagTable();
38
+ this.tag = new Gtk.TextTag(this.props.id);
39
+ this.applyStyleProps(null, this.props);
40
+ tagTable.add(this.tag);
41
+ if (this.props.priority !== undefined) {
42
+ this.tag.setPriority(this.props.priority);
43
+ }
44
+ this.applyTagToRange();
45
+ }
46
+ applyStyleProps(oldProps, newProps) {
47
+ if (!this.tag)
48
+ return;
49
+ applyStyleChanges(this.tag, oldProps, newProps);
50
+ }
51
+ getText() {
52
+ let text = "";
53
+ for (const child of this.children) {
54
+ text += child.getText();
55
+ }
56
+ return text;
57
+ }
58
+ getLength() {
59
+ let length = 0;
60
+ for (const child of this.children) {
61
+ length += child.getLength();
62
+ }
63
+ return length;
64
+ }
65
+ getChildren() {
66
+ return this.children;
67
+ }
68
+ applyTagToRange() {
69
+ const buffer = this.buffer;
70
+ const tag = this.tag;
71
+ if (!buffer || !tag)
72
+ return;
73
+ const length = this.getLength();
74
+ if (length === 0)
75
+ return;
76
+ const startIter = new Gtk.TextIter();
77
+ const endIter = new Gtk.TextIter();
78
+ buffer.getIterAtOffset(startIter, this.bufferOffset);
79
+ buffer.getIterAtOffset(endIter, this.bufferOffset + length);
80
+ buffer.applyTag(tag, startIter, endIter);
81
+ }
82
+ removeTagFromBuffer() {
83
+ const buffer = this.buffer;
84
+ const tag = this.tag;
85
+ if (!buffer || !tag)
86
+ return;
87
+ const startIter = new Gtk.TextIter();
88
+ const endIter = new Gtk.TextIter();
89
+ buffer.getStartIter(startIter);
90
+ buffer.getEndIter(endIter);
91
+ buffer.removeTag(tag, startIter, endIter);
92
+ }
93
+ reapplyTag() {
94
+ if (!this.buffer || !this.tag)
95
+ return;
96
+ this.removeTagFromBuffer();
97
+ this.applyTagToRange();
98
+ }
99
+ updateChildOffsets(startIndex) {
100
+ let offset = this.bufferOffset;
101
+ for (let i = 0; i < startIndex; i++) {
102
+ const child = this.children[i];
103
+ if (child)
104
+ offset += child.getLength();
105
+ }
106
+ for (let i = startIndex; i < this.children.length; i++) {
107
+ const child = this.children[i];
108
+ if (child) {
109
+ child.bufferOffset = offset;
110
+ offset += child.getLength();
111
+ }
112
+ }
113
+ }
114
+ onChildInserted(child) {
115
+ const index = this.children.indexOf(child);
116
+ if (index !== -1) {
117
+ this.updateChildOffsets(index);
118
+ }
119
+ this.parent?.onChildInserted(child);
120
+ }
121
+ onChildRemoved(child) {
122
+ this.parent?.onChildRemoved(child);
123
+ }
124
+ onChildTextChanged(child, oldLength, newLength) {
125
+ const index = this.children.indexOf(child);
126
+ if (index !== -1) {
127
+ this.updateChildOffsets(index + 1);
128
+ }
129
+ this.parent?.onChildTextChanged(child, oldLength, newLength);
130
+ }
131
+ appendChild(child) {
132
+ if (this.isTextContentChild(child)) {
133
+ const index = this.children.length;
134
+ this.children.push(child);
135
+ this.setChildParent(child);
136
+ if (child instanceof TextTagNode && this.buffer) {
137
+ child.setBuffer(this.buffer);
138
+ }
139
+ this.updateChildOffsets(index);
140
+ this.parent?.onChildInserted(child);
141
+ return;
142
+ }
143
+ super.appendChild(child);
144
+ }
145
+ removeChild(child) {
146
+ const index = this.children.indexOf(child);
147
+ if (index !== -1) {
148
+ this.children.splice(index, 1);
149
+ this.updateChildOffsets(index);
150
+ this.parent?.onChildRemoved(child);
151
+ return;
152
+ }
153
+ super.removeChild(child);
154
+ }
155
+ insertBefore(child, before) {
156
+ if (this.isTextContentChild(child)) {
157
+ const beforeIndex = this.children.indexOf(before);
158
+ const insertIndex = beforeIndex !== -1 ? beforeIndex : this.children.length;
159
+ this.children.splice(insertIndex, 0, child);
160
+ this.setChildParent(child);
161
+ if (child instanceof TextTagNode && this.buffer) {
162
+ child.setBuffer(this.buffer);
163
+ }
164
+ this.updateChildOffsets(insertIndex);
165
+ this.parent?.onChildInserted(child);
166
+ return;
167
+ }
168
+ super.insertBefore(child, before);
169
+ }
170
+ isTextContentChild(child) {
171
+ return child instanceof TextSegmentNode || child instanceof TextTagNode || child instanceof TextAnchorNode;
172
+ }
173
+ setChildParent(child) {
174
+ if (child instanceof TextSegmentNode || child instanceof TextTagNode) {
175
+ child.setParent(this);
176
+ }
177
+ }
178
+ updateProps(oldProps, newProps) {
179
+ super.updateProps(oldProps, newProps);
180
+ if (oldProps && oldProps.id !== newProps.id) {
181
+ throw new Error("TextTag id cannot be changed after creation");
182
+ }
183
+ if (this.tag) {
184
+ this.applyStyleProps(oldProps, newProps);
185
+ if (hasChanged(oldProps, newProps, "priority") && newProps.priority !== undefined) {
186
+ this.tag.setPriority(newProps.priority);
187
+ }
188
+ }
189
+ }
190
+ unmount() {
191
+ if (this.buffer && this.tag) {
192
+ this.removeTagFromBuffer();
193
+ const tagTable = this.buffer.getTagTable();
194
+ tagTable.remove(this.tag);
195
+ }
196
+ this.tag = null;
197
+ this.buffer = null;
198
+ this.children = [];
199
+ super.unmount();
200
+ }
201
+ }
202
+ registerNodeClass(TextTagNode);
@@ -1 +1,31 @@
1
+ import * as Gtk from "@gtkx/ffi/gtk";
2
+ import type { Node } from "../node.js";
3
+ import type { Container, ContainerClass, Props } from "../types.js";
4
+ import { TextBufferController } from "./internal/text-buffer-controller.js";
5
+ import type { TextContentChild, TextContentParent } from "./text-content.js";
6
+ import type { TextSegmentNode } from "./text-segment.js";
7
+ import { WidgetNode } from "./widget.js";
8
+ type TextViewProps = Props & {
9
+ enableUndo?: boolean;
10
+ onBufferChanged?: ((buffer: Gtk.TextBuffer) => void) | null;
11
+ onTextInserted?: ((buffer: Gtk.TextBuffer, offset: number, text: string) => void) | null;
12
+ onTextDeleted?: ((buffer: Gtk.TextBuffer, startOffset: number, endOffset: number) => void) | null;
13
+ onCanUndoChanged?: ((canUndo: boolean) => void) | null;
14
+ onCanRedoChanged?: ((canRedo: boolean) => void) | null;
15
+ };
16
+ export declare class TextViewNode extends WidgetNode<Gtk.TextView, TextViewProps> implements TextContentParent {
17
+ static priority: number;
18
+ protected bufferController: TextBufferController | null;
19
+ static matches(_type: string, containerOrClass?: Container | ContainerClass | null): boolean;
20
+ protected ensureBufferController(): TextBufferController;
21
+ protected createBufferController(): TextBufferController;
22
+ updateProps(oldProps: TextViewProps | null, newProps: TextViewProps): void;
23
+ protected applyOwnProps(oldProps: TextViewProps | null, newProps: TextViewProps): void;
24
+ appendChild(child: Node): void;
25
+ insertBefore(child: Node, before: Node): void;
26
+ removeChild(child: Node): void;
27
+ onChildInserted(child: TextContentChild): void;
28
+ onChildRemoved(child: TextContentChild): void;
29
+ onChildTextChanged(child: TextSegmentNode, oldLength: number, newLength: number): void;
30
+ }
1
31
  export {};
@@ -1,45 +1,73 @@
1
1
  import * as Gtk from "@gtkx/ffi/gtk";
2
2
  import * as GtkSource from "@gtkx/ffi/gtksource";
3
3
  import { registerNodeClass } from "../registry.js";
4
- import { isContainerType } from "./internal/utils.js";
5
- import { TextBufferNode } from "./text-buffer.js";
4
+ import { TextBufferController } from "./internal/text-buffer-controller.js";
5
+ import { filterProps, matchesAnyClass } from "./internal/utils.js";
6
6
  import { WidgetNode } from "./widget.js";
7
- class TextViewNode extends WidgetNode {
7
+ const OWN_PROPS = [
8
+ "enableUndo",
9
+ "onBufferChanged",
10
+ "onTextInserted",
11
+ "onTextDeleted",
12
+ "onCanUndoChanged",
13
+ "onCanRedoChanged",
14
+ ];
15
+ export class TextViewNode extends WidgetNode {
8
16
  static priority = 1;
9
- bufferChild;
17
+ bufferController = null;
10
18
  static matches(_type, containerOrClass) {
11
- if (isContainerType(GtkSource.View, containerOrClass))
19
+ if (matchesAnyClass([GtkSource.View], containerOrClass))
12
20
  return false;
13
- return isContainerType(Gtk.TextView, containerOrClass);
21
+ return matchesAnyClass([Gtk.TextView], containerOrClass);
22
+ }
23
+ ensureBufferController() {
24
+ if (!this.bufferController) {
25
+ this.bufferController = this.createBufferController();
26
+ }
27
+ return this.bufferController;
28
+ }
29
+ createBufferController() {
30
+ return new TextBufferController(this, this.container, () => new Gtk.TextBuffer());
31
+ }
32
+ updateProps(oldProps, newProps) {
33
+ super.updateProps(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
34
+ this.applyOwnProps(oldProps, newProps);
35
+ }
36
+ applyOwnProps(oldProps, newProps) {
37
+ this.ensureBufferController().applyOwnProps(oldProps, newProps);
14
38
  }
15
39
  appendChild(child) {
16
- if (this.tryAttachTextBuffer(child))
40
+ const controller = this.ensureBufferController();
41
+ if (controller.isTextContentChild(child)) {
42
+ controller.appendChild(child);
17
43
  return;
44
+ }
18
45
  super.appendChild(child);
19
46
  }
20
47
  insertBefore(child, before) {
21
- if (this.tryAttachTextBuffer(child))
48
+ const controller = this.ensureBufferController();
49
+ if (controller.isTextContentChild(child)) {
50
+ controller.insertBefore(child, before);
22
51
  return;
52
+ }
23
53
  super.insertBefore(child, before);
24
54
  }
25
55
  removeChild(child) {
26
- if (child instanceof TextBufferNode) {
27
- if (this.bufferChild === child) {
28
- this.bufferChild = undefined;
29
- }
56
+ const controller = this.ensureBufferController();
57
+ if (controller.isTextContentChild(child)) {
58
+ controller.removeChild(child);
30
59
  return;
31
60
  }
32
61
  super.removeChild(child);
33
62
  }
34
- tryAttachTextBuffer(child) {
35
- if (!(child instanceof TextBufferNode))
36
- return false;
37
- if (this.bufferChild) {
38
- throw new Error("TextView can only have one TextBuffer child");
39
- }
40
- this.bufferChild = child;
41
- child.setTextView(this.container);
42
- return true;
63
+ onChildInserted(child) {
64
+ this.ensureBufferController().onChildInserted(child);
65
+ }
66
+ onChildRemoved(child) {
67
+ this.ensureBufferController().onChildRemoved(child);
68
+ }
69
+ onChildTextChanged(child, oldLength, newLength) {
70
+ this.ensureBufferController().onChildTextChanged(child, oldLength, newLength);
43
71
  }
44
72
  }
45
73
  registerNodeClass(TextViewNode);
@@ -1,48 +1,40 @@
1
1
  import * as Adw from "@gtkx/ffi/adw";
2
2
  import { registerNodeClass } from "../registry.js";
3
- import { isContainerType } from "./internal/utils.js";
4
- import { SlotNode } from "./slot.js";
5
- import { ToggleNode } from "./toggle.js";
3
+ import { filterProps, hasChanged, matchesAnyClass } from "./internal/utils.js";
6
4
  import { WidgetNode } from "./widget.js";
5
+ const OWN_PROPS = ["onActiveChanged"];
7
6
  class ToggleGroupNode extends WidgetNode {
8
7
  static priority = 1;
8
+ notifyHandler = null;
9
9
  static matches(_type, containerOrClass) {
10
- return isContainerType(Adw.ToggleGroup, containerOrClass);
10
+ return matchesAnyClass([Adw.ToggleGroup], containerOrClass);
11
11
  }
12
- appendChild(child) {
13
- if (child instanceof ToggleNode) {
14
- child.setToggleGroup(this.container);
15
- child.addToGroup();
16
- return;
12
+ updateProps(oldProps, newProps) {
13
+ super.updateProps(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
14
+ if (hasChanged(oldProps, newProps, "onActiveChanged")) {
15
+ this.setupNotifyHandler(newProps.onActiveChanged);
17
16
  }
18
- if (child instanceof SlotNode || child instanceof WidgetNode) {
19
- super.appendChild(child);
20
- return;
21
- }
22
- throw new Error(`Cannot append '${child.typeName}' to 'ToggleGroup': expected x.Toggle or Widget`);
23
17
  }
24
- insertBefore(child, before) {
25
- if (child instanceof ToggleNode) {
26
- child.setToggleGroup(this.container);
27
- child.addToGroup();
28
- return;
18
+ setupNotifyHandler(callback) {
19
+ if (this.notifyHandler) {
20
+ this.signalStore.set(this, this.container, "notify", undefined);
21
+ this.notifyHandler = null;
29
22
  }
30
- if (child instanceof SlotNode || child instanceof WidgetNode) {
31
- super.insertBefore(child, before);
32
- return;
23
+ if (callback) {
24
+ this.notifyHandler = (pspec) => {
25
+ if (pspec.getName() === "active") {
26
+ callback(this.container.getActive(), this.container.getActiveName());
27
+ }
28
+ };
29
+ this.signalStore.set(this, this.container, "notify", this.notifyHandler);
33
30
  }
34
- throw new Error(`Cannot insert '${child.typeName}' into 'ToggleGroup': expected x.Toggle or Widget`);
35
31
  }
36
- removeChild(child) {
37
- if (child instanceof ToggleNode) {
38
- child.removeFromGroup();
39
- return;
40
- }
41
- if (child instanceof SlotNode || child instanceof WidgetNode) {
42
- super.removeChild(child);
43
- return;
32
+ unmount() {
33
+ if (this.notifyHandler) {
34
+ this.signalStore.set(this, this.container, "notify", undefined);
35
+ this.notifyHandler = null;
44
36
  }
45
- throw new Error(`Cannot remove '${child.typeName}' from 'ToggleGroup': expected x.Toggle or Widget`);
37
+ super.unmount();
46
38
  }
47
39
  }
48
40
  registerNodeClass(ToggleGroupNode);
@@ -1,15 +1 @@
1
- import * as Adw from "@gtkx/ffi/adw";
2
- import type { ToggleProps } from "../jsx.js";
3
- import { VirtualNode } from "./virtual.js";
4
- export declare class ToggleNode extends VirtualNode<ToggleProps> {
5
- static priority: number;
6
- private toggleGroup?;
7
- private toggle?;
8
- static matches(type: string): boolean;
9
- setToggleGroup(toggleGroup: Adw.ToggleGroup): void;
10
- addToGroup(): void;
11
- removeFromGroup(): void;
12
- updateProps(oldProps: ToggleProps | null, newProps: ToggleProps): void;
13
- unmount(): void;
14
- private applyProps;
15
- }
1
+ export {};
@@ -1,70 +1,78 @@
1
1
  import * as Adw from "@gtkx/ffi/adw";
2
2
  import { registerNodeClass } from "../registry.js";
3
3
  import { CommitPriority, scheduleAfterCommit } from "../scheduler.js";
4
+ import { hasChanged } from "./internal/utils.js";
4
5
  import { VirtualNode } from "./virtual.js";
5
- export class ToggleNode extends VirtualNode {
6
+ import { WidgetNode } from "./widget.js";
7
+ class ToggleNode extends VirtualNode {
6
8
  static priority = 1;
7
- toggleGroup;
8
- toggle;
9
+ toggleGroup = null;
10
+ toggle = null;
9
11
  static matches(type) {
10
12
  return type === "Toggle";
11
13
  }
12
- setToggleGroup(toggleGroup) {
13
- this.toggleGroup = toggleGroup;
14
+ canBeChildOf(parent) {
15
+ return parent instanceof WidgetNode && parent.container instanceof Adw.ToggleGroup;
14
16
  }
15
- addToGroup() {
16
- if (!this.toggleGroup || this.toggle)
17
+ attachTo(parent) {
18
+ if (!(parent instanceof WidgetNode) || !(parent.container instanceof Adw.ToggleGroup)) {
17
19
  return;
20
+ }
21
+ if (this.toggle)
22
+ return;
23
+ this.toggleGroup = parent.container;
18
24
  const toggleGroup = this.toggleGroup;
19
25
  this.toggle = new Adw.Toggle();
20
26
  scheduleAfterCommit(() => {
21
- if (this.toggle) {
22
- this.applyProps(this.props);
23
- toggleGroup.add(this.toggle);
27
+ const toggle = this.toggle;
28
+ if (toggle) {
29
+ this.applyOwnProps(null, this.props);
30
+ toggleGroup.add(toggle);
24
31
  }
25
- });
32
+ }, CommitPriority.NORMAL);
33
+ }
34
+ detachFrom(_parent) {
35
+ this.removeFromGroup();
26
36
  }
27
37
  removeFromGroup() {
28
38
  if (!this.toggleGroup || !this.toggle)
29
39
  return;
30
40
  const toggleGroup = this.toggleGroup;
31
41
  const toggle = this.toggle;
32
- this.toggle = undefined;
42
+ this.toggle = null;
33
43
  scheduleAfterCommit(() => {
34
44
  toggleGroup.remove(toggle);
35
45
  }, CommitPriority.HIGH);
36
46
  }
37
47
  updateProps(oldProps, newProps) {
38
48
  super.updateProps(oldProps, newProps);
39
- if (oldProps && this.toggle) {
40
- this.applyProps(newProps);
41
- }
49
+ this.applyOwnProps(oldProps, newProps);
42
50
  }
43
- unmount() {
44
- this.removeFromGroup();
45
- super.unmount();
46
- }
47
- applyProps(props) {
51
+ applyOwnProps(oldProps, newProps) {
48
52
  if (!this.toggle)
49
53
  return;
50
- if (props.id !== undefined && props.id !== this.toggle.getName()) {
51
- this.toggle.setName(props.id);
54
+ if (hasChanged(oldProps, newProps, "id") && newProps.id !== undefined) {
55
+ this.toggle.setName(newProps.id);
52
56
  }
53
- if (props.label !== undefined && props.label !== this.toggle.getLabel()) {
54
- this.toggle.setLabel(props.label);
57
+ if (hasChanged(oldProps, newProps, "label") && newProps.label !== undefined) {
58
+ this.toggle.setLabel(newProps.label);
55
59
  }
56
- if (props.iconName !== undefined && props.iconName !== this.toggle.getIconName()) {
57
- this.toggle.setIconName(props.iconName);
60
+ if (hasChanged(oldProps, newProps, "iconName") && newProps.iconName !== undefined) {
61
+ this.toggle.setIconName(newProps.iconName);
58
62
  }
59
- if (props.tooltip !== undefined && props.tooltip !== this.toggle.getTooltip()) {
60
- this.toggle.setTooltip(props.tooltip);
63
+ if (hasChanged(oldProps, newProps, "tooltip") && newProps.tooltip !== undefined) {
64
+ this.toggle.setTooltip(newProps.tooltip);
61
65
  }
62
- if (props.enabled !== undefined && props.enabled !== this.toggle.getEnabled()) {
63
- this.toggle.setEnabled(props.enabled);
66
+ if (hasChanged(oldProps, newProps, "enabled") && newProps.enabled !== undefined) {
67
+ this.toggle.setEnabled(newProps.enabled);
64
68
  }
65
- if (props.useUnderline !== undefined && props.useUnderline !== this.toggle.getUseUnderline()) {
66
- this.toggle.setUseUnderline(props.useUnderline);
69
+ if (hasChanged(oldProps, newProps, "useUnderline") && newProps.useUnderline !== undefined) {
70
+ this.toggle.setUseUnderline(newProps.useUnderline);
67
71
  }
68
72
  }
73
+ unmount() {
74
+ this.removeFromGroup();
75
+ super.unmount();
76
+ }
69
77
  }
70
78
  registerNodeClass(ToggleNode);