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.
- package/audit_runtime.c +12 -2
- package/core/System/Arena.nm +8 -1
- package/core/System/Buffer.nm +397 -8
- package/core/System/ClassBuffer.nm +156 -0
- package/core/System/Controls/Alert.nm +326 -0
- package/core/System/Controls/App.nm +147 -0
- package/core/System/Controls/Button.nm +119 -1
- package/core/System/Controls/CheckBox.nm +25 -1
- package/core/System/Controls/ColorPicker.nm +307 -0
- package/core/System/Controls/ComboBox.nm +430 -0
- package/core/System/Controls/Container.nm +843 -9
- package/core/System/Controls/Control.nm +443 -0
- package/core/System/Controls/DatePicker.nm +288 -0
- package/core/System/Controls/Form.nm +70 -0
- package/core/System/Controls/GroupBox.nm +267 -0
- package/core/System/Controls/ImageView.nm +311 -0
- package/core/System/Controls/LevelIndicator.nm +305 -0
- package/core/System/Controls/ListView.nm +633 -0
- package/core/System/Controls/Menu.nm +428 -0
- package/core/System/Controls/NumberInput.nm +56 -0
- package/core/System/Controls/OtpInput.nm +50 -0
- package/core/System/Controls/OutlineView.nm +598 -0
- package/core/System/Controls/Pagination.nm +142 -0
- package/core/System/Controls/Popover.nm +296 -0
- package/core/System/Controls/Progress.nm +348 -0
- package/core/System/Controls/Radio.nm +292 -0
- package/core/System/Controls/Scrollable.nm +584 -0
- package/core/System/Controls/SearchField.nm +326 -0
- package/core/System/Controls/SecureField.nm +344 -0
- package/core/System/Controls/Segmented.nm +380 -0
- package/core/System/Controls/Select.nm +340 -0
- package/core/System/Controls/Separator.nm +198 -0
- package/core/System/Controls/Sheet.nm +329 -0
- package/core/System/Controls/Slider.nm +315 -0
- package/core/System/Controls/Spinner.nm +287 -0
- package/core/System/Controls/SplitView.nm +509 -0
- package/core/System/Controls/Stepper.nm +349 -0
- package/core/System/Controls/Switch.nm +259 -0
- package/core/System/Controls/Table.nm +833 -0
- package/core/System/Controls/Tabs.nm +500 -0
- package/core/System/Controls/Text.nm +108 -11
- package/core/System/Controls/TextBox.nm +113 -2
- package/core/System/Controls/TextView.nm +329 -0
- package/core/System/Controls/Toggle.nm +346 -0
- package/core/System/Controls/Toolbar.nm +501 -0
- package/core/System/Controls/Tooltip.nm +76 -0
- package/core/System/Controls/Window.nm +1548 -91
- package/core/System/LinkedList.nm +8 -1
- package/core/System/List.nm +97 -7
- package/core/System/Map.nm +191 -18
- package/core/System/Mutex.nm +4 -4
- package/core/System/Random.nm +3 -4
- package/core/System/Set.nm +101 -13
- package/core/System/StableList.nm +371 -0
- package/core/System/Stream/Directory.nm +2 -2
- package/core/System/Stream/File.nm +2 -2
- package/core/System/Stream/Http.nm +2 -2
- package/core/System/String.nm +10 -5
- package/core/System/StringBuilder.nm +213 -2
- package/core/System/Text/CharIndex.nm +9 -9
- package/core/System/Text/Json.nm +60 -46
- package/core/System/Text/JsonTree.nm +120 -92
- package/core/System/Text/Regex.nm +23 -18
- package/core/System/Text/Utf8.nm +5 -5
- package/core/System/float.nm +36 -22
- package/core/System/int.nm +80 -28
- package/core/System/int16.nm +11 -0
- package/core/System/int32.nm +11 -0
- package/core/System/int64.nm +11 -0
- package/core/System/int8.nm +11 -0
- package/core/System/uint.nm +11 -0
- package/core/System/uint16.nm +11 -0
- package/core/System/uint32.nm +11 -0
- package/core/System/uint64.nm +11 -0
- package/core/System/uint8.nm +11 -0
- package/core/docs/System/StringBuilder.md +6 -0
- package/core/docs/System/Text/JsonTree.md +3 -2
- package/dist/index.mjs +38332 -30604
- package/package.json +1 -1
- package/src/bench_loop.nm +9 -9
|
@@ -0,0 +1,584 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A scrolling viewport hosting arbitrary controls on a document view
|
|
3
|
+
*
|
|
4
|
+
* An OWNING STRUCT (STRUCT_PLAN_3 Phase R, tranche 4 — the shape menu): the
|
|
5
|
+
* fields are platform handles, so the value is movable and its `#destroy`
|
|
6
|
+
* releases what they name. The constructor's `self` is the inline instance
|
|
7
|
+
* (the `.` accessor); methods keep the pointer form.
|
|
8
|
+
*
|
|
9
|
+
* The scroll view is framed like any control (it sits in a Grid cell), but
|
|
10
|
+
* its children live on a DOCUMENT VIEW: `content_window` hands back a
|
|
11
|
+
* Window-shaped value whose `contentView` is the document view itself (the
|
|
12
|
+
* NomenDocumentView NSView subclass answers `-contentView` with `self`), so
|
|
13
|
+
* control constructors and `Container.layout` work unchanged. The document
|
|
14
|
+
* view stays unflipped, so the engine's y-flip against `content_height()`
|
|
15
|
+
* (the document height) is the existing math — see the Scrollable design
|
|
16
|
+
* note in GUI.md. Per relayout pass: measure the content grid unbounded,
|
|
17
|
+
* `set_content_size`, then `content_grid.layout(content)`. `content_click`
|
|
18
|
+
* translates window-space clicks into document coordinates so content
|
|
19
|
+
* children can be hit-tested while scrolled. iOS defers to UIScrollView
|
|
20
|
+
* (TODO stubs; see GUI_PLAN Tier 2).
|
|
21
|
+
**/
|
|
22
|
+
pub mv struct Scrollable: Control {
|
|
23
|
+
var uint64 handle = 0
|
|
24
|
+
var uint64 doc = 0
|
|
25
|
+
|
|
26
|
+
// File-scope helper: the document view class. It answers `-contentView`
|
|
27
|
+
// with `self` so Window-expecting constructors add their controls to the
|
|
28
|
+
// document view (registered once, like NomenResizeDelegate).
|
|
29
|
+
pub func #init = (self, Window window) {
|
|
30
|
+
```
|
|
31
|
+
#arch: c
|
|
32
|
+
#platform: macos
|
|
33
|
+
#scope: file
|
|
34
|
+
static id nomen_doc_content_view(id self, SEL cmd) {
|
|
35
|
+
(void)cmd;
|
|
36
|
+
return self;
|
|
37
|
+
}
|
|
38
|
+
static id nomen_document_view_class(void) {
|
|
39
|
+
Class Dv = objc_getClass("NomenDocumentView");
|
|
40
|
+
if (!Dv) {
|
|
41
|
+
Dv = objc_allocateClassPair(objc_getClass("NSView"), "NomenDocumentView", 0);
|
|
42
|
+
if (Dv) {
|
|
43
|
+
class_addMethod(Dv, sel_registerName("contentView"), (IMP)nomen_doc_content_view, "@@:");
|
|
44
|
+
objc_registerClassPair(Dv);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return Dv;
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
```
|
|
51
|
+
#arch: aarch64_use_c
|
|
52
|
+
#platform: macos
|
|
53
|
+
#scope: file
|
|
54
|
+
static id nomen_doc_content_view(id self, SEL cmd) {
|
|
55
|
+
(void)cmd;
|
|
56
|
+
return self;
|
|
57
|
+
}
|
|
58
|
+
static id nomen_document_view_class(void) {
|
|
59
|
+
Class Dv = objc_getClass("NomenDocumentView");
|
|
60
|
+
if (!Dv) {
|
|
61
|
+
Dv = objc_allocateClassPair(objc_getClass("NSView"), "NomenDocumentView", 0);
|
|
62
|
+
if (Dv) {
|
|
63
|
+
class_addMethod(Dv, sel_registerName("contentView"), (IMP)nomen_doc_content_view, "@@:");
|
|
64
|
+
objc_registerClassPair(Dv);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return Dv;
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
```
|
|
71
|
+
#arch: c
|
|
72
|
+
#platform: macos
|
|
73
|
+
id sv = ((id(*)(id, SEL, CGRect))objc_msgSend)(
|
|
74
|
+
((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSScrollView"), sel_registerName("alloc")),
|
|
75
|
+
sel_registerName("initWithFrame:"),
|
|
76
|
+
((CGRect(*)(double, double, double, double))CGRectMake)(0, 0, 240, 160));
|
|
77
|
+
((void(*)(id, SEL, BOOL))objc_msgSend)(sv, sel_registerName("setHasVerticalScroller:"), 1);
|
|
78
|
+
((void(*)(id, SEL, BOOL))objc_msgSend)(sv, sel_registerName("setDrawsBackground:"), 0);
|
|
79
|
+
id doc = ((id(*)(id, SEL, CGRect))objc_msgSend)(
|
|
80
|
+
((id(*)(id, SEL))objc_msgSend)(nomen_document_view_class(), sel_registerName("alloc")),
|
|
81
|
+
sel_registerName("initWithFrame:"),
|
|
82
|
+
((CGRect(*)(double, double, double, double))CGRectMake)(0, 0, 0, 0));
|
|
83
|
+
((void(*)(id, SEL, id))objc_msgSend)(sv, sel_registerName("setDocumentView:"), doc);
|
|
84
|
+
((void(*)(id, SEL))objc_msgSend)(doc, sel_registerName("release"));
|
|
85
|
+
id contentView = ((id(*)(id, SEL))objc_msgSend)(
|
|
86
|
+
(id)window->handle, sel_registerName("contentView"));
|
|
87
|
+
((void(*)(id, SEL, id))objc_msgSend)(
|
|
88
|
+
contentView, sel_registerName("addSubview:"), sv);
|
|
89
|
+
self.handle = (uint64_t)sv;
|
|
90
|
+
self.doc = (uint64_t)((id(*)(id, SEL))objc_msgSend)(sv, sel_registerName("documentView"));
|
|
91
|
+
```
|
|
92
|
+
```
|
|
93
|
+
#arch: aarch64_use_c
|
|
94
|
+
#platform: macos
|
|
95
|
+
id sv = ((id(*)(id, SEL, CGRect))objc_msgSend)(
|
|
96
|
+
((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSScrollView"), sel_registerName("alloc")),
|
|
97
|
+
sel_registerName("initWithFrame:"),
|
|
98
|
+
((CGRect(*)(double, double, double, double))CGRectMake)(0, 0, 240, 160));
|
|
99
|
+
((void(*)(id, SEL, BOOL))objc_msgSend)(sv, sel_registerName("setHasVerticalScroller:"), 1);
|
|
100
|
+
((void(*)(id, SEL, BOOL))objc_msgSend)(sv, sel_registerName("setDrawsBackground:"), 0);
|
|
101
|
+
id doc = ((id(*)(id, SEL, CGRect))objc_msgSend)(
|
|
102
|
+
((id(*)(id, SEL))objc_msgSend)(nomen_document_view_class(), sel_registerName("alloc")),
|
|
103
|
+
sel_registerName("initWithFrame:"),
|
|
104
|
+
((CGRect(*)(double, double, double, double))CGRectMake)(0, 0, 0, 0));
|
|
105
|
+
((void(*)(id, SEL, id))objc_msgSend)(sv, sel_registerName("setDocumentView:"), doc);
|
|
106
|
+
((void(*)(id, SEL))objc_msgSend)(doc, sel_registerName("release"));
|
|
107
|
+
id contentView = ((id(*)(id, SEL))objc_msgSend)(
|
|
108
|
+
(id)window->handle, sel_registerName("contentView"));
|
|
109
|
+
((void(*)(id, SEL, id))objc_msgSend)(
|
|
110
|
+
contentView, sel_registerName("addSubview:"), sv);
|
|
111
|
+
self->handle = (uint64_t)sv;
|
|
112
|
+
self->doc = (uint64_t)((id(*)(id, SEL))objc_msgSend)(sv, sel_registerName("documentView"));
|
|
113
|
+
```
|
|
114
|
+
```
|
|
115
|
+
#arch: c
|
|
116
|
+
#platform: ios
|
|
117
|
+
/* TODO: iOS — UIScrollView + a UIView document view; the constructors'
|
|
118
|
+
* rootViewController.view path expects a UIWindow, so content_window
|
|
119
|
+
* needs the same `-contentView` trick on a UIView subclass (see
|
|
120
|
+
* GUI_PLAN Tier 2; defer with the other iOS stubs). */
|
|
121
|
+
```
|
|
122
|
+
```
|
|
123
|
+
#arch: aarch64_use_c
|
|
124
|
+
#platform: ios
|
|
125
|
+
/* TODO: iOS (see #init) */
|
|
126
|
+
```
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// A Window-shaped handle to the document view: pass it to control
|
|
130
|
+
// constructors and `Container.layout` to host controls in the scroll
|
|
131
|
+
// view. The value retains the document view (+1), so its scope-exit
|
|
132
|
+
// `#destroy` releases its OWN reference and the Scrollable's stays
|
|
133
|
+
// balanced — keep the Scrollable alive at least as long as the returned
|
|
134
|
+
// value.
|
|
135
|
+
pub func content_window = (self, out Window) {
|
|
136
|
+
```
|
|
137
|
+
#arch: c
|
|
138
|
+
#platform: macos
|
|
139
|
+
extern void *_Window_traits[];
|
|
140
|
+
struct Window w;
|
|
141
|
+
w._vt = (void *)&_Window_traits;
|
|
142
|
+
w.handle = self->doc;
|
|
143
|
+
((id(*)(id, SEL))objc_msgSend)((id)self->doc, sel_registerName("retain"));
|
|
144
|
+
return w;
|
|
145
|
+
```
|
|
146
|
+
```
|
|
147
|
+
#arch: aarch64_use_c
|
|
148
|
+
#platform: macos
|
|
149
|
+
extern void *Window_traits;
|
|
150
|
+
struct Window w;
|
|
151
|
+
w._vt = (void *)&Window_traits;
|
|
152
|
+
w.handle = self->doc;
|
|
153
|
+
((id(*)(id, SEL))objc_msgSend)((id)self->doc, sel_registerName("retain"));
|
|
154
|
+
return w;
|
|
155
|
+
```
|
|
156
|
+
```
|
|
157
|
+
#arch: c
|
|
158
|
+
#platform: ios
|
|
159
|
+
/* TODO: iOS (see #init) */
|
|
160
|
+
{
|
|
161
|
+
extern void *_Window_traits[];
|
|
162
|
+
struct Window w;
|
|
163
|
+
w._vt = (void *)&_Window_traits;
|
|
164
|
+
w.handle = 0;
|
|
165
|
+
return w;
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
```
|
|
169
|
+
#arch: aarch64_use_c
|
|
170
|
+
#platform: ios
|
|
171
|
+
/* TODO: iOS (see #init) */
|
|
172
|
+
{
|
|
173
|
+
extern void *Window_traits;
|
|
174
|
+
struct Window w;
|
|
175
|
+
w._vt = (void *)&Window_traits;
|
|
176
|
+
w.handle = 0;
|
|
177
|
+
return w;
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// The document view's native handle — pair with `handle` to register
|
|
183
|
+
// this scroll view's document via `Container.set_document` (the
|
|
184
|
+
// Window.run relayout registry). Scalars, so the registration call
|
|
185
|
+
// never holds two borrows of the same owner.
|
|
186
|
+
pub func doc_handle = (self, out uint64) {
|
|
187
|
+
return self.doc
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Size the document view to the laid-out content. Call between the
|
|
191
|
+
// content grid's unbounded `measure` and its `layout(content)` — the
|
|
192
|
+
// flip needs the document height to equal the content height before
|
|
193
|
+
// frames are applied (see the Scrollable design note in GUI.md). The
|
|
194
|
+
// height is clamped UP to the viewport: an unflipped document shorter
|
|
195
|
+
// than its clip view sits at the clip's BOTTOM, so a short list would
|
|
196
|
+
// render bunched at the bottom of the scroll region — filling the
|
|
197
|
+
// viewport keeps the content top-anchored (and drops the scrollbar).
|
|
198
|
+
pub func set_content_size = (self, int width, int height) {
|
|
199
|
+
```
|
|
200
|
+
#arch: c
|
|
201
|
+
#platform: macos
|
|
202
|
+
id clip = ((id(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("contentView"));
|
|
203
|
+
CGRect clip_bounds = ((CGRect(*)(id, SEL))objc_msgSend)(clip, sel_registerName("bounds"));
|
|
204
|
+
double frame_h = (double)height;
|
|
205
|
+
if (frame_h < clip_bounds.size.height) frame_h = clip_bounds.size.height;
|
|
206
|
+
((void(*)(id, SEL, CGSize))objc_msgSend)(
|
|
207
|
+
(id)self->doc, sel_registerName("setFrameSize:"),
|
|
208
|
+
((CGSize(*)(double, double))CGSizeMake)((double)width, frame_h));
|
|
209
|
+
```
|
|
210
|
+
```
|
|
211
|
+
#arch: aarch64_use_c
|
|
212
|
+
#platform: macos
|
|
213
|
+
id clip = ((id(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("contentView"));
|
|
214
|
+
CGRect clip_bounds = ((CGRect(*)(id, SEL))objc_msgSend)(clip, sel_registerName("bounds"));
|
|
215
|
+
double frame_h = (double)height;
|
|
216
|
+
if (frame_h < clip_bounds.size.height) frame_h = clip_bounds.size.height;
|
|
217
|
+
((void(*)(id, SEL, CGSize))objc_msgSend)(
|
|
218
|
+
(id)self->doc, sel_registerName("setFrameSize:"),
|
|
219
|
+
((CGSize(*)(double, double))CGSizeMake)((double)width, frame_h));
|
|
220
|
+
```
|
|
221
|
+
```
|
|
222
|
+
#arch: c
|
|
223
|
+
#platform: ios
|
|
224
|
+
/* TODO: iOS (see #init) */
|
|
225
|
+
```
|
|
226
|
+
```
|
|
227
|
+
#arch: aarch64_use_c
|
|
228
|
+
#platform: ios
|
|
229
|
+
/* TODO: iOS (see #init) */
|
|
230
|
+
```
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Scroll so the top of the document is visible. The document view is
|
|
234
|
+
// unflipped (the engine's flip math owns the coordinates), and NSScrollView
|
|
235
|
+
// initially shows an unflipped document's bottom-left corner — call once
|
|
236
|
+
// after the first layout.
|
|
237
|
+
pub func scroll_to_top = (self) {
|
|
238
|
+
```
|
|
239
|
+
#arch: c
|
|
240
|
+
#platform: macos
|
|
241
|
+
id clip = ((id(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("contentView"));
|
|
242
|
+
id doc = ((id(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("documentView"));
|
|
243
|
+
CGRect doc_frame = ((CGRect(*)(id, SEL))objc_msgSend)(doc, sel_registerName("frame"));
|
|
244
|
+
CGRect clip_bounds = ((CGRect(*)(id, SEL))objc_msgSend)(clip, sel_registerName("bounds"));
|
|
245
|
+
// Set the clip's bounds origin directly — the one primitive the live
|
|
246
|
+
// scroll machinery can't constrain short of the edge. The unflipped
|
|
247
|
+
// document's top edge is at doc height; the visible origin sits
|
|
248
|
+
// `doc_h - clip_h` up from the bottom.
|
|
249
|
+
CGPoint origin = ((CGPoint(*)(double, double))CGPointMake)(
|
|
250
|
+
0, doc_frame.size.height - clip_bounds.size.height);
|
|
251
|
+
((void(*)(id, SEL, CGPoint))objc_msgSend)(clip, sel_registerName("setBoundsOrigin:"), origin);
|
|
252
|
+
((void(*)(id, SEL, id))objc_msgSend)((id)self->handle, sel_registerName("reflectScrolledClipView:"), clip);
|
|
253
|
+
```
|
|
254
|
+
```
|
|
255
|
+
#arch: aarch64_use_c
|
|
256
|
+
#platform: macos
|
|
257
|
+
id clip = ((id(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("contentView"));
|
|
258
|
+
id doc = ((id(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("documentView"));
|
|
259
|
+
CGRect doc_frame = ((CGRect(*)(id, SEL))objc_msgSend)(doc, sel_registerName("frame"));
|
|
260
|
+
CGRect clip_bounds = ((CGRect(*)(id, SEL))objc_msgSend)(clip, sel_registerName("bounds"));
|
|
261
|
+
// Set the clip's bounds origin directly — the one primitive the live
|
|
262
|
+
// scroll machinery can't constrain short of the edge. The unflipped
|
|
263
|
+
// document's top edge is at doc height; the visible origin sits
|
|
264
|
+
// `doc_h - clip_h` up from the bottom.
|
|
265
|
+
CGPoint origin = ((CGPoint(*)(double, double))CGPointMake)(
|
|
266
|
+
0, doc_frame.size.height - clip_bounds.size.height);
|
|
267
|
+
((void(*)(id, SEL, CGPoint))objc_msgSend)(clip, sel_registerName("setBoundsOrigin:"), origin);
|
|
268
|
+
((void(*)(id, SEL, id))objc_msgSend)((id)self->handle, sel_registerName("reflectScrolledClipView:"), clip);
|
|
269
|
+
```
|
|
270
|
+
```
|
|
271
|
+
#arch: c
|
|
272
|
+
#platform: ios
|
|
273
|
+
/* TODO: iOS (see #init) */
|
|
274
|
+
```
|
|
275
|
+
```
|
|
276
|
+
#arch: aarch64_use_c
|
|
277
|
+
#platform: ios
|
|
278
|
+
/* TODO: iOS (see #init) */
|
|
279
|
+
```
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// How far the document is scrolled from its top, in document pixels
|
|
283
|
+
// (0 = top). Add this to a window-space click y (minus the scroll view's
|
|
284
|
+
// own origin) before hit-testing content children — see the Scrollable
|
|
285
|
+
// design note in GUI.md.
|
|
286
|
+
pub func scroll_offset_y = (self, out int) {
|
|
287
|
+
```
|
|
288
|
+
#arch: c
|
|
289
|
+
#platform: macos
|
|
290
|
+
id clip = ((id(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("contentView"));
|
|
291
|
+
id doc = ((id(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("documentView"));
|
|
292
|
+
CGRect doc_frame = ((CGRect(*)(id, SEL))objc_msgSend)(doc, sel_registerName("frame"));
|
|
293
|
+
CGRect clip_bounds = ((CGRect(*)(id, SEL))objc_msgSend)(clip, sel_registerName("bounds"));
|
|
294
|
+
int offset = (int)(doc_frame.size.height - clip_bounds.size.height - clip_bounds.origin.y);
|
|
295
|
+
return offset < 0 ? 0 : offset; // content shorter than the viewport can't scroll
|
|
296
|
+
```
|
|
297
|
+
```
|
|
298
|
+
#arch: aarch64_use_c
|
|
299
|
+
#platform: macos
|
|
300
|
+
id clip = ((id(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("contentView"));
|
|
301
|
+
id doc = ((id(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("documentView"));
|
|
302
|
+
CGRect doc_frame = ((CGRect(*)(id, SEL))objc_msgSend)(doc, sel_registerName("frame"));
|
|
303
|
+
CGRect clip_bounds = ((CGRect(*)(id, SEL))objc_msgSend)(clip, sel_registerName("bounds"));
|
|
304
|
+
int offset = (int)(doc_frame.size.height - clip_bounds.size.height - clip_bounds.origin.y);
|
|
305
|
+
return offset < 0 ? 0 : offset; // content shorter than the viewport can't scroll
|
|
306
|
+
```
|
|
307
|
+
```
|
|
308
|
+
#arch: c
|
|
309
|
+
#platform: ios
|
|
310
|
+
/* TODO: iOS (see #init) */
|
|
311
|
+
return 0;
|
|
312
|
+
```
|
|
313
|
+
```
|
|
314
|
+
#arch: aarch64_use_c
|
|
315
|
+
#platform: ios
|
|
316
|
+
/* TODO: iOS (see #init) */
|
|
317
|
+
return 0;
|
|
318
|
+
```
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Scroll so the BOTTOM of the document is visible (the unflipped document
|
|
322
|
+
// shows its bottom by default, so this restores the initial view after a
|
|
323
|
+
// `scroll_to_top`).
|
|
324
|
+
pub func scroll_to_bottom = (self) {
|
|
325
|
+
```
|
|
326
|
+
#arch: c
|
|
327
|
+
#platform: macos
|
|
328
|
+
id clip = ((id(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("contentView"));
|
|
329
|
+
// Set the clip's bounds origin directly — the one primitive the live
|
|
330
|
+
// scroll machinery can't constrain short of the edge. (0, 0) is the
|
|
331
|
+
// unflipped document's bottom-left corner.
|
|
332
|
+
((void(*)(id, SEL, CGPoint))objc_msgSend)(
|
|
333
|
+
clip, sel_registerName("setBoundsOrigin:"),
|
|
334
|
+
((CGPoint(*)(double, double))CGPointMake)(0, 0));
|
|
335
|
+
((void(*)(id, SEL, id))objc_msgSend)((id)self->handle, sel_registerName("reflectScrolledClipView:"), clip);
|
|
336
|
+
```
|
|
337
|
+
```
|
|
338
|
+
#arch: aarch64_use_c
|
|
339
|
+
#platform: macos
|
|
340
|
+
id clip = ((id(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("contentView"));
|
|
341
|
+
// Set the clip's bounds origin directly — the one primitive the live
|
|
342
|
+
// scroll machinery can't constrain short of the edge. (0, 0) is the
|
|
343
|
+
// unflipped document's bottom-left corner.
|
|
344
|
+
((void(*)(id, SEL, CGPoint))objc_msgSend)(
|
|
345
|
+
clip, sel_registerName("setBoundsOrigin:"),
|
|
346
|
+
((CGPoint(*)(double, double))CGPointMake)(0, 0));
|
|
347
|
+
((void(*)(id, SEL, id))objc_msgSend)((id)self->handle, sel_registerName("reflectScrolledClipView:"), clip);
|
|
348
|
+
```
|
|
349
|
+
```
|
|
350
|
+
#arch: c
|
|
351
|
+
#platform: ios
|
|
352
|
+
/* TODO: iOS (see #init) */
|
|
353
|
+
```
|
|
354
|
+
```
|
|
355
|
+
#arch: aarch64_use_c
|
|
356
|
+
#platform: ios
|
|
357
|
+
/* TODO: iOS (see #init) */
|
|
358
|
+
```
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
pub func set_hidden = (self, bool hidden) {
|
|
362
|
+
```
|
|
363
|
+
#arch: c
|
|
364
|
+
#platform: macos
|
|
365
|
+
((void(*)(id, SEL, BOOL))objc_msgSend)(
|
|
366
|
+
(id)self->handle, sel_registerName("setHidden:"), hidden ? 1 : 0);
|
|
367
|
+
```
|
|
368
|
+
```
|
|
369
|
+
#arch: aarch64_use_c
|
|
370
|
+
#platform: macos
|
|
371
|
+
((void(*)(id, SEL, BOOL))objc_msgSend)(
|
|
372
|
+
(id)self->handle, sel_registerName("setHidden:"), hidden ? 1 : 0);
|
|
373
|
+
```
|
|
374
|
+
```
|
|
375
|
+
#arch: c
|
|
376
|
+
#platform: ios
|
|
377
|
+
((void(*)(id, SEL, BOOL))objc_msgSend)(
|
|
378
|
+
(id)self->handle, sel_registerName("setHidden:"), hidden ? 1 : 0);
|
|
379
|
+
```
|
|
380
|
+
```
|
|
381
|
+
#arch: aarch64_use_c
|
|
382
|
+
#platform: ios
|
|
383
|
+
((void(*)(id, SEL, BOOL))objc_msgSend)(
|
|
384
|
+
(id)self->handle, sel_registerName("setHidden:"), hidden ? 1 : 0);
|
|
385
|
+
```
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// ── Control trait conformance ──
|
|
389
|
+
pub func set_frame = (ref self, int x, int y, int width, int height) {
|
|
390
|
+
```
|
|
391
|
+
#arch: c
|
|
392
|
+
#platform: macos
|
|
393
|
+
((void(*)(id, SEL, CGRect))objc_msgSend)(
|
|
394
|
+
(id)self->handle, sel_registerName("setFrame:"),
|
|
395
|
+
((CGRect(*)(double, double, double, double))CGRectMake)((double)x, (double)y, (double)width, (double)height));
|
|
396
|
+
```
|
|
397
|
+
```
|
|
398
|
+
#arch: aarch64_use_c
|
|
399
|
+
#platform: macos
|
|
400
|
+
((void(*)(id, SEL, CGRect))objc_msgSend)(
|
|
401
|
+
(id)self->handle, sel_registerName("setFrame:"),
|
|
402
|
+
((CGRect(*)(double, double, double, double))CGRectMake)((double)x, (double)y, (double)width, (double)height));
|
|
403
|
+
```
|
|
404
|
+
```
|
|
405
|
+
#arch: c
|
|
406
|
+
#platform: ios
|
|
407
|
+
/* TODO: iOS (see #init) */
|
|
408
|
+
```
|
|
409
|
+
```
|
|
410
|
+
#arch: aarch64_use_c
|
|
411
|
+
#platform: ios
|
|
412
|
+
/* TODO: iOS (see #init) */
|
|
413
|
+
```
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
pub func intrinsic_size = (self, out Size) {
|
|
417
|
+
var [w, h] = native_intrinsic(self.handle)
|
|
418
|
+
var s = Size()
|
|
419
|
+
s.width = w
|
|
420
|
+
s.height = h
|
|
421
|
+
return s
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
pub func measure = (self, BoxConstraints constraints, out Size) {
|
|
425
|
+
var Size s = self.intrinsic_size()
|
|
426
|
+
if s.width > constraints.max_width {
|
|
427
|
+
s.width = constraints.max_width
|
|
428
|
+
}
|
|
429
|
+
if s.width < constraints.min_width {
|
|
430
|
+
s.width = constraints.min_width
|
|
431
|
+
}
|
|
432
|
+
if s.height > constraints.max_height {
|
|
433
|
+
s.height = constraints.max_height
|
|
434
|
+
}
|
|
435
|
+
if s.height < constraints.min_height {
|
|
436
|
+
s.height = constraints.min_height
|
|
437
|
+
}
|
|
438
|
+
return s
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
func #destroy = () {
|
|
442
|
+
```
|
|
443
|
+
#arch: c
|
|
444
|
+
#platform: macos
|
|
445
|
+
if (self->handle) {
|
|
446
|
+
((void(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("removeFromSuperview"));
|
|
447
|
+
((void(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("release"));
|
|
448
|
+
self->handle = 0;
|
|
449
|
+
}
|
|
450
|
+
self->doc = 0;
|
|
451
|
+
```
|
|
452
|
+
```
|
|
453
|
+
#arch: aarch64_use_c
|
|
454
|
+
#platform: macos
|
|
455
|
+
if (self->handle) {
|
|
456
|
+
((void(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("removeFromSuperview"));
|
|
457
|
+
((void(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("release"));
|
|
458
|
+
self->handle = 0;
|
|
459
|
+
}
|
|
460
|
+
self->doc = 0;
|
|
461
|
+
```
|
|
462
|
+
```
|
|
463
|
+
#arch: c
|
|
464
|
+
#platform: ios
|
|
465
|
+
/* TODO: iOS (see #init) */
|
|
466
|
+
```
|
|
467
|
+
```
|
|
468
|
+
#arch: aarch64_use_c
|
|
469
|
+
#platform: ios
|
|
470
|
+
/* TODO: iOS (see #init) */
|
|
471
|
+
```
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// The on_scroll desugar's drain (docs/HANDLERS.md): the synthesized
|
|
475
|
+
// pump arm polls this per frame. True on any frame whose pump saw
|
|
476
|
+
// scroll-wheel events; the deltas ride the dispatch window —
|
|
477
|
+
// `win.scroll_dx()` / `win.scroll_dy()` (dy positive scrolling up/away,
|
|
478
|
+
// dx positive right; a trackpad frame sums every small event). Scroll
|
|
479
|
+
// is continuous input, not a click: the edge means "this frame
|
|
480
|
+
// scrolled", and the magnitudes are the payload. The record is
|
|
481
|
+
// window-level (broadcast, like the mouse-down record) — handlers that
|
|
482
|
+
// care about WHICH scrollable route by hit-testing or by reading
|
|
483
|
+
// `self.scroll_offset_y()` deltas.
|
|
484
|
+
pub func take_scroll = (self, out bool) {
|
|
485
|
+
```
|
|
486
|
+
#arch: c
|
|
487
|
+
#platform: macos
|
|
488
|
+
extern double nomen_scroll_dx_acc;
|
|
489
|
+
extern double nomen_scroll_dy_acc;
|
|
490
|
+
return (nomen_scroll_dx_acc != 0.0) || (nomen_scroll_dy_acc != 0.0);
|
|
491
|
+
```
|
|
492
|
+
```
|
|
493
|
+
#arch: aarch64_use_c
|
|
494
|
+
#platform: macos
|
|
495
|
+
extern double nomen_scroll_dx_acc;
|
|
496
|
+
extern double nomen_scroll_dy_acc;
|
|
497
|
+
return (nomen_scroll_dx_acc != 0.0) || (nomen_scroll_dy_acc != 0.0);
|
|
498
|
+
```
|
|
499
|
+
```
|
|
500
|
+
#arch: c
|
|
501
|
+
#platform: ios
|
|
502
|
+
return 0;
|
|
503
|
+
```
|
|
504
|
+
```
|
|
505
|
+
#arch: aarch64_use_c
|
|
506
|
+
#platform: ios
|
|
507
|
+
return 0;
|
|
508
|
+
```
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
// Translate a WINDOW-space click (top-left origin, as click_x/click_y
|
|
513
|
+
// return) into the scroll view's DOCUMENT coordinates, so content children
|
|
514
|
+
// can be hit-tested with the content grid's `contains` while scrolled. The
|
|
515
|
+
// visible top-left of the document moves with the scroll position (and the
|
|
516
|
+
// clip view's own origin), so a raw click is off by both. A free function
|
|
517
|
+
// (not a method): a raw-block-backed method returning a tuple fails the
|
|
518
|
+
// checker's destructuring — native_intrinsic's free-function shape works.
|
|
519
|
+
pub func content_click = (Scrollable scroll, int cx, int cy, out [int, int]) {
|
|
520
|
+
```
|
|
521
|
+
#arch: c
|
|
522
|
+
#platform: macos
|
|
523
|
+
id clip = ((id(*)(id, SEL))objc_msgSend)((id)scroll->handle, sel_registerName("contentView"));
|
|
524
|
+
id win = ((id(*)(id, SEL))objc_msgSend)((id)scroll->handle, sel_registerName("window"));
|
|
525
|
+
id cv = ((id(*)(id, SEL))objc_msgSend)(win, sel_registerName("contentView"));
|
|
526
|
+
CGRect cv_frame = ((CGRect(*)(id, SEL))objc_msgSend)(cv, sel_registerName("frame"));
|
|
527
|
+
CGRect clip_bounds = ((CGRect(*)(id, SEL))objc_msgSend)(clip, sel_registerName("bounds"));
|
|
528
|
+
// The visible rect in the window's content view (bottom-left origin).
|
|
529
|
+
CGRect visible = ((CGRect(*)(id, SEL, CGRect, id))objc_msgSend)(
|
|
530
|
+
clip, sel_registerName("convertRect:toView:"), clip_bounds, cv);
|
|
531
|
+
id doc = ((id(*)(id, SEL))objc_msgSend)((id)scroll->handle, sel_registerName("documentView"));
|
|
532
|
+
CGRect doc_frame = ((CGRect(*)(id, SEL))objc_msgSend)(doc, sel_registerName("frame"));
|
|
533
|
+
int visible_top = (int)(cv_frame.size.height - (visible.origin.y + visible.size.height));
|
|
534
|
+
int offset = (int)(doc_frame.size.height - clip_bounds.size.height - clip_bounds.origin.y);
|
|
535
|
+
if (offset < 0) offset = 0;
|
|
536
|
+
struct _Tuple_int_int r;
|
|
537
|
+
r._0 = cx - (int)visible.origin.x + (int)clip_bounds.origin.x;
|
|
538
|
+
r._1 = cy - visible_top + offset;
|
|
539
|
+
return r;
|
|
540
|
+
```
|
|
541
|
+
```
|
|
542
|
+
#arch: aarch64_use_c
|
|
543
|
+
#platform: macos
|
|
544
|
+
id clip = ((id(*)(id, SEL))objc_msgSend)((id)scroll->handle, sel_registerName("contentView"));
|
|
545
|
+
id win = ((id(*)(id, SEL))objc_msgSend)((id)scroll->handle, sel_registerName("window"));
|
|
546
|
+
id cv = ((id(*)(id, SEL))objc_msgSend)(win, sel_registerName("contentView"));
|
|
547
|
+
CGRect cv_frame = ((CGRect(*)(id, SEL))objc_msgSend)(cv, sel_registerName("frame"));
|
|
548
|
+
CGRect clip_bounds = ((CGRect(*)(id, SEL))objc_msgSend)(clip, sel_registerName("bounds"));
|
|
549
|
+
// The visible rect in the window's content view (bottom-left origin).
|
|
550
|
+
CGRect visible = ((CGRect(*)(id, SEL, CGRect, id))objc_msgSend)(
|
|
551
|
+
clip, sel_registerName("convertRect:toView:"), clip_bounds, cv);
|
|
552
|
+
id doc = ((id(*)(id, SEL))objc_msgSend)((id)scroll->handle, sel_registerName("documentView"));
|
|
553
|
+
CGRect doc_frame = ((CGRect(*)(id, SEL))objc_msgSend)(doc, sel_registerName("frame"));
|
|
554
|
+
int visible_top = (int)(cv_frame.size.height - (visible.origin.y + visible.size.height));
|
|
555
|
+
int offset = (int)(doc_frame.size.height - clip_bounds.size.height - clip_bounds.origin.y);
|
|
556
|
+
if (offset < 0) offset = 0;
|
|
557
|
+
struct _Tuple_int_int r;
|
|
558
|
+
r._0 = cx - (int)visible.origin.x + (int)clip_bounds.origin.x;
|
|
559
|
+
r._1 = cy - visible_top + offset;
|
|
560
|
+
return r;
|
|
561
|
+
```
|
|
562
|
+
```
|
|
563
|
+
#arch: c
|
|
564
|
+
#platform: ios
|
|
565
|
+
/* TODO: iOS (see #init) */
|
|
566
|
+
{
|
|
567
|
+
struct _Tuple_int_int r;
|
|
568
|
+
r._0 = 0;
|
|
569
|
+
r._1 = 0;
|
|
570
|
+
return r;
|
|
571
|
+
}
|
|
572
|
+
```
|
|
573
|
+
```
|
|
574
|
+
#arch: aarch64_use_c
|
|
575
|
+
#platform: ios
|
|
576
|
+
/* TODO: iOS (see #init) */
|
|
577
|
+
{
|
|
578
|
+
struct _Tuple_int_int r;
|
|
579
|
+
r._0 = 0;
|
|
580
|
+
r._1 = 0;
|
|
581
|
+
return r;
|
|
582
|
+
}
|
|
583
|
+
```
|
|
584
|
+
}
|