nomen-lang 0.7.0 → 0.8.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 (50) hide show
  1. package/core/System/Buffer.nm +32 -0
  2. package/core/System/ClassBuffer.nm +24 -0
  3. package/core/System/Controls/Alert.nm +326 -0
  4. package/core/System/Controls/App.nm +147 -0
  5. package/core/System/Controls/Button.nm +119 -1
  6. package/core/System/Controls/CheckBox.nm +24 -0
  7. package/core/System/Controls/ColorPicker.nm +307 -0
  8. package/core/System/Controls/ComboBox.nm +430 -0
  9. package/core/System/Controls/Container.nm +837 -9
  10. package/core/System/Controls/Control.nm +443 -0
  11. package/core/System/Controls/DatePicker.nm +288 -0
  12. package/core/System/Controls/Form.nm +70 -0
  13. package/core/System/Controls/GroupBox.nm +267 -0
  14. package/core/System/Controls/ImageView.nm +311 -0
  15. package/core/System/Controls/LevelIndicator.nm +305 -0
  16. package/core/System/Controls/ListView.nm +633 -0
  17. package/core/System/Controls/Menu.nm +428 -0
  18. package/core/System/Controls/NumberInput.nm +56 -0
  19. package/core/System/Controls/OtpInput.nm +50 -0
  20. package/core/System/Controls/OutlineView.nm +598 -0
  21. package/core/System/Controls/Pagination.nm +142 -0
  22. package/core/System/Controls/Popover.nm +296 -0
  23. package/core/System/Controls/Progress.nm +348 -0
  24. package/core/System/Controls/Radio.nm +292 -0
  25. package/core/System/Controls/Scrollable.nm +584 -0
  26. package/core/System/Controls/SearchField.nm +326 -0
  27. package/core/System/Controls/SecureField.nm +344 -0
  28. package/core/System/Controls/Segmented.nm +380 -0
  29. package/core/System/Controls/Select.nm +340 -0
  30. package/core/System/Controls/Separator.nm +198 -0
  31. package/core/System/Controls/Sheet.nm +329 -0
  32. package/core/System/Controls/Slider.nm +315 -0
  33. package/core/System/Controls/Spinner.nm +287 -0
  34. package/core/System/Controls/SplitView.nm +509 -0
  35. package/core/System/Controls/Stepper.nm +349 -0
  36. package/core/System/Controls/Switch.nm +259 -0
  37. package/core/System/Controls/Table.nm +833 -0
  38. package/core/System/Controls/Tabs.nm +500 -0
  39. package/core/System/Controls/Text.nm +108 -11
  40. package/core/System/Controls/TextBox.nm +112 -1
  41. package/core/System/Controls/TextView.nm +329 -0
  42. package/core/System/Controls/Toggle.nm +346 -0
  43. package/core/System/Controls/Toolbar.nm +501 -0
  44. package/core/System/Controls/Tooltip.nm +76 -0
  45. package/core/System/Controls/Window.nm +1549 -91
  46. package/core/System/List.nm +34 -0
  47. package/core/System/Map.nm +21 -4
  48. package/core/System/Set.nm +14 -0
  49. package/dist/index.mjs +3425 -710
  50. package/package.json +1 -1
