@gtkx/react 0.19.0 → 0.21.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 (289) hide show
  1. package/README.md +26 -62
  2. package/dist/components/compound.d.ts +40 -0
  3. package/dist/components/compound.d.ts.map +1 -0
  4. package/dist/components/compound.js +46 -0
  5. package/dist/components/compound.js.map +1 -0
  6. package/dist/components/list.d.ts +75 -0
  7. package/dist/components/list.d.ts.map +1 -0
  8. package/dist/components/list.js +81 -0
  9. package/dist/components/list.js.map +1 -0
  10. package/dist/components/slot-widget.d.ts +15 -0
  11. package/dist/components/slot-widget.d.ts.map +1 -0
  12. package/dist/components/slot-widget.js +37 -0
  13. package/dist/components/slot-widget.js.map +1 -0
  14. package/dist/errors.d.ts +6 -0
  15. package/dist/errors.d.ts.map +1 -1
  16. package/dist/errors.js +8 -6
  17. package/dist/errors.js.map +1 -1
  18. package/dist/generated/compounds.d.ts +2672 -0
  19. package/dist/generated/compounds.d.ts.map +1 -0
  20. package/dist/generated/compounds.js +2624 -0
  21. package/dist/generated/compounds.js.map +1 -0
  22. package/dist/generated/internal.d.ts +6 -7
  23. package/dist/generated/internal.d.ts.map +1 -1
  24. package/dist/generated/internal.js +3054 -1838
  25. package/dist/generated/internal.js.map +1 -1
  26. package/dist/generated/jsx.d.ts +2096 -4970
  27. package/dist/generated/jsx.d.ts.map +1 -1
  28. package/dist/generated/jsx.js +979 -3862
  29. package/dist/generated/jsx.js.map +1 -1
  30. package/dist/generated/registry.d.ts +1 -0
  31. package/dist/generated/registry.d.ts.map +1 -1
  32. package/dist/generated/registry.js +0 -1
  33. package/dist/generated/registry.js.map +1 -1
  34. package/dist/host-config.d.ts.map +1 -1
  35. package/dist/host-config.js +2 -0
  36. package/dist/host-config.js.map +1 -1
  37. package/dist/index.d.ts +2 -0
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +2 -0
  40. package/dist/index.js.map +1 -1
  41. package/dist/jsx.d.ts +157 -518
  42. package/dist/jsx.d.ts.map +1 -1
  43. package/dist/jsx.js +6 -393
  44. package/dist/jsx.js.map +1 -1
  45. package/dist/metadata.d.ts +1 -1
  46. package/dist/metadata.d.ts.map +1 -1
  47. package/dist/metadata.js +7 -3
  48. package/dist/metadata.js.map +1 -1
  49. package/dist/node.d.ts +0 -4
  50. package/dist/node.d.ts.map +1 -1
  51. package/dist/node.js +19 -41
  52. package/dist/node.js.map +1 -1
  53. package/dist/nodes/alert-dialog.d.ts +14 -0
  54. package/dist/nodes/alert-dialog.d.ts.map +1 -0
  55. package/dist/nodes/alert-dialog.js +41 -0
  56. package/dist/nodes/alert-dialog.js.map +1 -0
  57. package/dist/nodes/animation.d.ts +5 -4
  58. package/dist/nodes/animation.d.ts.map +1 -1
  59. package/dist/nodes/animation.js +65 -49
  60. package/dist/nodes/animation.js.map +1 -1
  61. package/dist/nodes/application.d.ts.map +1 -1
  62. package/dist/nodes/application.js +4 -0
  63. package/dist/nodes/application.js.map +1 -1
  64. package/dist/nodes/column-view-column.d.ts +19 -19
  65. package/dist/nodes/column-view-column.d.ts.map +1 -1
  66. package/dist/nodes/column-view-column.js +130 -119
  67. package/dist/nodes/column-view-column.js.map +1 -1
  68. package/dist/nodes/container-slot.d.ts +3 -1
  69. package/dist/nodes/container-slot.d.ts.map +1 -1
  70. package/dist/nodes/container-slot.js +28 -16
  71. package/dist/nodes/container-slot.js.map +1 -1
  72. package/dist/nodes/drawing-area.d.ts +3 -1
  73. package/dist/nodes/drawing-area.d.ts.map +1 -1
  74. package/dist/nodes/drawing-area.js +20 -22
  75. package/dist/nodes/drawing-area.js.map +1 -1
  76. package/dist/nodes/event-controller.d.ts.map +1 -1
  77. package/dist/nodes/event-controller.js +6 -16
  78. package/dist/nodes/event-controller.js.map +1 -1
  79. package/dist/nodes/fixed-child.d.ts +1 -0
  80. package/dist/nodes/fixed-child.d.ts.map +1 -1
  81. package/dist/nodes/fixed-child.js +13 -0
  82. package/dist/nodes/fixed-child.js.map +1 -1
  83. package/dist/nodes/grid-child.d.ts +1 -0
  84. package/dist/nodes/grid-child.d.ts.map +1 -1
  85. package/dist/nodes/grid-child.js +13 -0
  86. package/dist/nodes/grid-child.js.map +1 -1
  87. package/dist/nodes/internal/accessible.d.ts.map +1 -1
  88. package/dist/nodes/internal/accessible.js.map +1 -1
  89. package/dist/nodes/internal/bound-item.d.ts +4 -0
  90. package/dist/nodes/internal/bound-item.d.ts.map +1 -0
  91. package/dist/nodes/internal/bound-item.js +2 -0
  92. package/dist/nodes/internal/bound-item.js.map +1 -0
  93. package/dist/nodes/internal/construct.d.ts +1 -8
  94. package/dist/nodes/internal/construct.d.ts.map +1 -1
  95. package/dist/nodes/internal/construct.js +30 -54
  96. package/dist/nodes/internal/construct.js.map +1 -1
  97. package/dist/nodes/internal/widget.d.ts.map +1 -1
  98. package/dist/nodes/internal/widget.js +9 -10
  99. package/dist/nodes/internal/widget.js.map +1 -1
  100. package/dist/nodes/list-item-node.d.ts +12 -0
  101. package/dist/nodes/list-item-node.d.ts.map +1 -0
  102. package/dist/nodes/list-item-node.js +45 -0
  103. package/dist/nodes/list-item-node.js.map +1 -0
  104. package/dist/nodes/list.d.ts +100 -0
  105. package/dist/nodes/list.d.ts.map +1 -0
  106. package/dist/nodes/list.js +950 -0
  107. package/dist/nodes/list.js.map +1 -0
  108. package/dist/nodes/notebook-page.d.ts.map +1 -1
  109. package/dist/nodes/notebook-page.js +6 -2
  110. package/dist/nodes/notebook-page.js.map +1 -1
  111. package/dist/nodes/overlay-child.d.ts +2 -0
  112. package/dist/nodes/overlay-child.d.ts.map +1 -1
  113. package/dist/nodes/overlay-child.js +29 -8
  114. package/dist/nodes/overlay-child.js.map +1 -1
  115. package/dist/nodes/spin-row.d.ts +14 -0
  116. package/dist/nodes/spin-row.d.ts.map +1 -0
  117. package/dist/nodes/spin-row.js +46 -0
  118. package/dist/nodes/spin-row.js.map +1 -0
  119. package/dist/nodes/switch-row.d.ts +11 -0
  120. package/dist/nodes/switch-row.d.ts.map +1 -0
  121. package/dist/nodes/switch-row.js +15 -0
  122. package/dist/nodes/switch-row.js.map +1 -0
  123. package/dist/nodes/text-anchor.d.ts.map +1 -1
  124. package/dist/nodes/text-anchor.js +10 -0
  125. package/dist/nodes/text-anchor.js.map +1 -1
  126. package/dist/nodes/text-tag.d.ts.map +1 -1
  127. package/dist/nodes/text-tag.js +45 -39
  128. package/dist/nodes/text-tag.js.map +1 -1
  129. package/dist/nodes/toggle-group.d.ts +12 -6
  130. package/dist/nodes/toggle-group.d.ts.map +1 -1
  131. package/dist/nodes/toggle-group.js +53 -4
  132. package/dist/nodes/toggle-group.js.map +1 -1
  133. package/dist/nodes/widget.d.ts.map +1 -1
  134. package/dist/nodes/widget.js +16 -22
  135. package/dist/nodes/widget.js.map +1 -1
  136. package/dist/nodes/window.d.ts.map +1 -1
  137. package/dist/nodes/window.js +2 -2
  138. package/dist/nodes/window.js.map +1 -1
  139. package/dist/registry.d.ts +0 -2
  140. package/dist/registry.d.ts.map +1 -1
  141. package/dist/registry.js +11 -18
  142. package/dist/registry.js.map +1 -1
  143. package/dist/types.d.ts +3 -2
  144. package/dist/types.d.ts.map +1 -1
  145. package/dist/use-property.d.ts +29 -0
  146. package/dist/use-property.d.ts.map +1 -0
  147. package/dist/use-property.js +44 -0
  148. package/dist/use-property.js.map +1 -0
  149. package/dist/use-setting.d.ts +36 -0
  150. package/dist/use-setting.d.ts.map +1 -0
  151. package/dist/use-setting.js +68 -0
  152. package/dist/use-setting.js.map +1 -0
  153. package/package.json +5 -4
  154. package/src/components/compound.tsx +57 -0
  155. package/src/components/list.tsx +140 -0
  156. package/src/components/slot-widget.tsx +46 -0
  157. package/src/errors.ts +8 -7
  158. package/src/generated/compounds.ts +2741 -0
  159. package/src/generated/internal.ts +3059 -1840
  160. package/src/generated/jsx.ts +2509 -5350
  161. package/src/generated/registry.ts +2 -1
  162. package/src/host-config.ts +2 -0
  163. package/src/index.ts +2 -0
  164. package/src/jsx.ts +167 -581
  165. package/src/metadata.ts +7 -4
  166. package/src/node.ts +23 -39
  167. package/src/nodes/alert-dialog.ts +55 -0
  168. package/src/nodes/animation.ts +67 -60
  169. package/src/nodes/application.ts +5 -0
  170. package/src/nodes/column-view-column.ts +125 -128
  171. package/src/nodes/container-slot.ts +30 -17
  172. package/src/nodes/drawing-area.ts +23 -32
  173. package/src/nodes/event-controller.ts +6 -18
  174. package/src/nodes/fixed-child.ts +13 -0
  175. package/src/nodes/grid-child.ts +13 -0
  176. package/src/nodes/internal/accessible.ts +0 -1
  177. package/src/nodes/internal/bound-item.ts +4 -0
  178. package/src/nodes/internal/construct.ts +38 -68
  179. package/src/nodes/internal/widget.ts +9 -13
  180. package/src/nodes/list-item-node.ts +53 -0
  181. package/src/nodes/list.ts +1082 -0
  182. package/src/nodes/notebook-page.ts +6 -2
  183. package/src/nodes/overlay-child.ts +30 -9
  184. package/src/nodes/spin-row.ts +72 -0
  185. package/src/nodes/switch-row.ts +26 -0
  186. package/src/nodes/text-anchor.ts +9 -0
  187. package/src/nodes/text-tag.ts +45 -40
  188. package/src/nodes/toggle-group.ts +63 -9
  189. package/src/nodes/widget.ts +14 -26
  190. package/src/nodes/window.ts +2 -2
  191. package/src/registry.ts +18 -24
  192. package/src/types.ts +8 -2
  193. package/src/use-property.ts +58 -0
  194. package/src/use-setting.ts +96 -0
  195. package/dist/fiber-root.d.ts +0 -4
  196. package/dist/fiber-root.d.ts.map +0 -1
  197. package/dist/fiber-root.js +0 -6
  198. package/dist/fiber-root.js.map +0 -1
  199. package/dist/nodes/column-view.d.ts +0 -37
  200. package/dist/nodes/column-view.d.ts.map +0 -1
  201. package/dist/nodes/column-view.js +0 -205
  202. package/dist/nodes/column-view.js.map +0 -1
  203. package/dist/nodes/drop-down.d.ts +0 -37
  204. package/dist/nodes/drop-down.d.ts.map +0 -1
  205. package/dist/nodes/drop-down.js +0 -231
  206. package/dist/nodes/drop-down.js.map +0 -1
  207. package/dist/nodes/grid-view.d.ts +0 -30
  208. package/dist/nodes/grid-view.d.ts.map +0 -1
  209. package/dist/nodes/grid-view.js +0 -90
  210. package/dist/nodes/grid-view.js.map +0 -1
  211. package/dist/nodes/internal/base-item-renderer.d.ts +0 -28
  212. package/dist/nodes/internal/base-item-renderer.d.ts.map +0 -1
  213. package/dist/nodes/internal/base-item-renderer.js +0 -85
  214. package/dist/nodes/internal/base-item-renderer.js.map +0 -1
  215. package/dist/nodes/internal/grid-item-renderer.d.ts +0 -20
  216. package/dist/nodes/internal/grid-item-renderer.d.ts.map +0 -1
  217. package/dist/nodes/internal/grid-item-renderer.js +0 -66
  218. package/dist/nodes/internal/grid-item-renderer.js.map +0 -1
  219. package/dist/nodes/internal/header-item-renderer.d.ts +0 -23
  220. package/dist/nodes/internal/header-item-renderer.d.ts.map +0 -1
  221. package/dist/nodes/internal/header-item-renderer.js +0 -87
  222. package/dist/nodes/internal/header-item-renderer.js.map +0 -1
  223. package/dist/nodes/internal/header-renderer-manager.d.ts +0 -13
  224. package/dist/nodes/internal/header-renderer-manager.d.ts.map +0 -1
  225. package/dist/nodes/internal/header-renderer-manager.js +0 -20
  226. package/dist/nodes/internal/header-renderer-manager.js.map +0 -1
  227. package/dist/nodes/internal/list-item-renderer.d.ts +0 -27
  228. package/dist/nodes/internal/list-item-renderer.d.ts.map +0 -1
  229. package/dist/nodes/internal/list-item-renderer.js +0 -131
  230. package/dist/nodes/internal/list-item-renderer.js.map +0 -1
  231. package/dist/nodes/internal/list-store.d.ts +0 -21
  232. package/dist/nodes/internal/list-store.d.ts.map +0 -1
  233. package/dist/nodes/internal/list-store.js +0 -90
  234. package/dist/nodes/internal/list-store.js.map +0 -1
  235. package/dist/nodes/internal/sectioned-list-store.d.ts +0 -50
  236. package/dist/nodes/internal/sectioned-list-store.d.ts.map +0 -1
  237. package/dist/nodes/internal/sectioned-list-store.js +0 -250
  238. package/dist/nodes/internal/sectioned-list-store.js.map +0 -1
  239. package/dist/nodes/internal/selection-helpers.d.ts +0 -12
  240. package/dist/nodes/internal/selection-helpers.d.ts.map +0 -1
  241. package/dist/nodes/internal/selection-helpers.js +0 -25
  242. package/dist/nodes/internal/selection-helpers.js.map +0 -1
  243. package/dist/nodes/internal/selection-model-controller.d.ts +0 -26
  244. package/dist/nodes/internal/selection-model-controller.d.ts.map +0 -1
  245. package/dist/nodes/internal/selection-model-controller.js +0 -82
  246. package/dist/nodes/internal/selection-model-controller.js.map +0 -1
  247. package/dist/nodes/internal/simple-list-store.d.ts +0 -15
  248. package/dist/nodes/internal/simple-list-store.d.ts.map +0 -1
  249. package/dist/nodes/internal/simple-list-store.js +0 -110
  250. package/dist/nodes/internal/simple-list-store.js.map +0 -1
  251. package/dist/nodes/internal/tree-store.d.ts +0 -37
  252. package/dist/nodes/internal/tree-store.d.ts.map +0 -1
  253. package/dist/nodes/internal/tree-store.js +0 -253
  254. package/dist/nodes/internal/tree-store.js.map +0 -1
  255. package/dist/nodes/list-item.d.ts +0 -24
  256. package/dist/nodes/list-item.d.ts.map +0 -1
  257. package/dist/nodes/list-item.js +0 -83
  258. package/dist/nodes/list-item.js.map +0 -1
  259. package/dist/nodes/list-section.d.ts +0 -27
  260. package/dist/nodes/list-section.d.ts.map +0 -1
  261. package/dist/nodes/list-section.js +0 -43
  262. package/dist/nodes/list-section.js.map +0 -1
  263. package/dist/nodes/list-view.d.ts +0 -32
  264. package/dist/nodes/list-view.d.ts.map +0 -1
  265. package/dist/nodes/list-view.js +0 -123
  266. package/dist/nodes/list-view.js.map +0 -1
  267. package/dist/nodes/models/list.d.ts +0 -39
  268. package/dist/nodes/models/list.d.ts.map +0 -1
  269. package/dist/nodes/models/list.js +0 -207
  270. package/dist/nodes/models/list.js.map +0 -1
  271. package/src/fiber-root.ts +0 -20
  272. package/src/nodes/column-view.ts +0 -262
  273. package/src/nodes/drop-down.ts +0 -284
  274. package/src/nodes/grid-view.ts +0 -119
  275. package/src/nodes/internal/base-item-renderer.ts +0 -107
  276. package/src/nodes/internal/grid-item-renderer.ts +0 -78
  277. package/src/nodes/internal/header-item-renderer.ts +0 -105
  278. package/src/nodes/internal/header-renderer-manager.ts +0 -33
  279. package/src/nodes/internal/list-item-renderer.ts +0 -162
  280. package/src/nodes/internal/list-store.ts +0 -107
  281. package/src/nodes/internal/sectioned-list-store.ts +0 -287
  282. package/src/nodes/internal/selection-helpers.ts +0 -35
  283. package/src/nodes/internal/selection-model-controller.ts +0 -119
  284. package/src/nodes/internal/simple-list-store.ts +0 -116
  285. package/src/nodes/internal/tree-store.ts +0 -289
  286. package/src/nodes/list-item.ts +0 -107
  287. package/src/nodes/list-section.ts +0 -64
  288. package/src/nodes/list-view.ts +0 -164
  289. package/src/nodes/models/list.ts +0 -250
