nomen-lang 0.7.1 → 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 +2556 -656
  50. package/package.json +1 -1
@@ -0,0 +1,833 @@
1
+ /**
2
+ * A multi-column data table with header labels (NSTableView, view-based)
3
+ *
4
+ * An OWNING STRUCT (STRUCT_PLAN_3 Phase R, tranche 4 — the shape menu): the
5
+ * single field is a platform handle, so the value is movable and its
6
+ * `#destroy` releases what the handle names. The constructor's `self` is
7
+ * the inline instance (the `.` accessor); methods keep the pointer form.
8
+ *
9
+ * The data-source bridge generalizes ListView's (see that file) from rows
10
+ * to a GRID: cells live in a fixed-capacity C-global pool, addressed
11
+ * row-major (`text[row * cols + col]`); the column count is fixed at
12
+ * construction. Cells render through VIEW-BASED table cells
13
+ * (`tableView:viewForTableColumn:row:` returning an NSTableCellView whose
14
+ * identifier matches its column) so AppKit REUSES the views as rows scroll
15
+ * — the same recycling native tables get. Headers are live column labels
16
+ * (`set_header`). One Table per process (shared pool — the same trade
17
+ * ListView makes). Selection is POLLED (`selected_row`), like every value
18
+ * in the manual loop. Named `Table` with no stdlib collision (the ListView
19
+ * `List<T>` lesson). macOS-only (no iOS counterpart for a plain embeddable
20
+ * grid; see GUI_PLAN Tier 2 — the iOS blocks are TODO stubs).
21
+ **/
22
+ pub mv struct Table : Control {
23
+ var uint64 handle = 0
24
+ var uint64 table = 0
25
+
26
+ // File-scope helper: the cell pool (shared — one Table per process) and
27
+ // the delegate class answering the row count and building reusable cell
28
+ // views.
29
+ pub func #init = (self, Window window, int cols: cols > 0) {
30
+ ```
31
+ #arch: c
32
+ #platform: macos
33
+ #scope: file
34
+ #define NOMEN_TABLE_MAX_ROWS 256
35
+ #define NOMEN_TABLE_MAX_COLS 8
36
+ static char *g_table_cells[NOMEN_TABLE_MAX_ROWS * NOMEN_TABLE_MAX_COLS];
37
+ static long g_table_cols = 0;
38
+ static long g_table_rows = 0;
39
+ static id g_table_delegate = 0;
40
+
41
+ // Append an empty row (cells render as "" until set_cell); returns
42
+ // the new row index or -1 when the pool is full.
43
+ static long nomen_table_append_row(void) {
44
+ if (g_table_rows >= NOMEN_TABLE_MAX_ROWS) return -1;
45
+ for (long c = 0; c < g_table_cols; c++) {
46
+ g_table_cells[g_table_rows * g_table_cols + c] = 0;
47
+ }
48
+ g_table_rows += 1;
49
+ return g_table_rows - 1;
50
+ }
51
+
52
+ static void nomen_table_set_cell(long row, long col, const char *text) {
53
+ if (row < 0 || row >= g_table_rows) return;
54
+ if (col < 0 || col >= g_table_cols) return;
55
+ long i = row * g_table_cols + col;
56
+ free(g_table_cells[i]);
57
+ g_table_cells[i] = strdup(text);
58
+ }
59
+
60
+ static void nomen_table_remove_row(long row) {
61
+ if (row < 0 || row >= g_table_rows) return;
62
+ for (long c = 0; c < g_table_cols; c++) {
63
+ free(g_table_cells[row * g_table_cols + c]);
64
+ }
65
+ // Shift the tail rows left (cols pointers per row).
66
+ for (long r = row; r + 1 < g_table_rows; r++) {
67
+ for (long c = 0; c < g_table_cols; c++) {
68
+ g_table_cells[r * g_table_cols + c] =
69
+ g_table_cells[(r + 1) * g_table_cols + c];
70
+ }
71
+ }
72
+ g_table_rows -= 1;
73
+ }
74
+
75
+ static void nomen_table_clear(void) {
76
+ for (long i = 0; i < g_table_rows * g_table_cols; i++) {
77
+ free(g_table_cells[i]);
78
+ g_table_cells[i] = 0;
79
+ }
80
+ g_table_rows = 0;
81
+ }
82
+
83
+ static long nomen_table_number_of_rows(id self, SEL cmd, id tv) {
84
+ (void)self; (void)cmd; (void)tv;
85
+ return g_table_rows;
86
+ }
87
+
88
+ // The view-based cell: an NSTableCellView identified by its COLUMN,
89
+ // recycled through makeViewWithIdentifier as rows scroll (the reuse
90
+ // ListView's cell-based rows didn't have).
91
+ static id nomen_table_view_for_cell(id self, SEL cmd, id tv, id col, long row) {
92
+ (void)self; (void)cmd; (void)tv;
93
+ // The cell identifier is the COLUMN'S IDENTIFIER STRING (AppKit
94
+ // parses the identifier into an internal UIID — passing the
95
+ // NSTableColumn object itself traps in _NSInternalUIIDParse the
96
+ // first time a cell is actually built).
97
+ id col_id = ((id(*)(id, SEL))objc_msgSend)(col, sel_registerName("identifier"));
98
+ id cell = ((id(*)(id, SEL, id, id))objc_msgSend)(
99
+ tv, sel_registerName("makeViewWithIdentifier:owner:"), col_id, g_table_delegate);
100
+ if (!cell) {
101
+ cell = ((id(*)(id, SEL, CGRect))objc_msgSend)(
102
+ ((id(*)(id, SEL))objc_msgSend)(
103
+ (id)objc_getClass("NSTableCellView"), sel_registerName("alloc")),
104
+ sel_registerName("initWithFrame:"),
105
+ ((CGRect(*)(double, double, double, double))CGRectMake)(0, 0, 100, 22));
106
+ ((void(*)(id, SEL, id))objc_msgSend)(cell, sel_registerName("setIdentifier:"), col_id);
107
+ id tf = ((id(*)(id, SEL, CGRect))objc_msgSend)(
108
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSTextField"), sel_registerName("alloc")),
109
+ sel_registerName("initWithFrame:"),
110
+ ((CGRect(*)(double, double, double, double))CGRectMake)(0, 0, 100, 22));
111
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(tf, sel_registerName("setBezeled:"), 0);
112
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(tf, sel_registerName("setDrawsBackground:"), 0);
113
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(tf, sel_registerName("setEditable:"), 0);
114
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(tf, sel_registerName("setSelectable:"), 0);
115
+ ((void(*)(id, SEL, long))objc_msgSend)(tf, sel_registerName("setLineBreakMode:"), 4);
116
+ ((void(*)(id, SEL, unsigned long))objc_msgSend)(tf, sel_registerName("setAutoresizingMask:"), 2UL);
117
+ ((void(*)(id, SEL, id))objc_msgSend)(cell, sel_registerName("setTextField:"), tf);
118
+ ((void(*)(id, SEL, id))objc_msgSend)(cell, sel_registerName("addSubview:"), tf);
119
+ ((void(*)(id, SEL))objc_msgSend)(tf, sel_registerName("release"));
120
+ }
121
+ long c = ((long(*)(id, SEL, id))objc_msgSend)(
122
+ ((id(*)(id, SEL))objc_msgSend)(tv, sel_registerName("tableColumns")),
123
+ sel_registerName("indexOfObject:"), col);
124
+ const char *text = "";
125
+ if (row >= 0 && row < g_table_rows && c >= 0 && c < g_table_cols) {
126
+ const char *cell_text = g_table_cells[row * g_table_cols + c];
127
+ if (cell_text) text = cell_text;
128
+ }
129
+ id tf = ((id(*)(id, SEL))objc_msgSend)(cell, sel_registerName("textField"));
130
+ if (tf) {
131
+ ((void(*)(id, SEL, id))objc_msgSend)(
132
+ tf, sel_registerName("setStringValue:"),
133
+ ((id(*)(id, SEL, const char*))objc_msgSend)(
134
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), text));
135
+ }
136
+ return cell;
137
+ }
138
+
139
+ // The delegate's selection hook: every selection change — user click
140
+ // AND programmatic select_row — pushes the table view's handle into
141
+ // the shared selection record (the on_select feed; the ring lives
142
+ // in Control.nm next to the click ring).
143
+ static void nomen_table_selection_did_change(id self, SEL cmd, id note) {
144
+ (void)self; (void)cmd;
145
+ id tv = ((id(*)(id, SEL))objc_msgSend)(note, sel_registerName("object"));
146
+ extern void nomen_select_push(unsigned long long);
147
+ nomen_select_push((unsigned long long)(void *)tv);
148
+ }
149
+
150
+ static id nomen_table_delegate_class(void) {
151
+ Class Td = objc_getClass("NomenTableBridge");
152
+ if (!Td) {
153
+ Td = objc_allocateClassPair(objc_getClass("NSObject"), "NomenTableBridge", 0);
154
+ if (Td) {
155
+ class_addMethod(Td, sel_registerName("numberOfRowsInTableView:"),
156
+ (IMP)nomen_table_number_of_rows, "l@:@");
157
+ class_addMethod(Td, sel_registerName("tableView:viewForTableColumn:row:"),
158
+ (IMP)nomen_table_view_for_cell, "@@:@@@l");
159
+ class_addMethod(Td, sel_registerName("tableViewSelectionDidChange:"),
160
+ (IMP)nomen_table_selection_did_change, "v@:@");
161
+ objc_registerClassPair(Td);
162
+ }
163
+ }
164
+ if (!g_table_delegate) {
165
+ g_table_delegate = ((id(*)(id, SEL))objc_msgSend)(Td, sel_registerName("new"));
166
+ }
167
+ return g_table_delegate;
168
+ }
169
+ ```
170
+ ```
171
+ #arch: aarch64_use_c
172
+ #platform: macos
173
+ #scope: file
174
+ #define NOMEN_TABLE_MAX_ROWS 256
175
+ #define NOMEN_TABLE_MAX_COLS 8
176
+ static char *g_table_cells[NOMEN_TABLE_MAX_ROWS * NOMEN_TABLE_MAX_COLS];
177
+ static long g_table_cols = 0;
178
+ static long g_table_rows = 0;
179
+ static id g_table_delegate = 0;
180
+
181
+ // Append an empty row (cells render as "" until set_cell); returns
182
+ // the new row index or -1 when the pool is full.
183
+ static long nomen_table_append_row(void) {
184
+ if (g_table_rows >= NOMEN_TABLE_MAX_ROWS) return -1;
185
+ for (long c = 0; c < g_table_cols; c++) {
186
+ g_table_cells[g_table_rows * g_table_cols + c] = 0;
187
+ }
188
+ g_table_rows += 1;
189
+ return g_table_rows - 1;
190
+ }
191
+
192
+ static void nomen_table_set_cell(long row, long col, const char *text) {
193
+ if (row < 0 || row >= g_table_rows) return;
194
+ if (col < 0 || col >= g_table_cols) return;
195
+ long i = row * g_table_cols + col;
196
+ free(g_table_cells[i]);
197
+ g_table_cells[i] = strdup(text);
198
+ }
199
+
200
+ static void nomen_table_remove_row(long row) {
201
+ if (row < 0 || row >= g_table_rows) return;
202
+ for (long c = 0; c < g_table_cols; c++) {
203
+ free(g_table_cells[row * g_table_cols + c]);
204
+ }
205
+ // Shift the tail rows left (cols pointers per row).
206
+ for (long r = row; r + 1 < g_table_rows; r++) {
207
+ for (long c = 0; c < g_table_cols; c++) {
208
+ g_table_cells[r * g_table_cols + c] =
209
+ g_table_cells[(r + 1) * g_table_cols + c];
210
+ }
211
+ }
212
+ g_table_rows -= 1;
213
+ }
214
+
215
+ static void nomen_table_clear(void) {
216
+ for (long i = 0; i < g_table_rows * g_table_cols; i++) {
217
+ free(g_table_cells[i]);
218
+ g_table_cells[i] = 0;
219
+ }
220
+ g_table_rows = 0;
221
+ }
222
+
223
+ static long nomen_table_number_of_rows(id self, SEL cmd, id tv) {
224
+ (void)self; (void)cmd; (void)tv;
225
+ return g_table_rows;
226
+ }
227
+
228
+ // The view-based cell: an NSTableCellView identified by its COLUMN,
229
+ // recycled through makeViewWithIdentifier as rows scroll (the reuse
230
+ // ListView's cell-based rows didn't have).
231
+ static id nomen_table_view_for_cell(id self, SEL cmd, id tv, id col, long row) {
232
+ (void)self; (void)cmd; (void)tv;
233
+ // The cell identifier is the COLUMN'S IDENTIFIER STRING (AppKit
234
+ // parses the identifier into an internal UIID — passing the
235
+ // NSTableColumn object itself traps in _NSInternalUIIDParse the
236
+ // first time a cell is actually built).
237
+ id col_id = ((id(*)(id, SEL))objc_msgSend)(col, sel_registerName("identifier"));
238
+ id cell = ((id(*)(id, SEL, id, id))objc_msgSend)(
239
+ tv, sel_registerName("makeViewWithIdentifier:owner:"), col_id, g_table_delegate);
240
+ if (!cell) {
241
+ cell = ((id(*)(id, SEL, CGRect))objc_msgSend)(
242
+ ((id(*)(id, SEL))objc_msgSend)(
243
+ (id)objc_getClass("NSTableCellView"), sel_registerName("alloc")),
244
+ sel_registerName("initWithFrame:"),
245
+ ((CGRect(*)(double, double, double, double))CGRectMake)(0, 0, 100, 22));
246
+ ((void(*)(id, SEL, id))objc_msgSend)(cell, sel_registerName("setIdentifier:"), col_id);
247
+ id tf = ((id(*)(id, SEL, CGRect))objc_msgSend)(
248
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSTextField"), sel_registerName("alloc")),
249
+ sel_registerName("initWithFrame:"),
250
+ ((CGRect(*)(double, double, double, double))CGRectMake)(0, 0, 100, 22));
251
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(tf, sel_registerName("setBezeled:"), 0);
252
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(tf, sel_registerName("setDrawsBackground:"), 0);
253
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(tf, sel_registerName("setEditable:"), 0);
254
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(tf, sel_registerName("setSelectable:"), 0);
255
+ ((void(*)(id, SEL, long))objc_msgSend)(tf, sel_registerName("setLineBreakMode:"), 4);
256
+ ((void(*)(id, SEL, unsigned long))objc_msgSend)(tf, sel_registerName("setAutoresizingMask:"), 2UL);
257
+ ((void(*)(id, SEL, id))objc_msgSend)(cell, sel_registerName("setTextField:"), tf);
258
+ ((void(*)(id, SEL, id))objc_msgSend)(cell, sel_registerName("addSubview:"), tf);
259
+ ((void(*)(id, SEL))objc_msgSend)(tf, sel_registerName("release"));
260
+ }
261
+ long c = ((long(*)(id, SEL, id))objc_msgSend)(
262
+ ((id(*)(id, SEL))objc_msgSend)(tv, sel_registerName("tableColumns")),
263
+ sel_registerName("indexOfObject:"), col);
264
+ const char *text = "";
265
+ if (row >= 0 && row < g_table_rows && c >= 0 && c < g_table_cols) {
266
+ const char *cell_text = g_table_cells[row * g_table_cols + c];
267
+ if (cell_text) text = cell_text;
268
+ }
269
+ id tf = ((id(*)(id, SEL))objc_msgSend)(cell, sel_registerName("textField"));
270
+ if (tf) {
271
+ ((void(*)(id, SEL, id))objc_msgSend)(
272
+ tf, sel_registerName("setStringValue:"),
273
+ ((id(*)(id, SEL, const char*))objc_msgSend)(
274
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), text));
275
+ }
276
+ return cell;
277
+ }
278
+
279
+ // The delegate's selection hook: every selection change — user click
280
+ // AND programmatic select_row — pushes the table view's handle into
281
+ // the shared selection record (the on_select feed; the ring lives
282
+ // in Control.nm next to the click ring).
283
+ static void nomen_table_selection_did_change(id self, SEL cmd, id note) {
284
+ (void)self; (void)cmd;
285
+ id tv = ((id(*)(id, SEL))objc_msgSend)(note, sel_registerName("object"));
286
+ extern void nomen_select_push(unsigned long long);
287
+ nomen_select_push((unsigned long long)(void *)tv);
288
+ }
289
+
290
+ static id nomen_table_delegate_class(void) {
291
+ Class Td = objc_getClass("NomenTableBridge");
292
+ if (!Td) {
293
+ Td = objc_allocateClassPair(objc_getClass("NSObject"), "NomenTableBridge", 0);
294
+ if (Td) {
295
+ class_addMethod(Td, sel_registerName("numberOfRowsInTableView:"),
296
+ (IMP)nomen_table_number_of_rows, "l@:@");
297
+ class_addMethod(Td, sel_registerName("tableView:viewForTableColumn:row:"),
298
+ (IMP)nomen_table_view_for_cell, "@@:@@@l");
299
+ class_addMethod(Td, sel_registerName("tableViewSelectionDidChange:"),
300
+ (IMP)nomen_table_selection_did_change, "v@:@");
301
+ objc_registerClassPair(Td);
302
+ }
303
+ }
304
+ if (!g_table_delegate) {
305
+ g_table_delegate = ((id(*)(id, SEL))objc_msgSend)(Td, sel_registerName("new"));
306
+ }
307
+ return g_table_delegate;
308
+ }
309
+ ```
310
+ ```
311
+ #arch: c
312
+ #platform: macos
313
+ g_table_cols = (long)cols;
314
+ g_table_rows = 0;
315
+ id sv = ((id(*)(id, SEL, CGRect))objc_msgSend)(
316
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSScrollView"), sel_registerName("alloc")),
317
+ sel_registerName("initWithFrame:"),
318
+ ((CGRect(*)(double, double, double, double))CGRectMake)(0, 0, 300, 160));
319
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(sv, sel_registerName("setDrawsBackground:"), 0);
320
+ id tv = ((id(*)(id, SEL, CGRect))objc_msgSend)(
321
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSTableView"), sel_registerName("alloc")),
322
+ sel_registerName("initWithFrame:"),
323
+ ((CGRect(*)(double, double, double, double))CGRectMake)(0, 0, 300, 160));
324
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(tv, sel_registerName("setUsesAlternatingRowBackgroundColors:"), 1);
325
+ ((void(*)(id, SEL, double))objc_msgSend)(tv, sel_registerName("setRowHeight:"), 22.0);
326
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(tv, sel_registerName("setAllowsColumnSelection:"), 0);
327
+ ((void(*)(id, SEL, unsigned long))objc_msgSend)(tv, sel_registerName("setGridStyleMask:"), 0UL);
328
+ for (long c = 0; c < (long)cols; c++) {
329
+ char ident[16];
330
+ snprintf(ident, sizeof(ident), "col%ld", c);
331
+ id col = ((id(*)(id, SEL, id))objc_msgSend)(
332
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSTableColumn"), sel_registerName("alloc")),
333
+ sel_registerName("initWithIdentifier:"),
334
+ ((id(*)(id, SEL, const char*))objc_msgSend)(
335
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), ident));
336
+ ((void(*)(id, SEL, unsigned long))objc_msgSend)(col, sel_registerName("setResizingMask:"), 2UL);
337
+ ((void(*)(id, SEL, id))objc_msgSend)(tv, sel_registerName("addTableColumn:"), col);
338
+ ((void(*)(id, SEL))objc_msgSend)(col, sel_registerName("release"));
339
+ }
340
+ ((void(*)(id, SEL, id))objc_msgSend)(tv, sel_registerName("setDelegate:"), nomen_table_delegate_class());
341
+ ((void(*)(id, SEL, id))objc_msgSend)(tv, sel_registerName("setDataSource:"), nomen_table_delegate_class());
342
+ ((void(*)(id, SEL, id))objc_msgSend)(sv, sel_registerName("setDocumentView:"), tv);
343
+ ((void(*)(id, SEL))objc_msgSend)(tv, sel_registerName("release"));
344
+ id contentView = ((id(*)(id, SEL))objc_msgSend)(
345
+ (id)window->handle, sel_registerName("contentView"));
346
+ ((void(*)(id, SEL, id))objc_msgSend)(
347
+ contentView, sel_registerName("addSubview:"), sv);
348
+ self.handle = (uint64_t)sv;
349
+ self.table = (uint64_t)((id(*)(id, SEL))objc_msgSend)(sv, sel_registerName("documentView"));
350
+ ```
351
+ ```
352
+ #arch: aarch64_use_c
353
+ #platform: macos
354
+ g_table_cols = (long)cols;
355
+ g_table_rows = 0;
356
+ id sv = ((id(*)(id, SEL, CGRect))objc_msgSend)(
357
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSScrollView"), sel_registerName("alloc")),
358
+ sel_registerName("initWithFrame:"),
359
+ ((CGRect(*)(double, double, double, double))CGRectMake)(0, 0, 300, 160));
360
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(sv, sel_registerName("setDrawsBackground:"), 0);
361
+ id tv = ((id(*)(id, SEL, CGRect))objc_msgSend)(
362
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSTableView"), sel_registerName("alloc")),
363
+ sel_registerName("initWithFrame:"),
364
+ ((CGRect(*)(double, double, double, double))CGRectMake)(0, 0, 300, 160));
365
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(tv, sel_registerName("setUsesAlternatingRowBackgroundColors:"), 1);
366
+ ((void(*)(id, SEL, double))objc_msgSend)(tv, sel_registerName("setRowHeight:"), 22.0);
367
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(tv, sel_registerName("setAllowsColumnSelection:"), 0);
368
+ ((void(*)(id, SEL, unsigned long))objc_msgSend)(tv, sel_registerName("setGridStyleMask:"), 0UL);
369
+ for (long c = 0; c < (long)cols; c++) {
370
+ char ident[16];
371
+ snprintf(ident, sizeof(ident), "col%ld", c);
372
+ id col = ((id(*)(id, SEL, id))objc_msgSend)(
373
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSTableColumn"), sel_registerName("alloc")),
374
+ sel_registerName("initWithIdentifier:"),
375
+ ((id(*)(id, SEL, const char*))objc_msgSend)(
376
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), ident));
377
+ ((void(*)(id, SEL, unsigned long))objc_msgSend)(col, sel_registerName("setResizingMask:"), 2UL);
378
+ ((void(*)(id, SEL, id))objc_msgSend)(tv, sel_registerName("addTableColumn:"), col);
379
+ ((void(*)(id, SEL))objc_msgSend)(col, sel_registerName("release"));
380
+ }
381
+ ((void(*)(id, SEL, id))objc_msgSend)(tv, sel_registerName("setDelegate:"), nomen_table_delegate_class());
382
+ ((void(*)(id, SEL, id))objc_msgSend)(tv, sel_registerName("setDataSource:"), nomen_table_delegate_class());
383
+ ((void(*)(id, SEL, id))objc_msgSend)(sv, sel_registerName("setDocumentView:"), tv);
384
+ ((void(*)(id, SEL))objc_msgSend)(tv, sel_registerName("release"));
385
+ id contentView = ((id(*)(id, SEL))objc_msgSend)(
386
+ (id)window->handle, sel_registerName("contentView"));
387
+ ((void(*)(id, SEL, id))objc_msgSend)(
388
+ contentView, sel_registerName("addSubview:"), sv);
389
+ self->handle = (uint64_t)sv;
390
+ self->table = (uint64_t)((id(*)(id, SEL))objc_msgSend)(sv, sel_registerName("documentView"));
391
+ ```
392
+ ```
393
+ #arch: c
394
+ #platform: ios
395
+ /* TODO: iOS — UITableView + UITableViewDataSource with reusable
396
+ * cells, column composition on top (see GUI_PLAN Tier 2; defer). */
397
+ ```
398
+ ```
399
+ #arch: aarch64_use_c
400
+ #platform: ios
401
+ /* TODO: iOS (see #init) */
402
+ ```
403
+ }
404
+
405
+ // Set a column's header label (the live column title).
406
+ pub func set_header = (self, int col, string title) {
407
+ ```
408
+ #arch: c
409
+ #platform: macos
410
+ id cols = ((id(*)(id, SEL))objc_msgSend)((id)self->table, sel_registerName("tableColumns"));
411
+ long n = ((long(*)(id, SEL))objc_msgSend)(cols, sel_registerName("count"));
412
+ if (col < 0 || (long)col >= n) return;
413
+ id column = ((id(*)(id, SEL, unsigned long))objc_msgSend)(
414
+ cols, sel_registerName("objectAtIndex:"), (unsigned long)col);
415
+ id header = ((id(*)(id, SEL))objc_msgSend)(column, sel_registerName("headerCell"));
416
+ ((void(*)(id, SEL, id))objc_msgSend)(
417
+ header, sel_registerName("setStringValue:"),
418
+ ((id(*)(id, SEL, const char*))objc_msgSend)(
419
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), title.ptr));
420
+ ```
421
+ ```
422
+ #arch: aarch64_use_c
423
+ #platform: macos
424
+ id cols = ((id(*)(id, SEL))objc_msgSend)((id)self->table, sel_registerName("tableColumns"));
425
+ long n = ((long(*)(id, SEL))objc_msgSend)(cols, sel_registerName("count"));
426
+ if (col < 0 || (long)col >= n) return;
427
+ id column = ((id(*)(id, SEL, unsigned long))objc_msgSend)(
428
+ cols, sel_registerName("objectAtIndex:"), (unsigned long)col);
429
+ id header = ((id(*)(id, SEL))objc_msgSend)(column, sel_registerName("headerCell"));
430
+ ((void(*)(id, SEL, id))objc_msgSend)(
431
+ header, sel_registerName("setStringValue:"),
432
+ ((id(*)(id, SEL, const char*))objc_msgSend)(
433
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), title.ptr));
434
+ ```
435
+ ```
436
+ #arch: c
437
+ #platform: ios
438
+ /* TODO: iOS (see #init) */
439
+ ```
440
+ ```
441
+ #arch: aarch64_use_c
442
+ #platform: ios
443
+ /* TODO: iOS (see #init) */
444
+ ```
445
+ }
446
+
447
+ // Append an empty row and reload; cells render as "" until set_cell.
448
+ pub func add_row = (self) {
449
+ ```
450
+ #arch: c
451
+ #platform: macos
452
+ nomen_table_append_row();
453
+ ((void(*)(id, SEL))objc_msgSend)((id)self->table, sel_registerName("reloadData"));
454
+ ```
455
+ ```
456
+ #arch: aarch64_use_c
457
+ #platform: macos
458
+ nomen_table_append_row();
459
+ ((void(*)(id, SEL))objc_msgSend)((id)self->table, sel_registerName("reloadData"));
460
+ ```
461
+ ```
462
+ #arch: c
463
+ #platform: ios
464
+ /* TODO: iOS (see #init) */
465
+ ```
466
+ ```
467
+ #arch: aarch64_use_c
468
+ #platform: ios
469
+ /* TODO: iOS (see #init) */
470
+ ```
471
+ }
472
+
473
+ // Set one cell's text and reload.
474
+ pub func set_cell = (self, int row, int col, string text) {
475
+ ```
476
+ #arch: c
477
+ #platform: macos
478
+ nomen_table_set_cell((long)row, (long)col, text.ptr);
479
+ ((void(*)(id, SEL))objc_msgSend)((id)self->table, sel_registerName("reloadData"));
480
+ ```
481
+ ```
482
+ #arch: aarch64_use_c
483
+ #platform: macos
484
+ nomen_table_set_cell((long)row, (long)col, text.ptr);
485
+ ((void(*)(id, SEL))objc_msgSend)((id)self->table, sel_registerName("reloadData"));
486
+ ```
487
+ ```
488
+ #arch: c
489
+ #platform: ios
490
+ /* TODO: iOS (see #init) */
491
+ ```
492
+ ```
493
+ #arch: aarch64_use_c
494
+ #platform: ios
495
+ /* TODO: iOS (see #init) */
496
+ ```
497
+ }
498
+
499
+ // Delete row `index` and reload.
500
+ pub func remove_row = (self, int index) {
501
+ ```
502
+ #arch: c
503
+ #platform: macos
504
+ nomen_table_remove_row((long)index);
505
+ ((void(*)(id, SEL))objc_msgSend)((id)self->table, sel_registerName("reloadData"));
506
+ ```
507
+ ```
508
+ #arch: aarch64_use_c
509
+ #platform: macos
510
+ nomen_table_remove_row((long)index);
511
+ ((void(*)(id, SEL))objc_msgSend)((id)self->table, sel_registerName("reloadData"));
512
+ ```
513
+ ```
514
+ #arch: c
515
+ #platform: ios
516
+ /* TODO: iOS (see #init) */
517
+ ```
518
+ ```
519
+ #arch: aarch64_use_c
520
+ #platform: ios
521
+ /* TODO: iOS (see #init) */
522
+ ```
523
+ }
524
+
525
+ // Delete every row and reload.
526
+ pub func clear = (self) {
527
+ ```
528
+ #arch: c
529
+ #platform: macos
530
+ nomen_table_clear();
531
+ ((void(*)(id, SEL))objc_msgSend)((id)self->table, sel_registerName("reloadData"));
532
+ ```
533
+ ```
534
+ #arch: aarch64_use_c
535
+ #platform: macos
536
+ nomen_table_clear();
537
+ ((void(*)(id, SEL))objc_msgSend)((id)self->table, sel_registerName("reloadData"));
538
+ ```
539
+ ```
540
+ #arch: c
541
+ #platform: ios
542
+ /* TODO: iOS (see #init) */
543
+ ```
544
+ ```
545
+ #arch: aarch64_use_c
546
+ #platform: ios
547
+ /* TODO: iOS (see #init) */
548
+ ```
549
+ }
550
+
551
+ pub func row_count = (self, out int) {
552
+ ```
553
+ #arch: c
554
+ #platform: macos
555
+ return (int)g_table_rows;
556
+ ```
557
+ ```
558
+ #arch: aarch64_use_c
559
+ #platform: macos
560
+ return (int)g_table_rows;
561
+ ```
562
+ ```
563
+ #arch: c
564
+ #platform: ios
565
+ /* TODO: iOS (see #init) */
566
+ return 0;
567
+ ```
568
+ ```
569
+ #arch: aarch64_use_c
570
+ #platform: ios
571
+ /* TODO: iOS (see #init) */
572
+ return 0;
573
+ ```
574
+ }
575
+
576
+ pub func col_count = (self, out int) {
577
+ ```
578
+ #arch: c
579
+ #platform: macos
580
+ return (int)g_table_cols;
581
+ ```
582
+ ```
583
+ #arch: aarch64_use_c
584
+ #platform: macos
585
+ return (int)g_table_cols;
586
+ ```
587
+ ```
588
+ #arch: c
589
+ #platform: ios
590
+ /* TODO: iOS (see #init) */
591
+ return 0;
592
+ ```
593
+ ```
594
+ #arch: aarch64_use_c
595
+ #platform: ios
596
+ /* TODO: iOS (see #init) */
597
+ return 0;
598
+ ```
599
+ }
600
+
601
+ // A fresh copy of cell (row, col)'s text (mv — the caller owns it).
602
+ pub func cell = (self, int row, int col, out string) {
603
+ ```
604
+ #arch: c
605
+ #platform: macos
606
+ const char *text = "";
607
+ if (row >= 0 && (long)row < g_table_rows && col >= 0 && (long)col < g_table_cols) {
608
+ const char *v = g_table_cells[(long)row * g_table_cols + (long)col];
609
+ if (v) text = v;
610
+ }
611
+ return (nomen_string){ strdup(text), (long)strlen(text) };
612
+ ```
613
+ ```
614
+ #arch: aarch64_use_c
615
+ #platform: macos
616
+ const char *text = "";
617
+ if (row >= 0 && (long)row < g_table_rows && col >= 0 && (long)col < g_table_cols) {
618
+ const char *v = g_table_cells[(long)row * g_table_cols + (long)col];
619
+ if (v) text = v;
620
+ }
621
+ return (nomen_string){ strdup(text), (long)strlen(text) };
622
+ ```
623
+ ```
624
+ #arch: c
625
+ #platform: ios
626
+ /* TODO: iOS (see #init) */
627
+ return (nomen_string){ strdup(""), 0 };
628
+ ```
629
+ ```
630
+ #arch: aarch64_use_c
631
+ #platform: ios
632
+ /* TODO: iOS (see #init) */
633
+ return (nomen_string){ strdup(""), 0 };
634
+ ```
635
+ }
636
+
637
+ // The selected row, polled (no change callback in the manual loop);
638
+ // -1 = no selection.
639
+ pub func selected_row = (self, out int) {
640
+ ```
641
+ #arch: c
642
+ #platform: macos
643
+ return (int)((long(*)(id, SEL))objc_msgSend)((id)self->table, sel_registerName("selectedRow"));
644
+ ```
645
+ ```
646
+ #arch: aarch64_use_c
647
+ #platform: macos
648
+ return (int)((long(*)(id, SEL))objc_msgSend)((id)self->table, sel_registerName("selectedRow"));
649
+ ```
650
+ ```
651
+ #arch: c
652
+ #platform: ios
653
+ /* TODO: iOS (see #init) */
654
+ return -1;
655
+ ```
656
+ ```
657
+ #arch: aarch64_use_c
658
+ #platform: ios
659
+ /* TODO: iOS (see #init) */
660
+ return -1;
661
+ ```
662
+ }
663
+
664
+ // The on_select desugar's drain (docs/HANDLERS.md): true when the
665
+ // selected row changed since the last drain — user clicks AND
666
+ // programmatic select_row (the delegate observes both; a pre-selection
667
+ // in #init therefore fires on the first frame). The handler body reads
668
+ // the row through selected_row(). The record is keyed on the table
669
+ // view (what the delegate sees), not the scroll wrapper.
670
+ pub func take_select = (self, out bool) {
671
+ ```
672
+ #arch: c
673
+ #platform: macos
674
+ extern long nomen_select_take(unsigned long long);
675
+ return (long)nomen_select_take((unsigned long long)self->table);
676
+ ```
677
+ ```
678
+ #arch: aarch64_use_c
679
+ #platform: macos
680
+ extern long nomen_select_take(unsigned long long);
681
+ return (long)nomen_select_take((unsigned long long)self->table);
682
+ ```
683
+ ```
684
+ #arch: c
685
+ #platform: ios
686
+ /* TODO: iOS (see #init) */
687
+ return false;
688
+ ```
689
+ ```
690
+ #arch: aarch64_use_c
691
+ #platform: ios
692
+ /* TODO: iOS (see #init) */
693
+ return false;
694
+ ```
695
+ }
696
+
697
+ // Select a row programmatically (deselects the rest).
698
+ pub func select_row = (self, int index) {
699
+ ```
700
+ #arch: c
701
+ #platform: macos
702
+ id indexes = ((id(*)(id, SEL, unsigned long))objc_msgSend)(
703
+ (id)objc_getClass("NSIndexSet"), sel_registerName("indexSetWithIndex:"),
704
+ index < 0 ? 0UL : (unsigned long)index);
705
+ ((void(*)(id, SEL, id, BOOL))objc_msgSend)(
706
+ (id)self->table, sel_registerName("selectRowIndexes:byExtendingSelection:"),
707
+ indexes, 0);
708
+ ```
709
+ ```
710
+ #arch: aarch64_use_c
711
+ #platform: macos
712
+ id indexes = ((id(*)(id, SEL, unsigned long))objc_msgSend)(
713
+ (id)objc_getClass("NSIndexSet"), sel_registerName("indexSetWithIndex:"),
714
+ index < 0 ? 0UL : (unsigned long)index);
715
+ ((void(*)(id, SEL, id, BOOL))objc_msgSend)(
716
+ (id)self->table, sel_registerName("selectRowIndexes:byExtendingSelection:"),
717
+ indexes, 0);
718
+ ```
719
+ ```
720
+ #arch: c
721
+ #platform: ios
722
+ /* TODO: iOS (see #init) */
723
+ ```
724
+ ```
725
+ #arch: aarch64_use_c
726
+ #platform: ios
727
+ /* TODO: iOS (see #init) */
728
+ ```
729
+ }
730
+
731
+ pub func set_hidden = (self, bool hidden) {
732
+ ```
733
+ #arch: c
734
+ #platform: macos
735
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(
736
+ (id)self->handle, sel_registerName("setHidden:"), hidden ? 1 : 0);
737
+ ```
738
+ ```
739
+ #arch: aarch64_use_c
740
+ #platform: macos
741
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(
742
+ (id)self->handle, sel_registerName("setHidden:"), hidden ? 1 : 0);
743
+ ```
744
+ }
745
+
746
+ // ── Control trait conformance ──
747
+ pub func set_frame = (ref self, int x, int y, int width, int height) {
748
+ ```
749
+ #arch: c
750
+ #platform: macos
751
+ ((void(*)(id, SEL, CGRect))objc_msgSend)(
752
+ (id)self->handle, sel_registerName("setFrame:"),
753
+ ((CGRect(*)(double, double, double, double))CGRectMake)((double)x, (double)y, (double)width, (double)height));
754
+ ```
755
+ ```
756
+ #arch: aarch64_use_c
757
+ #platform: macos
758
+ ((void(*)(id, SEL, CGRect))objc_msgSend)(
759
+ (id)self->handle, sel_registerName("setFrame:"),
760
+ ((CGRect(*)(double, double, double, double))CGRectMake)((double)x, (double)y, (double)width, (double)height));
761
+ ```
762
+ ```
763
+ #arch: c
764
+ #platform: ios
765
+ /* TODO: iOS (see #init) */
766
+ ```
767
+ ```
768
+ #arch: aarch64_use_c
769
+ #platform: ios
770
+ /* TODO: iOS (see #init) */
771
+ ```
772
+ }
773
+
774
+ pub func intrinsic_size = (self, out Size) {
775
+ var [w, h] = native_intrinsic(self.handle)
776
+ var s = Size()
777
+ s.width = w
778
+ s.height = h
779
+ return s
780
+ }
781
+
782
+ pub func measure = (self, BoxConstraints constraints, out Size) {
783
+ var Size s = self.intrinsic_size()
784
+ if s.width > constraints.max_width {
785
+ s.width = constraints.max_width
786
+ }
787
+ if s.width < constraints.min_width {
788
+ s.width = constraints.min_width
789
+ }
790
+ if s.height > constraints.max_height {
791
+ s.height = constraints.max_height
792
+ }
793
+ if s.height < constraints.min_height {
794
+ s.height = constraints.min_height
795
+ }
796
+ return s
797
+ }
798
+
799
+ func #destroy = () {
800
+ ```
801
+ #arch: c
802
+ #platform: macos
803
+ nomen_table_clear();
804
+ if (self->handle) {
805
+ ((void(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("removeFromSuperview"));
806
+ ((void(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("release"));
807
+ self->handle = 0;
808
+ }
809
+ self->table = 0;
810
+ ```
811
+ ```
812
+ #arch: aarch64_use_c
813
+ #platform: macos
814
+ nomen_table_clear();
815
+ if (self->handle) {
816
+ ((void(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("removeFromSuperview"));
817
+ ((void(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("release"));
818
+ self->handle = 0;
819
+ }
820
+ self->table = 0;
821
+ ```
822
+ ```
823
+ #arch: c
824
+ #platform: ios
825
+ /* TODO: iOS (see #init) */
826
+ ```
827
+ ```
828
+ #arch: aarch64_use_c
829
+ #platform: ios
830
+ /* TODO: iOS (see #init) */
831
+ ```
832
+ }
833
+ }