@gtkx/react 0.18.9 → 0.20.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 (212) hide show
  1. package/dist/components/list.d.ts +35 -0
  2. package/dist/components/list.d.ts.map +1 -0
  3. package/dist/components/list.js +40 -0
  4. package/dist/components/list.js.map +1 -0
  5. package/dist/generated/internal.d.ts +8 -3
  6. package/dist/generated/internal.d.ts.map +1 -1
  7. package/dist/generated/internal.js +3553 -53
  8. package/dist/generated/internal.js.map +1 -1
  9. package/dist/generated/jsx.d.ts +178 -326
  10. package/dist/generated/jsx.d.ts.map +1 -1
  11. package/dist/generated/jsx.js +0 -324
  12. package/dist/generated/jsx.js.map +1 -1
  13. package/dist/host-config.d.ts.map +1 -1
  14. package/dist/host-config.js +48 -10
  15. package/dist/host-config.js.map +1 -1
  16. package/dist/jsx.d.ts +111 -54
  17. package/dist/jsx.d.ts.map +1 -1
  18. package/dist/jsx.js +3 -28
  19. package/dist/jsx.js.map +1 -1
  20. package/dist/metadata.d.ts +1 -0
  21. package/dist/metadata.d.ts.map +1 -1
  22. package/dist/metadata.js +7 -1
  23. package/dist/metadata.js.map +1 -1
  24. package/dist/node.d.ts +0 -2
  25. package/dist/node.d.ts.map +1 -1
  26. package/dist/node.js +19 -25
  27. package/dist/node.js.map +1 -1
  28. package/dist/nodes/application.d.ts.map +1 -1
  29. package/dist/nodes/application.js +4 -0
  30. package/dist/nodes/application.js.map +1 -1
  31. package/dist/nodes/column-view-column.d.ts +19 -16
  32. package/dist/nodes/column-view-column.d.ts.map +1 -1
  33. package/dist/nodes/column-view-column.js +129 -97
  34. package/dist/nodes/column-view-column.js.map +1 -1
  35. package/dist/nodes/event-controller.d.ts +1 -0
  36. package/dist/nodes/event-controller.d.ts.map +1 -1
  37. package/dist/nodes/event-controller.js +9 -7
  38. package/dist/nodes/event-controller.js.map +1 -1
  39. package/dist/nodes/fixed-child.d.ts +1 -2
  40. package/dist/nodes/fixed-child.d.ts.map +1 -1
  41. package/dist/nodes/fixed-child.js +21 -21
  42. package/dist/nodes/fixed-child.js.map +1 -1
  43. package/dist/nodes/font-dialog-button.d.ts +1 -1
  44. package/dist/nodes/font-dialog-button.d.ts.map +1 -1
  45. package/dist/nodes/font-dialog-button.js +8 -0
  46. package/dist/nodes/font-dialog-button.js.map +1 -1
  47. package/dist/nodes/internal/accessible.d.ts +5 -0
  48. package/dist/nodes/internal/accessible.d.ts.map +1 -0
  49. package/dist/nodes/internal/accessible.js +119 -0
  50. package/dist/nodes/internal/accessible.js.map +1 -0
  51. package/dist/nodes/internal/bound-item.d.ts +4 -0
  52. package/dist/nodes/internal/bound-item.d.ts.map +1 -0
  53. package/dist/nodes/internal/bound-item.js +2 -0
  54. package/dist/nodes/internal/bound-item.js.map +1 -0
  55. package/dist/nodes/internal/construct.d.ts +3 -0
  56. package/dist/nodes/internal/construct.d.ts.map +1 -0
  57. package/dist/nodes/internal/construct.js +44 -0
  58. package/dist/nodes/internal/construct.js.map +1 -0
  59. package/dist/nodes/internal/text-buffer-controller.d.ts +4 -0
  60. package/dist/nodes/internal/text-buffer-controller.d.ts.map +1 -1
  61. package/dist/nodes/internal/text-buffer-controller.js +49 -9
  62. package/dist/nodes/internal/text-buffer-controller.js.map +1 -1
  63. package/dist/nodes/internal/widget.d.ts.map +1 -1
  64. package/dist/nodes/internal/widget.js +4 -1
  65. package/dist/nodes/internal/widget.js.map +1 -1
  66. package/dist/nodes/list-item-node.d.ts +12 -0
  67. package/dist/nodes/list-item-node.d.ts.map +1 -0
  68. package/dist/nodes/list-item-node.js +23 -0
  69. package/dist/nodes/list-item-node.js.map +1 -0
  70. package/dist/nodes/list.d.ts +100 -0
  71. package/dist/nodes/list.d.ts.map +1 -0
  72. package/dist/nodes/list.js +950 -0
  73. package/dist/nodes/list.js.map +1 -0
  74. package/dist/nodes/notebook-page.d.ts.map +1 -1
  75. package/dist/nodes/notebook-page.js +4 -0
  76. package/dist/nodes/notebook-page.js.map +1 -1
  77. package/dist/nodes/shortcut.d.ts +3 -2
  78. package/dist/nodes/shortcut.d.ts.map +1 -1
  79. package/dist/nodes/shortcut.js +19 -4
  80. package/dist/nodes/shortcut.js.map +1 -1
  81. package/dist/nodes/text-anchor.d.ts.map +1 -1
  82. package/dist/nodes/text-anchor.js +7 -1
  83. package/dist/nodes/text-anchor.js.map +1 -1
  84. package/dist/nodes/text-tag.d.ts.map +1 -1
  85. package/dist/nodes/text-tag.js +5 -1
  86. package/dist/nodes/text-tag.js.map +1 -1
  87. package/dist/nodes/text-view.d.ts +1 -0
  88. package/dist/nodes/text-view.d.ts.map +1 -1
  89. package/dist/nodes/text-view.js +4 -0
  90. package/dist/nodes/text-view.js.map +1 -1
  91. package/dist/nodes/widget.d.ts +0 -2
  92. package/dist/nodes/widget.d.ts.map +1 -1
  93. package/dist/nodes/widget.js +51 -67
  94. package/dist/nodes/widget.js.map +1 -1
  95. package/dist/nodes/window.d.ts.map +1 -1
  96. package/dist/nodes/window.js +2 -2
  97. package/dist/nodes/window.js.map +1 -1
  98. package/dist/registry.d.ts +0 -2
  99. package/dist/registry.d.ts.map +1 -1
  100. package/dist/registry.js +4 -13
  101. package/dist/registry.js.map +1 -1
  102. package/dist/types.d.ts +2 -2
  103. package/dist/types.d.ts.map +1 -1
  104. package/package.json +5 -4
  105. package/src/components/list.tsx +83 -0
  106. package/src/generated/internal.ts +3559 -49
  107. package/src/generated/jsx.ts +178 -326
  108. package/src/host-config.ts +43 -10
  109. package/src/jsx.ts +121 -62
  110. package/src/metadata.ts +8 -1
  111. package/src/node.ts +23 -25
  112. package/src/nodes/application.ts +5 -0
  113. package/src/nodes/column-view-column.ts +125 -104
  114. package/src/nodes/event-controller.ts +8 -8
  115. package/src/nodes/fixed-child.ts +24 -23
  116. package/src/nodes/font-dialog-button.ts +10 -0
  117. package/src/nodes/internal/accessible.ts +155 -0
  118. package/src/nodes/internal/bound-item.ts +4 -0
  119. package/src/nodes/internal/construct.ts +60 -0
  120. package/src/nodes/internal/text-buffer-controller.ts +51 -8
  121. package/src/nodes/internal/widget.ts +3 -1
  122. package/src/nodes/list-item-node.ts +29 -0
  123. package/src/nodes/list.ts +1082 -0
  124. package/src/nodes/notebook-page.ts +4 -0
  125. package/src/nodes/shortcut.ts +22 -5
  126. package/src/nodes/text-anchor.ts +6 -1
  127. package/src/nodes/text-tag.ts +7 -1
  128. package/src/nodes/text-view.ts +5 -0
  129. package/src/nodes/widget.ts +47 -69
  130. package/src/nodes/window.ts +2 -2
  131. package/src/registry.ts +11 -17
  132. package/src/types.ts +7 -2
  133. package/dist/fiber-root.d.ts +0 -4
  134. package/dist/fiber-root.d.ts.map +0 -1
  135. package/dist/fiber-root.js +0 -6
  136. package/dist/fiber-root.js.map +0 -1
  137. package/dist/nodes/column-view.d.ts +0 -36
  138. package/dist/nodes/column-view.d.ts.map +0 -1
  139. package/dist/nodes/column-view.js +0 -175
  140. package/dist/nodes/column-view.js.map +0 -1
  141. package/dist/nodes/drop-down.d.ts +0 -27
  142. package/dist/nodes/drop-down.d.ts.map +0 -1
  143. package/dist/nodes/drop-down.js +0 -85
  144. package/dist/nodes/drop-down.js.map +0 -1
  145. package/dist/nodes/grid-view.d.ts +0 -29
  146. package/dist/nodes/grid-view.d.ts.map +0 -1
  147. package/dist/nodes/grid-view.js +0 -85
  148. package/dist/nodes/grid-view.js.map +0 -1
  149. package/dist/nodes/internal/base-item-renderer.d.ts +0 -28
  150. package/dist/nodes/internal/base-item-renderer.d.ts.map +0 -1
  151. package/dist/nodes/internal/base-item-renderer.js +0 -86
  152. package/dist/nodes/internal/base-item-renderer.js.map +0 -1
  153. package/dist/nodes/internal/grid-item-renderer.d.ts +0 -20
  154. package/dist/nodes/internal/grid-item-renderer.d.ts.map +0 -1
  155. package/dist/nodes/internal/grid-item-renderer.js +0 -66
  156. package/dist/nodes/internal/grid-item-renderer.js.map +0 -1
  157. package/dist/nodes/internal/list-item-renderer.d.ts +0 -27
  158. package/dist/nodes/internal/list-item-renderer.d.ts.map +0 -1
  159. package/dist/nodes/internal/list-item-renderer.js +0 -131
  160. package/dist/nodes/internal/list-item-renderer.js.map +0 -1
  161. package/dist/nodes/internal/list-store.d.ts +0 -22
  162. package/dist/nodes/internal/list-store.d.ts.map +0 -1
  163. package/dist/nodes/internal/list-store.js +0 -91
  164. package/dist/nodes/internal/list-store.js.map +0 -1
  165. package/dist/nodes/internal/selection-model-controller.d.ts +0 -26
  166. package/dist/nodes/internal/selection-model-controller.d.ts.map +0 -1
  167. package/dist/nodes/internal/selection-model-controller.js +0 -79
  168. package/dist/nodes/internal/selection-model-controller.js.map +0 -1
  169. package/dist/nodes/internal/simple-list-store.d.ts +0 -20
  170. package/dist/nodes/internal/simple-list-store.d.ts.map +0 -1
  171. package/dist/nodes/internal/simple-list-store.js +0 -87
  172. package/dist/nodes/internal/simple-list-store.js.map +0 -1
  173. package/dist/nodes/internal/tree-store.d.ts +0 -34
  174. package/dist/nodes/internal/tree-store.d.ts.map +0 -1
  175. package/dist/nodes/internal/tree-store.js +0 -208
  176. package/dist/nodes/internal/tree-store.js.map +0 -1
  177. package/dist/nodes/list-item.d.ts +0 -24
  178. package/dist/nodes/list-item.d.ts.map +0 -1
  179. package/dist/nodes/list-item.js +0 -83
  180. package/dist/nodes/list-item.js.map +0 -1
  181. package/dist/nodes/list-view.d.ts +0 -29
  182. package/dist/nodes/list-view.d.ts.map +0 -1
  183. package/dist/nodes/list-view.js +0 -83
  184. package/dist/nodes/list-view.js.map +0 -1
  185. package/dist/nodes/models/grid.d.ts +0 -28
  186. package/dist/nodes/models/grid.d.ts.map +0 -1
  187. package/dist/nodes/models/grid.js +0 -69
  188. package/dist/nodes/models/grid.js.map +0 -1
  189. package/dist/nodes/models/list.d.ts +0 -31
  190. package/dist/nodes/models/list.d.ts.map +0 -1
  191. package/dist/nodes/models/list.js +0 -93
  192. package/dist/nodes/models/list.js.map +0 -1
  193. package/dist/nodes/shortcut-controller.d.ts +0 -10
  194. package/dist/nodes/shortcut-controller.d.ts.map +0 -1
  195. package/dist/nodes/shortcut-controller.js +0 -23
  196. package/dist/nodes/shortcut-controller.js.map +0 -1
  197. package/src/fiber-root.ts +0 -20
  198. package/src/nodes/column-view.ts +0 -217
  199. package/src/nodes/drop-down.ts +0 -108
  200. package/src/nodes/grid-view.ts +0 -109
  201. package/src/nodes/internal/base-item-renderer.ts +0 -108
  202. package/src/nodes/internal/grid-item-renderer.ts +0 -78
  203. package/src/nodes/internal/list-item-renderer.ts +0 -162
  204. package/src/nodes/internal/list-store.ts +0 -105
  205. package/src/nodes/internal/selection-model-controller.ts +0 -115
  206. package/src/nodes/internal/simple-list-store.ts +0 -99
  207. package/src/nodes/internal/tree-store.ts +0 -237
  208. package/src/nodes/list-item.ts +0 -107
  209. package/src/nodes/list-view.ts +0 -113
  210. package/src/nodes/models/grid.ts +0 -105
  211. package/src/nodes/models/list.ts +0 -140
  212. package/src/nodes/shortcut-controller.ts +0 -27