@@ -0,0 +1,633 @@
1
+ /**
2
+ * A single-column scrolling list of text rows (NSTableView, cell-based).
3
+ *
4
+ * Named `ListView` (not `List`) to keep clear of the stdlib `List<T>` —
5
+ * the Controls type would otherwise shadow it in name resolution.
6
+ *
7
+ * An OWNING STRUCT (STRUCT_PLAN_3 Phase R, tranche 4 — the shape menu): the
8
+ * fields are platform handles, so the value is movable and its `#destroy`
9
+ * releases what they name. The constructor's `self` is the inline instance
10
+ * (the `.` accessor); methods keep the pointer form.
11
+ *
12
+ * The data source bridge: NSTableView asks its dataSource for the row count
13
+ * and each row's value, so the rows live in C globals (`g_list_rows`) that
14
+ * the delegate IMPs read — the Nomen-side API (`add_row`/`set_row`/…)
15
+ * mutates them and reloads. That is one List per process (the globals are
16
+ * shared — the same trade `Container`'s resize delegate already makes).
17
+ * Selection is POLLED (`selected_row`), like every value in the manual
18
+ * loop; there is no selection-change callback yet (GUI_PLAN cross-cutting
19
+ * follow-ups). The table is cell-based, so cells draw plain text with no
20
+ * view reuse; a multi-column Table with view-based (reusable) cells is a
21
+ * later tier-2 step. The table lives in an NSScrollView, so it scrolls like
22
+ * any document view. iOS defers to UITableView (TODO stubs; see GUI_PLAN
23
+ * Tier 2).
24
+ **/
25
+ pub mv struct ListView : Control {
26
+ var uint64 handle = 0
27
+ var uint64 table = 0
28
+
29
+ // File-scope helpers: the row storage (shared — one List per process)
30
+ // and the delegate class answering the two data-source questions.
31
+ pub func #init = (self, Window window) {
32
+ ```
33
+ #arch: c
34
+ #platform: macos
35
+ #scope: file
36
+ static char **g_list_rows = 0;
37
+ static long g_list_count = 0;
38
+ static long g_list_cap = 0;
39
+ static id g_list_delegate = 0;
40
+
41
+ // Append a NUL-terminated copy of `text`; returns the new count.
42
+ static long nomen_list_append(const char *text) {
43
+ if (g_list_count == g_list_cap) {
44
+ long cap = g_list_cap ? g_list_cap * 2 : 16;
45
+ char **rows = (char **)realloc(g_list_rows, (size_t)(cap * sizeof(char *)));
46
+ if (!rows) return g_list_count;
47
+ g_list_rows = rows;
48
+ g_list_cap = cap;
49
+ }
50
+ g_list_rows[g_list_count] = strdup(text);
51
+ g_list_count += 1;
52
+ return g_list_count;
53
+ }
54
+
55
+ // Free row `index`, shifting the tail left.
56
+ static void nomen_list_remove_at(long index) {
57
+ if (index < 0 || index >= g_list_count) return;
58
+ free(g_list_rows[index]);
59
+ for (long i = index; i + 1 < g_list_count; i++) {
60
+ g_list_rows[i] = g_list_rows[i + 1];
61
+ }
62
+ g_list_count -= 1;
63
+ }
64
+
65
+ static void nomen_list_clear_rows(void) {
66
+ for (long i = 0; i < g_list_count; i++) free(g_list_rows[i]);
67
+ g_list_count = 0;
68
+ }
69
+
70
+ static long nomen_list_number_of_rows(id self, SEL cmd, id tv) {
71
+ (void)self; (void)cmd; (void)tv;
72
+ return g_list_count;
73
+ }
74
+
75
+ static id nomen_list_object_value(id self, SEL cmd, id tv, id col, long row) {
76
+ (void)self; (void)cmd; (void)tv; (void)col;
77
+ const char *text = (row < 0 || row >= g_list_count) ? "" : g_list_rows[row];
78
+ return ((id(*)(id, SEL, const char*))objc_msgSend)(
79
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), text);
80
+ }
81
+
82
+ // The delegate's selection hook: every selection change — user click
83
+ // AND programmatic select_row — pushes the table view's handle into
84
+ // the shared selection record (the on_select feed; the ring lives
85
+ // in Control.nm next to the click ring).
86
+ static void nomen_list_selection_did_change(id self, SEL cmd, id note) {
87
+ (void)self; (void)cmd;
88
+ id tv = ((id(*)(id, SEL))objc_msgSend)(note, sel_registerName("object"));
89
+ extern void nomen_select_push(unsigned long long);
90
+ nomen_select_push((unsigned long long)(void *)tv);
91
+ }
92
+
93
+ static id nomen_list_delegate_class(void) {
94
+ Class Dl = objc_getClass("NomenListDelegate");
95
+ if (!Dl) {
96
+ Dl = objc_allocateClassPair(objc_getClass("NSObject"), "NomenListDelegate", 0);
97
+ if (Dl) {
98
+ class_addMethod(Dl, sel_registerName("numberOfRowsInTableView:"),
99
+ (IMP)nomen_list_number_of_rows, "l@:@");
100
+ class_addMethod(Dl, sel_registerName("tableView:objectValueForTableColumn:row:"),
101
+ (IMP)nomen_list_object_value, "@@:@@@l");
102
+ class_addMethod(Dl, sel_registerName("tableViewSelectionDidChange:"),
103
+ (IMP)nomen_list_selection_did_change, "v@:@");
104
+ objc_registerClassPair(Dl);
105
+ }
106
+ }
107
+ return Dl;
108
+ }
109
+ ```
110
+ ```
111
+ #arch: aarch64_use_c
112
+ #platform: macos
113
+ #scope: file
114
+ static char **g_list_rows = 0;
115
+ static long g_list_count = 0;
116
+ static long g_list_cap = 0;
117
+ static id g_list_delegate = 0;
118
+
119
+ // Append a NUL-terminated copy of `text`; returns the new count.
120
+ static long nomen_list_append(const char *text) {
121
+ if (g_list_count == g_list_cap) {
122
+ long cap = g_list_cap ? g_list_cap * 2 : 16;
123
+ char **rows = (char **)realloc(g_list_rows, (size_t)(cap * sizeof(char *)));
124
+ if (!rows) return g_list_count;
125
+ g_list_rows = rows;
126
+ g_list_cap = cap;
127
+ }
128
+ g_list_rows[g_list_count] = strdup(text);
129
+ g_list_count += 1;
130
+ return g_list_count;
131
+ }
132
+
133
+ // Free row `index`, shifting the tail left.
134
+ static void nomen_list_remove_at(long index) {
135
+ if (index < 0 || index >= g_list_count) return;
136
+ free(g_list_rows[index]);
137
+ for (long i = index; i + 1 < g_list_count; i++) {
138
+ g_list_rows[i] = g_list_rows[i + 1];
139
+ }
140
+ g_list_count -= 1;
141
+ }
142
+
143
+ static void nomen_list_clear_rows(void) {
144
+ for (long i = 0; i < g_list_count; i++) free(g_list_rows[i]);
145
+ g_list_count = 0;
146
+ }
147
+
148
+ static long nomen_list_number_of_rows(id self, SEL cmd, id tv) {
149
+ (void)self; (void)cmd; (void)tv;
150
+ return g_list_count;
151
+ }
152
+
153
+ static id nomen_list_object_value(id self, SEL cmd, id tv, id col, long row) {
154
+ (void)self; (void)cmd; (void)tv; (void)col;
155
+ const char *text = (row < 0 || row >= g_list_count) ? "" : g_list_rows[row];
156
+ return ((id(*)(id, SEL, const char*))objc_msgSend)(
157
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), text);
158
+ }
159
+
160
+ // The delegate's selection hook (see the c twin above).
161
+ static void nomen_list_selection_did_change(id self, SEL cmd, id note) {
162
+ (void)self; (void)cmd;
163
+ id tv = ((id(*)(id, SEL))objc_msgSend)(note, sel_registerName("object"));
164
+ extern void nomen_select_push(unsigned long long);
165
+ nomen_select_push((unsigned long long)(void *)tv);
166
+ }
167
+
168
+ static id nomen_list_delegate_class(void) {
169
+ Class Dl = objc_getClass("NomenListDelegate");
170
+ if (!Dl) {
171
+ Dl = objc_allocateClassPair(objc_getClass("NSObject"), "NomenListDelegate", 0);
172
+ if (Dl) {
173
+ class_addMethod(Dl, sel_registerName("numberOfRowsInTableView:"),
174
+ (IMP)nomen_list_number_of_rows, "l@:@");
175
+ class_addMethod(Dl, sel_registerName("tableView:objectValueForTableColumn:row:"),
176
+ (IMP)nomen_list_object_value, "@@:@@@l");
177
+ class_addMethod(Dl, sel_registerName("tableViewSelectionDidChange:"),
178
+ (IMP)nomen_list_selection_did_change, "v@:@");
179
+ objc_registerClassPair(Dl);
180
+ }
181
+ }
182
+ return Dl;
183
+ }
184
+ ```
185
+ ```
186
+ #arch: c
187
+ #platform: macos
188
+ id sv = ((id(*)(id, SEL, CGRect))objc_msgSend)(
189
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSScrollView"), sel_registerName("alloc")),
190
+ sel_registerName("initWithFrame:"),
191
+ ((CGRect(*)(double, double, double, double))CGRectMake)(0, 0, 200, 160));
192
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(sv, sel_registerName("setDrawsBackground:"), 0);
193
+ id tv = ((id(*)(id, SEL, CGRect))objc_msgSend)(
194
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSTableView"), sel_registerName("alloc")),
195
+ sel_registerName("initWithFrame:"),
196
+ ((CGRect(*)(double, double, double, double))CGRectMake)(0, 0, 200, 160));
197
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(tv, sel_registerName("setUsesAlternatingRowBackgroundColors:"), 0);
198
+ ((void(*)(id, SEL, double))objc_msgSend)(tv, sel_registerName("setRowHeight:"), 22.0);
199
+ ((void(*)(id, SEL, id))objc_msgSend)(tv, sel_registerName("setHeaderView:"), (id)0);
200
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(tv, sel_registerName("setAllowsColumnSelection:"), 0);
201
+ id col = ((id(*)(id, SEL, id))objc_msgSend)(
202
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSTableColumn"), sel_registerName("alloc")),
203
+ sel_registerName("initWithIdentifier:"),
204
+ ((id(*)(id, SEL, const char*))objc_msgSend)(
205
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), "main"));
206
+ ((void(*)(id, SEL, unsigned long))objc_msgSend)(col, sel_registerName("setResizingMask:"), 2UL);
207
+ ((void(*)(id, SEL, id))objc_msgSend)(tv, sel_registerName("addTableColumn:"), col);
208
+ ((void(*)(id, SEL))objc_msgSend)(col, sel_registerName("release"));
209
+ if (!g_list_delegate) {
210
+ g_list_delegate = ((id(*)(id, SEL))objc_msgSend)(nomen_list_delegate_class(), sel_registerName("new"));
211
+ }
212
+ ((void(*)(id, SEL, id))objc_msgSend)(tv, sel_registerName("setDelegate:"), g_list_delegate);
213
+ ((void(*)(id, SEL, id))objc_msgSend)(tv, sel_registerName("setDataSource:"), g_list_delegate);
214
+ ((void(*)(id, SEL, id))objc_msgSend)(sv, sel_registerName("setDocumentView:"), tv);
215
+ ((void(*)(id, SEL))objc_msgSend)(tv, sel_registerName("release"));
216
+ id contentView = ((id(*)(id, SEL))objc_msgSend)(
217
+ (id)window->handle, sel_registerName("contentView"));
218
+ ((void(*)(id, SEL, id))objc_msgSend)(
219
+ contentView, sel_registerName("addSubview:"), sv);
220
+ self.handle = (uint64_t)sv;
221
+ self.table = (uint64_t)((id(*)(id, SEL))objc_msgSend)(sv, sel_registerName("documentView"));
222
+ ```
223
+ ```
224
+ #arch: aarch64_use_c
225
+ #platform: macos
226
+ id sv = ((id(*)(id, SEL, CGRect))objc_msgSend)(
227
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSScrollView"), sel_registerName("alloc")),
228
+ sel_registerName("initWithFrame:"),
229
+ ((CGRect(*)(double, double, double, double))CGRectMake)(0, 0, 200, 160));
230
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(sv, sel_registerName("setDrawsBackground:"), 0);
231
+ id tv = ((id(*)(id, SEL, CGRect))objc_msgSend)(
232
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSTableView"), sel_registerName("alloc")),
233
+ sel_registerName("initWithFrame:"),
234
+ ((CGRect(*)(double, double, double, double))CGRectMake)(0, 0, 200, 160));
235
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(tv, sel_registerName("setUsesAlternatingRowBackgroundColors:"), 0);
236
+ ((void(*)(id, SEL, double))objc_msgSend)(tv, sel_registerName("setRowHeight:"), 22.0);
237
+ ((void(*)(id, SEL, id))objc_msgSend)(tv, sel_registerName("setHeaderView:"), (id)0);
238
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(tv, sel_registerName("setAllowsColumnSelection:"), 0);
239
+ id col = ((id(*)(id, SEL, id))objc_msgSend)(
240
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSTableColumn"), sel_registerName("alloc")),
241
+ sel_registerName("initWithIdentifier:"),
242
+ ((id(*)(id, SEL, const char*))objc_msgSend)(
243
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), "main"));
244
+ ((void(*)(id, SEL, unsigned long))objc_msgSend)(col, sel_registerName("setResizingMask:"), 2UL);
245
+ ((void(*)(id, SEL, id))objc_msgSend)(tv, sel_registerName("addTableColumn:"), col);
246
+ ((void(*)(id, SEL))objc_msgSend)(col, sel_registerName("release"));
247
+ if (!g_list_delegate) {
248
+ g_list_delegate = ((id(*)(id, SEL))objc_msgSend)(nomen_list_delegate_class(), sel_registerName("new"));
249
+ }
250
+ ((void(*)(id, SEL, id))objc_msgSend)(tv, sel_registerName("setDelegate:"), g_list_delegate);
251
+ ((void(*)(id, SEL, id))objc_msgSend)(tv, sel_registerName("setDataSource:"), g_list_delegate);
252
+ ((void(*)(id, SEL, id))objc_msgSend)(sv, sel_registerName("setDocumentView:"), tv);
253
+ ((void(*)(id, SEL))objc_msgSend)(tv, sel_registerName("release"));
254
+ id contentView = ((id(*)(id, SEL))objc_msgSend)(
255
+ (id)window->handle, sel_registerName("contentView"));
256
+ ((void(*)(id, SEL, id))objc_msgSend)(
257
+ contentView, sel_registerName("addSubview:"), sv);
258
+ self->handle = (uint64_t)sv;
259
+ self->table = (uint64_t)((id(*)(id, SEL))objc_msgSend)(sv, sel_registerName("documentView"));
260
+ ```
261
+ ```
262
+ #arch: c
263
+ #platform: ios
264
+ /* TODO: iOS — UITableView + UITableViewDataSource/Delegate bridge and
265
+ * reusable cells (see GUI_PLAN Tier 2; defer). */
266
+ ```
267
+ ```
268
+ #arch: aarch64_use_c
269
+ #platform: ios
270
+ /* TODO: iOS (see #init) */
271
+ ```
272
+ }
273
+
274
+ // Append a row (a NUL-terminated copy is stored) and reload.
275
+ pub func add_row = (self, string text) {
276
+ ```
277
+ #arch: c
278
+ #platform: macos
279
+ nomen_list_append(text.ptr);
280
+ ((void(*)(id, SEL))objc_msgSend)((id)self->table, sel_registerName("reloadData"));
281
+ ```
282
+ ```
283
+ #arch: aarch64_use_c
284
+ #platform: macos
285
+ nomen_list_append(text.ptr);
286
+ ((void(*)(id, SEL))objc_msgSend)((id)self->table, sel_registerName("reloadData"));
287
+ ```
288
+ ```
289
+ #arch: c
290
+ #platform: ios
291
+ /* TODO: iOS (see #init) */
292
+ ```
293
+ ```
294
+ #arch: aarch64_use_c
295
+ #platform: ios
296
+ /* TODO: iOS (see #init) */
297
+ ```
298
+ }
299
+
300
+ // Replace row `index`'s text and reload.
301
+ pub func set_row = (self, int index, string text) {
302
+ ```
303
+ #arch: c
304
+ #platform: macos
305
+ if (index < 0 || (long)index >= g_list_count) return;
306
+ free(g_list_rows[index]);
307
+ g_list_rows[index] = strdup(text.ptr);
308
+ ((void(*)(id, SEL))objc_msgSend)((id)self->table, sel_registerName("reloadData"));
309
+ ```
310
+ ```
311
+ #arch: aarch64_use_c
312
+ #platform: macos
313
+ if (index < 0 || (long)index >= g_list_count) return;
314
+ free(g_list_rows[index]);
315
+ g_list_rows[index] = strdup(text.ptr);
316
+ ((void(*)(id, SEL))objc_msgSend)((id)self->table, sel_registerName("reloadData"));
317
+ ```
318
+ ```
319
+ #arch: c
320
+ #platform: ios
321
+ /* TODO: iOS (see #init) */
322
+ ```
323
+ ```
324
+ #arch: aarch64_use_c
325
+ #platform: ios
326
+ /* TODO: iOS (see #init) */
327
+ ```
328
+ }
329
+
330
+ // Delete row `index` and reload.
331
+ pub func remove_row = (self, int index) {
332
+ ```
333
+ #arch: c
334
+ #platform: macos
335
+ nomen_list_remove_at((long)index);
336
+ ((void(*)(id, SEL))objc_msgSend)((id)self->table, sel_registerName("reloadData"));
337
+ ```
338
+ ```
339
+ #arch: aarch64_use_c
340
+ #platform: macos
341
+ nomen_list_remove_at((long)index);
342
+ ((void(*)(id, SEL))objc_msgSend)((id)self->table, sel_registerName("reloadData"));
343
+ ```
344
+ ```
345
+ #arch: c
346
+ #platform: ios
347
+ /* TODO: iOS (see #init) */
348
+ ```
349
+ ```
350
+ #arch: aarch64_use_c
351
+ #platform: ios
352
+ /* TODO: iOS (see #init) */
353
+ ```
354
+ }
355
+
356
+ // Delete every row and reload.
357
+ pub func clear = (self) {
358
+ ```
359
+ #arch: c
360
+ #platform: macos
361
+ nomen_list_clear_rows();
362
+ ((void(*)(id, SEL))objc_msgSend)((id)self->table, sel_registerName("reloadData"));
363
+ ```
364
+ ```
365
+ #arch: aarch64_use_c
366
+ #platform: macos
367
+ nomen_list_clear_rows();
368
+ ((void(*)(id, SEL))objc_msgSend)((id)self->table, sel_registerName("reloadData"));
369
+ ```
370
+ ```
371
+ #arch: c
372
+ #platform: ios
373
+ /* TODO: iOS (see #init) */
374
+ ```
375
+ ```
376
+ #arch: aarch64_use_c
377
+ #platform: ios
378
+ /* TODO: iOS (see #init) */
379
+ ```
380
+ }
381
+
382
+ pub func row_count = (self, out int) {
383
+ ```
384
+ #arch: c
385
+ #platform: macos
386
+ return (int)g_list_count;
387
+ ```
388
+ ```
389
+ #arch: aarch64_use_c
390
+ #platform: macos
391
+ return (int)g_list_count;
392
+ ```
393
+ ```
394
+ #arch: c
395
+ #platform: ios
396
+ /* TODO: iOS (see #init) */
397
+ return 0;
398
+ ```
399
+ ```
400
+ #arch: aarch64_use_c
401
+ #platform: ios
402
+ /* TODO: iOS (see #init) */
403
+ return 0;
404
+ ```
405
+ }
406
+
407
+ // A fresh copy of row `index`'s text (mv — the caller owns it).
408
+ pub func row = (self, int index, out string) {
409
+ ```
410
+ #arch: c
411
+ #platform: macos
412
+ const char *text = ((index < 0 || (long)index >= g_list_count) || !g_list_rows[index])
413
+ ? "" : g_list_rows[index];
414
+ return (nomen_string){ strdup(text), (long)strlen(text) };
415
+ ```
416
+ ```
417
+ #arch: aarch64_use_c
418
+ #platform: macos
419
+ const char *text = ((index < 0 || (long)index >= g_list_count) || !g_list_rows[index])
420
+ ? "" : g_list_rows[index];
421
+ return (nomen_string){ strdup(text), (long)strlen(text) };
422
+ ```
423
+ ```
424
+ #arch: c
425
+ #platform: ios
426
+ /* TODO: iOS (see #init) */
427
+ return (nomen_string){ strdup(""), 0 };
428
+ ```
429
+ ```
430
+ #arch: aarch64_use_c
431
+ #platform: ios
432
+ /* TODO: iOS (see #init) */
433
+ return (nomen_string){ strdup(""), 0 };
434
+ ```
435
+ }
436
+
437
+ // The selected row, polled (no change callback in the manual loop);
438
+ // -1 = no selection.
439
+ pub func selected_row = (self, out int) {
440
+ ```
441
+ #arch: c
442
+ #platform: macos
443
+ return (int)((long(*)(id, SEL))objc_msgSend)((id)self->table, sel_registerName("selectedRow"));
444
+ ```
445
+ ```
446
+ #arch: aarch64_use_c
447
+ #platform: macos
448
+ return (int)((long(*)(id, SEL))objc_msgSend)((id)self->table, sel_registerName("selectedRow"));
449
+ ```
450
+ ```
451
+ #arch: c
452
+ #platform: ios
453
+ /* TODO: iOS (see #init) */
454
+ return -1;
455
+ ```
456
+ ```
457
+ #arch: aarch64_use_c
458
+ #platform: ios
459
+ /* TODO: iOS (see #init) */
460
+ return -1;
461
+ ```
462
+ }
463
+
464
+ // The on_select desugar's drain (docs/HANDLERS.md): true when the
465
+ // selected row changed since the last drain — user clicks AND
466
+ // programmatic select_row (the delegate observes both; a pre-selection
467
+ // in #init therefore fires on the first frame). The handler body reads
468
+ // the row through selected_row(). The record is keyed on the table
469
+ // view (what the delegate sees), not the scroll wrapper.
470
+ pub func take_select = (self, out bool) {
471
+ ```
472
+ #arch: c
473
+ #platform: macos
474
+ extern long nomen_select_take(unsigned long long);
475
+ return (long)nomen_select_take((unsigned long long)self->table);
476
+ ```
477
+ ```
478
+ #arch: aarch64_use_c
479
+ #platform: macos
480
+ extern long nomen_select_take(unsigned long long);
481
+ return (long)nomen_select_take((unsigned long long)self->table);
482
+ ```
483
+ ```
484
+ #arch: c
485
+ #platform: ios
486
+ /* TODO: iOS (see #init) */
487
+ return false;
488
+ ```
489
+ ```
490
+ #arch: aarch64_use_c
491
+ #platform: ios
492
+ /* TODO: iOS (see #init) */
493
+ return false;
494
+ ```
495
+ }
496
+
497
+ // Select a row programmatically (deselects the rest).
498
+ pub func select_row = (self, int index) {
499
+ ```
500
+ #arch: c
501
+ #platform: macos
502
+ id indexes = ((id(*)(id, SEL, unsigned long))objc_msgSend)(
503
+ (id)objc_getClass("NSIndexSet"), sel_registerName("indexSetWithIndex:"),
504
+ index < 0 ? 0UL : (unsigned long)index);
505
+ ((void(*)(id, SEL, id, BOOL))objc_msgSend)(
506
+ (id)self->table, sel_registerName("selectRowIndexes:byExtendingSelection:"),
507
+ indexes, 0);
508
+ ```
509
+ ```
510
+ #arch: aarch64_use_c
511
+ #platform: macos
512
+ id indexes = ((id(*)(id, SEL, unsigned long))objc_msgSend)(
513
+ (id)objc_getClass("NSIndexSet"), sel_registerName("indexSetWithIndex:"),
514
+ index < 0 ? 0UL : (unsigned long)index);
515
+ ((void(*)(id, SEL, id, BOOL))objc_msgSend)(
516
+ (id)self->table, sel_registerName("selectRowIndexes:byExtendingSelection:"),
517
+ indexes, 0);
518
+ ```
519
+ ```
520
+ #arch: c
521
+ #platform: ios
522
+ /* TODO: iOS (see #init) */
523
+ ```
524
+ ```
525
+ #arch: aarch64_use_c
526
+ #platform: ios
527
+ /* TODO: iOS (see #init) */
528
+ ```
529
+ }
530
+
531
+ pub func set_hidden = (self, bool hidden) {
532
+ ```
533
+ #arch: c
534
+ #platform: macos
535
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(
536
+ (id)self->handle, sel_registerName("setHidden:"), hidden ? 1 : 0);
537
+ ```
538
+ ```
539
+ #arch: aarch64_use_c
540
+ #platform: macos
541
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(
542
+ (id)self->handle, sel_registerName("setHidden:"), hidden ? 1 : 0);
543
+ ```
544
+ }
545
+
546
+ // ── Control trait conformance ──
547
+ pub func set_frame = (ref self, int x, int y, int width, int height) {
548
+ ```
549
+ #arch: c
550
+ #platform: macos
551
+ ((void(*)(id, SEL, CGRect))objc_msgSend)(
552
+ (id)self->handle, sel_registerName("setFrame:"),
553
+ ((CGRect(*)(double, double, double, double))CGRectMake)((double)x, (double)y, (double)width, (double)height));
554
+ ```
555
+ ```
556
+ #arch: aarch64_use_c
557
+ #platform: macos
558
+ ((void(*)(id, SEL, CGRect))objc_msgSend)(
559
+ (id)self->handle, sel_registerName("setFrame:"),
560
+ ((CGRect(*)(double, double, double, double))CGRectMake)((double)x, (double)y, (double)width, (double)height));
561
+ ```
562
+ ```
563
+ #arch: c
564
+ #platform: ios
565
+ /* TODO: iOS (see #init) */
566
+ ```
567
+ ```
568
+ #arch: aarch64_use_c
569
+ #platform: ios
570
+ /* TODO: iOS (see #init) */
571
+ ```
572
+ }
573
+
574
+ pub func intrinsic_size = (self, out Size) {
575
+ var [w, h] = native_intrinsic(self.handle)
576
+ var s = Size()
577
+ s.width = w
578
+ s.height = h
579
+ return s
580
+ }
581
+
582
+ pub func measure = (self, BoxConstraints constraints, out Size) {
583
+ var Size s = self.intrinsic_size()
584
+ if s.width > constraints.max_width {
585
+ s.width = constraints.max_width
586
+ }
587
+ if s.width < constraints.min_width {
588
+ s.width = constraints.min_width
589
+ }
590
+ if s.height > constraints.max_height {
591
+ s.height = constraints.max_height
592
+ }
593
+ if s.height < constraints.min_height {
594
+ s.height = constraints.min_height
595
+ }
596
+ return s
597
+ }
598
+
599
+ func #destroy = () {
600
+ ```
601
+ #arch: c
602
+ #platform: macos
603
+ nomen_list_clear_rows();
604
+ if (self->handle) {
605
+ ((void(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("removeFromSuperview"));
606
+ ((void(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("release"));
607
+ self->handle = 0;
608
+ }
609
+ self->table = 0;
610
+ ```
611
+ ```
612
+ #arch: aarch64_use_c
613
+ #platform: macos
614
+ nomen_list_clear_rows();
615
+ if (self->handle) {
616
+ ((void(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("removeFromSuperview"));
617
+ ((void(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("release"));
618
+ self->handle = 0;
619
+ }
620
+ self->table = 0;
621
+ ```
622
+ ```
623
+ #arch: c
624
+ #platform: ios
625
+ /* TODO: iOS (see #init) */
626
+ ```
627
+ ```
628
+ #arch: aarch64_use_c
629
+ #platform: ios
630
+ /* TODO: iOS (see #init) */
631
+ ```
632
+ }
633
+ }