@effindomv2/fui-as 0.1.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 (137) hide show
  1. package/LICENSE.md +7 -0
  2. package/browser/src/common-harness/host-imports.ts +430 -0
  3. package/browser/src/common-harness/interop.ts +39 -0
  4. package/browser/src/common-harness/managed-harness-bitmap-host.ts +92 -0
  5. package/browser/src/common-harness/managed-harness-fetch-host.ts +201 -0
  6. package/browser/src/common-harness/managed-harness-file-host.ts +1101 -0
  7. package/browser/src/common-harness/managed-harness-file-payloads.ts +143 -0
  8. package/browser/src/common-harness/managed-harness-file-types.ts +106 -0
  9. package/browser/src/common-harness/managed-harness-session.ts +15 -0
  10. package/browser/src/common-harness/managed-harness.ts +1323 -0
  11. package/browser/src/common-harness/managed-history.ts +168 -0
  12. package/browser/src/common-harness/persisted-restore-policy.ts +50 -0
  13. package/browser/src/common-harness/persisted-ui-state-controller.ts +309 -0
  14. package/browser/src/common-harness/text-session-bridge.ts +452 -0
  15. package/browser/src/common-harness/types.ts +205 -0
  16. package/browser/src/common-harness/ui-chrome.ts +191 -0
  17. package/browser/src/common-harness/ui-imports.ts +529 -0
  18. package/browser/src/common-harness/wasm-module-cache.ts +47 -0
  19. package/browser/src/common-harness.ts +27 -0
  20. package/browser/src/file-processing-worker.ts +89 -0
  21. package/browser/src/host-events.ts +97 -0
  22. package/browser/src/host-services.ts +203 -0
  23. package/browser/src/index.ts +62 -0
  24. package/browser/src/persisted-ui-state.ts +206 -0
  25. package/browser/src/routed-harness.ts +198 -0
  26. package/browser/src/worker-bootstrap.ts +483 -0
  27. package/browser/src/worker-manager.ts +230 -0
  28. package/browser/src/worker-types.ts +50 -0
  29. package/package.json +89 -0
  30. package/scripts/build-demo-as.sh +91 -0
  31. package/scripts/build.sh +325 -0
  32. package/scripts/generate-host-events.ts +175 -0
  33. package/scripts/generate-host-services.ts +157 -0
  34. package/src/Fui.ts +205 -0
  35. package/src/FuiExports.ts +55 -0
  36. package/src/FuiPrimitives.ts +15 -0
  37. package/src/FuiWorker.ts +3 -0
  38. package/src/FuiWorkerExports.ts +6 -0
  39. package/src/bindings/ui.ts +531 -0
  40. package/src/color.ts +86 -0
  41. package/src/controls/AntiSelectionArea.ts +23 -0
  42. package/src/controls/Button.ts +750 -0
  43. package/src/controls/Checkbox.ts +181 -0
  44. package/src/controls/ContextMenu.ts +885 -0
  45. package/src/controls/ControlTemplateSet.ts +37 -0
  46. package/src/controls/Dialog.ts +355 -0
  47. package/src/controls/Dropdown.ts +856 -0
  48. package/src/controls/Form.ts +110 -0
  49. package/src/controls/NavLink.ts +211 -0
  50. package/src/controls/Popup.ts +129 -0
  51. package/src/controls/ProgressBar.ts +180 -0
  52. package/src/controls/RadioButton.ts +135 -0
  53. package/src/controls/RadioGroup.ts +244 -0
  54. package/src/controls/SelectionArea.ts +75 -0
  55. package/src/controls/Slider.ts +471 -0
  56. package/src/controls/Switch.ts +132 -0
  57. package/src/controls/TextArea.ts +20 -0
  58. package/src/controls/TextInput.ts +7 -0
  59. package/src/controls/index.ts +18 -0
  60. package/src/controls/internal/ButtonPresenter.ts +95 -0
  61. package/src/controls/internal/CheckboxIndicatorPresenter.ts +93 -0
  62. package/src/controls/internal/DropdownChevronPresenter.ts +67 -0
  63. package/src/controls/internal/DropdownFieldPresenter.ts +110 -0
  64. package/src/controls/internal/DropdownOptionRowPresenter.ts +82 -0
  65. package/src/controls/internal/PopupPresenter.ts +198 -0
  66. package/src/controls/internal/PressableIndicatorPresenter.ts +32 -0
  67. package/src/controls/internal/PressableLabeledControl.ts +221 -0
  68. package/src/controls/internal/RadioIndicatorPresenter.ts +73 -0
  69. package/src/controls/internal/SliderPresenter.ts +157 -0
  70. package/src/controls/internal/SwitchIndicatorPresenter.ts +72 -0
  71. package/src/controls/internal/TextInputCore.ts +695 -0
  72. package/src/controls/internal/TextInputPresenter.ts +72 -0
  73. package/src/controls/templating.ts +54 -0
  74. package/src/core/Action.ts +94 -0
  75. package/src/core/Actions.ts +37 -0
  76. package/src/core/Animation.ts +412 -0
  77. package/src/core/Application.ts +328 -0
  78. package/src/core/Assets.ts +264 -0
  79. package/src/core/AttachedProperties.ts +32 -0
  80. package/src/core/Bitmap.ts +70 -0
  81. package/src/core/BoundCallback.ts +104 -0
  82. package/src/core/Callbacks.ts +17 -0
  83. package/src/core/ContextMenuManager.ts +466 -0
  84. package/src/core/DebugApi.ts +30 -0
  85. package/src/core/Disposable.ts +10 -0
  86. package/src/core/DragDropManager.ts +179 -0
  87. package/src/core/DragGesture.ts +184 -0
  88. package/src/core/DynamicAssetIds.ts +24 -0
  89. package/src/core/Errors.ts +48 -0
  90. package/src/core/EventRouter.ts +408 -0
  91. package/src/core/ExternalDropManager.ts +122 -0
  92. package/src/core/Fetch.ts +264 -0
  93. package/src/core/FetchFfi.ts +15 -0
  94. package/src/core/File.ts +1002 -0
  95. package/src/core/FocusAdornerManager.ts +263 -0
  96. package/src/core/FocusVisibility.ts +36 -0
  97. package/src/core/FrameScheduler.ts +28 -0
  98. package/src/core/KeyboardScroll.ts +161 -0
  99. package/src/core/KeyboardScrollTracker.ts +386 -0
  100. package/src/core/Logger.ts +80 -0
  101. package/src/core/Navigation.ts +13 -0
  102. package/src/core/Node.ts +1708 -0
  103. package/src/core/PersistedState.ts +102 -0
  104. package/src/core/PersistedUiState.ts +142 -0
  105. package/src/core/Platform.ts +219 -0
  106. package/src/core/Signal.ts +89 -0
  107. package/src/core/Theme.ts +365 -0
  108. package/src/core/Timers.ts +129 -0
  109. package/src/core/ToolTip.ts +122 -0
  110. package/src/core/ToolTipManager.ts +459 -0
  111. package/src/core/Transitions.ts +34 -0
  112. package/src/core/Typography.ts +204 -0
  113. package/src/core/Worker.ts +196 -0
  114. package/src/core/bind.ts +37 -0
  115. package/src/core/event_exports.ts +596 -0
  116. package/src/core/ffi.ts +728 -0
  117. package/src/host-services/runtime.ts +25 -0
  118. package/src/nodes/FlexBox.ts +789 -0
  119. package/src/nodes/GradientStop.ts +9 -0
  120. package/src/nodes/Grid.ts +183 -0
  121. package/src/nodes/Image.ts +189 -0
  122. package/src/nodes/Portal.ts +14 -0
  123. package/src/nodes/RichText.ts +312 -0
  124. package/src/nodes/ScrollBar.ts +570 -0
  125. package/src/nodes/ScrollBox.ts +415 -0
  126. package/src/nodes/ScrollState.ts +10 -0
  127. package/src/nodes/ScrollView.ts +511 -0
  128. package/src/nodes/Svg.ts +142 -0
  129. package/src/nodes/Text.ts +145 -0
  130. package/src/nodes/TextCore.ts +558 -0
  131. package/src/nodes/VirtualList.ts +431 -0
  132. package/src/nodes/helpers.ts +25 -0
  133. package/src/nodes/index.ts +14 -0
  134. package/src/tsconfig.json +7 -0
  135. package/src/worker/Worker.ts +169 -0
  136. package/src/worker/WorkerJob.ts +65 -0
  137. package/src/worker/ffi.ts +23 -0
