nomen-lang 0.7.1 → 0.9.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 (80) hide show
  1. package/audit_runtime.c +12 -2
  2. package/core/System/Arena.nm +8 -1
  3. package/core/System/Buffer.nm +397 -8
  4. package/core/System/ClassBuffer.nm +156 -0
  5. package/core/System/Controls/Alert.nm +326 -0
  6. package/core/System/Controls/App.nm +147 -0
  7. package/core/System/Controls/Button.nm +119 -1
  8. package/core/System/Controls/CheckBox.nm +25 -1
  9. package/core/System/Controls/ColorPicker.nm +307 -0
  10. package/core/System/Controls/ComboBox.nm +430 -0
  11. package/core/System/Controls/Container.nm +843 -9
  12. package/core/System/Controls/Control.nm +443 -0
  13. package/core/System/Controls/DatePicker.nm +288 -0
  14. package/core/System/Controls/Form.nm +70 -0
  15. package/core/System/Controls/GroupBox.nm +267 -0
  16. package/core/System/Controls/ImageView.nm +311 -0
  17. package/core/System/Controls/LevelIndicator.nm +305 -0
  18. package/core/System/Controls/ListView.nm +633 -0
  19. package/core/System/Controls/Menu.nm +428 -0
  20. package/core/System/Controls/NumberInput.nm +56 -0
  21. package/core/System/Controls/OtpInput.nm +50 -0
  22. package/core/System/Controls/OutlineView.nm +598 -0
  23. package/core/System/Controls/Pagination.nm +142 -0
  24. package/core/System/Controls/Popover.nm +296 -0
  25. package/core/System/Controls/Progress.nm +348 -0
  26. package/core/System/Controls/Radio.nm +292 -0
  27. package/core/System/Controls/Scrollable.nm +584 -0
  28. package/core/System/Controls/SearchField.nm +326 -0
  29. package/core/System/Controls/SecureField.nm +344 -0
  30. package/core/System/Controls/Segmented.nm +380 -0
  31. package/core/System/Controls/Select.nm +340 -0
  32. package/core/System/Controls/Separator.nm +198 -0
  33. package/core/System/Controls/Sheet.nm +329 -0
  34. package/core/System/Controls/Slider.nm +315 -0
  35. package/core/System/Controls/Spinner.nm +287 -0
  36. package/core/System/Controls/SplitView.nm +509 -0
  37. package/core/System/Controls/Stepper.nm +349 -0
  38. package/core/System/Controls/Switch.nm +259 -0
  39. package/core/System/Controls/Table.nm +833 -0
  40. package/core/System/Controls/Tabs.nm +500 -0
  41. package/core/System/Controls/Text.nm +108 -11
  42. package/core/System/Controls/TextBox.nm +113 -2
  43. package/core/System/Controls/TextView.nm +329 -0
  44. package/core/System/Controls/Toggle.nm +346 -0
  45. package/core/System/Controls/Toolbar.nm +501 -0
  46. package/core/System/Controls/Tooltip.nm +76 -0
  47. package/core/System/Controls/Window.nm +1548 -91
  48. package/core/System/LinkedList.nm +8 -1
  49. package/core/System/List.nm +97 -7
  50. package/core/System/Map.nm +191 -18
  51. package/core/System/Mutex.nm +4 -4
  52. package/core/System/Random.nm +3 -4
  53. package/core/System/Set.nm +101 -13
  54. package/core/System/StableList.nm +371 -0
  55. package/core/System/Stream/Directory.nm +2 -2
  56. package/core/System/Stream/File.nm +2 -2
  57. package/core/System/Stream/Http.nm +2 -2
  58. package/core/System/String.nm +10 -5
  59. package/core/System/StringBuilder.nm +213 -2
  60. package/core/System/Text/CharIndex.nm +9 -9
  61. package/core/System/Text/Json.nm +60 -46
  62. package/core/System/Text/JsonTree.nm +120 -92
  63. package/core/System/Text/Regex.nm +23 -18
  64. package/core/System/Text/Utf8.nm +5 -5
  65. package/core/System/float.nm +36 -22
  66. package/core/System/int.nm +80 -28
  67. package/core/System/int16.nm +11 -0
  68. package/core/System/int32.nm +11 -0
  69. package/core/System/int64.nm +11 -0
  70. package/core/System/int8.nm +11 -0
  71. package/core/System/uint.nm +11 -0
  72. package/core/System/uint16.nm +11 -0
  73. package/core/System/uint32.nm +11 -0
  74. package/core/System/uint64.nm +11 -0
  75. package/core/System/uint8.nm +11 -0
  76. package/core/docs/System/StringBuilder.md +6 -0
  77. package/core/docs/System/Text/JsonTree.md +3 -2
  78. package/dist/index.mjs +38332 -30604
  79. package/package.json +1 -1
  80. package/src/bench_loop.nm +9 -9