@@ -0,0 +1,950 @@
1
+ import { getNativeId } from "@gtkx/ffi";
2
+ import * as Adw from "@gtkx/ffi/adw";
3
+ import * as Gio from "@gtkx/ffi/gio";
4
+ import * as Gtk from "@gtkx/ffi/gtk";
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 { SlotNode } from "./slot.js";
10
+ import { WidgetNode } from "./widget.js";
11
+ const OWN_PROPS = [
12
+ "items",
13
+ "renderItem",
14
+ "renderListItem",
15
+ "renderHeader",
16
+ "renderCell",
17
+ "autoexpand",
18
+ "selected",
19
+ "onSelectionChanged",
20
+ "selectionMode",
21
+ "selectedId",
22
+ "sortColumn",
23
+ "sortOrder",
24
+ "onSortChanged",
25
+ "estimatedItemHeight",
26
+ "estimatedItemWidth",
27
+ "estimatedRowHeight",
28
+ "__boundItemsRef",
29
+ "__rerender",
30
+ "__headerBoundItemsRef",
31
+ ];
32
+ const UNBOUND_POSITION = -1;
33
+ function resizeStringList(model, newSize) {
34
+ const oldSize = model.getNItems();
35
+ if (newSize > oldSize) {
36
+ model.splice(oldSize, 0, new Array(newSize - oldSize).fill(""));
37
+ }
38
+ else if (newSize < oldSize) {
39
+ model.splice(newSize, oldSize - newSize, []);
40
+ }
41
+ }
42
+ export class ListNode extends WidgetNode {
43
+ model = null;
44
+ selectionModel = null;
45
+ treeModel = null;
46
+ factory = null;
47
+ headerFactory = null;
48
+ listFactory = null;
49
+ containers = new Map();
50
+ containerKeys = new Map();
51
+ headerContainers = new Map();
52
+ headerContainerKeys = new Map();
53
+ listContainers = new Map();
54
+ listContainerKeys = new Map();
55
+ treeExpanders = new Map();
56
+ disposed = false;
57
+ boundItemsUpdateScheduled = false;
58
+ syncScheduled = false;
59
+ sectionModels = [];
60
+ sectionStore = null;
61
+ flattenModel = null;
62
+ treeChildModels = new Map();
63
+ queriedLeaves = new Set();
64
+ rootItemIds = [];
65
+ isValidChild(child) {
66
+ return (child instanceof ColumnViewColumnNode ||
67
+ child instanceof EventControllerNode ||
68
+ child instanceof SlotNode ||
69
+ child instanceof ContainerSlotNode);
70
+ }
71
+ appendChild(child) {
72
+ const isMove = child instanceof ColumnViewColumnNode && this.children.includes(child);
73
+ super.appendChild(child);
74
+ if (child instanceof ColumnViewColumnNode) {
75
+ const columnView = this.container;
76
+ if (isMove) {
77
+ columnView.removeColumn(child.getColumn());
78
+ }
79
+ else {
80
+ child.installActionGroup(columnView);
81
+ }
82
+ columnView.appendColumn(child.getColumn());
83
+ }
84
+ }
85
+ removeChild(child) {
86
+ if (child instanceof ColumnViewColumnNode) {
87
+ const columnView = this.container;
88
+ columnView.removeColumn(child.getColumn());
89
+ child.uninstallActionGroup(columnView);
90
+ }
91
+ super.removeChild(child);
92
+ }
93
+ insertBefore(child, before) {
94
+ const isMove = child instanceof ColumnViewColumnNode && this.children.includes(child);
95
+ super.insertBefore(child, before);
96
+ if (child instanceof ColumnViewColumnNode) {
97
+ const columnView = this.container;
98
+ if (isMove) {
99
+ columnView.removeColumn(child.getColumn());
100
+ }
101
+ else {
102
+ child.installActionGroup(columnView);
103
+ }
104
+ const position = this.getColumnPosition(child);
105
+ columnView.insertColumn(position, child.getColumn());
106
+ }
107
+ }
108
+ finalizeInitialChildren(props) {
109
+ this.commitUpdate(null, props);
110
+ this.setupModel();
111
+ this.setupFactory();
112
+ if (this.props.renderHeader && !this.isDropDown()) {
113
+ this.setupHeaderFactory();
114
+ }
115
+ this.setupSelectionModel(props);
116
+ this.assignModelToWidget();
117
+ this.assignFactoryToWidget();
118
+ this.syncModel();
119
+ return true;
120
+ }
121
+ commitUpdate(oldProps, newProps) {
122
+ super.commitUpdate(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
123
+ this.props = newProps;
124
+ if (oldProps === null)
125
+ return;
126
+ this.applyOwnProps(oldProps, newProps);
127
+ }
128
+ commitMount() {
129
+ this.connectSelectionSignal();
130
+ this.connectSortSignal();
131
+ this.applySelection(this.props.selected ?? null);
132
+ this.applySelectedId(this.props.selectedId ?? null);
133
+ }
134
+ detachDeletedInstance() {
135
+ this.disposed = true;
136
+ this.treeChildModels.clear();
137
+ this.queriedLeaves.clear();
138
+ this.treeExpanders.clear();
139
+ this.rootItemIds = [];
140
+ super.detachDeletedInstance();
141
+ }
142
+ getItems() {
143
+ return this.props.items ?? [];
144
+ }
145
+ collectFlatItems() {
146
+ const items = this.getItems();
147
+ const flat = [];
148
+ for (const item of items) {
149
+ if (item.section && item.children) {
150
+ for (const child of item.children) {
151
+ flat.push(child);
152
+ }
153
+ }
154
+ else {
155
+ flat.push(item);
156
+ }
157
+ }
158
+ return flat;
159
+ }
160
+ collectSections() {
161
+ const items = this.getItems();
162
+ const sections = [];
163
+ for (const item of items) {
164
+ if (item.section) {
165
+ sections.push(item);
166
+ }
167
+ }
168
+ return sections;
169
+ }
170
+ collectRootItems() {
171
+ return this.getItems().filter((item) => !item.section);
172
+ }
173
+ isDropDown() {
174
+ return this.container instanceof Gtk.DropDown || this.container instanceof Adw.ComboRow;
175
+ }
176
+ isColumnView() {
177
+ return this.container instanceof Gtk.ColumnView;
178
+ }
179
+ detectMode() {
180
+ const items = this.getItems();
181
+ for (const item of items) {
182
+ if (item.section)
183
+ return "sections";
184
+ if (item.children && item.children.length > 0)
185
+ return "tree";
186
+ }
187
+ return "flat";
188
+ }
189
+ hasSections() {
190
+ return this.getItems().some((item) => item.section);
191
+ }
192
+ isTreeMode() {
193
+ const items = this.getItems();
194
+ for (const item of items) {
195
+ if (!item.section && item.children && item.children.length > 0)
196
+ return true;
197
+ }
198
+ return false;
199
+ }
200
+ setupModel() {
201
+ this.model = new Gtk.StringList();
202
+ }
203
+ setupFactory() {
204
+ if (this.isColumnView())
205
+ return;
206
+ this.factory = new Gtk.SignalListItemFactory();
207
+ const isTree = this.isTreeMode();
208
+ this.factory.connect("setup", (_self, obj) => {
209
+ const listItem = obj;
210
+ if (isTree) {
211
+ const expander = new Gtk.TreeExpander();
212
+ listItem.setChild(expander);
213
+ this.containers.set(expander, UNBOUND_POSITION);
214
+ this.containerKeys.set(expander, String(getNativeId(expander.handle)));
215
+ this.treeExpanders.set(listItem, expander);
216
+ }
217
+ else {
218
+ const { width, height } = this.getEstimatedItemSize();
219
+ if (width !== -1 || height !== -1) {
220
+ const placeholder = new Gtk.Box();
221
+ placeholder.setSizeRequest(width, height);
222
+ listItem.setChild(placeholder);
223
+ }
224
+ this.containers.set(listItem, UNBOUND_POSITION);
225
+ this.containerKeys.set(listItem, String(getNativeId(listItem.handle)));
226
+ }
227
+ });
228
+ this.factory.connect("bind", (_self, obj) => {
229
+ if (this.disposed)
230
+ return;
231
+ const listItem = obj;
232
+ const position = listItem.getPosition();
233
+ if (isTree) {
234
+ const expander = this.treeExpanders.get(listItem);
235
+ const row = listItem.getItem();
236
+ expander.setListRow(row);
237
+ this.applyEstimatedItemSize(expander);
238
+ const treeItem = this.resolveTreeItem(row);
239
+ if (treeItem) {
240
+ this.applyTreeExpanderProps(expander, treeItem);
241
+ }
242
+ this.containers.set(expander, position);
243
+ }
244
+ else {
245
+ this.containers.set(listItem, position);
246
+ }
247
+ this.scheduleBoundItemsUpdate();
248
+ });
249
+ this.factory.connect("unbind", (_self, obj) => {
250
+ if (this.disposed)
251
+ return;
252
+ const listItem = obj;
253
+ if (isTree) {
254
+ const expander = this.treeExpanders.get(listItem);
255
+ this.containers.set(expander, UNBOUND_POSITION);
256
+ expander.setListRow(null);
257
+ }
258
+ else {
259
+ this.containers.set(listItem, UNBOUND_POSITION);
260
+ }
261
+ this.scheduleBoundItemsUpdate();
262
+ });
263
+ this.factory.connect("teardown", (_self, obj) => {
264
+ if (this.disposed)
265
+ return;
266
+ const listItem = obj;
267
+ if (isTree) {
268
+ const expander = this.treeExpanders.get(listItem);
269
+ if (expander) {
270
+ this.containers.delete(expander);
271
+ this.containerKeys.delete(expander);
272
+ }
273
+ this.treeExpanders.delete(listItem);
274
+ }
275
+ else {
276
+ this.containers.delete(listItem);
277
+ this.containerKeys.delete(listItem);
278
+ }
279
+ listItem.setChild(null);
280
+ });
281
+ if (this.props.renderListItem && this.isDropDown()) {
282
+ this.setupListFactory();
283
+ }
284
+ }
285
+ setupListFactory() {
286
+ this.listFactory = new Gtk.SignalListItemFactory();
287
+ this.listFactory.connect("setup", (_self, obj) => {
288
+ const listItem = obj;
289
+ this.listContainers.set(listItem, UNBOUND_POSITION);
290
+ this.listContainerKeys.set(listItem, String(getNativeId(listItem.handle)));
291
+ });
292
+ this.listFactory.connect("bind", (_self, obj) => {
293
+ const listItem = obj;
294
+ this.listContainers.set(listItem, listItem.getPosition());
295
+ this.scheduleBoundItemsUpdate();
296
+ });
297
+ this.listFactory.connect("unbind", (_self, obj) => {
298
+ const listItem = obj;
299
+ this.listContainers.set(listItem, UNBOUND_POSITION);
300
+ this.scheduleBoundItemsUpdate();
301
+ });
302
+ this.listFactory.connect("teardown", (_self, obj) => {
303
+ const listItem = obj;
304
+ this.listContainers.delete(listItem);
305
+ this.listContainerKeys.delete(listItem);
306
+ listItem.setChild(null);
307
+ });
308
+ }
309
+ setupHeaderFactory() {
310
+ this.headerFactory = new Gtk.SignalListItemFactory();
311
+ this.headerFactory.connect("setup", (_self, obj) => {
312
+ const listHeader = obj;
313
+ this.headerContainers.set(listHeader, UNBOUND_POSITION);
314
+ this.headerContainerKeys.set(listHeader, String(getNativeId(listHeader.handle)));
315
+ });
316
+ this.headerFactory.connect("bind", (_self, obj) => {
317
+ const listHeader = obj;
318
+ this.headerContainers.set(listHeader, listHeader.getStart());
319
+ this.scheduleBoundItemsUpdate();
320
+ });
321
+ this.headerFactory.connect("unbind", (_self, obj) => {
322
+ const listHeader = obj;
323
+ this.headerContainers.set(listHeader, UNBOUND_POSITION);
324
+ this.scheduleBoundItemsUpdate();
325
+ });
326
+ this.headerFactory.connect("teardown", (_self, obj) => {
327
+ const listHeader = obj;
328
+ this.headerContainers.delete(listHeader);
329
+ this.headerContainerKeys.delete(listHeader);
330
+ listHeader.setChild(null);
331
+ });
332
+ }
333
+ setupSelectionModel(props) {
334
+ const baseModel = this.getBaseModel();
335
+ const selectionMode = props.selectionMode ?? (this.isDropDown() ? null : Gtk.SelectionMode.SINGLE);
336
+ if (this.isDropDown()) {
337
+ this.selectionModel = null;
338
+ return;
339
+ }
340
+ if (selectionMode === Gtk.SelectionMode.MULTIPLE) {
341
+ this.selectionModel = new Gtk.MultiSelection(baseModel);
342
+ }
343
+ else if (selectionMode === Gtk.SelectionMode.NONE) {
344
+ this.selectionModel = new Gtk.NoSelection(baseModel);
345
+ }
346
+ else {
347
+ const sel = new Gtk.SingleSelection(baseModel);
348
+ sel.setAutoselect(false);
349
+ sel.setCanUnselect(true);
350
+ this.selectionModel = sel;
351
+ }
352
+ }
353
+ getBaseModel() {
354
+ if (this.treeModel)
355
+ return this.treeModel;
356
+ if (this.flattenModel)
357
+ return this.flattenModel;
358
+ return this.model;
359
+ }
360
+ assignModelToWidget() {
361
+ const widget = this.container;
362
+ if (this.isDropDown()) {
363
+ const dropDownModel = this.hasSections()
364
+ ? this.flattenModel
365
+ : this.model;
366
+ if (widget instanceof Gtk.DropDown) {
367
+ widget.setModel(dropDownModel);
368
+ }
369
+ else if (widget instanceof Adw.ComboRow) {
370
+ widget.setModel(dropDownModel);
371
+ }
372
+ return;
373
+ }
374
+ if (!this.selectionModel)
375
+ return;
376
+ if (widget instanceof Gtk.ListView) {
377
+ widget.setModel(this.selectionModel);
378
+ }
379
+ else if (widget instanceof Gtk.GridView) {
380
+ widget.setModel(this.selectionModel);
381
+ }
382
+ else if (widget instanceof Gtk.ColumnView) {
383
+ widget.setModel(this.selectionModel);
384
+ }
385
+ }
386
+ assignFactoryToWidget() {
387
+ const widget = this.container;
388
+ if (widget instanceof Gtk.ListView) {
389
+ widget.setFactory(this.factory);
390
+ if (this.headerFactory) {
391
+ widget.setHeaderFactory(this.headerFactory);
392
+ }
393
+ }
394
+ else if (widget instanceof Gtk.ColumnView) {
395
+ if (this.headerFactory) {
396
+ widget.setHeaderFactory(this.headerFactory);
397
+ }
398
+ }
399
+ else if (widget instanceof Gtk.GridView) {
400
+ widget.setFactory(this.factory);
401
+ }
402
+ else if (widget instanceof Gtk.DropDown) {
403
+ widget.setFactory(this.factory);
404
+ if (this.listFactory) {
405
+ widget.setListFactory(this.listFactory);
406
+ }
407
+ if (this.headerFactory) {
408
+ widget.setHeaderFactory(this.headerFactory);
409
+ }
410
+ }
411
+ else if (widget instanceof Adw.ComboRow) {
412
+ widget.setFactory(this.factory);
413
+ if (this.listFactory) {
414
+ widget.setListFactory(this.listFactory);
415
+ }
416
+ if (this.headerFactory) {
417
+ widget.setHeaderFactory(this.headerFactory);
418
+ }
419
+ }
420
+ }
421
+ syncModel() {
422
+ if (!this.model)
423
+ return;
424
+ const mode = this.detectMode();
425
+ if (mode === "sections") {
426
+ this.syncSectionModel();
427
+ return;
428
+ }
429
+ if (mode === "tree") {
430
+ this.syncTreeModel();
431
+ return;
432
+ }
433
+ const flatItems = this.collectFlatItems();
434
+ resizeStringList(this.model, flatItems.length);
435
+ this.scheduleBoundItemsUpdate();
436
+ }
437
+ syncTreeModel() {
438
+ if (!this.model)
439
+ return;
440
+ const rootItems = this.collectRootItems();
441
+ const newSize = rootItems.length;
442
+ if (!this.treeModel) {
443
+ this.model.splice(0, this.model.getNItems(), new Array(newSize).fill(""));
444
+ this.rootItemIds = rootItems.map((item) => item.id);
445
+ this.treeModel = new Gtk.TreeListModel(this.model, false, this.props.autoexpand ?? false, (_item) => this.createChildModel(_item));
446
+ if (this.selectionModel) {
447
+ if (this.selectionModel instanceof Gtk.SingleSelection) {
448
+ this.selectionModel.setModel(this.treeModel);
449
+ }
450
+ else if (this.selectionModel instanceof Gtk.MultiSelection) {
451
+ this.selectionModel.setModel(this.treeModel);
452
+ }
453
+ else if (this.selectionModel instanceof Gtk.NoSelection) {
454
+ this.selectionModel.setModel(this.treeModel);
455
+ }
456
+ }
457
+ this.scheduleBoundItemsUpdate();
458
+ return;
459
+ }
460
+ const oldSize = this.model.getNItems();
461
+ const overlap = Math.min(oldSize, newSize);
462
+ const transitionPositions = [];
463
+ for (let i = 0; i < overlap; i++) {
464
+ const obj = this.model.getObject(i);
465
+ if (!obj)
466
+ continue;
467
+ if (this.rootItemIds[i] !== rootItems[i]?.id) {
468
+ this.treeChildModels.delete(obj.handle);
469
+ this.queriedLeaves.delete(obj.handle);
470
+ transitionPositions.push(i);
471
+ continue;
472
+ }
473
+ const cachedChildModel = this.treeChildModels.get(obj.handle);
474
+ const newChildCount = rootItems[i]?.children?.length ?? 0;
475
+ if (cachedChildModel && newChildCount > 0) {
476
+ resizeStringList(cachedChildModel, newChildCount);
477
+ }
478
+ else if (cachedChildModel && newChildCount === 0) {
479
+ this.treeChildModels.delete(obj.handle);
480
+ transitionPositions.push(i);
481
+ }
482
+ else if (!cachedChildModel && newChildCount > 0) {
483
+ transitionPositions.push(i);
484
+ }
485
+ }
486
+ for (let i = overlap; i < oldSize; i++) {
487
+ const obj = this.model.getObject(i);
488
+ if (obj) {
489
+ this.treeChildModels.delete(obj.handle);
490
+ this.queriedLeaves.delete(obj.handle);
491
+ }
492
+ }
493
+ resizeStringList(this.model, newSize);
494
+ for (const pos of transitionPositions) {
495
+ if (pos < newSize) {
496
+ const oldObj = this.model.getObject(pos);
497
+ if (oldObj) {
498
+ this.queriedLeaves.delete(oldObj.handle);
499
+ this.treeChildModels.delete(oldObj.handle);
500
+ }
501
+ this.model.splice(pos, 1, [""]);
502
+ }
503
+ }
504
+ this.rootItemIds = rootItems.map((item) => item.id);
505
+ this.scheduleBoundItemsUpdate();
506
+ }
507
+ createChildModel(_item) {
508
+ const rootItems = this.collectRootItems();
509
+ const position = this.findStringObjectPosition(_item);
510
+ if (position === null || position >= rootItems.length) {
511
+ this.queriedLeaves.add(_item.handle);
512
+ return null;
513
+ }
514
+ const item = rootItems[position];
515
+ if (!item?.children || item.children.length === 0) {
516
+ this.queriedLeaves.add(_item.handle);
517
+ return null;
518
+ }
519
+ const childModel = new Gtk.StringList();
520
+ resizeStringList(childModel, item.children.length);
521
+ this.treeChildModels.set(_item.handle, childModel);
522
+ this.queriedLeaves.delete(_item.handle);
523
+ return childModel;
524
+ }
525
+ findStringObjectPosition(item) {
526
+ if (!this.model)
527
+ return null;
528
+ const nItems = this.model.getNItems();
529
+ for (let i = 0; i < nItems; i++) {
530
+ const obj = this.model.getObject(i);
531
+ if (obj && obj.handle === item.handle) {
532
+ return i;
533
+ }
534
+ }
535
+ return null;
536
+ }
537
+ syncSectionModel() {
538
+ if (!this.model)
539
+ return;
540
+ const sections = this.collectSections();
541
+ if (!this.sectionStore) {
542
+ this.sectionStore = new Gio.ListStore(Gtk.StringList.getGType());
543
+ this.flattenModel = new Gtk.FlattenListModel(this.sectionStore);
544
+ if (this.selectionModel) {
545
+ if (this.selectionModel instanceof Gtk.SingleSelection) {
546
+ this.selectionModel.setModel(this.flattenModel);
547
+ }
548
+ else if (this.selectionModel instanceof Gtk.MultiSelection) {
549
+ this.selectionModel.setModel(this.flattenModel);
550
+ }
551
+ else if (this.selectionModel instanceof Gtk.NoSelection) {
552
+ this.selectionModel.setModel(this.flattenModel);
553
+ }
554
+ }
555
+ if (this.isDropDown()) {
556
+ this.assignModelToWidget();
557
+ }
558
+ }
559
+ while (this.sectionModels.length > sections.length) {
560
+ this.sectionModels.pop();
561
+ this.sectionStore.remove(this.sectionStore.getNItems() - 1);
562
+ }
563
+ for (let i = 0; i < sections.length; i++) {
564
+ const section = sections[i];
565
+ const itemCount = section.children?.length ?? 0;
566
+ if (i >= this.sectionModels.length) {
567
+ const sectionModel = new Gtk.StringList();
568
+ resizeStringList(sectionModel, itemCount);
569
+ this.sectionModels.push(sectionModel);
570
+ this.sectionStore.append(sectionModel);
571
+ }
572
+ else {
573
+ resizeStringList(this.sectionModels[i], itemCount);
574
+ }
575
+ }
576
+ this.scheduleBoundItemsUpdate();
577
+ }
578
+ resolveTreeItem(row) {
579
+ const rootItems = this.collectRootItems();
580
+ const depth = row.getDepth();
581
+ if (depth === 0) {
582
+ const rootItem = row.getItem();
583
+ if (!rootItem)
584
+ return null;
585
+ const pos = this.findStringObjectPosition(rootItem);
586
+ if (pos === null)
587
+ return null;
588
+ return rootItems[pos] ?? null;
589
+ }
590
+ const parentRow = row.getParent();
591
+ if (!parentRow)
592
+ return null;
593
+ const parentItem = this.resolveTreeItem(parentRow);
594
+ if (!parentItem?.children)
595
+ return null;
596
+ const childItem = row.getItem();
597
+ if (!childItem)
598
+ return null;
599
+ const childModel = parentRow.getChildren();
600
+ if (childModel) {
601
+ for (let j = 0; j < childModel.getNItems(); j++) {
602
+ const obj = childModel.getObject(j);
603
+ if (obj && obj.handle === childItem.handle) {
604
+ return parentItem.children[j] ?? null;
605
+ }
606
+ }
607
+ }
608
+ return null;
609
+ }
610
+ applyTreeExpanderProps(expander, item) {
611
+ if (item.section)
612
+ return;
613
+ expander.setIndentForDepth(item.indentForDepth ?? true);
614
+ expander.setIndentForIcon(item.indentForIcon ?? true);
615
+ expander.setHideExpander(item.hideExpander ?? false);
616
+ }
617
+ resolveItemIdAtPosition(position) {
618
+ if (this.treeModel) {
619
+ const row = this.treeModel.getRow(position);
620
+ const item = row ? this.resolveTreeItem(row) : null;
621
+ return item?.id ?? null;
622
+ }
623
+ const flatItems = this.collectFlatItems();
624
+ return flatItems[position]?.id ?? null;
625
+ }
626
+ applyOwnProps(oldProps, newProps) {
627
+ if (hasChanged(oldProps, newProps, "items")) {
628
+ this.scheduleSync();
629
+ }
630
+ if (hasChanged(oldProps, newProps, "selected")) {
631
+ this.applySelection(newProps.selected ?? null);
632
+ }
633
+ if (hasChanged(oldProps, newProps, "selectedId")) {
634
+ this.applySelectedId(newProps.selectedId ?? null);
635
+ }
636
+ if (hasChanged(oldProps, newProps, "onSelectionChanged")) {
637
+ this.connectSelectionSignal();
638
+ }
639
+ if (hasChanged(oldProps, newProps, "selectionMode")) {
640
+ this.rebuildSelectionModel(newProps);
641
+ }
642
+ if (hasChanged(oldProps, newProps, "renderItem") ||
643
+ hasChanged(oldProps, newProps, "renderListItem") ||
644
+ hasChanged(oldProps, newProps, "renderHeader")) {
645
+ this.scheduleBoundItemsUpdate();
646
+ }
647
+ if (hasChanged(oldProps, newProps, "autoexpand") && this.treeModel) {
648
+ this.treeModel.setAutoexpand(newProps.autoexpand ?? false);
649
+ }
650
+ if (hasChanged(oldProps, newProps, "onSortChanged")) {
651
+ this.connectSortSignal();
652
+ }
653
+ if (hasChanged(oldProps, newProps, "sortColumn") || hasChanged(oldProps, newProps, "sortOrder")) {
654
+ this.applySortColumn(newProps);
655
+ }
656
+ }
657
+ rebuildSelectionModel(props) {
658
+ const baseModel = this.getBaseModel();
659
+ const selectionMode = props.selectionMode ?? Gtk.SelectionMode.SINGLE;
660
+ if (selectionMode === Gtk.SelectionMode.MULTIPLE) {
661
+ this.selectionModel = new Gtk.MultiSelection(baseModel);
662
+ }
663
+ else if (selectionMode === Gtk.SelectionMode.NONE) {
664
+ this.selectionModel = new Gtk.NoSelection(baseModel);
665
+ }
666
+ else {
667
+ const sel = new Gtk.SingleSelection(baseModel);
668
+ sel.setAutoselect(false);
669
+ sel.setCanUnselect(true);
670
+ this.selectionModel = sel;
671
+ }
672
+ this.assignModelToWidget();
673
+ this.connectSelectionSignal();
674
+ }
675
+ applySelection(ids) {
676
+ if (!this.selectionModel || this.isDropDown())
677
+ return;
678
+ if (!ids || ids.length === 0) {
679
+ if (this.selectionModel instanceof Gtk.SingleSelection) {
680
+ this.selectionModel.setSelected(Gtk.INVALID_LIST_POSITION);
681
+ }
682
+ else if (this.selectionModel instanceof Gtk.MultiSelection) {
683
+ this.selectionModel.unselectAll();
684
+ }
685
+ return;
686
+ }
687
+ const idSet = new Set(ids);
688
+ const nItems = this.selectionModel.getNItems();
689
+ if (this.selectionModel instanceof Gtk.SingleSelection) {
690
+ for (let i = 0; i < nItems; i++) {
691
+ const id = this.resolveItemIdAtPosition(i);
692
+ if (id && idSet.has(id)) {
693
+ this.selectionModel.setSelected(i);
694
+ return;
695
+ }
696
+ }
697
+ }
698
+ else if (this.selectionModel instanceof Gtk.MultiSelection) {
699
+ this.selectionModel.unselectAll();
700
+ for (let i = 0; i < nItems; i++) {
701
+ const id = this.resolveItemIdAtPosition(i);
702
+ if (id && idSet.has(id)) {
703
+ this.selectionModel.selectItem(i, false);
704
+ }
705
+ }
706
+ }
707
+ }
708
+ applySelectedId(id) {
709
+ if (!this.isDropDown())
710
+ return;
711
+ if (id === null || id === undefined)
712
+ return;
713
+ const flatItems = this.collectFlatItems();
714
+ for (let i = 0; i < flatItems.length; i++) {
715
+ if (flatItems[i]?.id === id) {
716
+ if (this.container instanceof Gtk.DropDown) {
717
+ this.container.setSelected(i);
718
+ }
719
+ else if (this.container instanceof Adw.ComboRow) {
720
+ this.container.setSelected(i);
721
+ }
722
+ return;
723
+ }
724
+ }
725
+ }
726
+ connectSelectionSignal() {
727
+ const { onSelectionChanged } = this.props;
728
+ if (this.isDropDown()) {
729
+ const handler = onSelectionChanged
730
+ ? () => {
731
+ const position = this.container instanceof Gtk.DropDown
732
+ ? this.container.getSelected()
733
+ : this.container instanceof Adw.ComboRow
734
+ ? this.container.getSelected()
735
+ : -1;
736
+ const flatItems = this.collectFlatItems();
737
+ const item = flatItems[position];
738
+ if (item) {
739
+ onSelectionChanged(item.id);
740
+ }
741
+ }
742
+ : undefined;
743
+ this.signalStore.set(this, this.container, "notify::selected", handler);
744
+ return;
745
+ }
746
+ if (!this.selectionModel)
747
+ return;
748
+ const handler = onSelectionChanged
749
+ ? () => {
750
+ const selection = this.selectionModel?.getSelection();
751
+ if (!selection)
752
+ return;
753
+ const ids = [];
754
+ const nItems = this.selectionModel?.getNItems() ?? 0;
755
+ if (this.treeModel) {
756
+ for (let i = 0; i < nItems; i++) {
757
+ if (selection.contains(i)) {
758
+ const row = this.treeModel.getRow(i);
759
+ const item = row ? this.resolveTreeItem(row) : null;
760
+ if (item)
761
+ ids.push(item.id);
762
+ }
763
+ }
764
+ }
765
+ else {
766
+ const flatItems = this.collectFlatItems();
767
+ for (let i = 0; i < nItems; i++) {
768
+ if (selection.contains(i)) {
769
+ const item = flatItems[i];
770
+ if (item)
771
+ ids.push(item.id);
772
+ }
773
+ }
774
+ }
775
+ onSelectionChanged(ids);
776
+ }
777
+ : undefined;
778
+ this.signalStore.set(this, this.selectionModel, "selection-changed", handler, {
779
+ blockable: false,
780
+ });
781
+ }
782
+ connectSortSignal() {
783
+ if (!this.isColumnView())
784
+ return;
785
+ const columnView = this.container;
786
+ const sorter = columnView.getSorter();
787
+ if (!sorter)
788
+ return;
789
+ const { onSortChanged } = this.props;
790
+ const handler = onSortChanged
791
+ ? () => {
792
+ const cvSorter = columnView.getSorter();
793
+ if (!cvSorter) {
794
+ onSortChanged(null, Gtk.SortType.ASCENDING);
795
+ return;
796
+ }
797
+ const primaryColumn = cvSorter.getPrimarySortColumn();
798
+ const primaryOrder = cvSorter.getPrimarySortOrder();
799
+ const columnId = primaryColumn?.getId() ?? null;
800
+ onSortChanged(columnId, primaryOrder);
801
+ }
802
+ : undefined;
803
+ this.signalStore.set(this, sorter, "changed", handler, { blockable: false });
804
+ }
805
+ applySortColumn(props) {
806
+ if (!this.isColumnView())
807
+ return;
808
+ const columnView = this.container;
809
+ const { sortColumn, sortOrder } = props;
810
+ if (sortColumn === null || sortColumn === undefined) {
811
+ columnView.sortByColumn(Gtk.SortType.ASCENDING, null);
812
+ return;
813
+ }
814
+ const column = this.findColumnById(sortColumn);
815
+ if (column) {
816
+ columnView.sortByColumn(sortOrder ?? Gtk.SortType.ASCENDING, column);
817
+ }
818
+ }
819
+ findColumnById(id) {
820
+ if (!this.isColumnView())
821
+ return null;
822
+ const columnView = this.container;
823
+ const columns = columnView.getColumns();
824
+ const nItems = columns.getNItems();
825
+ for (let i = 0; i < nItems; i++) {
826
+ const obj = columns.getObject(i);
827
+ if (obj && obj.getId() === id) {
828
+ return obj;
829
+ }
830
+ }
831
+ return null;
832
+ }
833
+ scheduleSync() {
834
+ if (this.syncScheduled)
835
+ return;
836
+ this.syncScheduled = true;
837
+ queueMicrotask(() => {
838
+ this.syncScheduled = false;
839
+ if (this.disposed)
840
+ return;
841
+ this.syncModel();
842
+ });
843
+ }
844
+ scheduleBoundItemsUpdate() {
845
+ if (this.boundItemsUpdateScheduled)
846
+ return;
847
+ this.boundItemsUpdateScheduled = true;
848
+ queueMicrotask(() => {
849
+ this.boundItemsUpdateScheduled = false;
850
+ if (this.disposed)
851
+ return;
852
+ this.rebuildBoundItems();
853
+ });
854
+ }
855
+ rebuildBoundItems() {
856
+ const { __boundItemsRef, __rerender, __headerBoundItemsRef, renderItem, renderListItem, renderHeader } = this.props;
857
+ if (!__boundItemsRef || !__rerender)
858
+ return;
859
+ const flatItems = this.collectFlatItems();
860
+ const newBoundItems = [];
861
+ if (this.isColumnView()) {
862
+ for (const child of this.children) {
863
+ if (child instanceof ColumnViewColumnNode) {
864
+ newBoundItems.push(...child.collectBoundItems(flatItems));
865
+ }
866
+ }
867
+ }
868
+ else {
869
+ const renderFn = renderItem ?? (this.isDropDown() ? (item) => String(item ?? "") : null);
870
+ if (renderFn) {
871
+ this.collectContainerBoundItems(this.containers, this.containerKeys, flatItems, renderFn, newBoundItems);
872
+ }
873
+ if (renderListItem && this.isDropDown()) {
874
+ this.collectContainerBoundItems(this.listContainers, this.listContainerKeys, flatItems, renderListItem, newBoundItems);
875
+ }
876
+ }
877
+ __boundItemsRef.current = newBoundItems;
878
+ if (__headerBoundItemsRef && renderHeader && this.sectionStore !== null) {
879
+ const sections = this.collectSections();
880
+ const headerBoundItems = [];
881
+ let sectionStart = 0;
882
+ for (let i = 0; i < sections.length; i++) {
883
+ const section = sections[i];
884
+ for (const [container, position] of this.headerContainers) {
885
+ if (position === UNBOUND_POSITION)
886
+ continue;
887
+ if (position === sectionStart) {
888
+ const key = this.headerContainerKeys.get(container);
889
+ if (key) {
890
+ const content = renderHeader(section.value);
891
+ headerBoundItems.push([content, container, key]);
892
+ }
893
+ }
894
+ }
895
+ sectionStart += section.children?.length ?? 0;
896
+ }
897
+ __headerBoundItemsRef.current = headerBoundItems;
898
+ }
899
+ __rerender();
900
+ }
901
+ collectContainerBoundItems(containers, containerKeys, flatItems, renderFn, out) {
902
+ const isTree = this.treeModel !== null;
903
+ for (const [container, position] of containers) {
904
+ if (position === UNBOUND_POSITION)
905
+ continue;
906
+ const key = containerKeys.get(container);
907
+ if (!key)
908
+ continue;
909
+ if (isTree) {
910
+ const expander = container;
911
+ const row = expander.getListRow() ?? null;
912
+ if (!row)
913
+ continue;
914
+ const item = this.resolveTreeItem(row);
915
+ if (!item)
916
+ continue;
917
+ const content = renderFn(item.value, row);
918
+ out.push([content, container, key]);
919
+ }
920
+ else {
921
+ const item = flatItems[position];
922
+ if (!item)
923
+ continue;
924
+ const content = renderFn(item.value);
925
+ out.push([content, container, key]);
926
+ }
927
+ }
928
+ }
929
+ getEstimatedItemSize() {
930
+ return {
931
+ width: this.props.estimatedItemWidth ?? -1,
932
+ height: this.props.estimatedItemHeight ?? -1,
933
+ };
934
+ }
935
+ applyEstimatedItemSize(widget) {
936
+ const { width, height } = this.getEstimatedItemSize();
937
+ widget.setSizeRequest(width, height);
938
+ }
939
+ getColumnPosition(columnNode) {
940
+ let columnIndex = 0;
941
+ for (const child of this.children) {
942
+ if (child === columnNode)
943
+ return columnIndex;
944
+ if (child instanceof ColumnViewColumnNode)
945
+ columnIndex++;
946
+ }
947
+ return columnIndex;
948
+ }
949
+ }
950
+ //# sourceMappingURL=list.js.map