@@ -0,0 +1,531 @@
1
+ import * as ffi from "../core/ffi";
2
+
3
+ function encodeUtf8(text: string): Uint8Array {
4
+ return Uint8Array.wrap(String.UTF8.encode(text, false));
5
+ }
6
+
7
+ export function reset(): void {
8
+ ffi.ui_reset();
9
+ }
10
+
11
+ export function createNode(type: u32): u64 {
12
+ return ffi.ui_create_node(type);
13
+ }
14
+
15
+ export function setNodeId(handle: u64, id: string): void {
16
+ const bytes = encodeUtf8(id);
17
+ ffi.ui_set_node_id(handle, bytes.length > 0 ? bytes.dataStart : 0, <u32>bytes.length);
18
+ }
19
+
20
+ export function setSemanticRole(handle: u64, role: u32): void {
21
+ ffi.ui_set_semantic_role(handle, role);
22
+ }
23
+
24
+ export function setSemanticLabel(handle: u64, label: string): void {
25
+ const bytes = encodeUtf8(label);
26
+ ffi.ui_set_semantic_label(handle, bytes.length > 0 ? bytes.dataStart : 0, <u32>bytes.length);
27
+ }
28
+
29
+ export function setSemanticChecked(handle: u64, checkedState: u32): void {
30
+ ffi.ui_set_semantic_checked(handle, checkedState);
31
+ }
32
+
33
+ export function setSemanticSelected(handle: u64, hasSelected: bool, selected: bool): void {
34
+ ffi.ui_set_semantic_selected(handle, hasSelected, selected);
35
+ }
36
+
37
+ export function setSemanticExpanded(handle: u64, hasExpanded: bool, expanded: bool): void {
38
+ ffi.ui_set_semantic_expanded(handle, hasExpanded, expanded);
39
+ }
40
+
41
+ export function setSemanticDisabled(handle: u64, hasDisabled: bool, disabled: bool): void {
42
+ ffi.ui_set_semantic_disabled(handle, hasDisabled, disabled);
43
+ }
44
+
45
+ export function setSemanticValueRange(
46
+ handle: u64,
47
+ hasValueRange: bool,
48
+ valueNow: f32,
49
+ valueMin: f32,
50
+ valueMax: f32,
51
+ ): void {
52
+ ffi.ui_set_semantic_value_range(handle, hasValueRange, valueNow, valueMin, valueMax);
53
+ }
54
+
55
+ export function setSemanticOrientation(handle: u64, orientation: u32): void {
56
+ ffi.ui_set_semantic_orientation(handle, orientation);
57
+ }
58
+
59
+ export function requestSemanticAnnouncement(handle: u64): void {
60
+ ffi.ui_request_semantic_announcement(handle);
61
+ }
62
+
63
+ export function pushSemanticScope(handle: u64): u32 {
64
+ return ffi.ui_push_semantic_scope(handle);
65
+ }
66
+
67
+ export function removeSemanticScope(token: u32): void {
68
+ ffi.ui_remove_semantic_scope(token);
69
+ }
70
+
71
+ export function deleteNode(handle: u64): void {
72
+ ffi.ui_delete_node(handle);
73
+ }
74
+
75
+ export function addChild(parent: u64, child: u64): void {
76
+ ffi.ui_node_add_child(parent, child);
77
+ }
78
+
79
+ export function removeChild(parent: u64, child: u64): void {
80
+ ffi.ui_node_remove_child(parent, child);
81
+ }
82
+
83
+ export function setIsPortal(handle: u64, flag: bool): void {
84
+ ffi.ui_set_is_portal(handle, flag);
85
+ }
86
+
87
+ export function setVisibility(handle: u64, visibility: u32): void {
88
+ ffi.ui_set_visibility(handle, visibility);
89
+ }
90
+
91
+ export function setRoot(handle: u64): void {
92
+ ffi.ui_set_root(handle);
93
+ }
94
+
95
+ export function setWidth(handle: u64, value: f32, unit: u32): void {
96
+ ffi.ui_set_width(handle, value, unit);
97
+ }
98
+
99
+ export function setHeight(handle: u64, value: f32, unit: u32): void {
100
+ ffi.ui_set_height(handle, value, unit);
101
+ }
102
+
103
+ export function setFlexDirection(handle: u64, direction: u32): void {
104
+ ffi.ui_set_flex_direction(handle, direction);
105
+ }
106
+
107
+ export function setFlexGrow(handle: u64, grow: f32): void {
108
+ ffi.ui_set_flex_grow(handle, grow);
109
+ }
110
+
111
+ export function setFlexBasis(handle: u64, basis: f32): void {
112
+ ffi.ui_set_flex_basis(handle, basis);
113
+ }
114
+
115
+ export function setJustifyContent(handle: u64, justify: u32): void {
116
+ ffi.ui_set_justify_content(handle, justify);
117
+ }
118
+
119
+ export function setAlignItems(handle: u64, align: u32): void {
120
+ ffi.ui_set_align_items(handle, align);
121
+ }
122
+
123
+ export function setPadding(handle: u64, left: f32, top: f32, right: f32, bottom: f32): void {
124
+ ffi.ui_set_padding(handle, left, top, right, bottom);
125
+ }
126
+
127
+ export function setMargin(handle: u64, left: f32, top: f32, right: f32, bottom: f32): void {
128
+ ffi.ui_set_margin(handle, left, top, right, bottom);
129
+ }
130
+
131
+ export function setPositionType(handle: u64, positionType: u32): void {
132
+ ffi.ui_set_position_type(handle, positionType);
133
+ }
134
+
135
+ export function setPosition(handle: u64, left: f32, top: f32, right: f32, bottom: f32): void {
136
+ ffi.ui_set_position(handle, left, top, right, bottom);
137
+ }
138
+
139
+ export function setIsSharedSizeScope(handle: u64, isScope: bool): void {
140
+ ffi.ui_set_is_shared_size_scope(handle, isScope);
141
+ }
142
+
143
+ export function gridSetColumns(handle: u64, values: Float32Array, types: Uint8Array): void {
144
+ ffi.ui_grid_set_columns(
145
+ handle,
146
+ <u32>values.length,
147
+ values.length > 0 ? values.dataStart : 0,
148
+ types.length > 0 ? types.dataStart : 0,
149
+ );
150
+ }
151
+
152
+ export function gridSetRows(handle: u64, values: Float32Array, types: Uint8Array): void {
153
+ ffi.ui_grid_set_rows(
154
+ handle,
155
+ <u32>values.length,
156
+ values.length > 0 ? values.dataStart : 0,
157
+ types.length > 0 ? types.dataStart : 0,
158
+ );
159
+ }
160
+
161
+ export function gridSetColumnSharedSizeGroup(handle: u64, index: u32, group: string): void {
162
+ const bytes = encodeUtf8(group);
163
+ ffi.ui_grid_set_column_shared_size_group(handle, index, bytes.length > 0 ? bytes.dataStart : 0, <u32>bytes.length);
164
+ }
165
+
166
+ export function gridSetRowSharedSizeGroup(handle: u64, index: u32, group: string): void {
167
+ const bytes = encodeUtf8(group);
168
+ ffi.ui_grid_set_row_shared_size_group(handle, index, bytes.length > 0 ? bytes.dataStart : 0, <u32>bytes.length);
169
+ }
170
+
171
+ export function setGridPlacement(handle: u64, row: u32, col: u32, rowSpan: u32, colSpan: u32): void {
172
+ ffi.ui_node_set_grid_placement(handle, row, col, rowSpan, colSpan);
173
+ }
174
+
175
+ export function setBackgroundColor(handle: u64, color: u32): void {
176
+ ffi.ui_set_bg_color(handle, color);
177
+ }
178
+
179
+ export function setBoxStyle(
180
+ handle: u64,
181
+ bgColor: u32,
182
+ topLeftRadius: f32,
183
+ topRightRadius: f32,
184
+ bottomRightRadius: f32,
185
+ bottomLeftRadius: f32,
186
+ borderWidth: f32,
187
+ borderColor: u32,
188
+ borderStyle: u32,
189
+ borderDashOn: f32,
190
+ borderDashOff: f32,
191
+ ): void {
192
+ ffi.ui_set_box_style(
193
+ handle,
194
+ bgColor,
195
+ topLeftRadius,
196
+ topRightRadius,
197
+ bottomRightRadius,
198
+ bottomLeftRadius,
199
+ borderWidth,
200
+ borderColor,
201
+ borderStyle,
202
+ borderDashOn,
203
+ borderDashOff,
204
+ );
205
+ }
206
+
207
+ export function setLayerEffect(handle: u64, opacity: f32, blurSigma: f32, blendMode: u32): void {
208
+ ffi.ui_set_layer_effect(handle, opacity, blurSigma, blendMode);
209
+ }
210
+
211
+ export function setDropShadow(
212
+ handle: u64,
213
+ color: u32,
214
+ offsetX: f32,
215
+ offsetY: f32,
216
+ blurSigma: f32,
217
+ spread: f32,
218
+ ): void {
219
+ ffi.ui_set_drop_shadow(handle, color, offsetX, offsetY, blurSigma, spread);
220
+ }
221
+
222
+ export function setBackgroundBlur(handle: u64, blurSigma: f32): void {
223
+ ffi.ui_set_background_blur(handle, blurSigma);
224
+ }
225
+
226
+ export function setImage(handle: u64, textureId: u32, objectFit: u32): void {
227
+ ffi.ui_set_image(handle, textureId, objectFit);
228
+ }
229
+
230
+ export function setImageNine(
231
+ handle: u64,
232
+ textureId: u32,
233
+ insetLeft: f32,
234
+ insetTop: f32,
235
+ insetRight: f32,
236
+ insetBottom: f32,
237
+ ): void {
238
+ ffi.ui_set_image_nine(handle, textureId, insetLeft, insetTop, insetRight, insetBottom);
239
+ }
240
+
241
+ export function setSvg(handle: u64, svgId: u32, tintColor: u32): void {
242
+ ffi.ui_set_svg(handle, svgId, tintColor);
243
+ }
244
+
245
+ export function setLinearGradient(
246
+ handle: u64,
247
+ startX: f32,
248
+ startY: f32,
249
+ endX: f32,
250
+ endY: f32,
251
+ offsets: Float32Array,
252
+ colors: Uint32Array,
253
+ ): void {
254
+ if (offsets.length == 0) {
255
+ return;
256
+ }
257
+ ffi.ui_set_linear_gradient(
258
+ handle,
259
+ startX,
260
+ startY,
261
+ endX,
262
+ endY,
263
+ <u32>offsets.length,
264
+ );
265
+ for (let i = 0; i < offsets.length; ++i) {
266
+ ffi.ui_push_linear_gradient_stop(handle, unchecked(offsets[i]), unchecked(colors[i]));
267
+ }
268
+ }
269
+
270
+ export function setClipToBounds(handle: u64, clip: bool): void {
271
+ ffi.ui_set_clip_to_bounds(handle, clip);
272
+ }
273
+
274
+ export function setInteractive(handle: u64, flag: bool): void {
275
+ ffi.ui_set_interactive(handle, flag);
276
+ }
277
+
278
+ export function setScrollProxyTarget(handle: u64, scrollHandle: u64): void {
279
+ ffi.ui_set_scroll_proxy_target(handle, scrollHandle);
280
+ }
281
+
282
+ export function setScrollEnabled(handle: u64, enabledX: bool, enabledY: bool): void {
283
+ ffi.ui_set_scroll_enabled(handle, enabledX, enabledY);
284
+ }
285
+
286
+ export function setShowScrollbars(handle: u64, showScrollbars: bool): void {
287
+ ffi.ui_set_show_scrollbars(handle, showScrollbars);
288
+ }
289
+
290
+ export function setScrollFriction(handle: u64, friction: f32): void {
291
+ ffi.ui_set_scroll_friction(handle, friction);
292
+ }
293
+
294
+ export function setFocusable(handle: u64, flag: bool, tabIndex: i32): void {
295
+ ffi.ui_set_focusable(handle, flag, tabIndex);
296
+ }
297
+
298
+ export function requestFocus(handle: u64): void {
299
+ ffi.ui_request_focus(handle);
300
+ }
301
+
302
+ export function setText(handle: u64, text: string): void {
303
+ const bytes = encodeUtf8(text);
304
+ ffi.ui_set_text(handle, bytes.length > 0 ? bytes.dataStart : 0, <u32>bytes.length);
305
+ }
306
+
307
+ export function setTextStyleRuns(handle: u64, runsWords: Uint32Array): void {
308
+ ffi.ui_set_text_style_runs(handle, <u32>(runsWords.length / 7), runsWords.length > 0 ? runsWords.dataStart : 0);
309
+ }
310
+
311
+ export function loadSvg(svgId: u32, url: string): void {
312
+ const bytes = encodeUtf8(url);
313
+ ffi.fui_load_svg(svgId, bytes.length > 0 ? bytes.dataStart : 0, <u32>bytes.length);
314
+ }
315
+
316
+ export function loadTexture(textureId: u32, url: string): void {
317
+ const bytes = encodeUtf8(url);
318
+ ffi.fui_load_texture(textureId, bytes.length > 0 ? bytes.dataStart : 0, <u32>bytes.length);
319
+ }
320
+
321
+ export function releaseSvg(svgId: u32): void {
322
+ ffi.fui_release_svg(svgId);
323
+ }
324
+
325
+ export function releaseTexture(textureId: u32): void {
326
+ ffi.fui_release_texture(textureId);
327
+ }
328
+
329
+ export function bitmapCommit(textureId: u32, bytes: Uint8Array, width: u32, height: u32): void {
330
+ ffi.fui_bitmap_commit(
331
+ textureId,
332
+ bytes.length > 0 ? bytes.dataStart : 0,
333
+ <u32>bytes.length,
334
+ width,
335
+ height,
336
+ );
337
+ }
338
+
339
+ export function bitmapRelease(textureId: u32): void {
340
+ ffi.fui_bitmap_release(textureId);
341
+ }
342
+
343
+ export function loadFont(fontId: u32, url: string): void {
344
+ const bytes = encodeUtf8(url);
345
+ ffi.fui_load_font(fontId, bytes.length > 0 ? bytes.dataStart : 0, <u32>bytes.length);
346
+ }
347
+
348
+ export function startTimer(timerId: u32, delayMs: i32): void {
349
+ ffi.fui_start_timer(timerId, delayMs);
350
+ }
351
+
352
+ export function cancelTimer(timerId: u32): void {
353
+ ffi.fui_cancel_timer(timerId);
354
+ }
355
+
356
+ export function nowMs(): f64 {
357
+ return ffi.fui_now_ms();
358
+ }
359
+
360
+ export function setFont(handle: u64, fontId: u32, size: f32): void {
361
+ ffi.ui_set_font(handle, fontId, size);
362
+ }
363
+
364
+ export function setLineHeight(handle: u64, lineHeight: f32): void {
365
+ ffi.ui_set_line_height(handle, lineHeight);
366
+ }
367
+
368
+ export function registerFontFallback(fontId: u32, fallbackFontId: u32): void {
369
+ ffi.ui_register_font_fallback(fontId, fallbackFontId);
370
+ }
371
+
372
+ export function setTextColor(handle: u64, color: u32): void {
373
+ ffi.ui_set_text_color(handle, color);
374
+ }
375
+
376
+ export function setTextAlign(handle: u64, align: u32): void {
377
+ ffi.ui_set_text_align(handle, align);
378
+ }
379
+
380
+ export function setTextVerticalAlign(handle: u64, align: u32): void {
381
+ ffi.ui_set_text_vertical_align(handle, align);
382
+ }
383
+
384
+ export function setTextLimits(handle: u64, maxChars: i32, maxLines: i32): void {
385
+ ffi.ui_set_text_limits(handle, maxChars, maxLines);
386
+ }
387
+
388
+ export function setTextWrapping(handle: u64, wrap: bool): void {
389
+ ffi.ui_set_text_wrapping(handle, wrap);
390
+ }
391
+
392
+ export function setTextOverflow(handle: u64, overflow: u32): void {
393
+ ffi.ui_set_text_overflow(handle, overflow);
394
+ }
395
+
396
+ export function setTextOverflowFade(handle: u64, horizontal: bool, vertical: bool): void {
397
+ ffi.ui_set_text_overflow_fade(handle, horizontal, vertical);
398
+ }
399
+
400
+ export function setTextObscured(handle: u64, obscured: bool): void {
401
+ ffi.ui_set_text_obscured(handle, obscured);
402
+ }
403
+
404
+ export function setEditable(handle: u64, editable: bool): void {
405
+ ffi.ui_set_editable(handle, editable);
406
+ }
407
+
408
+ export function setCaretColor(handle: u64, color: u32): void {
409
+ ffi.ui_set_caret_color(handle, color);
410
+ }
411
+
412
+ export function setScrollOffset(handle: u64, offsetX: f32, offsetY: f32): void {
413
+ ffi.ui_set_scroll_offset(handle, offsetX, offsetY);
414
+ }
415
+
416
+ export function setScrollContentSize(handle: u64, contentWidth: f32, contentHeight: f32): void {
417
+ ffi.ui_set_scroll_content_size(handle, contentWidth, contentHeight);
418
+ }
419
+
420
+ export function clearMomentumScroll(): void {
421
+ ffi.ui_clear_momentum_scroll();
422
+ }
423
+
424
+ export function setSelectable(handle: u64, selectable: bool, selectionColor: u32): void {
425
+ ffi.ui_set_selectable(handle, selectable, selectionColor);
426
+ }
427
+
428
+ export function setSelectionArea(handle: u64, isArea: bool): void {
429
+ ffi.ui_set_selection_area(handle, isArea);
430
+ }
431
+
432
+ export function setSelectionAreaBarrier(handle: u64, isBarrier: bool): void {
433
+ ffi.ui_set_selection_area_barrier(handle, isBarrier);
434
+ }
435
+
436
+ export function clearSelection(handle: u64): void {
437
+ ffi.ui_clear_selection(handle);
438
+ }
439
+
440
+ export function retargetSelection(fromHandle: u64, toHandle: u64): void {
441
+ ffi.ui_retarget_selection(fromHandle, toHandle);
442
+ }
443
+
444
+ export function isPointInSelection(x: f32, y: f32): bool {
445
+ return ffi.ui_is_point_in_selection(x, y);
446
+ }
447
+
448
+ export function setTextSelectionRange(handle: u64, selectionStart: u32, selectionEnd: u32): void {
449
+ ffi.ui_set_text_selection_range(handle, selectionStart, selectionEnd);
450
+ }
451
+
452
+ export function clearCurrentSelection(): void {
453
+ ffi.ui_clear_current_selection();
454
+ }
455
+
456
+ export function copyCurrentSelection(): void {
457
+ ffi.ui_copy_current_selection();
458
+ }
459
+
460
+ export function canUndoTextEdit(handle: u64): bool {
461
+ return ffi.ui_can_undo_text_edit(handle);
462
+ }
463
+
464
+ export function canRedoTextEdit(handle: u64): bool {
465
+ return ffi.ui_can_redo_text_edit(handle);
466
+ }
467
+
468
+ export function hasTextSelection(handle: u64): bool {
469
+ return ffi.ui_has_text_selection(handle);
470
+ }
471
+
472
+ export function undoTextEdit(handle: u64): void {
473
+ ffi.ui_undo_text_edit(handle);
474
+ }
475
+
476
+ export function redoTextEdit(handle: u64): void {
477
+ ffi.ui_redo_text_edit(handle);
478
+ }
479
+
480
+ export function copyTextSelection(handle: u64): void {
481
+ ffi.ui_copy_text_selection(handle);
482
+ }
483
+
484
+ export function cutTextSelection(handle: u64): void {
485
+ ffi.ui_cut_text_selection(handle);
486
+ }
487
+
488
+ export function replaceTextRange(handle: u64, start: u32, end: u32, text: string, caret: u32): void {
489
+ const bytes = encodeUtf8(text);
490
+ ffi.ui_replace_text_range(handle, start, end, bytes.length > 0 ? bytes.dataStart : 0, <u32>bytes.length, caret);
491
+ }
492
+
493
+ export function pasteText(handle: u64): void {
494
+ ffi.ui_paste_text(handle);
495
+ }
496
+
497
+ export function selectAllText(handle: u64): void {
498
+ ffi.ui_select_all_text(handle);
499
+ }
500
+
501
+ export function commitFrame(): void {
502
+ ffi.ui_commit_frame();
503
+ }
504
+
505
+ export function tryGetBounds(handle: u64): Float32Array | null {
506
+ const values = new Float32Array(4);
507
+ const found = ffi.ui_get_bounds(
508
+ handle,
509
+ values.dataStart,
510
+ values.dataStart + sizeof<f32>(),
511
+ values.dataStart + (sizeof<f32>() * 2),
512
+ values.dataStart + (sizeof<f32>() * 3),
513
+ );
514
+ return found ? values : null;
515
+ }
516
+
517
+ export function resizeWindow(width: f32, height: f32): void {
518
+ ffi.ui_resize_window(width, height);
519
+ }
520
+
521
+ export function requestRender(): void {
522
+ ffi.request_render();
523
+ }
524
+
525
+ export function getViewportWidth(): f32 {
526
+ return ffi.get_viewport_width();
527
+ }
528
+
529
+ export function getViewportHeight(): f32 {
530
+ return ffi.get_viewport_height();
531
+ }
package/src/color.ts ADDED
@@ -0,0 +1,86 @@
1
+ // v2 UI colors are packed as 0xRRGGBBAA.
2
+ export function rgba(red: u32, green: u32, blue: u32, alpha: u32): u32 {
3
+ return ((red & 0xff) << 24) | ((green & 0xff) << 16) | ((blue & 0xff) << 8) | (alpha & 0xff);
4
+ }
5
+
6
+ export function rgb(red: u32, green: u32, blue: u32): u32 {
7
+ return rgba(red, green, blue, 0xff);
8
+ }
9
+
10
+ function clampUnit(value: f32): f32 {
11
+ if (value < <f32>0.0) {
12
+ return <f32>0.0;
13
+ }
14
+ if (value > <f32>1.0) {
15
+ return <f32>1.0;
16
+ }
17
+ return value;
18
+ }
19
+
20
+ function hueToRgb(p: f32, q: f32, t: f32): f32 {
21
+ if (t < 0.0) {
22
+ t += 1.0;
23
+ }
24
+ if (t > 1.0) {
25
+ t -= 1.0;
26
+ }
27
+ if (t < (1.0 / 6.0)) {
28
+ return p + (q - p) * 6.0 * t;
29
+ }
30
+ if (t < (1.0 / 2.0)) {
31
+ return q;
32
+ }
33
+ if (t < (2.0 / 3.0)) {
34
+ return p + (q - p) * ((2.0 / 3.0) - t) * 6.0;
35
+ }
36
+ return p;
37
+ }
38
+
39
+ export function hslToColor(hue: f32, saturation: f32, lightness: f32): u32 {
40
+ const normalizedHue = hue % 360.0;
41
+ const h = normalizedHue < 0.0 ? normalizedHue + 360.0 : normalizedHue;
42
+ const s = clampUnit(saturation);
43
+ const l = clampUnit(lightness);
44
+ const hueFraction: f32 = h / <f32>360.0;
45
+ if (s <= 0.0) {
46
+ const channel = <u32>(l * 255.0);
47
+ return rgb(channel, channel, channel);
48
+ }
49
+
50
+ const q: f32 = l < <f32>0.5 ? l * (<f32>1.0 + s) : l + s - (l * s);
51
+ const p: f32 = (<f32>2.0 * l) - q;
52
+ const red = <u32>(clampUnit(hueToRgb(p, q, hueFraction + <f32>(1.0 / 3.0))) * 255.0);
53
+ const green = <u32>(clampUnit(hueToRgb(p, q, hueFraction)) * 255.0);
54
+ const blue = <u32>(clampUnit(hueToRgb(p, q, hueFraction - <f32>(1.0 / 3.0))) * 255.0);
55
+ return rgb(red, green, blue);
56
+ }
57
+
58
+ function colorRed(color: u32): u32 {
59
+ return (color >>> 24) & 0xff;
60
+ }
61
+
62
+ function colorGreen(color: u32): u32 {
63
+ return (color >>> 16) & 0xff;
64
+ }
65
+
66
+ function colorBlue(color: u32): u32 {
67
+ return (color >>> 8) & 0xff;
68
+ }
69
+
70
+ function colorAlpha(color: u32): u32 {
71
+ return color & 0xff;
72
+ }
73
+
74
+ function mixChannel(from: u32, to: u32, amount: f32): u32 {
75
+ const weight = clampUnit(amount);
76
+ return <u32>Math.round(<f32>from + ((<f32>to - <f32>from) * weight));
77
+ }
78
+
79
+ export function mixColor(from: u32, to: u32, amount: f32): u32 {
80
+ return rgba(
81
+ mixChannel(colorRed(from), colorRed(to), amount),
82
+ mixChannel(colorGreen(from), colorGreen(to), amount),
83
+ mixChannel(colorBlue(from), colorBlue(to), amount),
84
+ mixChannel(colorAlpha(from), colorAlpha(to), amount),
85
+ );
86
+ }
@@ -0,0 +1,23 @@
1
+ import * as ui from "../bindings/ui";
2
+ import { HandleValue } from "../core/ffi";
3
+ import { FlexBox } from "../nodes/FlexBox";
4
+
5
+ /**
6
+ * Prevents a parent SelectionArea from collecting selectable nodes inside
7
+ * this subtree. Nested SelectionArea islands within AntiSelectionArea are
8
+ * unaffected and become independent cross-selection roots.
9
+ */
10
+ export class AntiSelectionArea extends FlexBox {
11
+ get isSelectionBarrier(): bool {
12
+ return true;
13
+ }
14
+
15
+ build(): u64 {
16
+ if (this.builtHandle != <u64>HandleValue.Invalid) {
17
+ return this.builtHandle;
18
+ }
19
+ const handle = super.build();
20
+ ui.setSelectionAreaBarrier(handle, true);
21
+ return handle;
22
+ }
23
+ }