@@ -0,0 +1,500 @@
1
+ /**
2
+ * A container of pages with a clickable tab bar (NSTabView)
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 page count is fixed at construction. Each page hosts controls on its
10
+ * own view: `content_window(index)` hands back a Window-shaped value whose
11
+ * `contentView` is the page view itself (NomenTabPageView answers
12
+ * `-contentView` with `self` — the Scrollable trick), so control
13
+ * constructors and `Container.layout` target a page unchanged. NSTabView
14
+ * sizes page views to its content area, so the engine's y-flip against
15
+ * `content_height()` (the page height) is the existing math. Page switching
16
+ * is native; laid-out frames stay valid across switches. iOS has no
17
+ * NSTabView counterpart (UITabBarController is app-level chrome — see
18
+ * GUI_PLAN Tier 2; defer with TODO stubs).
19
+ **/
20
+ pub mv struct Tabs: Control {
21
+ var uint64 handle = 0
22
+
23
+ // File-scope helper: the page view class. It answers `-contentView` with
24
+ // `self` so Window-expecting constructors add their controls to the page
25
+ // view (registered once, like NomenResizeDelegate).
26
+ pub func #init = (self, Window window, int count) {
27
+ ```
28
+ #arch: c
29
+ #platform: macos
30
+ #scope: file
31
+ static id nomen_tab_content_view(id self, SEL cmd) {
32
+ (void)cmd;
33
+ return self;
34
+ }
35
+ static id nomen_tab_page_class(void) {
36
+ Class Pv = objc_getClass("NomenTabPageView");
37
+ if (!Pv) {
38
+ Pv = objc_allocateClassPair(objc_getClass("NSView"), "NomenTabPageView", 0);
39
+ if (Pv) {
40
+ class_addMethod(Pv, sel_registerName("contentView"), (IMP)nomen_tab_content_view, "@@:");
41
+ objc_registerClassPair(Pv);
42
+ }
43
+ }
44
+ return Pv;
45
+ }
46
+
47
+ // The shared tab-view delegate: reports every tab switch — user
48
+ // clicks AND programmatic selectTabViewItem — by pushing the tab
49
+ // view's handle into the shared selection record (the on_select
50
+ // feed; the ring lives in Control.nm next to the click ring).
51
+ static void nomen_tab_did_select(id self, SEL cmd, id tv, id item) {
52
+ (void)self; (void)cmd; (void)item;
53
+ extern void nomen_select_push(unsigned long long);
54
+ nomen_select_push((unsigned long long)(void *)tv);
55
+ }
56
+ static id g_tab_delegate = 0;
57
+ static id nomen_tab_delegate(void) {
58
+ Class Td = objc_getClass("NomenTabsDelegate");
59
+ if (!Td) {
60
+ Td = objc_allocateClassPair(objc_getClass("NSObject"), "NomenTabsDelegate", 0);
61
+ if (Td) {
62
+ class_addMethod(Td, sel_registerName("tabView:didSelectTabViewItem:"),
63
+ (IMP)nomen_tab_did_select, "v@:@@");
64
+ objc_registerClassPair(Td);
65
+ }
66
+ }
67
+ if (!g_tab_delegate) {
68
+ g_tab_delegate = ((id(*)(id, SEL))objc_msgSend)(Td, sel_registerName("new"));
69
+ }
70
+ return g_tab_delegate;
71
+ }
72
+ ```
73
+ ```
74
+ #arch: aarch64_use_c
75
+ #platform: macos
76
+ #scope: file
77
+ static id nomen_tab_content_view(id self, SEL cmd) {
78
+ (void)cmd;
79
+ return self;
80
+ }
81
+ static id nomen_tab_page_class(void) {
82
+ Class Pv = objc_getClass("NomenTabPageView");
83
+ if (!Pv) {
84
+ Pv = objc_allocateClassPair(objc_getClass("NSView"), "NomenTabPageView", 0);
85
+ if (Pv) {
86
+ class_addMethod(Pv, sel_registerName("contentView"), (IMP)nomen_tab_content_view, "@@:");
87
+ objc_registerClassPair(Pv);
88
+ }
89
+ }
90
+ return Pv;
91
+ }
92
+
93
+ // The shared tab-view delegate (see the c twin above).
94
+ static void nomen_tab_did_select(id self, SEL cmd, id tv, id item) {
95
+ (void)self; (void)cmd; (void)item;
96
+ extern void nomen_select_push(unsigned long long);
97
+ nomen_select_push((unsigned long long)(void *)tv);
98
+ }
99
+ static id g_tab_delegate = 0;
100
+ static id nomen_tab_delegate(void) {
101
+ Class Td = objc_getClass("NomenTabsDelegate");
102
+ if (!Td) {
103
+ Td = objc_allocateClassPair(objc_getClass("NSObject"), "NomenTabsDelegate", 0);
104
+ if (Td) {
105
+ class_addMethod(Td, sel_registerName("tabView:didSelectTabViewItem:"),
106
+ (IMP)nomen_tab_did_select, "v@:@@");
107
+ objc_registerClassPair(Td);
108
+ }
109
+ }
110
+ if (!g_tab_delegate) {
111
+ g_tab_delegate = ((id(*)(id, SEL))objc_msgSend)(Td, sel_registerName("new"));
112
+ }
113
+ return g_tab_delegate;
114
+ }
115
+ ```
116
+ ```
117
+ #arch: c
118
+ #platform: macos
119
+ id tv = ((id(*)(id, SEL, CGRect))objc_msgSend)(
120
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSTabView"), sel_registerName("alloc")),
121
+ sel_registerName("initWithFrame:"),
122
+ ((CGRect(*)(double, double, double, double))CGRectMake)(0, 0, 300, 200));
123
+ for (long i = 0; i < (long)count; i++) {
124
+ id item = ((id(*)(id, SEL, id))objc_msgSend)(
125
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSTabViewItem"), sel_registerName("alloc")),
126
+ sel_registerName("initWithIdentifier:"), (id)0);
127
+ id page = ((id(*)(id, SEL, CGRect))objc_msgSend)(
128
+ ((id(*)(id, SEL))objc_msgSend)(nomen_tab_page_class(), sel_registerName("alloc")),
129
+ sel_registerName("initWithFrame:"),
130
+ ((CGRect(*)(double, double, double, double))CGRectMake)(0, 0, 0, 0));
131
+ ((void(*)(id, SEL, id))objc_msgSend)(
132
+ item, sel_registerName("setLabel:"),
133
+ ((id(*)(id, SEL, const char*))objc_msgSend)(
134
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), ""));
135
+ ((void(*)(id, SEL, id))objc_msgSend)(item, sel_registerName("setView:"), page);
136
+ ((void(*)(id, SEL))objc_msgSend)(page, sel_registerName("release"));
137
+ ((void(*)(id, SEL, id))objc_msgSend)(tv, sel_registerName("addTabViewItem:"), item);
138
+ ((void(*)(id, SEL))objc_msgSend)(item, sel_registerName("release"));
139
+ }
140
+ id contentView = ((id(*)(id, SEL))objc_msgSend)(
141
+ (id)window->handle, sel_registerName("contentView"));
142
+ ((void(*)(id, SEL, id))objc_msgSend)(
143
+ contentView, sel_registerName("addSubview:"), tv);
144
+ ((void(*)(id, SEL, id))objc_msgSend)(
145
+ tv, sel_registerName("setDelegate:"), nomen_tab_delegate());
146
+ self.handle = (uint64_t)tv;
147
+ ```
148
+ ```
149
+ #arch: aarch64_use_c
150
+ #platform: macos
151
+ id tv = ((id(*)(id, SEL, CGRect))objc_msgSend)(
152
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSTabView"), sel_registerName("alloc")),
153
+ sel_registerName("initWithFrame:"),
154
+ ((CGRect(*)(double, double, double, double))CGRectMake)(0, 0, 300, 200));
155
+ for (long i = 0; i < (long)count; i++) {
156
+ id item = ((id(*)(id, SEL, id))objc_msgSend)(
157
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSTabViewItem"), sel_registerName("alloc")),
158
+ sel_registerName("initWithIdentifier:"), (id)0);
159
+ id page = ((id(*)(id, SEL, CGRect))objc_msgSend)(
160
+ ((id(*)(id, SEL))objc_msgSend)(nomen_tab_page_class(), sel_registerName("alloc")),
161
+ sel_registerName("initWithFrame:"),
162
+ ((CGRect(*)(double, double, double, double))CGRectMake)(0, 0, 0, 0));
163
+ ((void(*)(id, SEL, id))objc_msgSend)(
164
+ item, sel_registerName("setLabel:"),
165
+ ((id(*)(id, SEL, const char*))objc_msgSend)(
166
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), ""));
167
+ ((void(*)(id, SEL, id))objc_msgSend)(item, sel_registerName("setView:"), page);
168
+ ((void(*)(id, SEL))objc_msgSend)(page, sel_registerName("release"));
169
+ ((void(*)(id, SEL, id))objc_msgSend)(tv, sel_registerName("addTabViewItem:"), item);
170
+ ((void(*)(id, SEL))objc_msgSend)(item, sel_registerName("release"));
171
+ }
172
+ id contentView = ((id(*)(id, SEL))objc_msgSend)(
173
+ (id)window->handle, sel_registerName("contentView"));
174
+ ((void(*)(id, SEL, id))objc_msgSend)(
175
+ contentView, sel_registerName("addSubview:"), tv);
176
+ ((void(*)(id, SEL, id))objc_msgSend)(
177
+ tv, sel_registerName("setDelegate:"), nomen_tab_delegate());
178
+ self->handle = (uint64_t)tv;
179
+ ```
180
+ ```
181
+ #arch: c
182
+ #platform: ios
183
+ /* TODO: iOS — no NSTabView counterpart (UITabBarController is
184
+ * app-level chrome, not an embeddable control; see GUI_PLAN Tier 2;
185
+ * defer). */
186
+ ```
187
+ ```
188
+ #arch: aarch64_use_c
189
+ #platform: ios
190
+ /* TODO: iOS (see #init) */
191
+ ```
192
+ }
193
+
194
+ // A Window-shaped handle to page `index`'s view: pass it to control
195
+ // constructors and `Container.layout` to host controls on that page. The
196
+ // value retains the page view (+1), so its scope-exit `#destroy` releases
197
+ // its OWN reference and the Tabs' stays balanced — keep the Tabs alive at
198
+ // least as long as the returned value.
199
+ pub func content_window = (self, int index, out Window) {
200
+ ```
201
+ #arch: c
202
+ #platform: macos
203
+ id item = ((id(*)(id, SEL, long))objc_msgSend)(
204
+ (id)self->handle, sel_registerName("tabViewItemAtIndex:"), (long)index);
205
+ id page = ((id(*)(id, SEL))objc_msgSend)(item, sel_registerName("view"));
206
+ extern void *_Window_traits[];
207
+ struct Window w;
208
+ w._vt = (void *)&_Window_traits;
209
+ w.handle = (uint64_t)page;
210
+ ((id(*)(id, SEL))objc_msgSend)(page, sel_registerName("retain"));
211
+ return w;
212
+ ```
213
+ ```
214
+ #arch: aarch64_use_c
215
+ #platform: macos
216
+ id item = ((id(*)(id, SEL, long))objc_msgSend)(
217
+ (id)self->handle, sel_registerName("tabViewItemAtIndex:"), (long)index);
218
+ id page = ((id(*)(id, SEL))objc_msgSend)(item, sel_registerName("view"));
219
+ extern void *Window_traits;
220
+ struct Window w;
221
+ w._vt = (void *)&Window_traits;
222
+ w.handle = (uint64_t)page;
223
+ ((id(*)(id, SEL))objc_msgSend)(page, sel_registerName("retain"));
224
+ return w;
225
+ ```
226
+ ```
227
+ #arch: c
228
+ #platform: ios
229
+ /* TODO: iOS (see #init) */
230
+ {
231
+ extern void *_Window_traits[];
232
+ struct Window w;
233
+ w._vt = (void *)&_Window_traits;
234
+ w.handle = 0;
235
+ return w;
236
+ }
237
+ ```
238
+ ```
239
+ #arch: aarch64_use_c
240
+ #platform: ios
241
+ /* TODO: iOS (see #init) */
242
+ {
243
+ extern void *Window_traits;
244
+ struct Window w;
245
+ w._vt = (void *)&Window_traits;
246
+ w.handle = 0;
247
+ return w;
248
+ }
249
+ ```
250
+ }
251
+
252
+ pub func set_label = (self, int index, string title) {
253
+ ```
254
+ #arch: c
255
+ #platform: macos
256
+ id item = ((id(*)(id, SEL, long))objc_msgSend)(
257
+ (id)self->handle, sel_registerName("tabViewItemAtIndex:"), (long)index);
258
+ ((void(*)(id, SEL, id))objc_msgSend)(
259
+ item, sel_registerName("setLabel:"),
260
+ ((id(*)(id, SEL, const char*))objc_msgSend)(
261
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), title.ptr));
262
+ ```
263
+ ```
264
+ #arch: aarch64_use_c
265
+ #platform: macos
266
+ id item = ((id(*)(id, SEL, long))objc_msgSend)(
267
+ (id)self->handle, sel_registerName("tabViewItemAtIndex:"), (long)index);
268
+ ((void(*)(id, SEL, id))objc_msgSend)(
269
+ item, sel_registerName("setLabel:"),
270
+ ((id(*)(id, SEL, const char*))objc_msgSend)(
271
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), title.ptr));
272
+ ```
273
+ ```
274
+ #arch: c
275
+ #platform: ios
276
+ /* TODO: iOS (see #init) */
277
+ ```
278
+ ```
279
+ #arch: aarch64_use_c
280
+ #platform: ios
281
+ /* TODO: iOS (see #init) */
282
+ ```
283
+ }
284
+
285
+ pub func set_selected = (self, int index) {
286
+ ```
287
+ #arch: c
288
+ #platform: macos
289
+ ((void(*)(id, SEL, long))objc_msgSend)(
290
+ (id)self->handle, sel_registerName("selectTabViewItemAtIndex:"), (long)index);
291
+ ```
292
+ ```
293
+ #arch: aarch64_use_c
294
+ #platform: macos
295
+ ((void(*)(id, SEL, long))objc_msgSend)(
296
+ (id)self->handle, sel_registerName("selectTabViewItemAtIndex:"), (long)index);
297
+ ```
298
+ ```
299
+ #arch: c
300
+ #platform: ios
301
+ /* TODO: iOS (see #init) */
302
+ ```
303
+ ```
304
+ #arch: aarch64_use_c
305
+ #platform: ios
306
+ /* TODO: iOS (see #init) */
307
+ ```
308
+ }
309
+
310
+ pub func selected_index = (self, out int) {
311
+ ```
312
+ #arch: c
313
+ #platform: macos
314
+ id item = ((id(*)(id, SEL))objc_msgSend)(
315
+ (id)self->handle, sel_registerName("selectedTabViewItem"));
316
+ if (!item) return 0;
317
+ return (int)((long(*)(id, SEL, id))objc_msgSend)(
318
+ (id)self->handle, sel_registerName("indexOfTabViewItem:"), item);
319
+ ```
320
+ ```
321
+ #arch: aarch64_use_c
322
+ #platform: macos
323
+ id item = ((id(*)(id, SEL))objc_msgSend)(
324
+ (id)self->handle, sel_registerName("selectedTabViewItem"));
325
+ if (!item) return 0;
326
+ return (int)((long(*)(id, SEL, id))objc_msgSend)(
327
+ (id)self->handle, sel_registerName("indexOfTabViewItem:"), item);
328
+ ```
329
+ ```
330
+ #arch: c
331
+ #platform: ios
332
+ /* TODO: iOS (see #init) */
333
+ return 0;
334
+ ```
335
+ ```
336
+ #arch: aarch64_use_c
337
+ #platform: ios
338
+ /* TODO: iOS (see #init) */
339
+ return 0;
340
+ ```
341
+ }
342
+
343
+ // The on_select desugar's drain (docs/HANDLERS.md): true when the
344
+ // selected tab changed since the last drain — user clicks AND
345
+ // programmatic set_selected (the delegate observes both; a
346
+ // pre-selection in #init therefore fires on the first frame). The
347
+ // handler body reads the page through selected_index().
348
+ pub func take_select = (self, out bool) {
349
+ ```
350
+ #arch: c
351
+ #platform: macos
352
+ extern long nomen_select_take(unsigned long long);
353
+ return (long)nomen_select_take((unsigned long long)self->handle);
354
+ ```
355
+ ```
356
+ #arch: aarch64_use_c
357
+ #platform: macos
358
+ extern long nomen_select_take(unsigned long long);
359
+ return (long)nomen_select_take((unsigned long long)self->handle);
360
+ ```
361
+ ```
362
+ #arch: c
363
+ #platform: ios
364
+ /* TODO: iOS (see #init) */
365
+ return false;
366
+ ```
367
+ ```
368
+ #arch: aarch64_use_c
369
+ #platform: ios
370
+ /* TODO: iOS (see #init) */
371
+ return false;
372
+ ```
373
+ }
374
+
375
+ pub func count = (self, out int) {
376
+ ```
377
+ #arch: c
378
+ #platform: macos
379
+ return (int)((long(*)(id, SEL))objc_msgSend)(
380
+ (id)self->handle, sel_registerName("numberOfTabViewItems"));
381
+ ```
382
+ ```
383
+ #arch: aarch64_use_c
384
+ #platform: macos
385
+ return (int)((long(*)(id, SEL))objc_msgSend)(
386
+ (id)self->handle, sel_registerName("numberOfTabViewItems"));
387
+ ```
388
+ ```
389
+ #arch: c
390
+ #platform: ios
391
+ /* TODO: iOS (see #init) */
392
+ return 0;
393
+ ```
394
+ ```
395
+ #arch: aarch64_use_c
396
+ #platform: ios
397
+ /* TODO: iOS (see #init) */
398
+ return 0;
399
+ ```
400
+ }
401
+
402
+ pub func set_hidden = (self, bool hidden) {
403
+ ```
404
+ #arch: c
405
+ #platform: macos
406
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(
407
+ (id)self->handle, sel_registerName("setHidden:"), hidden ? 1 : 0);
408
+ ```
409
+ ```
410
+ #arch: aarch64_use_c
411
+ #platform: macos
412
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(
413
+ (id)self->handle, sel_registerName("setHidden:"), hidden ? 1 : 0);
414
+ ```
415
+ }
416
+
417
+ // ── Control trait conformance ──
418
+ pub func set_frame = (ref self, int x, int y, int width, int height) {
419
+ ```
420
+ #arch: c
421
+ #platform: macos
422
+ ((void(*)(id, SEL, CGRect))objc_msgSend)(
423
+ (id)self->handle, sel_registerName("setFrame:"),
424
+ ((CGRect(*)(double, double, double, double))CGRectMake)((double)x, (double)y, (double)width, (double)height));
425
+ ```
426
+ ```
427
+ #arch: aarch64_use_c
428
+ #platform: macos
429
+ ((void(*)(id, SEL, CGRect))objc_msgSend)(
430
+ (id)self->handle, sel_registerName("setFrame:"),
431
+ ((CGRect(*)(double, double, double, double))CGRectMake)((double)x, (double)y, (double)width, (double)height));
432
+ ```
433
+ ```
434
+ #arch: c
435
+ #platform: ios
436
+ /* TODO: iOS (see #init) */
437
+ ```
438
+ ```
439
+ #arch: aarch64_use_c
440
+ #platform: ios
441
+ /* TODO: iOS (see #init) */
442
+ ```
443
+ }
444
+
445
+ pub func intrinsic_size = (self, out Size) {
446
+ var [w, h] = native_intrinsic(self.handle)
447
+ var s = Size()
448
+ s.width = w
449
+ s.height = h
450
+ return s
451
+ }
452
+
453
+ pub func measure = (self, BoxConstraints constraints, out Size) {
454
+ var Size s = self.intrinsic_size()
455
+ if s.width > constraints.max_width {
456
+ s.width = constraints.max_width
457
+ }
458
+ if s.width < constraints.min_width {
459
+ s.width = constraints.min_width
460
+ }
461
+ if s.height > constraints.max_height {
462
+ s.height = constraints.max_height
463
+ }
464
+ if s.height < constraints.min_height {
465
+ s.height = constraints.min_height
466
+ }
467
+ return s
468
+ }
469
+
470
+ func #destroy = () {
471
+ ```
472
+ #arch: c
473
+ #platform: macos
474
+ if (self->handle) {
475
+ ((void(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("removeFromSuperview"));
476
+ ((void(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("release"));
477
+ self->handle = 0;
478
+ }
479
+ ```
480
+ ```
481
+ #arch: aarch64_use_c
482
+ #platform: macos
483
+ if (self->handle) {
484
+ ((void(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("removeFromSuperview"));
485
+ ((void(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("release"));
486
+ self->handle = 0;
487
+ }
488
+ ```
489
+ ```
490
+ #arch: c
491
+ #platform: ios
492
+ /* TODO: iOS (see #init) */
493
+ ```
494
+ ```
495
+ #arch: aarch64_use_c
496
+ #platform: ios
497
+ /* TODO: iOS (see #init) */
498
+ ```
499
+ }
500
+ }
@@ -2,13 +2,23 @@
2
2
  * A read-only text label control