@@ -1,217 +0,0 @@
1
- import * as Gtk from "@gtkx/ffi/gtk";
2
- import type { GtkColumnViewProps } from "../jsx.js";
3
- import type { Node } from "../node.js";
4
- import type { Container } from "../types.js";
5
- import { ColumnViewColumnNode } from "./column-view-column.js";
6
- import { ContainerSlotNode } from "./container-slot.js";
7
- import { EventControllerNode } from "./event-controller.js";
8
- import { filterProps, hasChanged } from "./internal/props.js";
9
- import { ListItemNode } from "./list-item.js";
10
- import { ListModel, type ListModelProps } from "./models/list.js";
11
- import { SlotNode } from "./slot.js";
12
- import { WidgetNode } from "./widget.js";
13
-
14
- const OWN_PROPS = ["sortColumn", "sortOrder", "onSortChanged", "estimatedRowHeight"] as const;
15
-
16
- type ColumnViewProps = Pick<GtkColumnViewProps, (typeof OWN_PROPS)[number]> & ListModelProps;
17
- type ColumnViewChild = ListItemNode | ColumnViewColumnNode | EventControllerNode | SlotNode | ContainerSlotNode;
18
-
19
- export class ColumnViewNode extends WidgetNode<Gtk.ColumnView, ColumnViewProps, ColumnViewChild> {
20
- private handleSortChange: (() => void) | null = null;
21
- private list: ListModel;
22
-
23
- public override isValidChild(child: Node): boolean {
24
- return (
25
- child instanceof ListItemNode ||
26
- child instanceof ColumnViewColumnNode ||
27
- child instanceof EventControllerNode ||
28
- child instanceof SlotNode ||
29
- child instanceof ContainerSlotNode
30
- );
31
- }
32
- private columnNodes = new Set<ColumnViewColumnNode>();
33
- private estimatedRowHeight: number | null = null;
34
-
35
- constructor(typeName: string, props: ColumnViewProps, container: Gtk.ColumnView, rootContainer: Container) {
36
- super(typeName, props, container, rootContainer);
37
- this.list = new ListModel(
38
- { owner: this, signalStore: this.signalStore },
39
- {
40
- selectionMode: props.selectionMode,
41
- selected: props.selected,
42
- onSelectionChanged: props.onSelectionChanged,
43
- },
44
- );
45
- this.list.getStore().setOnItemUpdated((id) => {
46
- for (const column of this.columnNodes) {
47
- column.rebindItem(id);
48
- }
49
- });
50
- }
51
-
52
- public override appendChild(child: ColumnViewChild): void {
53
- super.appendChild(child);
54
-
55
- if (child instanceof ListItemNode) {
56
- this.list.appendChild(child);
57
- return;
58
- }
59
-
60
- if (!(child instanceof ColumnViewColumnNode)) return;
61
-
62
- const existingColumn = this.findColumnInView(child.getColumn());
63
-
64
- if (existingColumn) {
65
- this.container.removeColumn(existingColumn);
66
- }
67
-
68
- child.setStore(this.list.getStore());
69
- child.setEstimatedRowHeight(this.estimatedRowHeight);
70
- this.container.appendColumn(child.getColumn());
71
- child.attachToColumnView(this.container);
72
- this.columnNodes.add(child);
73
- }
74
-
75
- public override insertBefore(child: ColumnViewChild, before: ColumnViewChild): void {
76
- super.insertBefore(child, before);
77
-
78
- if (child instanceof ListItemNode) {
79
- if (before instanceof ListItemNode) {
80
- this.list.insertBefore(child, before);
81
- }
82
- return;
83
- }
84
-
85
- if (!(child instanceof ColumnViewColumnNode)) return;
86
-
87
- const existingColumn = this.findColumnInView(child.getColumn());
88
-
89
- if (existingColumn) {
90
- this.container.removeColumn(existingColumn);
91
- }
92
-
93
- child.setStore(this.list.getStore());
94
- child.setEstimatedRowHeight(this.estimatedRowHeight);
95
-
96
- if (before instanceof ColumnViewColumnNode) {
97
- const beforeIndex = this.getColumnIndex(before.getColumn());
98
- this.container.insertColumn(beforeIndex, child.getColumn());
99
- } else {
100
- this.container.appendColumn(child.getColumn());
101
- }
102
-
103
- child.attachToColumnView(this.container);
104
- this.columnNodes.add(child);
105
- }
106
-
107
- public override removeChild(child: ColumnViewChild): void {
108
- if (child instanceof ListItemNode) {
109
- this.list.removeChild(child);
110
- super.removeChild(child);
111
- return;
112
- }
113
-
114
- if (child instanceof ColumnViewColumnNode) {
115
- child.detachFromColumnView();
116
-
117
- const existingColumn = this.findColumnInView(child.getColumn());
118
-
119
- if (existingColumn) {
120
- this.container.removeColumn(existingColumn);
121
- }
122
-
123
- child.setStore(null);
124
- this.columnNodes.delete(child);
125
- }
126
-
127
- super.removeChild(child);
128
- }
129
-
130
- public override finalizeInitialChildren(props: ColumnViewProps): boolean {
131
- super.finalizeInitialChildren(props);
132
- return true;
133
- }
134
-
135
- public override commitUpdate(oldProps: ColumnViewProps | null, newProps: ColumnViewProps): void {
136
- super.commitUpdate(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
137
- this.applyOwnProps(oldProps, newProps);
138
- this.list.updateProps(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
139
- }
140
-
141
- public override commitMount(): void {
142
- super.commitMount();
143
- this.list.flushBatch();
144
- this.container.setModel(this.list.getSelectionModel());
145
- }
146
-
147
- public override detachDeletedInstance(): void {
148
- this.columnNodes.clear();
149
- super.detachDeletedInstance();
150
- }
151
-
152
- private applyOwnProps(oldProps: ColumnViewProps | null, newProps: ColumnViewProps): void {
153
- if (hasChanged(oldProps, newProps, "onSortChanged")) {
154
- const sorter = this.container.getSorter();
155
- const onSortChanged = newProps.onSortChanged;
156
-
157
- if (sorter instanceof Gtk.ColumnViewSorter) {
158
- this.handleSortChange = () => {
159
- onSortChanged?.(sorter.getPrimarySortColumn()?.getId() ?? null, sorter.getPrimarySortOrder());
160
- };
161
-
162
- this.signalStore.set(this, sorter, "changed", this.handleSortChange);
163
- }
164
- }
165
-
166
- if (hasChanged(oldProps, newProps, "sortColumn") || hasChanged(oldProps, newProps, "sortOrder")) {
167
- const sortColumn = newProps.sortColumn;
168
- const sortOrder = newProps.sortOrder ?? Gtk.SortType.ASCENDING;
169
-
170
- if (!sortColumn) {
171
- this.container.sortByColumn(sortOrder, undefined);
172
- } else {
173
- this.container.sortByColumn(sortOrder, this.getColumn(sortColumn));
174
- }
175
- }
176
-
177
- if (hasChanged(oldProps, newProps, "estimatedRowHeight")) {
178
- this.estimatedRowHeight = newProps.estimatedRowHeight ?? null;
179
- for (const column of this.columnNodes) {
180
- column.setEstimatedRowHeight(this.estimatedRowHeight);
181
- }
182
- }
183
- }
184
-
185
- private findColumn<T>(predicate: (column: Gtk.ColumnViewColumn, index: number) => T | null): T | null {
186
- const columns = this.container.getColumns();
187
- for (let i = 0; i < columns.getNItems(); i++) {
188
- const column = columns.getObject(i);
189
- if (!(column instanceof Gtk.ColumnViewColumn)) continue;
190
- const result = predicate(column, i);
191
- if (result !== null) return result;
192
- }
193
- return null;
194
- }
195
-
196
- private getColumn(columnId: string): Gtk.ColumnViewColumn {
197
- const column = this.findColumn((col) => (col.getId() === columnId ? col : null));
198
- if (!column) {
199
- throw new Error(`Unable to find column '${columnId}' in ${this.typeName}`);
200
- }
201
- return column;
202
- }
203
-
204
- private getColumnIndex(column: Gtk.ColumnViewColumn): number {
205
- const targetId = column.getId();
206
- const index = this.findColumn((col, i) => (col.getId() === targetId ? i : null));
207
- if (index === null) {
208
- throw new Error(`Unable to find column '${targetId}' in ${this.typeName}`);
209
- }
210
- return index;
211
- }
212
-
213
- private findColumnInView(column: Gtk.ColumnViewColumn): Gtk.ColumnViewColumn | null {
214
- const targetId = column.getId();
215
- return this.findColumn((col) => (col.getId() === targetId ? col : null));
216
- }
217
- }
@@ -1,108 +0,0 @@
1
- import type { AdwComboRowProps, GtkDropDownProps } from "../jsx.js";
2
- import type { Node } from "../node.js";
3
- import type { DropDownWidget } from "../registry.js";
4
- import type { Container } from "../types.js";
5
- import { ContainerSlotNode } from "./container-slot.js";
6
- import { EventControllerNode } from "./event-controller.js";
7
- import { filterProps, hasChanged } from "./internal/props.js";
8
- import { SimpleListStore } from "./internal/simple-list-store.js";
9
- import { ListItemNode } from "./list-item.js";
10
- import { SlotNode } from "./slot.js";
11
- import { WidgetNode } from "./widget.js";
12
-
13
- const OWN_PROPS = ["selectedId", "onSelectionChanged"] as const;
14
-
15
- type DropDownProps = Pick<GtkDropDownProps | AdwComboRowProps, (typeof OWN_PROPS)[number]>;
16
-
17
- type DropDownChild = ListItemNode | EventControllerNode | SlotNode | ContainerSlotNode;
18
-
19
- export class DropDownNode extends WidgetNode<DropDownWidget, DropDownProps, DropDownChild> {
20
- private store = new SimpleListStore();
21
- private initialSelectedId: string | null | undefined;
22
-
23
- public override isValidChild(child: Node): boolean {
24
- return (
25
- child instanceof ListItemNode ||
26
- child instanceof EventControllerNode ||
27
- child instanceof SlotNode ||
28
- child instanceof ContainerSlotNode
29
- );
30
- }
31
-
32
- constructor(typeName: string, props: DropDownProps, container: DropDownWidget, rootContainer: Container) {
33
- super(typeName, props, container, rootContainer);
34
- this.store.beginBatch();
35
- this.initialSelectedId = props.selectedId;
36
- this.container.setModel(this.store.getModel());
37
- }
38
-
39
- public override finalizeInitialChildren(props: DropDownProps): boolean {
40
- super.finalizeInitialChildren(props);
41
- this.store.flushBatch();
42
- this.reapplyInitialSelectedId();
43
- return false;
44
- }
45
-
46
- private reapplyInitialSelectedId(): void {
47
- if (this.initialSelectedId == null) return;
48
- const index = this.store.getIndexById(this.initialSelectedId);
49
- this.initialSelectedId = undefined;
50
- if (index !== null) {
51
- this.container.setSelected(index);
52
- }
53
- }
54
-
55
- public override appendChild(child: DropDownChild): void {
56
- super.appendChild(child);
57
- if (child instanceof ListItemNode) {
58
- child.setStore(this.store);
59
- this.store.addItem(child.props.id, child.props.value as string);
60
- }
61
- }
62
-
63
- public override insertBefore(child: DropDownChild, before: DropDownChild): void {
64
- super.insertBefore(child, before);
65
- if (child instanceof ListItemNode && before instanceof ListItemNode) {
66
- child.setStore(this.store);
67
- this.store.insertItemBefore(child.props.id, before.props.id, child.props.value as string);
68
- }
69
- }
70
-
71
- public override removeChild(child: DropDownChild): void {
72
- if (child instanceof ListItemNode) {
73
- this.store.removeItem(child.props.id);
74
- }
75
- super.removeChild(child);
76
- }
77
-
78
- public override commitUpdate(oldProps: DropDownProps | null, newProps: DropDownProps): void {
79
- super.commitUpdate(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
80
- this.applyOwnProps(oldProps, newProps);
81
- }
82
-
83
- private applyOwnProps(oldProps: DropDownProps | null, newProps: DropDownProps): void {
84
- if (hasChanged(oldProps, newProps, "onSelectionChanged")) {
85
- const onSelectionChanged = newProps.onSelectionChanged;
86
-
87
- const handleSelectionChange = onSelectionChanged
88
- ? () => {
89
- const selectedIndex = this.container.getSelected();
90
- const id = this.store.getIdAtIndex(selectedIndex);
91
- if (id !== null) {
92
- onSelectionChanged(id);
93
- }
94
- }
95
- : undefined;
96
-
97
- this.signalStore.set(this, this.container, "notify::selected", handleSelectionChange);
98
- }
99
-
100
- if (hasChanged(oldProps, newProps, "selectedId")) {
101
- const index = newProps.selectedId != null ? this.store.getIndexById(newProps.selectedId) : null;
102
-
103
- if (index !== null) {
104
- this.container.setSelected(index);
105
- }
106
- }
107
- }
108
- }
@@ -1,109 +0,0 @@
1
- import type * as Gtk from "@gtkx/ffi/gtk";
2
- import type { GtkGridViewProps } from "../jsx.js";
3
- import type { Node } from "../node.js";
4
- import type { Container } from "../types.js";
5
- import { ContainerSlotNode } from "./container-slot.js";
6
- import { EventControllerNode } from "./event-controller.js";
7
- import { GridItemRenderer } from "./internal/grid-item-renderer.js";
8
- import { filterProps, hasChanged } from "./internal/props.js";
9
- import { ListItemNode } from "./list-item.js";
10
- import { GridModel, type GridModelProps } from "./models/grid.js";
11
- import { SlotNode } from "./slot.js";
12
- import { WidgetNode } from "./widget.js";
13
-
14
- const OWN_PROPS = ["renderItem", "estimatedItemHeight"] as const;
15
-
16
- type GridViewProps = Pick<GtkGridViewProps, (typeof OWN_PROPS)[number]> & GridModelProps;
17
-
18
- type GridViewChild = ListItemNode | EventControllerNode | SlotNode | ContainerSlotNode;
19
-
20
- export class GridViewNode extends WidgetNode<Gtk.GridView, GridViewProps, GridViewChild> {
21
- private itemRenderer: GridItemRenderer;
22
- private grid: GridModel;
23
-
24
- constructor(typeName: string, props: GridViewProps, container: Gtk.GridView, rootContainer: Container) {
25
- super(typeName, props, container, rootContainer);
26
- this.grid = new GridModel(
27
- { owner: this, signalStore: this.signalStore },
28
- {
29
- selectionMode: props.selectionMode,
30
- selected: props.selected,
31
- onSelectionChanged: props.onSelectionChanged,
32
- },
33
- );
34
- this.itemRenderer = new GridItemRenderer(this.signalStore);
35
- this.itemRenderer.setStore(this.grid.getStore());
36
- this.grid.getStore().setOnItemUpdated((id) => this.itemRenderer.rebindItem(id));
37
- this.container.setFactory(this.itemRenderer.getFactory());
38
- }
39
-
40
- public override isValidChild(child: Node): boolean {
41
- if (child instanceof EventControllerNode || child instanceof SlotNode || child instanceof ContainerSlotNode)
42
- return true;
43
- if (!(child instanceof ListItemNode)) return false;
44
- if (child.getChildNodes().length > 0) {
45
- throw new Error("GtkGridView does not support nested ListItems. Use GtkListView for tree lists.");
46
- }
47
- return true;
48
- }
49
-
50
- public override appendChild(child: GridViewChild): void {
51
- super.appendChild(child);
52
- if (child instanceof ListItemNode) {
53
- this.grid.appendChild(child);
54
- }
55
- }
56
-
57
- public override insertBefore(child: GridViewChild, before: GridViewChild): void {
58
- super.insertBefore(child, before);
59
- if (child instanceof ListItemNode && before instanceof ListItemNode) {
60
- this.grid.insertBefore(child, before);
61
- }
62
- }
63
-
64
- public override removeChild(child: GridViewChild): void {
65
- if (child instanceof ListItemNode) {
66
- this.grid.removeChild(child);
67
- }
68
- super.removeChild(child);
69
- }
70
-
71
- public override finalizeInitialChildren(props: GridViewProps): boolean {
72
- super.finalizeInitialChildren(props);
73
- return true;
74
- }
75
-
76
- public override commitUpdate(oldProps: GridViewProps | null, newProps: GridViewProps): void {
77
- super.commitUpdate(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
78
- this.applyOwnProps(oldProps, newProps);
79
- }
80
-
81
- public override commitMount(): void {
82
- super.commitMount();
83
- this.grid.flushBatch();
84
- this.container.setModel(this.grid.getSelectionModel());
85
- }
86
-
87
- public override detachDeletedInstance(): void {
88
- this.itemRenderer.dispose();
89
- super.detachDeletedInstance();
90
- }
91
-
92
- private applyOwnProps(oldProps: GridViewProps | null, newProps: GridViewProps): void {
93
- if (hasChanged(oldProps, newProps, "renderItem")) {
94
- this.itemRenderer.setRenderFn(newProps.renderItem ?? null);
95
- }
96
-
97
- if (hasChanged(oldProps, newProps, "estimatedItemHeight")) {
98
- this.itemRenderer.setEstimatedItemHeight(newProps.estimatedItemHeight ?? null);
99
- }
100
-
101
- const previousModel = this.grid.getSelectionModel();
102
- this.grid.updateProps(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
103
- const currentModel = this.grid.getSelectionModel();
104
-
105
- if (previousModel !== currentModel) {
106
- this.container.setModel(currentModel);
107
- }
108
- }
109
- }
@@ -1,108 +0,0 @@
1
- import * as Gtk from "@gtkx/ffi/gtk";
2
- import type { ReactNode } from "react";
3
- import type Reconciler from "react-reconciler";
4
- import { createFiberRoot } from "../../fiber-root.js";
5
- import { reconciler } from "../../reconciler.js";
6
- import type { SignalStore } from "./signal-store.js";
7
-
8
- export abstract class BaseItemRenderer<TStore = unknown> {
9
- protected factory: Gtk.SignalListItemFactory;
10
- protected fiberRoots = new Map<Gtk.ListItem, Reconciler.FiberRoot>();
11
- protected tornDown = new Set<Gtk.ListItem>();
12
- protected estimatedItemHeight: number | null = null;
13
- private store: TStore | null = null;
14
- protected signalStore: SignalStore;
15
-
16
- constructor(signalStore: SignalStore) {
17
- this.signalStore = signalStore;
18
- this.factory = new Gtk.SignalListItemFactory();
19
- this.initializeFactory();
20
- }
21
-
22
- public getFactory(): Gtk.SignalListItemFactory {
23
- return this.factory;
24
- }
25
-
26
- public setEstimatedItemHeight(height: number | null): void {
27
- this.estimatedItemHeight = height;
28
- }
29
-
30
- public setStore(store: TStore | null): void {
31
- this.store = store;
32
- }
33
-
34
- protected getStore(): TStore {
35
- if (!this.store) {
36
- throw new Error(`Expected store to be set on ${this.constructor.name}`);
37
- }
38
- return this.store;
39
- }
40
-
41
- public dispose(): void {
42
- this.signalStore.clear(this);
43
- this.fiberRoots.clear();
44
- this.tornDown.clear();
45
- }
46
-
47
- protected abstract renderItem(listItem: Gtk.ListItem): ReactNode;
48
- protected abstract onSetup(listItem: Gtk.ListItem): Gtk.Widget;
49
- protected abstract onBind(listItem: Gtk.ListItem, fiberRoot: Reconciler.FiberRoot): void;
50
- protected abstract onUnbind(listItem: Gtk.ListItem): void;
51
-
52
- protected onSetupComplete(_listItem: Gtk.ListItem): void {}
53
- protected onTeardown(_listItem: Gtk.ListItem): void {}
54
-
55
- protected createBox(): Gtk.Box {
56
- const box = new Gtk.Box(Gtk.Orientation.HORIZONTAL);
57
- box.setValign(Gtk.Align.CENTER);
58
-
59
- if (this.estimatedItemHeight !== null) {
60
- box.setSizeRequest(-1, this.estimatedItemHeight);
61
- }
62
-
63
- return box;
64
- }
65
-
66
- protected clearBoxSizeRequest(box: Gtk.Widget): void {
67
- if (box instanceof Gtk.Box) {
68
- box.setSizeRequest(-1, -1);
69
- }
70
- }
71
-
72
- private initializeFactory(): void {
73
- this.signalStore.set(this, this.factory, "setup", (listItem: Gtk.ListItem) => {
74
- const container = this.onSetup(listItem);
75
- const fiberRoot = createFiberRoot(container);
76
- this.fiberRoots.set(listItem, fiberRoot);
77
- const element = this.renderItem(listItem);
78
- reconciler.getInstance().updateContainer(element, fiberRoot, null, () => {
79
- if (this.tornDown.has(listItem)) return;
80
- this.onSetupComplete(listItem);
81
- });
82
- });
83
-
84
- this.signalStore.set(this, this.factory, "bind", (listItem: Gtk.ListItem) => {
85
- const fiberRoot = this.fiberRoots.get(listItem);
86
- if (!fiberRoot) return;
87
- this.onBind(listItem, fiberRoot);
88
- });
89
-
90
- this.signalStore.set(this, this.factory, "unbind", (listItem: Gtk.ListItem) => {
91
- this.onUnbind(listItem);
92
- });
93
-
94
- this.signalStore.set(this, this.factory, "teardown", (listItem: Gtk.ListItem) => {
95
- const fiberRoot = this.fiberRoots.get(listItem);
96
-
97
- if (fiberRoot) {
98
- this.tornDown.add(listItem);
99
- this.onTeardown(listItem);
100
- reconciler.getInstance().updateContainer(null, fiberRoot, null, () => {});
101
- queueMicrotask(() => {
102
- this.fiberRoots.delete(listItem);
103
- this.tornDown.delete(listItem);
104
- });
105
- }
106
- });
107
- }
108
- }
@@ -1,78 +0,0 @@
1
- import * as Gtk from "@gtkx/ffi/gtk";
2
- import type { ReactNode } from "react";
3
- import type Reconciler from "react-reconciler";
4
- import { reconciler } from "../../reconciler.js";
5
- import { BaseItemRenderer } from "./base-item-renderer.js";
6
- import type { ListStore } from "./list-store.js";
7
-
8
- type GridRenderItemFn<T> = (item: T | null) => ReactNode;
9
-
10
- export class GridItemRenderer extends BaseItemRenderer<ListStore> {
11
- private renderFn: GridRenderItemFn<unknown> | null = () => null;
12
- private boundItems = new Map<string, Gtk.ListItem>();
13
-
14
- public setRenderFn(renderFn: GridRenderItemFn<unknown> | null): void {
15
- this.renderFn = renderFn;
16
- this.rebindAllItems();
17
- }
18
-
19
- public rebindAllItems(): void {
20
- for (const id of this.boundItems.keys()) {
21
- this.rebindItem(id);
22
- }
23
- }
24
-
25
- public rebindItem(id: string): void {
26
- const listItem = this.boundItems.get(id);
27
- if (!listItem) return;
28
-
29
- const fiberRoot = this.fiberRoots.get(listItem);
30
- if (!fiberRoot) return;
31
-
32
- const item = this.getStore().getItem(id);
33
- const element = this.renderFn?.(item);
34
-
35
- reconciler.getInstance().updateContainer(element, fiberRoot, null, () => {});
36
- }
37
-
38
- protected override renderItem(_listItem: Gtk.ListItem): ReactNode {
39
- return this.renderFn?.(null);
40
- }
41
-
42
- private getItemFromListItem(listItem: Gtk.ListItem): string | null {
43
- const stringObject = listItem.getItem();
44
- if (!(stringObject instanceof Gtk.StringObject)) return null;
45
- return stringObject.getString();
46
- }
47
-
48
- protected override onSetup(listItem: Gtk.ListItem): Gtk.Widget {
49
- const box = this.createBox();
50
- listItem.setChild(box);
51
- return box;
52
- }
53
-
54
- protected override onBind(listItem: Gtk.ListItem, fiberRoot: Reconciler.FiberRoot): void {
55
- const id = this.getItemFromListItem(listItem);
56
- if (id !== null) {
57
- this.boundItems.set(id, listItem);
58
- }
59
-
60
- const item = id !== null ? this.getStore().getItem(id) : null;
61
- const element = this.renderFn?.(item);
62
-
63
- reconciler.getInstance().updateContainer(element, fiberRoot, null, () => {
64
- if (this.tornDown.has(listItem)) return;
65
- if (this.estimatedItemHeight !== null) return;
66
- const currentFiberRoot = this.fiberRoots.get(listItem);
67
- if (!currentFiberRoot) return;
68
- this.clearBoxSizeRequest(currentFiberRoot.containerInfo);
69
- });
70
- }
71
-
72
- protected override onUnbind(listItem: Gtk.ListItem): void {
73
- const id = this.getItemFromListItem(listItem);
74
- if (id !== null) {
75
- this.boundItems.delete(id);
76
- }
77
- }
78
- }