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,501 @@
1
+ /**
2
+ * A window toolbar with labeled push-button items (NSToolbar)
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
+ * NSToolbar is delegate-driven: the shared delegate answers the identifier
10
+ * questions from the fixed item count and builds each item as a labeled
11
+ * push button (NSButton view) targeted at the shared action recorder — so
12
+ * `clicked_item` polls the last click edge-triggered, like Menu, and
13
+ * `on_item_select` is the registered form. Attaching
14
+ * a toolbar shrinks the window's contentView (AppKit owns the layout rect),
15
+ * so create the Toolbar BEFORE the first grid layout. One Toolbar per
16
+ * process (the shared delegate + tag storage — the same trade List and Menu
17
+ * already make). macOS-only (NSToolbar has no iOS counterpart; see GUI_PLAN
18
+ * Tier 2 — the iOS blocks are TODO stubs).
19
+ **/
20
+ pub mv struct Toolbar : Control {
21
+ var uint64 handle = 0
22
+
23
+ // File-scope helper: the shared delegate + action recorder (shared — one
24
+ // Toolbar per process).
25
+ pub func #init = (self, Window window, int count) {
26
+ ```
27
+ #arch: c
28
+ #platform: macos
29
+ #scope: file
30
+ static long g_toolbar_last_tag = -1;
31
+ static long g_toolbar_count = 0;
32
+ static id g_toolbar_delegate = 0;
33
+ // Per-item custom labels ("": fall back to "Item <index>"). Indexed
34
+ // by item tag; the delegate's item builder reads it lazily.
35
+ static char g_toolbar_labels[32][64];
36
+
37
+ static void nomen_toolbar_action(id self, SEL cmd, id sender) {
38
+ (void)self; (void)cmd;
39
+ g_toolbar_last_tag = ((long(*)(id, SEL))objc_msgSend)(sender, sel_registerName("tag"));
40
+ }
41
+
42
+ // The identifier list is "0"…"count-1" — the index doubles as the tag.
43
+ static id nomen_toolbar_identifiers(void) {
44
+ id array = ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSMutableArray"), sel_registerName("array"));
45
+ for (long i = 0; i < g_toolbar_count; i++) {
46
+ char buf[16];
47
+ snprintf(buf, sizeof(buf), "%ld", i);
48
+ ((void(*)(id, SEL, id))objc_msgSend)(array, sel_registerName("addObject:"),
49
+ ((id(*)(id, SEL, const char*))objc_msgSend)(
50
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), buf));
51
+ }
52
+ return array;
53
+ }
54
+
55
+ static id nomen_toolbar_item(id self, SEL cmd, id tv, id ident, long insert) {
56
+ (void)self; (void)cmd; (void)tv; (void)insert;
57
+ long idx = ((long(*)(id, SEL))objc_msgSend)(ident, sel_registerName("intValue"));
58
+ id item = ((id(*)(id, SEL, id))objc_msgSend)(
59
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSToolbarItem"), sel_registerName("alloc")),
60
+ sel_registerName("initWithItemIdentifier:"), ident);
61
+ char fallback[32];
62
+ snprintf(fallback, sizeof(fallback), "Item %ld", idx);
63
+ const char *text =
64
+ (idx >= 0 && idx < 32 && g_toolbar_labels[idx][0]) ? g_toolbar_labels[idx] : fallback;
65
+ id title = ((id(*)(id, SEL, const char*))objc_msgSend)(
66
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), text);
67
+ ((void(*)(id, SEL, id))objc_msgSend)(item, sel_registerName("setLabel:"), title);
68
+ ((void(*)(id, SEL, long))objc_msgSend)(item, sel_registerName("setTag:"), idx);
69
+ id btn = ((id(*)(id, SEL, CGRect))objc_msgSend)(
70
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSButton"), sel_registerName("alloc")),
71
+ sel_registerName("initWithFrame:"),
72
+ ((CGRect(*)(double, double, double, double))CGRectMake)(0, 0, 64, 28));
73
+ ((void(*)(id, SEL, unsigned long))objc_msgSend)(btn, sel_registerName("setButtonType:"), 1);
74
+ ((void(*)(id, SEL, id))objc_msgSend)(btn, sel_registerName("setTitle:"), title);
75
+ ((void(*)(id, SEL, SEL))objc_msgSend)(
76
+ btn, sel_registerName("setAction:"), sel_registerName("nomenToolbarAction:"));
77
+ ((void(*)(id, SEL, id))objc_msgSend)(btn, sel_registerName("setTarget:"), g_toolbar_delegate);
78
+ ((void(*)(id, SEL, id))objc_msgSend)(item, sel_registerName("setView:"), btn);
79
+ ((void(*)(id, SEL))objc_msgSend)(btn, sel_registerName("release"));
80
+ return item;
81
+ }
82
+
83
+ // Store an item's custom label and apply it to the live item (items
84
+ // are built lazily by the delegate, so the table the builder reads is
85
+ // the source of truth).
86
+ void nomen_toolbar_set_label(id toolbar, int idx, const char *text) {
87
+ if (idx < 0 || idx >= 32) return;
88
+ snprintf(g_toolbar_labels[idx], sizeof(g_toolbar_labels[idx]), "%s", text);
89
+ if (!toolbar) return;
90
+ id items = ((id(*)(id, SEL))objc_msgSend)(toolbar, sel_registerName("items"));
91
+ long n = ((long(*)(id, SEL))objc_msgSend)(items, sel_registerName("count"));
92
+ for (long i = 0; i < n; i++) {
93
+ id item = ((id(*)(id, SEL, long))objc_msgSend)(items, sel_registerName("objectAtIndex:"), i);
94
+ if (((long(*)(id, SEL))objc_msgSend)(item, sel_registerName("tag")) != idx) continue;
95
+ id title = ((id(*)(id, SEL, const char*))objc_msgSend)(
96
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), text);
97
+ ((void(*)(id, SEL, id))objc_msgSend)(item, sel_registerName("setLabel:"), title);
98
+ id view = ((id(*)(id, SEL))objc_msgSend)(item, sel_registerName("view"));
99
+ if (view) {
100
+ ((void(*)(id, SEL, id))objc_msgSend)(view, sel_registerName("setTitle:"), title);
101
+ }
102
+ }
103
+ }
104
+
105
+ static id nomen_toolbar_delegate_class(void) {
106
+ Class Td = objc_getClass("NomenToolbarDelegate");
107
+ if (!Td) {
108
+ Td = objc_allocateClassPair(objc_getClass("NSObject"), "NomenToolbarDelegate", 0);
109
+ if (Td) {
110
+ class_addMethod(Td, sel_registerName("toolbarAllowedItemIdentifiers:"),
111
+ (IMP)nomen_toolbar_identifiers, "@@:@");
112
+ class_addMethod(Td, sel_registerName("toolbarDefaultItemIdentifiers:"),
113
+ (IMP)nomen_toolbar_identifiers, "@@:@");
114
+ class_addMethod(Td, sel_registerName("toolbar:itemForItemIdentifier:willBeInsertedIntoToolbar:"),
115
+ (IMP)nomen_toolbar_item, "@@:@@@c");
116
+ objc_registerClassPair(Td);
117
+ }
118
+ }
119
+ if (!g_toolbar_delegate) {
120
+ g_toolbar_delegate = ((id(*)(id, SEL))objc_msgSend)(Td, sel_registerName("new"));
121
+ }
122
+ return g_toolbar_delegate;
123
+ }
124
+
125
+ // Edge-triggered read: the poll consumes the tag (resets to -1).
126
+ long nomen_toolbar_last_tag(void) {
127
+ long tag = g_toolbar_last_tag;
128
+ g_toolbar_last_tag = -1;
129
+ return tag;
130
+ }
131
+
132
+ // The on_item_select drain's consume-and-stash (see Menu.nm): the
133
+ // drain consumes the selected tag like the poll and stashes it for
134
+ // the handler body to read through Toolbar.selected_item.
135
+ long g_toolbar_selected_tag = -1;
136
+ unsigned char nomen_toolbar_take_select(void) {
137
+ long tag = nomen_toolbar_last_tag();
138
+ if (tag < 0) return 0;
139
+ g_toolbar_selected_tag = tag;
140
+ return 1;
141
+ }
142
+ long nomen_toolbar_selected_tag(void) {
143
+ return g_toolbar_selected_tag;
144
+ }
145
+ ```
146
+ ```
147
+ #arch: aarch64_use_c
148
+ #platform: macos
149
+ #scope: file
150
+ static long g_toolbar_last_tag = -1;
151
+ static long g_toolbar_count = 0;
152
+ static id g_toolbar_delegate = 0;
153
+ // Per-item custom labels ("": fall back to "Item <index>"). Indexed
154
+ // by item tag; the delegate's item builder reads it lazily.
155
+ static char g_toolbar_labels[32][64];
156
+
157
+ static void nomen_toolbar_action(id self, SEL cmd, id sender) {
158
+ (void)self; (void)cmd;
159
+ g_toolbar_last_tag = ((long(*)(id, SEL))objc_msgSend)(sender, sel_registerName("tag"));
160
+ }
161
+
162
+ // The identifier list is "0"…"count-1" — the index doubles as the tag.
163
+ static id nomen_toolbar_identifiers(void) {
164
+ id array = ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSMutableArray"), sel_registerName("array"));
165
+ for (long i = 0; i < g_toolbar_count; i++) {
166
+ char buf[16];
167
+ snprintf(buf, sizeof(buf), "%ld", i);
168
+ ((void(*)(id, SEL, id))objc_msgSend)(array, sel_registerName("addObject:"),
169
+ ((id(*)(id, SEL, const char*))objc_msgSend)(
170
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), buf));
171
+ }
172
+ return array;
173
+ }
174
+
175
+ static id nomen_toolbar_item(id self, SEL cmd, id tv, id ident, long insert) {
176
+ (void)self; (void)cmd; (void)tv; (void)insert;
177
+ long idx = ((long(*)(id, SEL))objc_msgSend)(ident, sel_registerName("intValue"));
178
+ id item = ((id(*)(id, SEL, id))objc_msgSend)(
179
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSToolbarItem"), sel_registerName("alloc")),
180
+ sel_registerName("initWithItemIdentifier:"), ident);
181
+ char fallback[32];
182
+ snprintf(fallback, sizeof(fallback), "Item %ld", idx);
183
+ const char *text =
184
+ (idx >= 0 && idx < 32 && g_toolbar_labels[idx][0]) ? g_toolbar_labels[idx] : fallback;
185
+ id title = ((id(*)(id, SEL, const char*))objc_msgSend)(
186
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), text);
187
+ ((void(*)(id, SEL, id))objc_msgSend)(item, sel_registerName("setLabel:"), title);
188
+ ((void(*)(id, SEL, long))objc_msgSend)(item, sel_registerName("setTag:"), idx);
189
+ id btn = ((id(*)(id, SEL, CGRect))objc_msgSend)(
190
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSButton"), sel_registerName("alloc")),
191
+ sel_registerName("initWithFrame:"),
192
+ ((CGRect(*)(double, double, double, double))CGRectMake)(0, 0, 64, 28));
193
+ ((void(*)(id, SEL, unsigned long))objc_msgSend)(btn, sel_registerName("setButtonType:"), 1);
194
+ ((void(*)(id, SEL, id))objc_msgSend)(btn, sel_registerName("setTitle:"), title);
195
+ ((void(*)(id, SEL, SEL))objc_msgSend)(
196
+ btn, sel_registerName("setAction:"), sel_registerName("nomenToolbarAction:"));
197
+ ((void(*)(id, SEL, id))objc_msgSend)(btn, sel_registerName("setTarget:"), g_toolbar_delegate);
198
+ ((void(*)(id, SEL, id))objc_msgSend)(item, sel_registerName("setView:"), btn);
199
+ ((void(*)(id, SEL))objc_msgSend)(btn, sel_registerName("release"));
200
+ return item;
201
+ }
202
+
203
+ // Store an item's custom label and apply it to the live item (items
204
+ // are built lazily by the delegate, so the table the builder reads is
205
+ // the source of truth).
206
+ void nomen_toolbar_set_label(id toolbar, int idx, const char *text) {
207
+ if (idx < 0 || idx >= 32) return;
208
+ snprintf(g_toolbar_labels[idx], sizeof(g_toolbar_labels[idx]), "%s", text);
209
+ if (!toolbar) return;
210
+ id items = ((id(*)(id, SEL))objc_msgSend)(toolbar, sel_registerName("items"));
211
+ long n = ((long(*)(id, SEL))objc_msgSend)(items, sel_registerName("count"));
212
+ for (long i = 0; i < n; i++) {
213
+ id item = ((id(*)(id, SEL, long))objc_msgSend)(items, sel_registerName("objectAtIndex:"), i);
214
+ if (((long(*)(id, SEL))objc_msgSend)(item, sel_registerName("tag")) != idx) continue;
215
+ id title = ((id(*)(id, SEL, const char*))objc_msgSend)(
216
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), text);
217
+ ((void(*)(id, SEL, id))objc_msgSend)(item, sel_registerName("setLabel:"), title);
218
+ id view = ((id(*)(id, SEL))objc_msgSend)(item, sel_registerName("view"));
219
+ if (view) {
220
+ ((void(*)(id, SEL, id))objc_msgSend)(view, sel_registerName("setTitle:"), title);
221
+ }
222
+ }
223
+ }
224
+
225
+ static id nomen_toolbar_delegate_class(void) {
226
+ Class Td = objc_getClass("NomenToolbarDelegate");
227
+ if (!Td) {
228
+ Td = objc_allocateClassPair(objc_getClass("NSObject"), "NomenToolbarDelegate", 0);
229
+ if (Td) {
230
+ class_addMethod(Td, sel_registerName("toolbarAllowedItemIdentifiers:"),
231
+ (IMP)nomen_toolbar_identifiers, "@@:@");
232
+ class_addMethod(Td, sel_registerName("toolbarDefaultItemIdentifiers:"),
233
+ (IMP)nomen_toolbar_identifiers, "@@:@");
234
+ class_addMethod(Td, sel_registerName("toolbar:itemForItemIdentifier:willBeInsertedIntoToolbar:"),
235
+ (IMP)nomen_toolbar_item, "@@:@@@c");
236
+ objc_registerClassPair(Td);
237
+ }
238
+ }
239
+ if (!g_toolbar_delegate) {
240
+ g_toolbar_delegate = ((id(*)(id, SEL))objc_msgSend)(Td, sel_registerName("new"));
241
+ }
242
+ return g_toolbar_delegate;
243
+ }
244
+
245
+ // Edge-triggered read: the poll consumes the tag (resets to -1).
246
+ long nomen_toolbar_last_tag(void) {
247
+ long tag = g_toolbar_last_tag;
248
+ g_toolbar_last_tag = -1;
249
+ return tag;
250
+ }
251
+
252
+ // The on_item_select drain's consume-and-stash (see the c twin
253
+ // above).
254
+ long g_toolbar_selected_tag = -1;
255
+ unsigned char nomen_toolbar_take_select(void) {
256
+ long tag = nomen_toolbar_last_tag();
257
+ if (tag < 0) return 0;
258
+ g_toolbar_selected_tag = tag;
259
+ return 1;
260
+ }
261
+ long nomen_toolbar_selected_tag(void) {
262
+ return g_toolbar_selected_tag;
263
+ }
264
+ ```
265
+ ```
266
+ #arch: c
267
+ #platform: macos
268
+ g_toolbar_count = (long)count;
269
+ id toolbar = ((id(*)(id, SEL, id))objc_msgSend)(
270
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSToolbar"), sel_registerName("alloc")),
271
+ sel_registerName("initWithIdentifier:"),
272
+ ((id(*)(id, SEL, const char*))objc_msgSend)(
273
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), "main"));
274
+ ((void(*)(id, SEL, id))objc_msgSend)(toolbar, sel_registerName("setDelegate:"), nomen_toolbar_delegate_class());
275
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(toolbar, sel_registerName("setAllowsUserCustomization:"), 0);
276
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(toolbar, sel_registerName("setAutosavesConfiguration:"), 0);
277
+ ((void(*)(id, SEL, id))objc_msgSend)((id)window->handle, sel_registerName("setToolbar:"), toolbar);
278
+ self.handle = (uint64_t)toolbar;
279
+ ```
280
+ ```
281
+ #arch: aarch64_use_c
282
+ #platform: macos
283
+ g_toolbar_count = (long)count;
284
+ id toolbar = ((id(*)(id, SEL, id))objc_msgSend)(
285
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSToolbar"), sel_registerName("alloc")),
286
+ sel_registerName("initWithIdentifier:"),
287
+ ((id(*)(id, SEL, const char*))objc_msgSend)(
288
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), "main"));
289
+ ((void(*)(id, SEL, id))objc_msgSend)(toolbar, sel_registerName("setDelegate:"), nomen_toolbar_delegate_class());
290
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(toolbar, sel_registerName("setAllowsUserCustomization:"), 0);
291
+ ((void(*)(id, SEL, BOOL))objc_msgSend)(toolbar, sel_registerName("setAutosavesConfiguration:"), 0);
292
+ ((void(*)(id, SEL, id))objc_msgSend)((id)window->handle, sel_registerName("setToolbar:"), toolbar);
293
+ self->handle = (uint64_t)toolbar;
294
+ ```
295
+ ```
296
+ #arch: c
297
+ #platform: ios
298
+ /* TODO: iOS — no NSToolbar counterpart for window chrome (see
299
+ * GUI_PLAN Tier 2; defer). */
300
+ ```
301
+ ```
302
+ #arch: aarch64_use_c
303
+ #platform: ios
304
+ /* TODO: iOS (see #init) */
305
+ ```
306
+ }
307
+
308
+ // Set an item's label (the text under its button). Items are built
309
+ // lazily by the shared delegate, so the label lands in the table the
310
+ // builder reads and is applied to the live item immediately.
311
+ pub func set_label = (self, int index, string label) {
312
+ ```
313
+ #arch: c
314
+ #platform: macos
315
+ extern void nomen_toolbar_set_label(id toolbar, int idx, const char *text);
316
+ nomen_toolbar_set_label((id)self->handle, index, label.ptr);
317
+ ```
318
+ ```
319
+ #arch: aarch64_use_c
320
+ #platform: macos
321
+ extern void nomen_toolbar_set_label(id toolbar, int idx, const char *text);
322
+ nomen_toolbar_set_label((id)self->handle, index, label.ptr);
323
+ ```
324
+ ```
325
+ #arch: c
326
+ #platform: ios
327
+ /* TODO: iOS (see #init) */
328
+ ```
329
+ ```
330
+ #arch: aarch64_use_c
331
+ #platform: ios
332
+ /* TODO: iOS (see #init) */
333
+ ```
334
+ }
335
+
336
+ // The fixed item count.
337
+ pub func count = (self, out int) {
338
+ ```
339
+ #arch: c
340
+ #platform: macos
341
+ id items = ((id(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("items"));
342
+ return (int)((long(*)(id, SEL))objc_msgSend)(items, sel_registerName("count"));
343
+ ```
344
+ ```
345
+ #arch: aarch64_use_c
346
+ #platform: macos
347
+ id items = ((id(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("items"));
348
+ return (int)((long(*)(id, SEL))objc_msgSend)(items, sel_registerName("count"));
349
+ ```
350
+ ```
351
+ #arch: c
352
+ #platform: ios
353
+ /* TODO: iOS (see #init) */
354
+ return 0;
355
+ ```
356
+ ```
357
+ #arch: aarch64_use_c
358
+ #platform: ios
359
+ /* TODO: iOS (see #init) */
360
+ return 0;
361
+ ```
362
+ }
363
+
364
+ // The tag of the most recently clicked item since the last read
365
+ // (edge-triggered; -1 = none). Poll it in the manual loop.
366
+ pub func clicked_item = (self, out int) {
367
+ ```
368
+ #arch: c
369
+ #platform: macos
370
+ extern long nomen_toolbar_last_tag(void);
371
+ return (int)nomen_toolbar_last_tag();
372
+ ```
373
+ ```
374
+ #arch: aarch64_use_c
375
+ #platform: macos
376
+ extern long nomen_toolbar_last_tag(void);
377
+ return (int)nomen_toolbar_last_tag();
378
+ ```
379
+ ```
380
+ #arch: c
381
+ #platform: ios
382
+ /* TODO: iOS (see #init) */
383
+ return -1;
384
+ ```
385
+ ```
386
+ #arch: aarch64_use_c
387
+ #platform: ios
388
+ /* TODO: iOS (see #init) */
389
+ return -1;
390
+ ```
391
+ }
392
+
393
+ // The on_item_select desugar's drain (docs/HANDLERS.md): the synthesized
394
+ // pump arm polls this per frame. The selection is CONSUMED by the drain
395
+ // — like the poll, one record has one consumer, so a selection fires an
396
+ // arm exactly once — and the consumed tag is stashed for the handler
397
+ // body, which reads it through selected_item. The poll and the drain
398
+ // share one record: a selection consumed by one never reaches the other.
399
+ pub func take_item_select = (self, out bool) {
400
+ ```
401
+ #arch: c
402
+ #platform: macos
403
+ extern unsigned char nomen_toolbar_take_select(void);
404
+ return nomen_toolbar_take_select();
405
+ ```
406
+ ```
407
+ #arch: aarch64_use_c
408
+ #platform: macos
409
+ extern unsigned char nomen_toolbar_take_select(void);
410
+ return nomen_toolbar_take_select();
411
+ ```
412
+ ```
413
+ #arch: c
414
+ #platform: ios
415
+ /* TODO: iOS (see #init) */
416
+ return false;
417
+ ```
418
+ ```
419
+ #arch: aarch64_use_c
420
+ #platform: ios
421
+ /* TODO: iOS (see #init) */
422
+ return false;
423
+ ```
424
+ }
425
+
426
+ // The tag the last take_item_select consumed (-1 before the first
427
+ // selection) — the handler body's payload getter, the control-scoped
428
+ // analog of the dispatch-window getters (win.click_x() et al).
429
+ pub func selected_item = (self, out int) {
430
+ ```
431
+ #arch: c
432
+ #platform: macos
433
+ extern long nomen_toolbar_selected_tag(void);
434
+ return (int)nomen_toolbar_selected_tag();
435
+ ```
436
+ ```
437
+ #arch: aarch64_use_c
438
+ #platform: macos
439
+ extern long nomen_toolbar_selected_tag(void);
440
+ return (int)nomen_toolbar_selected_tag();
441
+ ```
442
+ ```
443
+ #arch: c
444
+ #platform: ios
445
+ /* TODO: iOS (see #init) */
446
+ return -1;
447
+ ```
448
+ ```
449
+ #arch: aarch64_use_c
450
+ #platform: ios
451
+ /* TODO: iOS (see #init) */
452
+ return -1;
453
+ ```
454
+ }
455
+
456
+ // ── Control trait conformance ──
457
+ // A toolbar is window chrome: the layout engine never frames it (AppKit
458
+ // owns the layout rect and shrinks the contentView itself).
459
+ pub func set_frame = (ref self, int x, int y, int width, int height) {
460
+ // No-op: the NSWindow carries the toolbar's geometry.
461
+ }
462
+
463
+ pub func intrinsic_size = (self, out Size) {
464
+ var s = Size()
465
+ return s
466
+ }
467
+
468
+ pub func measure = (self, BoxConstraints constraints, out Size) {
469
+ var s = Size()
470
+ return s
471
+ }
472
+
473
+ func #destroy = () {
474
+ ```
475
+ #arch: c
476
+ #platform: macos
477
+ if (self->handle) {
478
+ ((void(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("release"));
479
+ self->handle = 0;
480
+ }
481
+ ```
482
+ ```
483
+ #arch: aarch64_use_c
484
+ #platform: macos
485
+ if (self->handle) {
486
+ ((void(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("release"));
487
+ self->handle = 0;
488
+ }
489
+ ```
490
+ ```
491
+ #arch: c
492
+ #platform: ios
493
+ /* TODO: iOS (see #init) */
494
+ ```
495
+ ```
496
+ #arch: aarch64_use_c
497
+ #platform: ios
498
+ /* TODO: iOS (see #init) */
499
+ ```
500
+ }
501
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Tooltip helpers — attach hover text to any control by its handle
3
+ *
4
+ * Not a control: a tooltip is one property of the view the handle names,
5
+ * so this is a pair of free functions over `view.toolTip` (macOS). The
6
+ * helper shape means ANY control gains tooltips without per-control API
7
+ * surface — pass `button.handle`. iOS has no hover concept (TODO stubs;
8
+ * see GUI_PLAN Tier 1 #18).
9
+ **/
10
+
11
+ // Attach (or clear, with "") hover text for the view `handle` names.
12
+ pub func set_tooltip = (uint64 handle, string text) {
13
+ ```
14
+ #arch: c
15
+ #platform: macos
16
+ ((void(*)(id, SEL, id))objc_msgSend)(
17
+ (id)handle, sel_registerName("setToolTip:"),
18
+ ((id(*)(id, SEL, const char*))objc_msgSend)(
19
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), text.ptr));
20
+ ```
21
+ ```
22
+ #arch: aarch64_use_c
23
+ #platform: macos
24
+ ((void(*)(id, SEL, id))objc_msgSend)(
25
+ (id)handle, sel_registerName("setToolTip:"),
26
+ ((id(*)(id, SEL, const char*))objc_msgSend)(
27
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), text.ptr));
28
+ ```
29
+ ```
30
+ #arch: c
31
+ #platform: ios
32
+ /* TODO: iOS — no hover/tooltips (see GUI_PLAN Tier 1 #18). */
33
+ ```
34
+ ```
35
+ #arch: aarch64_use_c
36
+ #platform: ios
37
+ /* TODO: iOS — no hover/tooltips (see GUI_PLAN Tier 1 #18). */
38
+ ```
39
+ }
40
+
41
+ // The tooltip text currently attached to the view `handle` names ("" when
42
+ // none).
43
+ pub func get_tooltip = (uint64 handle, out string) {
44
+ ```
45
+ #arch: c
46
+ #platform: macos
47
+ id str = ((id(*)(id, SEL))objc_msgSend)(
48
+ (id)handle, sel_registerName("toolTip"));
49
+ if (!str) return (nomen_string){ strdup(""), 0 };
50
+ const char *cstr = ((const char*(*)(id, SEL))objc_msgSend)(
51
+ str, sel_registerName("UTF8String"));
52
+ return (nomen_string){ strdup(cstr), (long)strlen(cstr) };
53
+ ```
54
+ ```
55
+ #arch: aarch64_use_c
56
+ #platform: macos
57
+ id str = ((id(*)(id, SEL))objc_msgSend)(
58
+ (id)handle, sel_registerName("toolTip"));
59
+ if (!str) return (nomen_string){ strdup(""), 0 };
60
+ const char *cstr = ((const char*(*)(id, SEL))objc_msgSend)(
61
+ str, sel_registerName("UTF8String"));
62
+ return (nomen_string){ strdup(cstr), (long)strlen(cstr) };
63
+ ```
64
+ ```
65
+ #arch: c
66
+ #platform: ios
67
+ /* TODO: iOS (see set_tooltip) */
68
+ return (nomen_string){ strdup(""), 0 };
69
+ ```
70
+ ```
71
+ #arch: aarch64_use_c
72
+ #platform: ios
73
+ /* TODO: iOS (see set_tooltip) */
74
+ return (nomen_string){ strdup(""), 0 };
75
+ ```
76
+ }