3
3
  *
4
4
  * An OWNING STRUCT (STRUCT_PLAN_3 Phase R, tranche 4 — the shape menu): the
5
- * AppKit handle plus the cached label text mv with the value, and the
6
- * `#destroy` releases what the handle names. The constructor's `self` is
7
- * the inline instance (the `.` accessor); methods keep the pointer form.
5
+ * single field is the AppKit handle, and the `#destroy` releases what it
6
+ * names. The constructor's `self` is the inline instance (the `.` accessor);
7
+ * methods keep the pointer form.
8
+ *
9
+ * The label carries NO Nomen-side text cache — sizing reads the native
10
+ * control (`native_intrinsic`), and `set_text` is a bare receiver that only
11
+ * mutates the native view. That keeps the struct write-once after
12
+ * construction, which is what lets the `#handle` twin mirror it (see
13
+ * GUI.md, "Click events" and the `#handle` note).
8
14
  **/
9
- pub mv struct Text : Control {
15
+ pub mv struct Text: Control {
10
16
  var uint64 handle = 0
11
- var text = ""
17
+
18
+ // The `#handle` hook synthesizes `NameHandle` — a copyable, non-owning
19
+ // twin (same public bare-self methods, no destroy) so closures can
20
+ // capture this control without moving it. See GUI.md, "Handles".
21
+ #handle = () { }
12
22
 
13
23
  pub func #init = (self, Window window) {
14
24
  ```
@@ -97,8 +107,7 @@ pub mv struct Text : Control {
97
107
  ```
98
108
  }
99
109
 
100
- pub func set_text = (ref self, string text) {
101
- self.text = text.copy()
110
+ pub func set_text = (self, string text) {
102
111
  ```
103
112
  #arch: c
104
113
  #platform: macos
@@ -133,22 +142,110 @@ pub mv struct Text : Control {
133
142
  ```
134
143
  }
135
144
 
145
+ // The label's current text, read from the native control (the label
146
+ // carries no Nomen-side text cache).
147
+ pub func get_text = (self, out string) {
148
+ ```
149
+ #arch: c
150
+ #platform: macos
151
+ id str = ((id(*)(id, SEL))objc_msgSend)(
152
+ (id)self->handle, sel_registerName("stringValue"));
153
+ const char *cstr = ((const char*(*)(id, SEL))objc_msgSend)(
154
+ str, sel_registerName("UTF8String"));
155
+ return (nomen_string){ strdup(cstr), (long)strlen(cstr) };
156
+ ```
157
+ ```
158
+ #arch: aarch64_use_c
159
+ #platform: macos
160
+ id str = ((id(*)(id, SEL))objc_msgSend)(
161
+ (id)self->handle, sel_registerName("stringValue"));
162
+ const char *cstr = ((const char*(*)(id, SEL))objc_msgSend)(
163
+ str, sel_registerName("UTF8String"));
164
+ return (nomen_string){ strdup(cstr), (long)strlen(cstr) };
165
+ ```
166
+ ```
167
+ #arch: c
168
+ #platform: ios
169
+ id str = ((id(*)(id, SEL))objc_msgSend)(
170
+ (id)self->handle, sel_registerName("text"));
171
+ const char *cstr = ((const char*(*)(id, SEL))objc_msgSend)(
172
+ str, sel_registerName("UTF8String"));
173
+ return (nomen_string){ strdup(cstr), (long)strlen(cstr) };
174
+ ```
175
+ ```
176
+ #arch: aarch64_use_c
177
+ #platform: ios
178
+ id str = ((id(*)(id, SEL))objc_msgSend)(
179
+ (id)self->handle, sel_registerName("text"));
180
+ const char *cstr = ((const char*(*)(id, SEL))objc_msgSend)(
181
+ str, sel_registerName("UTF8String"));
182
+ return (nomen_string){ strdup(cstr), (long)strlen(cstr) };
183
+ ```
184
+ }
185
+
186
+ // Switch the label between the regular and bold system font. Bold is for
187
+ // section headings, so they read as headers rather than sibling labels.
188
+ pub func set_bold = (self, bool bold) {
189
+ ```
190
+ #arch: c
191
+ #platform: macos
192
+ CGFloat size = ((CGFloat(*)(id, SEL))objc_msgSend)(
193
+ (id)objc_getClass("NSFont"), sel_registerName("systemFontSize"));
194
+ id font = ((id(*)(id, SEL, CGFloat))objc_msgSend)(
195
+ (id)objc_getClass("NSFont"),
196
+ sel_registerName(bold ? "boldSystemFontOfSize:" : "systemFontOfSize:"), size);
197
+ ((void(*)(id, SEL, id))objc_msgSend)((id)self->handle, sel_registerName("setFont:"), font);
198
+ ```
199
+ ```
200
+ #arch: aarch64_use_c
201
+ #platform: macos
202
+ CGFloat size = ((CGFloat(*)(id, SEL))objc_msgSend)(
203
+ (id)objc_getClass("NSFont"), sel_registerName("systemFontSize"));
204
+ id font = ((id(*)(id, SEL, CGFloat))objc_msgSend)(
205
+ (id)objc_getClass("NSFont"),
206
+ sel_registerName(bold ? "boldSystemFontOfSize:" : "systemFontOfSize:"), size);
207
+ ((void(*)(id, SEL, id))objc_msgSend)((id)self->handle, sel_registerName("setFont:"), font);
208
+ ```
209
+ ```
210
+ #arch: c
211
+ #platform: ios
212
+ CGFloat size = ((CGFloat(*)(id, SEL))objc_msgSend)(
213
+ (id)objc_getClass("UIFont"), sel_registerName("labelFontSize"));
214
+ id font = ((id(*)(id, SEL, CGFloat))objc_msgSend)(
215
+ (id)objc_getClass("UIFont"),
216
+ sel_registerName(bold ? "boldSystemFontOfSize:" : "systemFontOfSize:"), size);
217
+ ((void(*)(id, SEL, id))objc_msgSend)((id)self->handle, sel_registerName("setFont:"), font);
218
+ ```
219
+ ```
220
+ #arch: aarch64_use_c
221
+ #platform: ios
222
+ CGFloat size = ((CGFloat(*)(id, SEL))objc_msgSend)(
223
+ (id)objc_getClass("UIFont"), sel_registerName("labelFontSize"));
224
+ id font = ((id(*)(id, SEL, CGFloat))objc_msgSend)(
225
+ (id)objc_getClass("UIFont"),
226
+ sel_registerName(bold ? "boldSystemFontOfSize:" : "systemFontOfSize:"), size);
227
+ ((void(*)(id, SEL, id))objc_msgSend)((id)self->handle, sel_registerName("setFont:"), font);
228
+ ```
229
+ }
230
+
136
231
  // ── Control trait conformance ──
137
232
  // A text control sizes to its content. v1 assumes an 8px monospace font, so a
138
233
  // line is `text.length × 8` wide and 8px tall (see GUI.md "Native control
139
234
  // refactor"). The default frame is 0,0,0,0; layout drives the real rectangle.
140
235
 
141
236
  pub func measure = (self, BoxConstraints constraints, out Size) {
237
+ var [w, h] = native_intrinsic(self.handle)
142
238
  var s = Size()
143
- s.width = self.text.length * 8
144
- s.height = 8
239
+ s.width = w
240
+ s.height = h
145
241
  return s
146
242
  }
147
243
 
148
244
  pub func intrinsic_size = (self, out Size) {
245
+ var [w, h] = native_intrinsic(self.handle)
149
246
  var s = Size()
150
- s.width = self.text.length * 8
151
- s.height = 8
247
+ s.width = w
248
+ s.height = h
152
249
  return s
153
250
  }
154
251