@effindomv2/fui-rs 0.1.3

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 (115) hide show
  1. package/COMMERCIAL.md +7 -0
  2. package/Cargo.toml +34 -0
  3. package/LICENSE.md +9 -0
  4. package/README.md +88 -0
  5. package/package.json +54 -0
  6. package/scripts/build.sh +227 -0
  7. package/scripts/check-runtime-dependency.sh +41 -0
  8. package/scripts/framework-host-services.ts +40 -0
  9. package/scripts/generate-host-events.ts +17 -0
  10. package/scripts/generate-host-services.ts +28 -0
  11. package/scripts/hostgen/common.ts +73 -0
  12. package/scripts/hostgen/registry.ts +159 -0
  13. package/scripts/hostgen/rust-host-events.ts +171 -0
  14. package/scripts/hostgen/rust-host-services.ts +257 -0
  15. package/src/animation.rs +625 -0
  16. package/src/app.rs +324 -0
  17. package/src/assets.rs +572 -0
  18. package/src/bindings/mod.rs +1 -0
  19. package/src/bindings/ui.rs +705 -0
  20. package/src/bitmap.rs +317 -0
  21. package/src/bridge_callbacks.rs +242 -0
  22. package/src/context_menu_manager.rs +332 -0
  23. package/src/controls/anti_selection_area.rs +54 -0
  24. package/src/controls/button.rs +542 -0
  25. package/src/controls/checkbox.rs +372 -0
  26. package/src/controls/combobox.rs +1574 -0
  27. package/src/controls/context_menu.rs +1367 -0
  28. package/src/controls/control_template_set.rs +46 -0
  29. package/src/controls/control_tokens.rs +596 -0
  30. package/src/controls/dialog.rs +590 -0
  31. package/src/controls/dropdown.rs +1010 -0
  32. package/src/controls/form.rs +229 -0
  33. package/src/controls/internal/button_presenter.rs +142 -0
  34. package/src/controls/internal/checkbox_indicator_presenter.rs +210 -0
  35. package/src/controls/internal/dropdown_chevron_presenter.rs +134 -0
  36. package/src/controls/internal/dropdown_field_presenter.rs +269 -0
  37. package/src/controls/internal/dropdown_option_row_presenter.rs +184 -0
  38. package/src/controls/internal/mod.rs +13 -0
  39. package/src/controls/internal/pressable_indicator_presenter.rs +26 -0
  40. package/src/controls/internal/pressable_labeled_control.rs +492 -0
  41. package/src/controls/internal/radio_indicator_presenter.rs +208 -0
  42. package/src/controls/internal/selectable_popup_list.rs +597 -0
  43. package/src/controls/internal/slider_presenter.rs +282 -0
  44. package/src/controls/internal/switch_indicator_presenter.rs +235 -0
  45. package/src/controls/internal/text_input_core.rs +1074 -0
  46. package/src/controls/internal/text_input_presenter.rs +108 -0
  47. package/src/controls/mod.rs +235 -0
  48. package/src/controls/nav_link.rs +395 -0
  49. package/src/controls/popup.rs +191 -0
  50. package/src/controls/progress_bar.rs +287 -0
  51. package/src/controls/radio_button.rs +348 -0
  52. package/src/controls/radio_group.rs +283 -0
  53. package/src/controls/selection_area.rs +82 -0
  54. package/src/controls/shared.rs +68 -0
  55. package/src/controls/slider.rs +701 -0
  56. package/src/controls/switch.rs +293 -0
  57. package/src/controls/templating.rs +49 -0
  58. package/src/controls/tests.rs +3905 -0
  59. package/src/controls/text_area.rs +207 -0
  60. package/src/controls/text_input.rs +192 -0
  61. package/src/debug.rs +146 -0
  62. package/src/drag_drop.rs +424 -0
  63. package/src/drag_gesture.rs +258 -0
  64. package/src/drawing.rs +385 -0
  65. package/src/event.rs +1603 -0
  66. package/src/external_drop.rs +467 -0
  67. package/src/fetch.rs +500 -0
  68. package/src/ffi.rs +3542 -0
  69. package/src/file.rs +1677 -0
  70. package/src/focus_adorner.rs +307 -0
  71. package/src/focus_visibility.rs +121 -0
  72. package/src/frame_scheduler.rs +159 -0
  73. package/src/frame_signal.rs +64 -0
  74. package/src/generated/ffi.rs +798 -0
  75. package/src/generated/framework_host_services.rs +74 -0
  76. package/src/generated/mod.rs +2 -0
  77. package/src/host_services.rs +162 -0
  78. package/src/image_sampling.rs +78 -0
  79. package/src/keyboard_scroll.rs +137 -0
  80. package/src/keyboard_scroll_tracker.rs +385 -0
  81. package/src/lib.rs +547 -0
  82. package/src/logger.rs +56 -0
  83. package/src/mobile_text_selection_toolbar.rs +1034 -0
  84. package/src/navigation.rs +48 -0
  85. package/src/node/core.rs +2210 -0
  86. package/src/node/custom_drawable.rs +149 -0
  87. package/src/node/flex_box.rs +874 -0
  88. package/src/node/grid.rs +304 -0
  89. package/src/node/helpers.rs +442 -0
  90. package/src/node/image.rs +506 -0
  91. package/src/node/mod.rs +315 -0
  92. package/src/node/scroll_bar.rs +845 -0
  93. package/src/node/scroll_box.rs +514 -0
  94. package/src/node/scroll_state.rs +121 -0
  95. package/src/node/scroll_view.rs +557 -0
  96. package/src/node/svg_node.rs +474 -0
  97. package/src/node/text_node.rs +633 -0
  98. package/src/node/virtual_list.rs +678 -0
  99. package/src/panic_hook.rs +36 -0
  100. package/src/persisted.rs +274 -0
  101. package/src/platform.rs +556 -0
  102. package/src/popup_presenter.rs +344 -0
  103. package/src/selection_handle_adorner.rs +838 -0
  104. package/src/signal.rs +134 -0
  105. package/src/text.rs +1065 -0
  106. package/src/theme.rs +571 -0
  107. package/src/timers.rs +106 -0
  108. package/src/tool_tip.rs +167 -0
  109. package/src/tool_tip_manager.rs +691 -0
  110. package/src/transitions.rs +41 -0
  111. package/src/typography.rs +520 -0
  112. package/src/viewport.rs +108 -0
  113. package/src/worker.rs +308 -0
  114. package/src/worker_job.rs +82 -0
  115. package/src/worker_runtime.rs +172 -0
package/src/ffi.rs ADDED
@@ -0,0 +1,3542 @@
1
+ pub use crate::generated::ffi::*;
2
+
3
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
4
+ #[derive(Debug, Clone, PartialEq)]
5
+ pub enum Call {
6
+ Reset,
7
+ CreateNode {
8
+ node_type: u32,
9
+ handle: u64,
10
+ },
11
+ DeleteNode {
12
+ handle: u64,
13
+ },
14
+ NodeAddChild {
15
+ parent: u64,
16
+ child: u64,
17
+ },
18
+ NodeRemoveChild {
19
+ parent: u64,
20
+ child: u64,
21
+ },
22
+ SetRoot {
23
+ handle: u64,
24
+ },
25
+ SetNodeId {
26
+ handle: u64,
27
+ node_id: String,
28
+ },
29
+ SetSemanticRole {
30
+ handle: u64,
31
+ role_enum: u32,
32
+ },
33
+ SetSemanticExpanded {
34
+ handle: u64,
35
+ has_expanded: bool,
36
+ is_expanded: bool,
37
+ },
38
+ SetSemanticLabel {
39
+ handle: u64,
40
+ label: String,
41
+ },
42
+ SetSemanticChecked {
43
+ handle: u64,
44
+ checked_state_enum: u32,
45
+ },
46
+ SetSemanticSelected {
47
+ handle: u64,
48
+ has_selected: bool,
49
+ selected: bool,
50
+ },
51
+ SetSemanticDisabled {
52
+ handle: u64,
53
+ has_disabled: bool,
54
+ disabled: bool,
55
+ },
56
+ SetSemanticValueRange {
57
+ handle: u64,
58
+ has_value_range: bool,
59
+ value_now: f32,
60
+ value_min: f32,
61
+ value_max: f32,
62
+ },
63
+ SetSemanticOrientation {
64
+ handle: u64,
65
+ orientation_enum: u32,
66
+ },
67
+ RequestSemanticAnnouncement {
68
+ handle: u64,
69
+ },
70
+ PushSemanticScope {
71
+ handle: u64,
72
+ token: u32,
73
+ },
74
+ RemoveSemanticScope {
75
+ token: u32,
76
+ },
77
+ SetIsPortal {
78
+ handle: u64,
79
+ is_portal: bool,
80
+ },
81
+ SetVisibility {
82
+ handle: u64,
83
+ visibility_enum: u32,
84
+ },
85
+ SetWidth {
86
+ handle: u64,
87
+ value: f32,
88
+ unit_enum: u32,
89
+ },
90
+ SetHeight {
91
+ handle: u64,
92
+ value: f32,
93
+ unit_enum: u32,
94
+ },
95
+ SetFillWidth {
96
+ handle: u64,
97
+ fill: bool,
98
+ },
99
+ SetFillHeight {
100
+ handle: u64,
101
+ fill: bool,
102
+ },
103
+ SetFillWidthPercent {
104
+ handle: u64,
105
+ percent: f32,
106
+ },
107
+ SetFillHeightPercent {
108
+ handle: u64,
109
+ percent: f32,
110
+ },
111
+ SetMinWidth {
112
+ handle: u64,
113
+ value: f32,
114
+ unit_enum: u32,
115
+ },
116
+ SetMaxWidth {
117
+ handle: u64,
118
+ value: f32,
119
+ unit_enum: u32,
120
+ },
121
+ SetMinHeight {
122
+ handle: u64,
123
+ value: f32,
124
+ unit_enum: u32,
125
+ },
126
+ SetMaxHeight {
127
+ handle: u64,
128
+ value: f32,
129
+ unit_enum: u32,
130
+ },
131
+ SetBgColor {
132
+ handle: u64,
133
+ color: u32,
134
+ },
135
+ SetBoxStyle {
136
+ handle: u64,
137
+ bg_color: u32,
138
+ radius_tl: f32,
139
+ radius_tr: f32,
140
+ radius_br: f32,
141
+ radius_bl: f32,
142
+ border_width: f32,
143
+ border_color: u32,
144
+ border_style_enum: u32,
145
+ border_dash_on: f32,
146
+ border_dash_off: f32,
147
+ },
148
+ SetLinearGradient {
149
+ handle: u64,
150
+ sx: f32,
151
+ sy: f32,
152
+ ex: f32,
153
+ ey: f32,
154
+ offsets: Vec<f32>,
155
+ colors: Vec<u32>,
156
+ },
157
+ SetDropShadow {
158
+ handle: u64,
159
+ color: u32,
160
+ offset_x: f32,
161
+ offset_y: f32,
162
+ blur_sigma: f32,
163
+ spread: f32,
164
+ },
165
+ SetLayerEffect {
166
+ handle: u64,
167
+ opacity: f32,
168
+ blur_sigma: f32,
169
+ blend_mode_enum: u32,
170
+ },
171
+ SetBackgroundBlur {
172
+ handle: u64,
173
+ blur_sigma: f32,
174
+ },
175
+ SetText {
176
+ handle: u64,
177
+ text: String,
178
+ },
179
+ SetTextStyleRuns {
180
+ handle: u64,
181
+ run_count: u32,
182
+ words: Vec<u32>,
183
+ },
184
+ PrepareNode {
185
+ handle: u64,
186
+ },
187
+ SetDynamicTextCharset {
188
+ handle: u64,
189
+ charset: String,
190
+ },
191
+ GetTextMetrics {
192
+ handle: u64,
193
+ },
194
+ SetFont {
195
+ handle: u64,
196
+ font_id: u32,
197
+ size: f32,
198
+ },
199
+ RegisterFontFallback {
200
+ font_id: u32,
201
+ fallback_font_id: u32,
202
+ },
203
+ SetLineHeight {
204
+ handle: u64,
205
+ line_height: f32,
206
+ },
207
+ SetTextColor {
208
+ handle: u64,
209
+ color: u32,
210
+ },
211
+ SetTextAlign {
212
+ handle: u64,
213
+ align_enum: u32,
214
+ },
215
+ SetTextVerticalAlign {
216
+ handle: u64,
217
+ align_enum: u32,
218
+ },
219
+ SetTextLimits {
220
+ handle: u64,
221
+ max_chars: i32,
222
+ max_lines: i32,
223
+ },
224
+ SetTextWrapping {
225
+ handle: u64,
226
+ wrap: bool,
227
+ },
228
+ SetTextOverflow {
229
+ handle: u64,
230
+ overflow_enum: u32,
231
+ },
232
+ SetTextOverflowFade {
233
+ handle: u64,
234
+ horizontal: bool,
235
+ vertical: bool,
236
+ },
237
+ SetSelectable {
238
+ handle: u64,
239
+ selectable: bool,
240
+ selection_color: u32,
241
+ },
242
+ SetTextSelectionRange {
243
+ handle: u64,
244
+ start: u32,
245
+ end: u32,
246
+ },
247
+ SetEditable {
248
+ handle: u64,
249
+ editable: bool,
250
+ },
251
+ SetEditorCommandKeys {
252
+ handle: u64,
253
+ enabled: bool,
254
+ },
255
+ SetEditorAcceptsTab {
256
+ handle: u64,
257
+ enabled: bool,
258
+ },
259
+ ReplaceTextRange {
260
+ handle: u64,
261
+ start: u32,
262
+ end: u32,
263
+ text: String,
264
+ caret: u32,
265
+ },
266
+ SetTextObscured {
267
+ handle: u64,
268
+ obscured: bool,
269
+ },
270
+ SetCaretColor {
271
+ handle: u64,
272
+ color: u32,
273
+ },
274
+ RegisterTextInputMetadata {
275
+ handle: u64,
276
+ is_password: bool,
277
+ hint: String,
278
+ },
279
+ SetPreserveSelectionOnPointerDown {
280
+ handle: u64,
281
+ preserve: bool,
282
+ },
283
+ SetInteractive {
284
+ handle: u64,
285
+ interactive: bool,
286
+ },
287
+ SetFocusable {
288
+ handle: u64,
289
+ focusable: bool,
290
+ tab_index: i32,
291
+ },
292
+ RequestFocus {
293
+ handle: u64,
294
+ },
295
+ SetPadding {
296
+ handle: u64,
297
+ left: f32,
298
+ top: f32,
299
+ right: f32,
300
+ bottom: f32,
301
+ },
302
+ SetFlexDirection {
303
+ handle: u64,
304
+ dir_enum: u32,
305
+ },
306
+ SetFlexBasis {
307
+ handle: u64,
308
+ basis: f32,
309
+ },
310
+ SetJustifyContent {
311
+ handle: u64,
312
+ justify_enum: u32,
313
+ },
314
+ SetAlignItems {
315
+ handle: u64,
316
+ align_enum: u32,
317
+ },
318
+ SetAlignSelf {
319
+ handle: u64,
320
+ align_enum: u32,
321
+ },
322
+ SetMargin {
323
+ handle: u64,
324
+ left: f32,
325
+ top: f32,
326
+ right: f32,
327
+ bottom: f32,
328
+ },
329
+ SetPositionType {
330
+ handle: u64,
331
+ pos_enum: u32,
332
+ },
333
+ SetPosition {
334
+ handle: u64,
335
+ left: f32,
336
+ top: f32,
337
+ right: f32,
338
+ bottom: f32,
339
+ },
340
+ SetIsSharedSizeScope {
341
+ handle: u64,
342
+ is_scope: bool,
343
+ },
344
+ SetCustomDrawable {
345
+ handle: u64,
346
+ is_custom_drawable: bool,
347
+ },
348
+ SetFlexWrap {
349
+ handle: u64,
350
+ wrap_enum: u32,
351
+ },
352
+ SetClipToBounds {
353
+ handle: u64,
354
+ clip: bool,
355
+ },
356
+ SetSelectionArea {
357
+ handle: u64,
358
+ is_area: bool,
359
+ },
360
+ SetSelectionAreaBarrier {
361
+ handle: u64,
362
+ is_barrier: bool,
363
+ },
364
+ ClearSelection {
365
+ text_node_handle: u64,
366
+ },
367
+ RetargetSelection {
368
+ from_text_node_handle: u64,
369
+ to_text_node_handle: u64,
370
+ },
371
+ GridSetColumns {
372
+ handle: u64,
373
+ values: Vec<f32>,
374
+ type_enums: Vec<u8>,
375
+ },
376
+ GridSetRows {
377
+ handle: u64,
378
+ values: Vec<f32>,
379
+ type_enums: Vec<u8>,
380
+ },
381
+ GridSetColumnSharedSizeGroup {
382
+ handle: u64,
383
+ index: u32,
384
+ group: String,
385
+ },
386
+ GridSetRowSharedSizeGroup {
387
+ handle: u64,
388
+ index: u32,
389
+ group: String,
390
+ },
391
+ NodeSetGridPlacement {
392
+ handle: u64,
393
+ row: u32,
394
+ col: u32,
395
+ row_span: u32,
396
+ col_span: u32,
397
+ },
398
+ SetImage {
399
+ handle: u64,
400
+ texture_id: u32,
401
+ object_fit_enum: u32,
402
+ sampling_kind: u32,
403
+ max_aniso: u32,
404
+ },
405
+ SetImageNine {
406
+ handle: u64,
407
+ texture_id: u32,
408
+ inset_left: f32,
409
+ inset_top: f32,
410
+ inset_right: f32,
411
+ inset_bottom: f32,
412
+ sampling_kind: u32,
413
+ max_aniso: u32,
414
+ },
415
+ SetSvg {
416
+ handle: u64,
417
+ svg_id: u32,
418
+ tint_color: u32,
419
+ sampling_kind: u32,
420
+ max_aniso: u32,
421
+ },
422
+ SetScrollProxyTarget {
423
+ handle: u64,
424
+ scroll_handle: u64,
425
+ },
426
+ SetScrollEnabled {
427
+ handle: u64,
428
+ enabled_x: bool,
429
+ enabled_y: bool,
430
+ },
431
+ SetScrollFriction {
432
+ handle: u64,
433
+ friction: f32,
434
+ },
435
+ SetSmoothScrolling {
436
+ handle: u64,
437
+ smooth_scrolling: bool,
438
+ },
439
+ SetScrollOffset {
440
+ handle: u64,
441
+ offset_x: f32,
442
+ offset_y: f32,
443
+ },
444
+ ClearMomentumScroll,
445
+ SetScrollContentSize {
446
+ handle: u64,
447
+ content_width: f32,
448
+ content_height: f32,
449
+ },
450
+ CommitFrame,
451
+ ResizeWindow {
452
+ logical_w: f32,
453
+ logical_h: f32,
454
+ },
455
+ RequestRender,
456
+ GetViewportWidth,
457
+ GetViewportHeight,
458
+ GetDevicePixelRatio,
459
+ SetPointerCapture {
460
+ handle: u64,
461
+ },
462
+ ReleasePointerCapture,
463
+ CanNavigateBack,
464
+ CanNavigateForward,
465
+ NavigateBack,
466
+ NavigateForward,
467
+ ReloadPage,
468
+ CopyText {
469
+ text: String,
470
+ },
471
+ HasTextSelectionSnapshot {
472
+ handle: u64,
473
+ },
474
+ CopyTextSelectionSnapshot {
475
+ handle: u64,
476
+ },
477
+ CutFocusedTextSelection,
478
+ CutTextSelectionSnapshot {
479
+ handle: u64,
480
+ },
481
+ DeleteFocusedTextRange {
482
+ start: u32,
483
+ end: u32,
484
+ },
485
+ CommitTextActionFocus {
486
+ handle: u64,
487
+ },
488
+ CopyCurrentSelection,
489
+ HasTextSelection {
490
+ handle: u64,
491
+ },
492
+ UndoTextEdit {
493
+ handle: u64,
494
+ },
495
+ RedoTextEdit {
496
+ handle: u64,
497
+ },
498
+ CopyTextSelection {
499
+ handle: u64,
500
+ },
501
+ CutTextSelection {
502
+ handle: u64,
503
+ },
504
+ PasteText {
505
+ handle: u64,
506
+ },
507
+ SelectAllText {
508
+ handle: u64,
509
+ },
510
+ SelectWordAt {
511
+ handle: u64,
512
+ x: f32,
513
+ y: f32,
514
+ },
515
+ ClearCurrentSelection,
516
+ IsPointInSelection {
517
+ x: f32,
518
+ y: f32,
519
+ },
520
+ GetTextRangeRectCount {
521
+ handle: u64,
522
+ start: u32,
523
+ end: u32,
524
+ },
525
+ CopyTextRangeRects {
526
+ handle: u64,
527
+ start: u32,
528
+ end: u32,
529
+ max_rect_count: u32,
530
+ },
531
+ CopyCrossSelectionEndpointRects {
532
+ handle: u64,
533
+ },
534
+ BeginSelectionEndpointDrag {
535
+ handle: u64,
536
+ endpoint: u32,
537
+ },
538
+ StartTimer {
539
+ timer_id: u32,
540
+ delay_ms: i32,
541
+ },
542
+ CancelTimer {
543
+ timer_id: u32,
544
+ },
545
+ SetCursor {
546
+ style: u32,
547
+ },
548
+ NavigateTo {
549
+ target: String,
550
+ open_in_new_tab: bool,
551
+ },
552
+ ShowUrlPreview {
553
+ url: String,
554
+ },
555
+ HideUrlPreview,
556
+ Log {
557
+ category: String,
558
+ message: String,
559
+ },
560
+ LogsEnabled,
561
+ IsDarkMode,
562
+ GetAccentColor,
563
+ GetPlatformFamily,
564
+ IsCoarsePointer,
565
+ LoadSvg {
566
+ svg_id: u32,
567
+ url: String,
568
+ },
569
+ ReleaseSvg {
570
+ svg_id: u32,
571
+ },
572
+ LoadTexture {
573
+ texture_id: u32,
574
+ url: String,
575
+ },
576
+ ReleaseTexture {
577
+ texture_id: u32,
578
+ },
579
+ LoadFont {
580
+ font_id: u32,
581
+ url: String,
582
+ },
583
+ BitmapCommit {
584
+ texture_id: u32,
585
+ bytes: Vec<u8>,
586
+ width: u32,
587
+ height: u32,
588
+ },
589
+ BitmapCommitDirty {
590
+ texture_id: u32,
591
+ bytes: Vec<u8>,
592
+ full_width: u32,
593
+ full_height: u32,
594
+ sub_x: u32,
595
+ sub_y: u32,
596
+ sub_w: u32,
597
+ sub_h: u32,
598
+ },
599
+ BitmapRelease {
600
+ texture_id: u32,
601
+ },
602
+ RenderNodeToRgba {
603
+ handle: u64,
604
+ width: u32,
605
+ height: u32,
606
+ out_capacity: u32,
607
+ scale: f32,
608
+ x: f32,
609
+ y: f32,
610
+ },
611
+ FetchStart {
612
+ request_id: u32,
613
+ method: String,
614
+ url: String,
615
+ headers: Vec<String>,
616
+ body: Vec<u8>,
617
+ },
618
+ FetchCancel {
619
+ request_id: u32,
620
+ },
621
+ SetPersistedScrollOffset {
622
+ node_id: String,
623
+ x: f32,
624
+ y: f32,
625
+ },
626
+ TryGetPersistedScrollOffset {
627
+ node_id: String,
628
+ },
629
+ SetPersistedState {
630
+ node_id: String,
631
+ kind: String,
632
+ version: u32,
633
+ payload: String,
634
+ },
635
+ CopyPersistedState {
636
+ node_id: String,
637
+ kind: String,
638
+ },
639
+ WorkerStartString {
640
+ worker_id: u32,
641
+ wasm_path: String,
642
+ entry: String,
643
+ input: String,
644
+ },
645
+ WorkerCancel {
646
+ worker_id: u32,
647
+ },
648
+ FileCapabilities,
649
+ FilePick {
650
+ request_id: u32,
651
+ accept: String,
652
+ multiple: bool,
653
+ },
654
+ FileReadChunk {
655
+ request_id: u32,
656
+ file_id: String,
657
+ offset_bytes: u64,
658
+ max_bytes: u32,
659
+ },
660
+ FileSaveText {
661
+ request_id: u32,
662
+ suggested_name: String,
663
+ mime_type: String,
664
+ file_extension: String,
665
+ text: String,
666
+ },
667
+ FileSaveBytes {
668
+ request_id: u32,
669
+ suggested_name: String,
670
+ mime_type: String,
671
+ file_extension: String,
672
+ bytes: Vec<u8>,
673
+ },
674
+ FileCreateWriter {
675
+ request_id: u32,
676
+ suggested_name: String,
677
+ mime_type: String,
678
+ file_extension: String,
679
+ },
680
+ FileWriterWriteText {
681
+ request_id: u32,
682
+ writer_id: String,
683
+ text: String,
684
+ },
685
+ FileWriterWriteBytes {
686
+ request_id: u32,
687
+ writer_id: String,
688
+ bytes: Vec<u8>,
689
+ },
690
+ FileWriterFinish {
691
+ request_id: u32,
692
+ writer_id: String,
693
+ },
694
+ FileProcessWorkerStart {
695
+ request_id: u32,
696
+ worker_wasm_path: String,
697
+ worker_entry_name: String,
698
+ file_id: String,
699
+ suggested_name: String,
700
+ chunk_bytes: u32,
701
+ save_to_picked_file: bool,
702
+ },
703
+ FileProcessWorkerCancel {
704
+ request_id: u32,
705
+ },
706
+ PathCreate {
707
+ path_id: u32,
708
+ },
709
+ PathDestroy {
710
+ path_id: u32,
711
+ },
712
+ PathMoveTo {
713
+ path_id: u32,
714
+ x: f32,
715
+ y: f32,
716
+ },
717
+ PathLineTo {
718
+ path_id: u32,
719
+ x: f32,
720
+ y: f32,
721
+ },
722
+ PathQuadTo {
723
+ path_id: u32,
724
+ cx: f32,
725
+ cy: f32,
726
+ x: f32,
727
+ y: f32,
728
+ },
729
+ PathCubicTo {
730
+ path_id: u32,
731
+ cx1: f32,
732
+ cy1: f32,
733
+ cx2: f32,
734
+ cy2: f32,
735
+ x: f32,
736
+ y: f32,
737
+ },
738
+ PathClose {
739
+ path_id: u32,
740
+ },
741
+ PathAddRect {
742
+ path_id: u32,
743
+ x: f32,
744
+ y: f32,
745
+ w: f32,
746
+ h: f32,
747
+ },
748
+ PathAddCircle {
749
+ path_id: u32,
750
+ cx: f32,
751
+ cy: f32,
752
+ r: f32,
753
+ },
754
+ CanvasDrawRect {
755
+ canvas_ptr: usize,
756
+ x: f32,
757
+ y: f32,
758
+ w: f32,
759
+ h: f32,
760
+ fill_color: u32,
761
+ stroke_color: u32,
762
+ stroke_width: f32,
763
+ },
764
+ CanvasDrawCircle {
765
+ canvas_ptr: usize,
766
+ cx: f32,
767
+ cy: f32,
768
+ radius: f32,
769
+ fill_color: u32,
770
+ stroke_color: u32,
771
+ stroke_width: f32,
772
+ },
773
+ CanvasDrawLine {
774
+ canvas_ptr: usize,
775
+ x1: f32,
776
+ y1: f32,
777
+ x2: f32,
778
+ y2: f32,
779
+ color: u32,
780
+ stroke_width: f32,
781
+ },
782
+ CanvasDrawRoundRect {
783
+ canvas_ptr: usize,
784
+ x: f32,
785
+ y: f32,
786
+ w: f32,
787
+ h: f32,
788
+ rx: f32,
789
+ ry: f32,
790
+ fill_color: u32,
791
+ stroke_color: u32,
792
+ stroke_width: f32,
793
+ },
794
+ CanvasDrawPath {
795
+ canvas_ptr: usize,
796
+ path_id: u32,
797
+ fill_color: u32,
798
+ stroke_color: u32,
799
+ stroke_width: f32,
800
+ },
801
+ CanvasDrawTextNode {
802
+ canvas_ptr: usize,
803
+ handle_lo: u32,
804
+ handle_hi: u32,
805
+ x: f32,
806
+ y: f32,
807
+ },
808
+ CanvasDrawImage {
809
+ canvas_ptr: usize,
810
+ texture_id: u32,
811
+ x: f32,
812
+ y: f32,
813
+ w: f32,
814
+ h: f32,
815
+ sampling_kind: u32,
816
+ max_aniso: u32,
817
+ },
818
+ CanvasDrawSvg {
819
+ canvas_ptr: usize,
820
+ svg_id: u32,
821
+ x: f32,
822
+ y: f32,
823
+ w: f32,
824
+ h: f32,
825
+ },
826
+ CanvasDrawBatch {
827
+ canvas_ptr: usize,
828
+ words: Vec<u32>,
829
+ },
830
+ CanvasCreateOffscreen {
831
+ width: u32,
832
+ height: u32,
833
+ offscreen_id: u32,
834
+ },
835
+ CanvasGetOffscreenPtr {
836
+ offscreen_id: u32,
837
+ },
838
+ CanvasReadOffscreenPixels {
839
+ offscreen_id: u32,
840
+ width: u32,
841
+ height: u32,
842
+ },
843
+ CanvasDestroyOffscreen {
844
+ offscreen_id: u32,
845
+ },
846
+ CanvasSave {
847
+ canvas_ptr: usize,
848
+ },
849
+ CanvasRestore {
850
+ canvas_ptr: usize,
851
+ },
852
+ CanvasTranslate {
853
+ canvas_ptr: usize,
854
+ x: f32,
855
+ y: f32,
856
+ },
857
+ CanvasScale {
858
+ canvas_ptr: usize,
859
+ sx: f32,
860
+ sy: f32,
861
+ },
862
+ CanvasRotate {
863
+ canvas_ptr: usize,
864
+ degrees: f32,
865
+ },
866
+ CanvasClipRect {
867
+ canvas_ptr: usize,
868
+ x: f32,
869
+ y: f32,
870
+ w: f32,
871
+ h: f32,
872
+ },
873
+ CanvasClipRoundRect {
874
+ canvas_ptr: usize,
875
+ x: f32,
876
+ y: f32,
877
+ w: f32,
878
+ h: f32,
879
+ tl: f32,
880
+ tr: f32,
881
+ br: f32,
882
+ bl: f32,
883
+ },
884
+ GetBounds {
885
+ handle: u64,
886
+ },
887
+ GetVisibleBounds {
888
+ handle: u64,
889
+ },
890
+ }
891
+
892
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
893
+ thread_local! {
894
+ static CALLS: std::cell::RefCell<Vec<Call>> = const { std::cell::RefCell::new(Vec::new()) };
895
+ static NEXT_HANDLE: std::cell::Cell<u64> = const { std::cell::Cell::new(1) };
896
+ static VIEWPORT: std::cell::Cell<(f32, f32)> = const { std::cell::Cell::new((320.0, 220.0)) };
897
+ static DEVICE_PIXEL_RATIO: std::cell::Cell<f32> = const { std::cell::Cell::new(1.0) };
898
+ static CAN_NAVIGATE_BACK: std::cell::Cell<bool> = const { std::cell::Cell::new(false) };
899
+ static CAN_NAVIGATE_FORWARD: std::cell::Cell<bool> = const { std::cell::Cell::new(false) };
900
+ static LOGS_ENABLED: std::cell::Cell<bool> = const { std::cell::Cell::new(true) };
901
+ static HOST_NOW_MS: std::cell::Cell<f64> = const { std::cell::Cell::new(0.0) };
902
+ static SYSTEM_DARK_MODE: std::cell::Cell<bool> = const { std::cell::Cell::new(true) };
903
+ static SYSTEM_ACCENT_COLOR: std::cell::Cell<u32> = const { std::cell::Cell::new(0x2563EBFF) };
904
+ static PLATFORM_FAMILY: std::cell::Cell<u32> = const { std::cell::Cell::new(0) };
905
+ static COARSE_POINTER: std::cell::Cell<bool> = const { std::cell::Cell::new(false) };
906
+ static HAS_TEXT_SELECTION_SNAPSHOT: std::cell::Cell<bool> = const { std::cell::Cell::new(false) };
907
+ static HAS_TEXT_SELECTION: std::cell::Cell<bool> = const { std::cell::Cell::new(false) };
908
+ static IS_POINT_IN_SELECTION: std::cell::Cell<bool> = const { std::cell::Cell::new(false) };
909
+ static TEXT_RANGE_RECTS: std::cell::RefCell<Vec<(f32, f32, f32, f32)>> = const { std::cell::RefCell::new(Vec::new()) };
910
+ static CROSS_SELECTION_ENDPOINT_RECTS: std::cell::RefCell<Option<[(f32, f32, f32, f32); 2]>> = const { std::cell::RefCell::new(None) };
911
+ static BEGIN_SELECTION_ENDPOINT_DRAG_RESULT: std::cell::Cell<bool> = const { std::cell::Cell::new(true) };
912
+ static CAN_UNDO_TEXT_EDIT: std::cell::Cell<bool> = const { std::cell::Cell::new(false) };
913
+ static CAN_REDO_TEXT_EDIT: std::cell::Cell<bool> = const { std::cell::Cell::new(false) };
914
+ static NEXT_PATH_ID: std::cell::Cell<u32> = const { std::cell::Cell::new(1) };
915
+ static NEXT_OFFSCREEN_ID: std::cell::Cell<u32> = const { std::cell::Cell::new(1) };
916
+ static TEXT_METRICS: std::cell::Cell<(f32, f32, f32, u32, f32)> = const { std::cell::Cell::new((100.0, 20.0, 15.0, 1, 100.0)) };
917
+ static PERSISTED_SCROLL: std::cell::RefCell<std::collections::HashMap<String, (f32, f32)>> = std::cell::RefCell::new(std::collections::HashMap::new());
918
+ static PERSISTED_TEXT: std::cell::RefCell<std::collections::HashMap<(String, String), (u32, String)>> = std::cell::RefCell::new(std::collections::HashMap::new());
919
+ static DEBUG_TREE_WORDS: std::cell::RefCell<Vec<u32>> = const { std::cell::RefCell::new(Vec::new()) };
920
+ static NEXT_SEMANTIC_SCOPE_TOKEN: std::cell::Cell<u32> = const { std::cell::Cell::new(1) };
921
+ static VISIBLE_BOUNDS: std::cell::RefCell<Option<(f32, f32, f32, f32)>> = const { std::cell::RefCell::new(None) };
922
+ }
923
+
924
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
925
+ fn push_call(call: Call) {
926
+ CALLS.with(|calls| calls.borrow_mut().push(call));
927
+ }
928
+
929
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
930
+ pub mod test {
931
+ use super::{
932
+ Call, BEGIN_SELECTION_ENDPOINT_DRAG_RESULT, CALLS, CAN_NAVIGATE_BACK, CAN_NAVIGATE_FORWARD,
933
+ CAN_REDO_TEXT_EDIT, CAN_UNDO_TEXT_EDIT, COARSE_POINTER, CROSS_SELECTION_ENDPOINT_RECTS,
934
+ DEBUG_TREE_WORDS, DEVICE_PIXEL_RATIO, HAS_TEXT_SELECTION, HAS_TEXT_SELECTION_SNAPSHOT,
935
+ HOST_NOW_MS, IS_POINT_IN_SELECTION, LOGS_ENABLED, NEXT_HANDLE, NEXT_OFFSCREEN_ID,
936
+ NEXT_PATH_ID, NEXT_SEMANTIC_SCOPE_TOKEN, PERSISTED_SCROLL, PERSISTED_TEXT, PLATFORM_FAMILY,
937
+ SYSTEM_ACCENT_COLOR, SYSTEM_DARK_MODE, TEXT_METRICS, TEXT_RANGE_RECTS, VIEWPORT,
938
+ VISIBLE_BOUNDS,
939
+ };
940
+
941
+ pub fn reset() {
942
+ crate::theme::current_theme();
943
+ CALLS.with(|calls| calls.borrow_mut().clear());
944
+ NEXT_HANDLE.with(|next| next.set(1));
945
+ VIEWPORT.with(|viewport| viewport.set((320.0, 220.0)));
946
+ DEVICE_PIXEL_RATIO.with(|value| value.set(1.0));
947
+ CAN_NAVIGATE_BACK.with(|value| value.set(false));
948
+ CAN_NAVIGATE_FORWARD.with(|value| value.set(false));
949
+ LOGS_ENABLED.with(|value| value.set(true));
950
+ HOST_NOW_MS.with(|value| value.set(0.0));
951
+ SYSTEM_DARK_MODE.with(|value| value.set(true));
952
+ SYSTEM_ACCENT_COLOR.with(|value| value.set(0x2563EBFF));
953
+ PLATFORM_FAMILY.with(|value| value.set(0));
954
+ COARSE_POINTER.with(|value| value.set(false));
955
+ HAS_TEXT_SELECTION_SNAPSHOT.with(|value| value.set(false));
956
+ HAS_TEXT_SELECTION.with(|value| value.set(false));
957
+ IS_POINT_IN_SELECTION.with(|value| value.set(false));
958
+ TEXT_RANGE_RECTS.with(|value| value.borrow_mut().clear());
959
+ CROSS_SELECTION_ENDPOINT_RECTS.with(|value| value.borrow_mut().take());
960
+ BEGIN_SELECTION_ENDPOINT_DRAG_RESULT.with(|value| value.set(true));
961
+ CAN_UNDO_TEXT_EDIT.with(|value| value.set(false));
962
+ CAN_REDO_TEXT_EDIT.with(|value| value.set(false));
963
+ NEXT_PATH_ID.with(|next| next.set(1));
964
+ NEXT_OFFSCREEN_ID.with(|next| next.set(1));
965
+ TEXT_METRICS.with(|value| value.set((100.0, 20.0, 15.0, 1, 100.0)));
966
+ PERSISTED_SCROLL.with(|map| map.borrow_mut().clear());
967
+ PERSISTED_TEXT.with(|map| map.borrow_mut().clear());
968
+ DEBUG_TREE_WORDS.with(|words| words.borrow_mut().clear());
969
+ NEXT_SEMANTIC_SCOPE_TOKEN.with(|next| next.set(1));
970
+ VISIBLE_BOUNDS.with(|bounds| bounds.borrow_mut().take());
971
+ }
972
+
973
+ pub fn take_calls() -> Vec<Call> {
974
+ CALLS.with(|calls| std::mem::take(&mut *calls.borrow_mut()))
975
+ }
976
+
977
+ pub fn set_viewport(width: f32, height: f32) {
978
+ VIEWPORT.with(|viewport| viewport.set((width, height)));
979
+ }
980
+
981
+ pub fn set_device_pixel_ratio(value: f32) {
982
+ DEVICE_PIXEL_RATIO.with(|dpr| dpr.set(value));
983
+ }
984
+
985
+ pub fn set_can_navigate_back(value: bool) {
986
+ CAN_NAVIGATE_BACK.with(|flag| flag.set(value));
987
+ }
988
+
989
+ pub fn set_can_navigate_forward(value: bool) {
990
+ CAN_NAVIGATE_FORWARD.with(|flag| flag.set(value));
991
+ }
992
+
993
+ pub fn set_logs_enabled(value: bool) {
994
+ LOGS_ENABLED.with(|flag| flag.set(value));
995
+ }
996
+
997
+ pub fn set_host_now_ms(value: f64) {
998
+ HOST_NOW_MS.with(|slot| slot.set(value));
999
+ }
1000
+
1001
+ pub fn host_now_ms() -> f64 {
1002
+ HOST_NOW_MS.with(|slot| slot.get())
1003
+ }
1004
+
1005
+ pub fn set_system_dark_mode(value: bool) {
1006
+ SYSTEM_DARK_MODE.with(|flag| flag.set(value));
1007
+ }
1008
+
1009
+ pub fn set_system_accent_color(value: u32) {
1010
+ SYSTEM_ACCENT_COLOR.with(|color| color.set(value));
1011
+ }
1012
+
1013
+ pub fn set_platform_family(value: u32) {
1014
+ PLATFORM_FAMILY.with(|family| family.set(value));
1015
+ }
1016
+
1017
+ pub fn set_coarse_pointer(value: bool) {
1018
+ COARSE_POINTER.with(|flag| flag.set(value));
1019
+ }
1020
+
1021
+ pub fn set_has_text_selection_snapshot(value: bool) {
1022
+ HAS_TEXT_SELECTION_SNAPSHOT.with(|flag| flag.set(value));
1023
+ }
1024
+
1025
+ pub fn set_has_text_selection(value: bool) {
1026
+ HAS_TEXT_SELECTION.with(|flag| flag.set(value));
1027
+ }
1028
+
1029
+ pub fn set_is_point_in_selection(value: bool) {
1030
+ IS_POINT_IN_SELECTION.with(|flag| flag.set(value));
1031
+ }
1032
+
1033
+ pub fn set_text_range_rects(rects: &[(f32, f32, f32, f32)]) {
1034
+ TEXT_RANGE_RECTS.with(|slot| {
1035
+ let mut buffer = slot.borrow_mut();
1036
+ buffer.clear();
1037
+ buffer.extend_from_slice(rects);
1038
+ });
1039
+ }
1040
+
1041
+ pub fn set_cross_selection_endpoint_rects(value: Option<[(f32, f32, f32, f32); 2]>) {
1042
+ CROSS_SELECTION_ENDPOINT_RECTS.with(|slot| {
1043
+ *slot.borrow_mut() = value;
1044
+ });
1045
+ }
1046
+
1047
+ pub fn set_begin_selection_endpoint_drag_result(value: bool) {
1048
+ BEGIN_SELECTION_ENDPOINT_DRAG_RESULT.with(|slot| slot.set(value));
1049
+ }
1050
+
1051
+ pub fn set_can_undo_text_edit(value: bool) {
1052
+ CAN_UNDO_TEXT_EDIT.with(|flag| flag.set(value));
1053
+ }
1054
+
1055
+ pub fn set_can_redo_text_edit(value: bool) {
1056
+ CAN_REDO_TEXT_EDIT.with(|flag| flag.set(value));
1057
+ }
1058
+
1059
+ pub fn set_text_metrics(
1060
+ width: f32,
1061
+ height: f32,
1062
+ baseline: f32,
1063
+ line_count: u32,
1064
+ max_line_width: f32,
1065
+ ) {
1066
+ TEXT_METRICS.with(|value| value.set((width, height, baseline, line_count, max_line_width)));
1067
+ }
1068
+
1069
+ pub fn set_debug_tree_words(words: &[u32]) {
1070
+ DEBUG_TREE_WORDS.with(|slot| {
1071
+ let mut buffer = slot.borrow_mut();
1072
+ buffer.clear();
1073
+ buffer.extend_from_slice(words);
1074
+ });
1075
+ }
1076
+
1077
+ pub fn set_visible_bounds(value: Option<(f32, f32, f32, f32)>) {
1078
+ VISIBLE_BOUNDS.with(|slot| {
1079
+ *slot.borrow_mut() = value;
1080
+ });
1081
+ }
1082
+ }
1083
+
1084
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1085
+ pub unsafe fn ui_reset() {
1086
+ push_call(Call::Reset);
1087
+ }
1088
+
1089
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1090
+ pub unsafe fn ui_create_node(type_: u32) -> u64 {
1091
+ let handle = NEXT_HANDLE.with(|next| {
1092
+ let handle = next.get();
1093
+ next.set(handle + 1);
1094
+ handle
1095
+ });
1096
+ push_call(Call::CreateNode {
1097
+ node_type: type_,
1098
+ handle,
1099
+ });
1100
+ handle
1101
+ }
1102
+
1103
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1104
+ pub unsafe fn ui_delete_node(handle: u64) {
1105
+ push_call(Call::DeleteNode { handle });
1106
+ }
1107
+
1108
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1109
+ pub unsafe fn ui_node_add_child(parent: u64, child: u64) {
1110
+ push_call(Call::NodeAddChild { parent, child });
1111
+ }
1112
+
1113
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1114
+ pub unsafe fn ui_node_remove_child(parent: u64, child: u64) {
1115
+ push_call(Call::NodeRemoveChild { parent, child });
1116
+ }
1117
+
1118
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1119
+ pub unsafe fn ui_set_root(handle: u64) {
1120
+ push_call(Call::SetRoot { handle });
1121
+ }
1122
+
1123
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1124
+ pub unsafe fn ui_set_node_id(handle: u64, utf8_id: *const u8, len: u32) {
1125
+ let node_id = if utf8_id.is_null() || len == 0 {
1126
+ String::new()
1127
+ } else {
1128
+ String::from_utf8_lossy(std::slice::from_raw_parts(utf8_id, len as usize)).into_owned()
1129
+ };
1130
+ push_call(Call::SetNodeId { handle, node_id });
1131
+ }
1132
+
1133
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1134
+ pub unsafe fn ui_set_semantic_role(handle: u64, role_enum: u32) {
1135
+ push_call(Call::SetSemanticRole { handle, role_enum });
1136
+ }
1137
+
1138
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1139
+ pub unsafe fn ui_set_semantic_expanded(handle: u64, has_expanded: bool, is_expanded: bool) {
1140
+ push_call(Call::SetSemanticExpanded {
1141
+ handle,
1142
+ has_expanded,
1143
+ is_expanded,
1144
+ });
1145
+ }
1146
+
1147
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1148
+ pub unsafe fn ui_set_semantic_label(handle: u64, utf8_label: *const u8, len: u32) {
1149
+ let label = if utf8_label.is_null() || len == 0 {
1150
+ String::new()
1151
+ } else {
1152
+ String::from_utf8_lossy(std::slice::from_raw_parts(utf8_label, len as usize)).into_owned()
1153
+ };
1154
+ push_call(Call::SetSemanticLabel { handle, label });
1155
+ }
1156
+
1157
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1158
+ pub unsafe fn ui_set_semantic_checked(handle: u64, checked_state_enum: u32) {
1159
+ push_call(Call::SetSemanticChecked {
1160
+ handle,
1161
+ checked_state_enum,
1162
+ });
1163
+ }
1164
+
1165
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1166
+ pub unsafe fn ui_set_semantic_selected(handle: u64, has_selected: bool, is_selected: bool) {
1167
+ push_call(Call::SetSemanticSelected {
1168
+ handle,
1169
+ has_selected,
1170
+ selected: is_selected,
1171
+ });
1172
+ }
1173
+
1174
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1175
+ pub unsafe fn ui_set_semantic_disabled(handle: u64, has_disabled: bool, disabled: bool) {
1176
+ push_call(Call::SetSemanticDisabled {
1177
+ handle,
1178
+ has_disabled,
1179
+ disabled,
1180
+ });
1181
+ }
1182
+
1183
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1184
+ pub unsafe fn ui_set_semantic_value_range(
1185
+ handle: u64,
1186
+ has_value_range: bool,
1187
+ value_now: f32,
1188
+ value_min: f32,
1189
+ value_max: f32,
1190
+ ) {
1191
+ push_call(Call::SetSemanticValueRange {
1192
+ handle,
1193
+ has_value_range,
1194
+ value_now,
1195
+ value_min,
1196
+ value_max,
1197
+ });
1198
+ }
1199
+
1200
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1201
+ pub unsafe fn ui_set_semantic_orientation(handle: u64, orientation_enum: u32) {
1202
+ push_call(Call::SetSemanticOrientation {
1203
+ handle,
1204
+ orientation_enum,
1205
+ });
1206
+ }
1207
+
1208
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1209
+ pub unsafe fn ui_request_semantic_announcement(handle: u64) {
1210
+ push_call(Call::RequestSemanticAnnouncement { handle });
1211
+ }
1212
+
1213
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1214
+ pub unsafe fn ui_push_semantic_scope(handle: u64) -> u32 {
1215
+ let token = NEXT_SEMANTIC_SCOPE_TOKEN.with(|next| {
1216
+ let token = next.get();
1217
+ next.set(token + 1);
1218
+ token
1219
+ });
1220
+ push_call(Call::PushSemanticScope { handle, token });
1221
+ token
1222
+ }
1223
+
1224
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1225
+ pub unsafe fn ui_remove_semantic_scope(token: u32) {
1226
+ push_call(Call::RemoveSemanticScope { token });
1227
+ }
1228
+
1229
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1230
+ pub unsafe fn ui_set_is_portal(handle: u64, is_portal: bool) {
1231
+ push_call(Call::SetIsPortal { handle, is_portal });
1232
+ }
1233
+
1234
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1235
+ pub unsafe fn ui_set_visibility(handle: u64, visibility_enum: u32) {
1236
+ push_call(Call::SetVisibility {
1237
+ handle,
1238
+ visibility_enum,
1239
+ });
1240
+ }
1241
+
1242
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1243
+ pub unsafe fn ui_set_width(handle: u64, value: f32, unit_enum: u32) {
1244
+ push_call(Call::SetWidth {
1245
+ handle,
1246
+ value,
1247
+ unit_enum,
1248
+ });
1249
+ }
1250
+
1251
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1252
+ pub unsafe fn ui_set_height(handle: u64, value: f32, unit_enum: u32) {
1253
+ push_call(Call::SetHeight {
1254
+ handle,
1255
+ value,
1256
+ unit_enum,
1257
+ });
1258
+ }
1259
+
1260
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1261
+ pub unsafe fn ui_set_fill_width(handle: u64, fill: bool) {
1262
+ push_call(Call::SetFillWidth { handle, fill });
1263
+ }
1264
+
1265
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1266
+ pub unsafe fn ui_set_fill_height(handle: u64, fill: bool) {
1267
+ push_call(Call::SetFillHeight { handle, fill });
1268
+ }
1269
+
1270
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1271
+ pub unsafe fn ui_set_fill_width_percent(handle: u64, percent: f32) {
1272
+ push_call(Call::SetFillWidthPercent { handle, percent });
1273
+ }
1274
+
1275
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1276
+ pub unsafe fn ui_set_fill_height_percent(handle: u64, percent: f32) {
1277
+ push_call(Call::SetFillHeightPercent { handle, percent });
1278
+ }
1279
+
1280
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1281
+ pub unsafe fn ui_set_min_width(handle: u64, value: f32, unit_enum: u32) {
1282
+ push_call(Call::SetMinWidth {
1283
+ handle,
1284
+ value,
1285
+ unit_enum,
1286
+ });
1287
+ }
1288
+
1289
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1290
+ pub unsafe fn ui_set_max_width(handle: u64, value: f32, unit_enum: u32) {
1291
+ push_call(Call::SetMaxWidth {
1292
+ handle,
1293
+ value,
1294
+ unit_enum,
1295
+ });
1296
+ }
1297
+
1298
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1299
+ pub unsafe fn ui_set_min_height(handle: u64, value: f32, unit_enum: u32) {
1300
+ push_call(Call::SetMinHeight {
1301
+ handle,
1302
+ value,
1303
+ unit_enum,
1304
+ });
1305
+ }
1306
+
1307
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1308
+ pub unsafe fn ui_set_max_height(handle: u64, value: f32, unit_enum: u32) {
1309
+ push_call(Call::SetMaxHeight {
1310
+ handle,
1311
+ value,
1312
+ unit_enum,
1313
+ });
1314
+ }
1315
+
1316
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1317
+ pub unsafe fn ui_set_bg_color(handle: u64, color: u32) {
1318
+ push_call(Call::SetBgColor { handle, color });
1319
+ }
1320
+
1321
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1322
+ pub unsafe fn ui_set_box_style(
1323
+ handle: u64,
1324
+ bg_color: u32,
1325
+ radius_tl: f32,
1326
+ radius_tr: f32,
1327
+ radius_br: f32,
1328
+ radius_bl: f32,
1329
+ border_width: f32,
1330
+ border_color: u32,
1331
+ border_style_enum: u32,
1332
+ border_dash_on: f32,
1333
+ border_dash_off: f32,
1334
+ ) {
1335
+ push_call(Call::SetBoxStyle {
1336
+ handle,
1337
+ bg_color,
1338
+ radius_tl,
1339
+ radius_tr,
1340
+ radius_br,
1341
+ radius_bl,
1342
+ border_width,
1343
+ border_color,
1344
+ border_style_enum,
1345
+ border_dash_on,
1346
+ border_dash_off,
1347
+ });
1348
+ }
1349
+
1350
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1351
+ pub unsafe fn ui_set_linear_gradient(
1352
+ handle: u64,
1353
+ sx: f32,
1354
+ sy: f32,
1355
+ ex: f32,
1356
+ ey: f32,
1357
+ stop_count: u32,
1358
+ offsets: *const f32,
1359
+ colors: *const u32,
1360
+ ) {
1361
+ let len = stop_count as usize;
1362
+ let copied_offsets = if offsets.is_null() || len == 0 {
1363
+ Vec::new()
1364
+ } else {
1365
+ std::slice::from_raw_parts(offsets, len).to_vec()
1366
+ };
1367
+ let copied_colors = if colors.is_null() || len == 0 {
1368
+ Vec::new()
1369
+ } else {
1370
+ std::slice::from_raw_parts(colors, len).to_vec()
1371
+ };
1372
+ push_call(Call::SetLinearGradient {
1373
+ handle,
1374
+ sx,
1375
+ sy,
1376
+ ex,
1377
+ ey,
1378
+ offsets: copied_offsets,
1379
+ colors: copied_colors,
1380
+ });
1381
+ }
1382
+
1383
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1384
+ pub unsafe fn ui_set_drop_shadow(
1385
+ handle: u64,
1386
+ color: u32,
1387
+ offset_x: f32,
1388
+ offset_y: f32,
1389
+ blur_sigma: f32,
1390
+ spread: f32,
1391
+ ) {
1392
+ push_call(Call::SetDropShadow {
1393
+ handle,
1394
+ color,
1395
+ offset_x,
1396
+ offset_y,
1397
+ blur_sigma,
1398
+ spread,
1399
+ });
1400
+ }
1401
+
1402
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1403
+ pub unsafe fn ui_set_layer_effect(
1404
+ handle: u64,
1405
+ opacity: f32,
1406
+ blur_sigma: f32,
1407
+ blend_mode_enum: u32,
1408
+ ) {
1409
+ push_call(Call::SetLayerEffect {
1410
+ handle,
1411
+ opacity,
1412
+ blur_sigma,
1413
+ blend_mode_enum,
1414
+ });
1415
+ }
1416
+
1417
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1418
+ pub unsafe fn ui_set_background_blur(handle: u64, blur_sigma: f32) {
1419
+ push_call(Call::SetBackgroundBlur { handle, blur_sigma });
1420
+ }
1421
+
1422
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1423
+ pub unsafe fn ui_set_text(handle: u64, utf8_str: *const u8, len: u32) {
1424
+ let text = if utf8_str.is_null() || len == 0 {
1425
+ String::new()
1426
+ } else {
1427
+ String::from_utf8_lossy(std::slice::from_raw_parts(utf8_str, len as usize)).into_owned()
1428
+ };
1429
+ push_call(Call::SetText { handle, text });
1430
+ }
1431
+
1432
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1433
+ pub unsafe fn ui_set_text_style_runs(handle: u64, run_count: u32, runs_words: *const u32) {
1434
+ let len = (run_count as usize).saturating_mul(7);
1435
+ let words = if runs_words.is_null() || len == 0 {
1436
+ Vec::new()
1437
+ } else {
1438
+ std::slice::from_raw_parts(runs_words, len).to_vec()
1439
+ };
1440
+ push_call(Call::SetTextStyleRuns {
1441
+ handle,
1442
+ run_count,
1443
+ words,
1444
+ });
1445
+ }
1446
+
1447
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1448
+ pub unsafe fn ui_prepare_node(handle: u64) -> u32 {
1449
+ push_call(Call::PrepareNode { handle });
1450
+ handle as u32
1451
+ }
1452
+
1453
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1454
+ pub unsafe fn ui_set_dynamic_text_charset(handle: u64, utf8_charset: *const u8, len: u32) {
1455
+ let charset = if utf8_charset.is_null() || len == 0 {
1456
+ String::new()
1457
+ } else {
1458
+ String::from_utf8_lossy(std::slice::from_raw_parts(utf8_charset, len as usize)).into_owned()
1459
+ };
1460
+ push_call(Call::SetDynamicTextCharset { handle, charset });
1461
+ }
1462
+
1463
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1464
+ pub unsafe fn ui_get_text_metrics(
1465
+ handle: u64,
1466
+ out_width: *mut f32,
1467
+ out_height: *mut f32,
1468
+ out_baseline: *mut f32,
1469
+ out_line_count: *mut u32,
1470
+ out_max_line_width: *mut f32,
1471
+ ) -> bool {
1472
+ push_call(Call::GetTextMetrics { handle });
1473
+ let (width, height, baseline, line_count, max_line_width) =
1474
+ TEXT_METRICS.with(|value| value.get());
1475
+ if !out_width.is_null() {
1476
+ *out_width = width;
1477
+ }
1478
+ if !out_height.is_null() {
1479
+ *out_height = height;
1480
+ }
1481
+ if !out_baseline.is_null() {
1482
+ *out_baseline = baseline;
1483
+ }
1484
+ if !out_line_count.is_null() {
1485
+ *out_line_count = line_count;
1486
+ }
1487
+ if !out_max_line_width.is_null() {
1488
+ *out_max_line_width = max_line_width;
1489
+ }
1490
+ true
1491
+ }
1492
+
1493
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1494
+ pub unsafe fn ui_set_font(handle: u64, font_id: u32, size: f32) {
1495
+ push_call(Call::SetFont {
1496
+ handle,
1497
+ font_id,
1498
+ size,
1499
+ });
1500
+ }
1501
+
1502
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1503
+ pub unsafe fn ui_register_font_fallback(font_id: u32, fallback_font_id: u32) {
1504
+ push_call(Call::RegisterFontFallback {
1505
+ font_id,
1506
+ fallback_font_id,
1507
+ });
1508
+ }
1509
+
1510
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1511
+ pub unsafe fn ui_set_line_height(handle: u64, line_height: f32) {
1512
+ push_call(Call::SetLineHeight {
1513
+ handle,
1514
+ line_height,
1515
+ });
1516
+ }
1517
+
1518
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1519
+ pub unsafe fn ui_set_text_color(handle: u64, color: u32) {
1520
+ push_call(Call::SetTextColor { handle, color });
1521
+ }
1522
+
1523
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1524
+ pub unsafe fn ui_set_text_align(handle: u64, align_enum: u32) {
1525
+ push_call(Call::SetTextAlign { handle, align_enum });
1526
+ }
1527
+
1528
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1529
+ pub unsafe fn ui_set_text_vertical_align(handle: u64, align_enum: u32) {
1530
+ push_call(Call::SetTextVerticalAlign { handle, align_enum });
1531
+ }
1532
+
1533
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1534
+ pub unsafe fn ui_set_text_limits(handle: u64, max_chars: i32, max_lines: i32) {
1535
+ push_call(Call::SetTextLimits {
1536
+ handle,
1537
+ max_chars,
1538
+ max_lines,
1539
+ });
1540
+ }
1541
+
1542
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1543
+ pub unsafe fn ui_set_text_wrapping(handle: u64, wrap: bool) {
1544
+ push_call(Call::SetTextWrapping { handle, wrap });
1545
+ }
1546
+
1547
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1548
+ pub unsafe fn ui_set_text_obscured(handle: u64, obscured: bool) {
1549
+ push_call(Call::SetTextObscured { handle, obscured });
1550
+ }
1551
+
1552
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1553
+ pub unsafe fn ui_set_text_overflow(handle: u64, overflow_enum: u32) {
1554
+ push_call(Call::SetTextOverflow {
1555
+ handle,
1556
+ overflow_enum,
1557
+ });
1558
+ }
1559
+
1560
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1561
+ pub unsafe fn ui_set_text_overflow_fade(handle: u64, horizontal: bool, vertical: bool) {
1562
+ push_call(Call::SetTextOverflowFade {
1563
+ handle,
1564
+ horizontal,
1565
+ vertical,
1566
+ });
1567
+ }
1568
+
1569
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1570
+ pub unsafe fn ui_set_selectable(handle: u64, selectable: bool, selection_color: u32) {
1571
+ push_call(Call::SetSelectable {
1572
+ handle,
1573
+ selectable,
1574
+ selection_color,
1575
+ });
1576
+ }
1577
+
1578
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1579
+ pub unsafe fn ui_set_editable(handle: u64, editable: bool) {
1580
+ push_call(Call::SetEditable { handle, editable });
1581
+ }
1582
+
1583
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1584
+ pub unsafe fn ui_set_editor_command_keys(handle: u64, enabled: bool) {
1585
+ push_call(Call::SetEditorCommandKeys { handle, enabled });
1586
+ }
1587
+
1588
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1589
+ pub unsafe fn ui_set_editor_accepts_tab(handle: u64, enabled: bool) {
1590
+ push_call(Call::SetEditorAcceptsTab { handle, enabled });
1591
+ }
1592
+
1593
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1594
+ pub unsafe fn ui_replace_text_range(
1595
+ handle: u64,
1596
+ start: u32,
1597
+ end: u32,
1598
+ text_ptr: *const u8,
1599
+ text_len: u32,
1600
+ caret: u32,
1601
+ ) {
1602
+ let text = if text_ptr.is_null() || text_len == 0 {
1603
+ String::new()
1604
+ } else {
1605
+ let bytes = std::slice::from_raw_parts(text_ptr, text_len as usize);
1606
+ String::from_utf8_lossy(bytes).into_owned()
1607
+ };
1608
+ push_call(Call::ReplaceTextRange {
1609
+ handle,
1610
+ start,
1611
+ end,
1612
+ text,
1613
+ caret,
1614
+ });
1615
+ }
1616
+
1617
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1618
+ pub unsafe fn ui_set_caret_color(handle: u64, color: u32) {
1619
+ push_call(Call::SetCaretColor { handle, color });
1620
+ }
1621
+
1622
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1623
+ pub unsafe fn ui_set_text_selection_range(handle: u64, start: u32, end: u32) {
1624
+ push_call(Call::SetTextSelectionRange { handle, start, end });
1625
+ }
1626
+
1627
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1628
+ pub unsafe fn ui_set_preserve_selection_on_pointer_down(handle: u64, preserve: bool) {
1629
+ push_call(Call::SetPreserveSelectionOnPointerDown { handle, preserve });
1630
+ }
1631
+
1632
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1633
+ pub unsafe fn fui_register_text_input_metadata(
1634
+ handle: u64,
1635
+ is_password: bool,
1636
+ hint_ptr: usize,
1637
+ hint_len: u32,
1638
+ ) {
1639
+ let hint = if hint_ptr == 0 || hint_len == 0 {
1640
+ String::new()
1641
+ } else {
1642
+ let bytes = std::slice::from_raw_parts(hint_ptr as *const u8, hint_len as usize);
1643
+ String::from_utf8_lossy(bytes).into_owned()
1644
+ };
1645
+ push_call(Call::RegisterTextInputMetadata {
1646
+ handle,
1647
+ is_password,
1648
+ hint,
1649
+ });
1650
+ }
1651
+
1652
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1653
+ pub unsafe fn ui_set_interactive(handle: u64, interactive: bool) {
1654
+ push_call(Call::SetInteractive {
1655
+ handle,
1656
+ interactive,
1657
+ });
1658
+ }
1659
+
1660
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1661
+ pub unsafe fn ui_set_focusable(handle: u64, focusable: bool, tab_index: i32) {
1662
+ push_call(Call::SetFocusable {
1663
+ handle,
1664
+ focusable,
1665
+ tab_index,
1666
+ });
1667
+ }
1668
+
1669
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1670
+ pub unsafe fn ui_request_focus(handle: u64) {
1671
+ push_call(Call::RequestFocus { handle });
1672
+ }
1673
+
1674
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1675
+ pub unsafe fn ui_set_padding(handle: u64, left: f32, top: f32, right: f32, bottom: f32) {
1676
+ push_call(Call::SetPadding {
1677
+ handle,
1678
+ left,
1679
+ top,
1680
+ right,
1681
+ bottom,
1682
+ });
1683
+ }
1684
+
1685
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1686
+ pub unsafe fn ui_set_flex_direction(handle: u64, dir_enum: u32) {
1687
+ push_call(Call::SetFlexDirection { handle, dir_enum });
1688
+ }
1689
+
1690
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1691
+ pub unsafe fn ui_set_flex_basis(handle: u64, basis: f32) {
1692
+ push_call(Call::SetFlexBasis { handle, basis });
1693
+ }
1694
+
1695
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1696
+ pub unsafe fn ui_set_justify_content(handle: u64, justify_enum: u32) {
1697
+ push_call(Call::SetJustifyContent {
1698
+ handle,
1699
+ justify_enum,
1700
+ });
1701
+ }
1702
+
1703
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1704
+ pub unsafe fn ui_set_align_items(handle: u64, align_enum: u32) {
1705
+ push_call(Call::SetAlignItems { handle, align_enum });
1706
+ }
1707
+
1708
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1709
+ pub unsafe fn ui_set_align_self(handle: u64, align_enum: u32) {
1710
+ push_call(Call::SetAlignSelf { handle, align_enum });
1711
+ }
1712
+
1713
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1714
+ pub unsafe fn ui_set_margin(handle: u64, left: f32, top: f32, right: f32, bottom: f32) {
1715
+ push_call(Call::SetMargin {
1716
+ handle,
1717
+ left,
1718
+ top,
1719
+ right,
1720
+ bottom,
1721
+ });
1722
+ }
1723
+
1724
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1725
+ pub unsafe fn ui_set_position_type(handle: u64, pos_enum: u32) {
1726
+ push_call(Call::SetPositionType { handle, pos_enum });
1727
+ }
1728
+
1729
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1730
+ pub unsafe fn ui_set_position(handle: u64, left: f32, top: f32, right: f32, bottom: f32) {
1731
+ push_call(Call::SetPosition {
1732
+ handle,
1733
+ left,
1734
+ top,
1735
+ right,
1736
+ bottom,
1737
+ });
1738
+ }
1739
+
1740
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1741
+ pub unsafe fn ui_set_is_shared_size_scope(handle: u64, is_scope: bool) {
1742
+ push_call(Call::SetIsSharedSizeScope { handle, is_scope });
1743
+ }
1744
+
1745
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1746
+ pub unsafe fn ui_set_custom_drawable(handle: u64, is_custom_drawable: bool) {
1747
+ push_call(Call::SetCustomDrawable {
1748
+ handle,
1749
+ is_custom_drawable,
1750
+ });
1751
+ }
1752
+
1753
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1754
+ pub unsafe fn ui_set_flex_wrap(handle: u64, wrap_enum: u32) {
1755
+ push_call(Call::SetFlexWrap { handle, wrap_enum });
1756
+ }
1757
+
1758
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1759
+ pub unsafe fn ui_set_clip_to_bounds(handle: u64, clip: bool) {
1760
+ push_call(Call::SetClipToBounds { handle, clip });
1761
+ }
1762
+
1763
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1764
+ pub unsafe fn ui_set_selection_area(handle: u64, is_area: bool) {
1765
+ push_call(Call::SetSelectionArea { handle, is_area });
1766
+ }
1767
+
1768
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1769
+ pub unsafe fn ui_set_selection_area_barrier(handle: u64, is_barrier: bool) {
1770
+ push_call(Call::SetSelectionAreaBarrier { handle, is_barrier });
1771
+ }
1772
+
1773
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1774
+ pub unsafe fn ui_clear_selection(text_node_handle: u64) {
1775
+ push_call(Call::ClearSelection { text_node_handle });
1776
+ }
1777
+
1778
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1779
+ pub unsafe fn ui_retarget_selection(from_text_node_handle: u64, to_text_node_handle: u64) {
1780
+ push_call(Call::RetargetSelection {
1781
+ from_text_node_handle,
1782
+ to_text_node_handle,
1783
+ });
1784
+ }
1785
+
1786
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1787
+ pub unsafe fn ui_grid_set_columns(handle: u64, count: u32, values: *const f32, types: *const u8) {
1788
+ let len = count as usize;
1789
+ let copied_values = if values.is_null() || len == 0 {
1790
+ Vec::new()
1791
+ } else {
1792
+ std::slice::from_raw_parts(values, len).to_vec()
1793
+ };
1794
+ let copied_types = if types.is_null() || len == 0 {
1795
+ Vec::new()
1796
+ } else {
1797
+ std::slice::from_raw_parts(types, len).to_vec()
1798
+ };
1799
+ push_call(Call::GridSetColumns {
1800
+ handle,
1801
+ values: copied_values,
1802
+ type_enums: copied_types,
1803
+ });
1804
+ }
1805
+
1806
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1807
+ pub unsafe fn ui_grid_set_rows(handle: u64, count: u32, values: *const f32, types: *const u8) {
1808
+ let len = count as usize;
1809
+ let copied_values = if values.is_null() || len == 0 {
1810
+ Vec::new()
1811
+ } else {
1812
+ std::slice::from_raw_parts(values, len).to_vec()
1813
+ };
1814
+ let copied_types = if types.is_null() || len == 0 {
1815
+ Vec::new()
1816
+ } else {
1817
+ std::slice::from_raw_parts(types, len).to_vec()
1818
+ };
1819
+ push_call(Call::GridSetRows {
1820
+ handle,
1821
+ values: copied_values,
1822
+ type_enums: copied_types,
1823
+ });
1824
+ }
1825
+
1826
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1827
+ pub unsafe fn ui_grid_set_column_shared_size_group(
1828
+ handle: u64,
1829
+ index: u32,
1830
+ utf8_group: *const u8,
1831
+ len: u32,
1832
+ ) {
1833
+ let group = if utf8_group.is_null() || len == 0 {
1834
+ String::new()
1835
+ } else {
1836
+ String::from_utf8_lossy(std::slice::from_raw_parts(utf8_group, len as usize)).into_owned()
1837
+ };
1838
+ push_call(Call::GridSetColumnSharedSizeGroup {
1839
+ handle,
1840
+ index,
1841
+ group,
1842
+ });
1843
+ }
1844
+
1845
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1846
+ pub unsafe fn ui_grid_set_row_shared_size_group(
1847
+ handle: u64,
1848
+ index: u32,
1849
+ utf8_group: *const u8,
1850
+ len: u32,
1851
+ ) {
1852
+ let group = if utf8_group.is_null() || len == 0 {
1853
+ String::new()
1854
+ } else {
1855
+ String::from_utf8_lossy(std::slice::from_raw_parts(utf8_group, len as usize)).into_owned()
1856
+ };
1857
+ push_call(Call::GridSetRowSharedSizeGroup {
1858
+ handle,
1859
+ index,
1860
+ group,
1861
+ });
1862
+ }
1863
+
1864
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1865
+ pub unsafe fn ui_node_set_grid_placement(
1866
+ child: u64,
1867
+ row: u32,
1868
+ col: u32,
1869
+ row_span: u32,
1870
+ col_span: u32,
1871
+ ) {
1872
+ push_call(Call::NodeSetGridPlacement {
1873
+ handle: child,
1874
+ row,
1875
+ col,
1876
+ row_span,
1877
+ col_span,
1878
+ });
1879
+ }
1880
+
1881
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1882
+ pub unsafe fn ui_set_image(
1883
+ handle: u64,
1884
+ texture_id: u32,
1885
+ object_fit_enum: u32,
1886
+ sampling_kind: u32,
1887
+ max_aniso: u32,
1888
+ ) {
1889
+ push_call(Call::SetImage {
1890
+ handle,
1891
+ texture_id,
1892
+ object_fit_enum,
1893
+ sampling_kind,
1894
+ max_aniso,
1895
+ });
1896
+ }
1897
+
1898
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1899
+ pub unsafe fn ui_set_image_nine(
1900
+ handle: u64,
1901
+ texture_id: u32,
1902
+ inset_left: f32,
1903
+ inset_top: f32,
1904
+ inset_right: f32,
1905
+ inset_bottom: f32,
1906
+ sampling_kind: u32,
1907
+ max_aniso: u32,
1908
+ ) {
1909
+ push_call(Call::SetImageNine {
1910
+ handle,
1911
+ texture_id,
1912
+ inset_left,
1913
+ inset_top,
1914
+ inset_right,
1915
+ inset_bottom,
1916
+ sampling_kind,
1917
+ max_aniso,
1918
+ });
1919
+ }
1920
+
1921
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1922
+ pub unsafe fn ui_set_svg(
1923
+ handle: u64,
1924
+ svg_id: u32,
1925
+ tint_color: u32,
1926
+ sampling_kind: u32,
1927
+ max_aniso: u32,
1928
+ ) {
1929
+ push_call(Call::SetSvg {
1930
+ handle,
1931
+ svg_id,
1932
+ tint_color,
1933
+ sampling_kind,
1934
+ max_aniso,
1935
+ });
1936
+ }
1937
+
1938
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1939
+ pub unsafe fn ui_set_scroll_proxy_target(handle: u64, scroll_handle: u64) {
1940
+ push_call(Call::SetScrollProxyTarget {
1941
+ handle,
1942
+ scroll_handle,
1943
+ });
1944
+ }
1945
+
1946
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1947
+ pub unsafe fn ui_set_scroll_enabled(handle: u64, enabled_x: bool, enabled_y: bool) {
1948
+ push_call(Call::SetScrollEnabled {
1949
+ handle,
1950
+ enabled_x,
1951
+ enabled_y,
1952
+ });
1953
+ }
1954
+
1955
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1956
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1957
+ pub unsafe fn ui_set_scroll_friction(handle: u64, friction: f32) {
1958
+ push_call(Call::SetScrollFriction { handle, friction });
1959
+ }
1960
+
1961
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1962
+ pub unsafe fn ui_set_smooth_scrolling(handle: u64, smooth_scrolling: bool) {
1963
+ push_call(Call::SetSmoothScrolling {
1964
+ handle,
1965
+ smooth_scrolling,
1966
+ });
1967
+ }
1968
+
1969
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1970
+ pub unsafe fn ui_set_scroll_offset(handle: u64, offset_x: f32, offset_y: f32) {
1971
+ push_call(Call::SetScrollOffset {
1972
+ handle,
1973
+ offset_x,
1974
+ offset_y,
1975
+ });
1976
+ }
1977
+
1978
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1979
+ pub unsafe fn ui_set_scroll_content_size(handle: u64, content_width: f32, content_height: f32) {
1980
+ push_call(Call::SetScrollContentSize {
1981
+ handle,
1982
+ content_width,
1983
+ content_height,
1984
+ });
1985
+ }
1986
+
1987
+ #[cfg(target_arch = "wasm32")]
1988
+ pub unsafe fn ui_clear_momentum_scroll() {
1989
+ crate::generated::ffi::ui_clear_momentum_scroll()
1990
+ }
1991
+
1992
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1993
+ pub unsafe fn ui_clear_momentum_scroll() {
1994
+ push_call(Call::ClearMomentumScroll);
1995
+ }
1996
+
1997
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
1998
+ pub unsafe fn ui_commit_frame() {
1999
+ push_call(Call::CommitFrame);
2000
+ }
2001
+
2002
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2003
+ pub unsafe fn ui_resize_window(logical_w: f32, logical_h: f32) {
2004
+ VIEWPORT.with(|viewport| viewport.set((logical_w, logical_h)));
2005
+ push_call(Call::ResizeWindow {
2006
+ logical_w,
2007
+ logical_h,
2008
+ });
2009
+ }
2010
+
2011
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2012
+ pub unsafe fn request_render() {
2013
+ push_call(Call::RequestRender);
2014
+ }
2015
+
2016
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2017
+ pub unsafe fn get_viewport_width() -> f32 {
2018
+ push_call(Call::GetViewportWidth);
2019
+ VIEWPORT.with(|viewport| viewport.get().0)
2020
+ }
2021
+
2022
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2023
+ pub unsafe fn get_viewport_height() -> f32 {
2024
+ push_call(Call::GetViewportHeight);
2025
+ VIEWPORT.with(|viewport| viewport.get().1)
2026
+ }
2027
+
2028
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2029
+ pub unsafe fn get_device_pixel_ratio() -> f32 {
2030
+ push_call(Call::GetDevicePixelRatio);
2031
+ DEVICE_PIXEL_RATIO.with(|value| value.get())
2032
+ }
2033
+
2034
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2035
+ pub unsafe fn fui_set_pointer_capture(handle: u64) {
2036
+ push_call(Call::SetPointerCapture { handle });
2037
+ }
2038
+
2039
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2040
+ pub unsafe fn fui_release_pointer_capture() {
2041
+ push_call(Call::ReleasePointerCapture);
2042
+ }
2043
+
2044
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2045
+ pub unsafe fn fui_can_navigate_back() -> bool {
2046
+ push_call(Call::CanNavigateBack);
2047
+ CAN_NAVIGATE_BACK.with(|value| value.get())
2048
+ }
2049
+
2050
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2051
+ pub unsafe fn fui_can_navigate_forward() -> bool {
2052
+ push_call(Call::CanNavigateForward);
2053
+ CAN_NAVIGATE_FORWARD.with(|value| value.get())
2054
+ }
2055
+
2056
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2057
+ pub unsafe fn fui_navigate_back() {
2058
+ push_call(Call::NavigateBack);
2059
+ }
2060
+
2061
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2062
+ pub unsafe fn fui_navigate_forward() {
2063
+ push_call(Call::NavigateForward);
2064
+ }
2065
+
2066
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2067
+ pub unsafe fn fui_reload_page() {
2068
+ push_call(Call::ReloadPage);
2069
+ }
2070
+
2071
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2072
+ pub unsafe fn fui_copy_text(ptr: usize, len: u32) {
2073
+ let text = if ptr == 0 || len == 0 {
2074
+ String::new()
2075
+ } else {
2076
+ let bytes = std::slice::from_raw_parts(ptr as *const u8, len as usize);
2077
+ String::from_utf8_lossy(bytes).into_owned()
2078
+ };
2079
+ push_call(Call::CopyText { text });
2080
+ }
2081
+
2082
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2083
+ pub unsafe fn fui_has_text_selection_snapshot(handle: u64) -> bool {
2084
+ push_call(Call::HasTextSelectionSnapshot { handle });
2085
+ HAS_TEXT_SELECTION_SNAPSHOT.with(|value| value.get())
2086
+ }
2087
+
2088
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2089
+ pub unsafe fn fui_copy_text_selection_snapshot(handle: u64) -> bool {
2090
+ push_call(Call::CopyTextSelectionSnapshot { handle });
2091
+ true
2092
+ }
2093
+
2094
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2095
+ pub unsafe fn fui_cut_focused_text_selection() -> bool {
2096
+ push_call(Call::CutFocusedTextSelection);
2097
+ true
2098
+ }
2099
+
2100
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2101
+ pub unsafe fn fui_cut_text_selection_snapshot(handle: u64) -> bool {
2102
+ push_call(Call::CutTextSelectionSnapshot { handle });
2103
+ true
2104
+ }
2105
+
2106
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2107
+ pub unsafe fn fui_delete_focused_text_range(start: u32, end: u32) -> bool {
2108
+ push_call(Call::DeleteFocusedTextRange { start, end });
2109
+ true
2110
+ }
2111
+
2112
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2113
+ pub unsafe fn fui_commit_text_action_focus(handle: u64) {
2114
+ push_call(Call::CommitTextActionFocus { handle });
2115
+ }
2116
+
2117
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2118
+ pub unsafe fn ui_copy_current_selection() {
2119
+ push_call(Call::CopyCurrentSelection);
2120
+ }
2121
+
2122
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2123
+ pub unsafe fn ui_has_text_selection(handle: u64) -> bool {
2124
+ push_call(Call::HasTextSelection { handle });
2125
+ HAS_TEXT_SELECTION.with(|value| value.get())
2126
+ }
2127
+
2128
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2129
+ pub unsafe fn ui_undo_text_edit(handle: u64) {
2130
+ push_call(Call::UndoTextEdit { handle });
2131
+ }
2132
+
2133
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2134
+ pub unsafe fn ui_redo_text_edit(handle: u64) {
2135
+ push_call(Call::RedoTextEdit { handle });
2136
+ }
2137
+
2138
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2139
+ pub unsafe fn ui_copy_text_selection(handle: u64) {
2140
+ push_call(Call::CopyTextSelection { handle });
2141
+ }
2142
+
2143
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2144
+ pub unsafe fn ui_cut_text_selection(handle: u64) {
2145
+ push_call(Call::CutTextSelection { handle });
2146
+ }
2147
+
2148
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2149
+ pub unsafe fn ui_paste_text(handle: u64) {
2150
+ push_call(Call::PasteText { handle });
2151
+ }
2152
+
2153
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2154
+ pub unsafe fn ui_select_all_text(handle: u64) {
2155
+ push_call(Call::SelectAllText { handle });
2156
+ }
2157
+
2158
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2159
+ pub unsafe fn ui_select_word_at(handle: u64, logical_x: f32, logical_y: f32) -> bool {
2160
+ push_call(Call::SelectWordAt {
2161
+ handle,
2162
+ x: logical_x,
2163
+ y: logical_y,
2164
+ });
2165
+ true
2166
+ }
2167
+
2168
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2169
+ pub unsafe fn ui_clear_current_selection() {
2170
+ push_call(Call::ClearCurrentSelection);
2171
+ }
2172
+
2173
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2174
+ pub unsafe fn ui_is_point_in_selection(logical_x: f32, logical_y: f32) -> bool {
2175
+ push_call(Call::IsPointInSelection {
2176
+ x: logical_x,
2177
+ y: logical_y,
2178
+ });
2179
+ IS_POINT_IN_SELECTION.with(|value| value.get())
2180
+ }
2181
+
2182
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2183
+ pub unsafe fn ui_get_text_range_rect_count(handle: u64, start: u32, end: u32) -> u32 {
2184
+ push_call(Call::GetTextRangeRectCount { handle, start, end });
2185
+ TEXT_RANGE_RECTS.with(|value| value.borrow().len() as u32)
2186
+ }
2187
+
2188
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2189
+ pub unsafe fn ui_copy_text_range_rects(
2190
+ handle: u64,
2191
+ start: u32,
2192
+ end: u32,
2193
+ out_rect_words: *mut f32,
2194
+ max_rect_count: u32,
2195
+ ) -> u32 {
2196
+ push_call(Call::CopyTextRangeRects {
2197
+ handle,
2198
+ start,
2199
+ end,
2200
+ max_rect_count,
2201
+ });
2202
+ let rects = TEXT_RANGE_RECTS.with(|value| value.borrow().clone());
2203
+ let copied = rects.len().min(max_rect_count as usize);
2204
+ if !out_rect_words.is_null() {
2205
+ for (index, (x, y, width, height)) in rects.iter().take(copied).enumerate() {
2206
+ let base = index * 4;
2207
+ *out_rect_words.add(base) = *x;
2208
+ *out_rect_words.add(base + 1) = *y;
2209
+ *out_rect_words.add(base + 2) = *width;
2210
+ *out_rect_words.add(base + 3) = *height;
2211
+ }
2212
+ }
2213
+ copied as u32
2214
+ }
2215
+
2216
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2217
+ pub unsafe fn ui_copy_cross_selection_endpoint_rects(
2218
+ area_handle: u64,
2219
+ out_rect_words: *mut f32,
2220
+ ) -> bool {
2221
+ push_call(Call::CopyCrossSelectionEndpointRects {
2222
+ handle: area_handle,
2223
+ });
2224
+ let Some(rects) = CROSS_SELECTION_ENDPOINT_RECTS.with(|value| *value.borrow()) else {
2225
+ return false;
2226
+ };
2227
+ if !out_rect_words.is_null() {
2228
+ let [(sx, sy, sw, sh), (ex, ey, ew, eh)] = rects;
2229
+ *out_rect_words.add(0) = sx;
2230
+ *out_rect_words.add(1) = sy;
2231
+ *out_rect_words.add(2) = sw;
2232
+ *out_rect_words.add(3) = sh;
2233
+ *out_rect_words.add(4) = ex;
2234
+ *out_rect_words.add(5) = ey;
2235
+ *out_rect_words.add(6) = ew;
2236
+ *out_rect_words.add(7) = eh;
2237
+ }
2238
+ true
2239
+ }
2240
+
2241
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2242
+ pub unsafe fn ui_begin_selection_endpoint_drag(handle: u64, endpoint: u32) -> bool {
2243
+ push_call(Call::BeginSelectionEndpointDrag { handle, endpoint });
2244
+ BEGIN_SELECTION_ENDPOINT_DRAG_RESULT.with(|value| value.get())
2245
+ }
2246
+
2247
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2248
+ pub unsafe fn fui_start_timer(timer_id: u32, delay_ms: i32) {
2249
+ push_call(Call::StartTimer { timer_id, delay_ms });
2250
+ }
2251
+
2252
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2253
+ pub unsafe fn fui_cancel_timer(timer_id: u32) {
2254
+ push_call(Call::CancelTimer { timer_id });
2255
+ }
2256
+
2257
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2258
+ pub unsafe fn fui_set_cursor(style: u32) {
2259
+ push_call(Call::SetCursor { style });
2260
+ }
2261
+
2262
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2263
+ pub unsafe fn fui_navigate_to(ptr: usize, len: u32, open_in_new_tab: bool) {
2264
+ let target = if ptr == 0 || len == 0 {
2265
+ String::new()
2266
+ } else {
2267
+ String::from_utf8_lossy(std::slice::from_raw_parts(ptr as *const u8, len as usize))
2268
+ .into_owned()
2269
+ };
2270
+ push_call(Call::NavigateTo {
2271
+ target,
2272
+ open_in_new_tab,
2273
+ });
2274
+ }
2275
+
2276
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2277
+ pub unsafe fn fui_show_url_preview(ptr: usize, len: u32) {
2278
+ let url = if ptr == 0 || len == 0 {
2279
+ String::new()
2280
+ } else {
2281
+ String::from_utf8_lossy(std::slice::from_raw_parts(ptr as *const u8, len as usize))
2282
+ .into_owned()
2283
+ };
2284
+ push_call(Call::ShowUrlPreview { url });
2285
+ }
2286
+
2287
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2288
+ pub unsafe fn fui_hide_url_preview() {
2289
+ push_call(Call::HideUrlPreview);
2290
+ }
2291
+
2292
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2293
+ pub unsafe fn fui_log(
2294
+ category_ptr: usize,
2295
+ category_len: u32,
2296
+ message_ptr: usize,
2297
+ message_len: u32,
2298
+ ) {
2299
+ let category = if category_ptr == 0 || category_len == 0 {
2300
+ String::new()
2301
+ } else {
2302
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2303
+ category_ptr as *const u8,
2304
+ category_len as usize,
2305
+ ))
2306
+ .into_owned()
2307
+ };
2308
+ let message = if message_ptr == 0 || message_len == 0 {
2309
+ String::new()
2310
+ } else {
2311
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2312
+ message_ptr as *const u8,
2313
+ message_len as usize,
2314
+ ))
2315
+ .into_owned()
2316
+ };
2317
+ push_call(Call::Log { category, message });
2318
+ }
2319
+
2320
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2321
+ pub unsafe fn fui_logs_enabled() -> bool {
2322
+ push_call(Call::LogsEnabled);
2323
+ LOGS_ENABLED.with(|value| value.get())
2324
+ }
2325
+
2326
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2327
+ pub unsafe fn fui_is_dark_mode() -> bool {
2328
+ push_call(Call::IsDarkMode);
2329
+ SYSTEM_DARK_MODE.with(|value| value.get())
2330
+ }
2331
+
2332
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2333
+ pub unsafe fn fui_get_accent_color() -> u32 {
2334
+ push_call(Call::GetAccentColor);
2335
+ SYSTEM_ACCENT_COLOR.with(|value| value.get())
2336
+ }
2337
+
2338
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2339
+ pub unsafe fn fui_get_platform_family() -> u32 {
2340
+ push_call(Call::GetPlatformFamily);
2341
+ PLATFORM_FAMILY.with(|value| value.get())
2342
+ }
2343
+
2344
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2345
+ pub unsafe fn fui_is_coarse_pointer() -> bool {
2346
+ push_call(Call::IsCoarsePointer);
2347
+ COARSE_POINTER.with(|value| value.get())
2348
+ }
2349
+
2350
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2351
+ pub unsafe fn fui_load_svg(svg_id: u32, ptr: usize, len: u32) {
2352
+ let url = if ptr == 0 || len == 0 {
2353
+ String::new()
2354
+ } else {
2355
+ String::from_utf8_lossy(std::slice::from_raw_parts(ptr as *const u8, len as usize))
2356
+ .into_owned()
2357
+ };
2358
+ push_call(Call::LoadSvg { svg_id, url });
2359
+ }
2360
+
2361
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2362
+ pub unsafe fn fui_release_svg(svg_id: u32) {
2363
+ push_call(Call::ReleaseSvg { svg_id });
2364
+ }
2365
+
2366
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2367
+ pub unsafe fn fui_load_texture(texture_id: u32, ptr: usize, len: u32) {
2368
+ let url = if ptr == 0 || len == 0 {
2369
+ String::new()
2370
+ } else {
2371
+ String::from_utf8_lossy(std::slice::from_raw_parts(ptr as *const u8, len as usize))
2372
+ .into_owned()
2373
+ };
2374
+ push_call(Call::LoadTexture { texture_id, url });
2375
+ }
2376
+
2377
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2378
+ pub unsafe fn fui_release_texture(texture_id: u32) {
2379
+ push_call(Call::ReleaseTexture { texture_id });
2380
+ }
2381
+
2382
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2383
+ pub unsafe fn fui_load_font(font_id: u32, ptr: usize, len: u32) {
2384
+ let url = if ptr == 0 || len == 0 {
2385
+ String::new()
2386
+ } else {
2387
+ String::from_utf8_lossy(std::slice::from_raw_parts(ptr as *const u8, len as usize))
2388
+ .into_owned()
2389
+ };
2390
+ push_call(Call::LoadFont { font_id, url });
2391
+ }
2392
+
2393
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2394
+ pub unsafe fn fui_bitmap_commit(
2395
+ texture_id: u32,
2396
+ bytes_ptr: usize,
2397
+ bytes_len: u32,
2398
+ width: u32,
2399
+ height: u32,
2400
+ ) {
2401
+ let bytes = if bytes_ptr == 0 || bytes_len == 0 {
2402
+ Vec::new()
2403
+ } else {
2404
+ std::slice::from_raw_parts(bytes_ptr as *const u8, bytes_len as usize).to_vec()
2405
+ };
2406
+ push_call(Call::BitmapCommit {
2407
+ texture_id,
2408
+ bytes,
2409
+ width,
2410
+ height,
2411
+ });
2412
+ }
2413
+
2414
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2415
+ pub unsafe fn fui_bitmap_commit_dirty(
2416
+ texture_id: u32,
2417
+ bytes_ptr: usize,
2418
+ bytes_len: u32,
2419
+ full_width: u32,
2420
+ full_height: u32,
2421
+ sub_x: u32,
2422
+ sub_y: u32,
2423
+ sub_w: u32,
2424
+ sub_h: u32,
2425
+ ) {
2426
+ let bytes = if bytes_ptr == 0 || bytes_len == 0 {
2427
+ Vec::new()
2428
+ } else {
2429
+ std::slice::from_raw_parts(bytes_ptr as *const u8, bytes_len as usize).to_vec()
2430
+ };
2431
+ push_call(Call::BitmapCommitDirty {
2432
+ texture_id,
2433
+ bytes,
2434
+ full_width,
2435
+ full_height,
2436
+ sub_x,
2437
+ sub_y,
2438
+ sub_w,
2439
+ sub_h,
2440
+ });
2441
+ }
2442
+
2443
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2444
+ pub unsafe fn fui_bitmap_release(texture_id: u32) {
2445
+ push_call(Call::BitmapRelease { texture_id });
2446
+ }
2447
+
2448
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2449
+ pub unsafe fn fui_render_node_to_rgba(
2450
+ handle: u64,
2451
+ width: u32,
2452
+ height: u32,
2453
+ _out_ptr: usize,
2454
+ out_capacity: u32,
2455
+ scale: f32,
2456
+ x: f32,
2457
+ y: f32,
2458
+ ) -> u32 {
2459
+ push_call(Call::RenderNodeToRgba {
2460
+ handle,
2461
+ width,
2462
+ height,
2463
+ out_capacity,
2464
+ scale,
2465
+ x,
2466
+ y,
2467
+ });
2468
+ out_capacity
2469
+ }
2470
+
2471
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2472
+ pub unsafe fn fui_fetch_start(
2473
+ request_id: u32,
2474
+ method_ptr: usize,
2475
+ method_len: u32,
2476
+ url_ptr: usize,
2477
+ url_len: u32,
2478
+ headers_ptr: usize,
2479
+ headers_len: u32,
2480
+ body_ptr: usize,
2481
+ body_len: u32,
2482
+ ) {
2483
+ let method = if method_ptr == 0 || method_len == 0 {
2484
+ String::new()
2485
+ } else {
2486
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2487
+ method_ptr as *const u8,
2488
+ method_len as usize,
2489
+ ))
2490
+ .into_owned()
2491
+ };
2492
+ let url = if url_ptr == 0 || url_len == 0 {
2493
+ String::new()
2494
+ } else {
2495
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2496
+ url_ptr as *const u8,
2497
+ url_len as usize,
2498
+ ))
2499
+ .into_owned()
2500
+ };
2501
+ let headers = if headers_ptr == 0 || headers_len < 4 {
2502
+ Vec::new()
2503
+ } else {
2504
+ let bytes = std::slice::from_raw_parts(headers_ptr as *const u8, headers_len as usize);
2505
+ let mut cursor = 0usize;
2506
+ let count = u32::from_le_bytes(bytes[cursor..cursor + 4].try_into().unwrap_or([0, 0, 0, 0]))
2507
+ as usize;
2508
+ cursor += 4;
2509
+ let mut parts = Vec::with_capacity(count);
2510
+ for _ in 0..count {
2511
+ if cursor + 4 > bytes.len() {
2512
+ break;
2513
+ }
2514
+ let len =
2515
+ u32::from_le_bytes(bytes[cursor..cursor + 4].try_into().unwrap_or([0, 0, 0, 0]))
2516
+ as usize;
2517
+ cursor += 4;
2518
+ if cursor + len > bytes.len() {
2519
+ break;
2520
+ }
2521
+ parts.push(String::from_utf8_lossy(&bytes[cursor..cursor + len]).into_owned());
2522
+ cursor += len;
2523
+ }
2524
+ parts
2525
+ };
2526
+ let body = if body_ptr == 0 || body_len == 0 {
2527
+ Vec::new()
2528
+ } else {
2529
+ std::slice::from_raw_parts(body_ptr as *const u8, body_len as usize).to_vec()
2530
+ };
2531
+ push_call(Call::FetchStart {
2532
+ request_id,
2533
+ method,
2534
+ url,
2535
+ headers,
2536
+ body,
2537
+ });
2538
+ }
2539
+
2540
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2541
+ pub unsafe fn fui_fetch_cancel(request_id: u32) {
2542
+ push_call(Call::FetchCancel { request_id });
2543
+ }
2544
+
2545
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2546
+ pub unsafe fn fui_set_persisted_scroll_offset(
2547
+ node_id_ptr: usize,
2548
+ node_id_len: u32,
2549
+ x: f32,
2550
+ y: f32,
2551
+ ) {
2552
+ let node_id = if node_id_ptr == 0 || node_id_len == 0 {
2553
+ String::new()
2554
+ } else {
2555
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2556
+ node_id_ptr as *const u8,
2557
+ node_id_len as usize,
2558
+ ))
2559
+ .into_owned()
2560
+ };
2561
+ push_call(Call::SetPersistedScrollOffset {
2562
+ node_id: node_id.clone(),
2563
+ x,
2564
+ y,
2565
+ });
2566
+ if !node_id.is_empty() {
2567
+ PERSISTED_SCROLL.with(|map| {
2568
+ map.borrow_mut().insert(node_id, (x, y));
2569
+ });
2570
+ }
2571
+ }
2572
+
2573
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2574
+ pub unsafe fn fui_try_get_persisted_scroll_offset(
2575
+ node_id_ptr: usize,
2576
+ node_id_len: u32,
2577
+ out_x: usize,
2578
+ out_y: usize,
2579
+ ) -> bool {
2580
+ let node_id = if node_id_ptr == 0 || node_id_len == 0 {
2581
+ String::new()
2582
+ } else {
2583
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2584
+ node_id_ptr as *const u8,
2585
+ node_id_len as usize,
2586
+ ))
2587
+ .into_owned()
2588
+ };
2589
+ push_call(Call::TryGetPersistedScrollOffset {
2590
+ node_id: node_id.clone(),
2591
+ });
2592
+ let entry = PERSISTED_SCROLL.with(|map| map.borrow().get(&node_id).copied());
2593
+ let Some((x, y)) = entry else {
2594
+ return false;
2595
+ };
2596
+ if out_x != 0 {
2597
+ *(out_x as *mut f32) = x;
2598
+ }
2599
+ if out_y != 0 {
2600
+ *(out_y as *mut f32) = y;
2601
+ }
2602
+ true
2603
+ }
2604
+
2605
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2606
+ pub unsafe fn fui_set_persisted_state(
2607
+ node_id_ptr: usize,
2608
+ node_id_len: u32,
2609
+ kind_ptr: usize,
2610
+ kind_len: u32,
2611
+ version: u32,
2612
+ payload_ptr: usize,
2613
+ payload_len: u32,
2614
+ ) {
2615
+ let node_id = if node_id_ptr == 0 || node_id_len == 0 {
2616
+ String::new()
2617
+ } else {
2618
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2619
+ node_id_ptr as *const u8,
2620
+ node_id_len as usize,
2621
+ ))
2622
+ .into_owned()
2623
+ };
2624
+ let kind = if kind_ptr == 0 || kind_len == 0 {
2625
+ String::new()
2626
+ } else {
2627
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2628
+ kind_ptr as *const u8,
2629
+ kind_len as usize,
2630
+ ))
2631
+ .into_owned()
2632
+ };
2633
+ let payload = if payload_ptr == 0 || payload_len == 0 {
2634
+ String::new()
2635
+ } else {
2636
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2637
+ payload_ptr as *const u8,
2638
+ payload_len as usize,
2639
+ ))
2640
+ .into_owned()
2641
+ };
2642
+ push_call(Call::SetPersistedState {
2643
+ node_id: node_id.clone(),
2644
+ kind: kind.clone(),
2645
+ version,
2646
+ payload: payload.clone(),
2647
+ });
2648
+ if !node_id.is_empty() && !kind.is_empty() {
2649
+ PERSISTED_TEXT.with(|map| {
2650
+ map.borrow_mut().insert((node_id, kind), (version, payload));
2651
+ });
2652
+ }
2653
+ }
2654
+
2655
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2656
+ pub unsafe fn fui_copy_persisted_state(
2657
+ node_id_ptr: usize,
2658
+ node_id_len: u32,
2659
+ kind_ptr: usize,
2660
+ kind_len: u32,
2661
+ out_version_ptr: usize,
2662
+ payload_ptr: usize,
2663
+ payload_capacity: u32,
2664
+ ) -> i32 {
2665
+ let node_id = if node_id_ptr == 0 || node_id_len == 0 {
2666
+ String::new()
2667
+ } else {
2668
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2669
+ node_id_ptr as *const u8,
2670
+ node_id_len as usize,
2671
+ ))
2672
+ .into_owned()
2673
+ };
2674
+ let kind = if kind_ptr == 0 || kind_len == 0 {
2675
+ String::new()
2676
+ } else {
2677
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2678
+ kind_ptr as *const u8,
2679
+ kind_len as usize,
2680
+ ))
2681
+ .into_owned()
2682
+ };
2683
+ push_call(Call::CopyPersistedState {
2684
+ node_id: node_id.clone(),
2685
+ kind: kind.clone(),
2686
+ });
2687
+ let Some((version, payload)) =
2688
+ PERSISTED_TEXT.with(|map| map.borrow().get(&(node_id, kind)).cloned())
2689
+ else {
2690
+ return -1;
2691
+ };
2692
+ if out_version_ptr != 0 {
2693
+ *(out_version_ptr as *mut u32) = version;
2694
+ }
2695
+ let bytes = payload.as_bytes();
2696
+ if bytes.len() > payload_capacity as usize {
2697
+ return bytes.len() as i32;
2698
+ }
2699
+ if payload_ptr != 0 && !bytes.is_empty() {
2700
+ std::ptr::copy_nonoverlapping(bytes.as_ptr(), payload_ptr as *mut u8, bytes.len());
2701
+ }
2702
+ bytes.len() as i32
2703
+ }
2704
+
2705
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2706
+ pub unsafe fn fui_worker_start_string(
2707
+ worker_id: u32,
2708
+ wasm_path_ptr: usize,
2709
+ wasm_path_len: u32,
2710
+ entry_ptr: usize,
2711
+ entry_len: u32,
2712
+ input_ptr: usize,
2713
+ input_len: u32,
2714
+ ) {
2715
+ let wasm_path = if wasm_path_ptr == 0 || wasm_path_len == 0 {
2716
+ String::new()
2717
+ } else {
2718
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2719
+ wasm_path_ptr as *const u8,
2720
+ wasm_path_len as usize,
2721
+ ))
2722
+ .into_owned()
2723
+ };
2724
+ let entry = if entry_ptr == 0 || entry_len == 0 {
2725
+ String::new()
2726
+ } else {
2727
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2728
+ entry_ptr as *const u8,
2729
+ entry_len as usize,
2730
+ ))
2731
+ .into_owned()
2732
+ };
2733
+ let input = if input_ptr == 0 || input_len == 0 {
2734
+ String::new()
2735
+ } else {
2736
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2737
+ input_ptr as *const u8,
2738
+ input_len as usize,
2739
+ ))
2740
+ .into_owned()
2741
+ };
2742
+ push_call(Call::WorkerStartString {
2743
+ worker_id,
2744
+ wasm_path,
2745
+ entry,
2746
+ input,
2747
+ });
2748
+ }
2749
+
2750
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2751
+ pub unsafe fn fui_worker_cancel(worker_id: u32) {
2752
+ push_call(Call::WorkerCancel { worker_id });
2753
+ }
2754
+
2755
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2756
+ pub unsafe fn fui_file_capabilities() -> u32 {
2757
+ push_call(Call::FileCapabilities);
2758
+ (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6)
2759
+ }
2760
+
2761
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2762
+ pub unsafe fn fui_file_pick(request_id: u32, accept_ptr: usize, accept_len: u32, multiple: bool) {
2763
+ let accept = if accept_ptr == 0 || accept_len == 0 {
2764
+ String::new()
2765
+ } else {
2766
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2767
+ accept_ptr as *const u8,
2768
+ accept_len as usize,
2769
+ ))
2770
+ .into_owned()
2771
+ };
2772
+ push_call(Call::FilePick {
2773
+ request_id,
2774
+ accept,
2775
+ multiple,
2776
+ });
2777
+ }
2778
+
2779
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2780
+ pub unsafe fn fui_file_read_chunk(
2781
+ request_id: u32,
2782
+ file_id_ptr: usize,
2783
+ file_id_len: u32,
2784
+ offset_bytes: u64,
2785
+ max_bytes: u32,
2786
+ ) {
2787
+ let file_id = if file_id_ptr == 0 || file_id_len == 0 {
2788
+ String::new()
2789
+ } else {
2790
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2791
+ file_id_ptr as *const u8,
2792
+ file_id_len as usize,
2793
+ ))
2794
+ .into_owned()
2795
+ };
2796
+ push_call(Call::FileReadChunk {
2797
+ request_id,
2798
+ file_id,
2799
+ offset_bytes,
2800
+ max_bytes,
2801
+ });
2802
+ }
2803
+
2804
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2805
+ pub unsafe fn fui_file_save_text(
2806
+ request_id: u32,
2807
+ suggested_name_ptr: usize,
2808
+ suggested_name_len: u32,
2809
+ mime_type_ptr: usize,
2810
+ mime_type_len: u32,
2811
+ file_extension_ptr: usize,
2812
+ file_extension_len: u32,
2813
+ text_ptr: usize,
2814
+ text_len: u32,
2815
+ ) {
2816
+ let suggested_name = if suggested_name_ptr == 0 || suggested_name_len == 0 {
2817
+ String::new()
2818
+ } else {
2819
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2820
+ suggested_name_ptr as *const u8,
2821
+ suggested_name_len as usize,
2822
+ ))
2823
+ .into_owned()
2824
+ };
2825
+ let mime_type = if mime_type_ptr == 0 || mime_type_len == 0 {
2826
+ String::new()
2827
+ } else {
2828
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2829
+ mime_type_ptr as *const u8,
2830
+ mime_type_len as usize,
2831
+ ))
2832
+ .into_owned()
2833
+ };
2834
+ let file_extension = if file_extension_ptr == 0 || file_extension_len == 0 {
2835
+ String::new()
2836
+ } else {
2837
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2838
+ file_extension_ptr as *const u8,
2839
+ file_extension_len as usize,
2840
+ ))
2841
+ .into_owned()
2842
+ };
2843
+ let text = if text_ptr == 0 || text_len == 0 {
2844
+ String::new()
2845
+ } else {
2846
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2847
+ text_ptr as *const u8,
2848
+ text_len as usize,
2849
+ ))
2850
+ .into_owned()
2851
+ };
2852
+ push_call(Call::FileSaveText {
2853
+ request_id,
2854
+ suggested_name,
2855
+ mime_type,
2856
+ file_extension,
2857
+ text,
2858
+ });
2859
+ }
2860
+
2861
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2862
+ pub unsafe fn fui_file_save_bytes(
2863
+ request_id: u32,
2864
+ suggested_name_ptr: usize,
2865
+ suggested_name_len: u32,
2866
+ mime_type_ptr: usize,
2867
+ mime_type_len: u32,
2868
+ file_extension_ptr: usize,
2869
+ file_extension_len: u32,
2870
+ bytes_ptr: usize,
2871
+ bytes_len: u32,
2872
+ ) {
2873
+ let suggested_name = if suggested_name_ptr == 0 || suggested_name_len == 0 {
2874
+ String::new()
2875
+ } else {
2876
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2877
+ suggested_name_ptr as *const u8,
2878
+ suggested_name_len as usize,
2879
+ ))
2880
+ .into_owned()
2881
+ };
2882
+ let mime_type = if mime_type_ptr == 0 || mime_type_len == 0 {
2883
+ String::new()
2884
+ } else {
2885
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2886
+ mime_type_ptr as *const u8,
2887
+ mime_type_len as usize,
2888
+ ))
2889
+ .into_owned()
2890
+ };
2891
+ let file_extension = if file_extension_ptr == 0 || file_extension_len == 0 {
2892
+ String::new()
2893
+ } else {
2894
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2895
+ file_extension_ptr as *const u8,
2896
+ file_extension_len as usize,
2897
+ ))
2898
+ .into_owned()
2899
+ };
2900
+ let bytes = if bytes_ptr == 0 || bytes_len == 0 {
2901
+ Vec::new()
2902
+ } else {
2903
+ std::slice::from_raw_parts(bytes_ptr as *const u8, bytes_len as usize).to_vec()
2904
+ };
2905
+ push_call(Call::FileSaveBytes {
2906
+ request_id,
2907
+ suggested_name,
2908
+ mime_type,
2909
+ file_extension,
2910
+ bytes,
2911
+ });
2912
+ }
2913
+
2914
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2915
+ pub unsafe fn fui_file_create_writer(
2916
+ request_id: u32,
2917
+ suggested_name_ptr: usize,
2918
+ suggested_name_len: u32,
2919
+ mime_type_ptr: usize,
2920
+ mime_type_len: u32,
2921
+ file_extension_ptr: usize,
2922
+ file_extension_len: u32,
2923
+ ) {
2924
+ let suggested_name = if suggested_name_ptr == 0 || suggested_name_len == 0 {
2925
+ String::new()
2926
+ } else {
2927
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2928
+ suggested_name_ptr as *const u8,
2929
+ suggested_name_len as usize,
2930
+ ))
2931
+ .into_owned()
2932
+ };
2933
+ let mime_type = if mime_type_ptr == 0 || mime_type_len == 0 {
2934
+ String::new()
2935
+ } else {
2936
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2937
+ mime_type_ptr as *const u8,
2938
+ mime_type_len as usize,
2939
+ ))
2940
+ .into_owned()
2941
+ };
2942
+ let file_extension = if file_extension_ptr == 0 || file_extension_len == 0 {
2943
+ String::new()
2944
+ } else {
2945
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2946
+ file_extension_ptr as *const u8,
2947
+ file_extension_len as usize,
2948
+ ))
2949
+ .into_owned()
2950
+ };
2951
+ push_call(Call::FileCreateWriter {
2952
+ request_id,
2953
+ suggested_name,
2954
+ mime_type,
2955
+ file_extension,
2956
+ });
2957
+ }
2958
+
2959
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2960
+ pub unsafe fn fui_file_writer_write_text(
2961
+ request_id: u32,
2962
+ writer_id_ptr: usize,
2963
+ writer_id_len: u32,
2964
+ text_ptr: usize,
2965
+ text_len: u32,
2966
+ ) {
2967
+ let writer_id = if writer_id_ptr == 0 || writer_id_len == 0 {
2968
+ String::new()
2969
+ } else {
2970
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2971
+ writer_id_ptr as *const u8,
2972
+ writer_id_len as usize,
2973
+ ))
2974
+ .into_owned()
2975
+ };
2976
+ let text = if text_ptr == 0 || text_len == 0 {
2977
+ String::new()
2978
+ } else {
2979
+ String::from_utf8_lossy(std::slice::from_raw_parts(
2980
+ text_ptr as *const u8,
2981
+ text_len as usize,
2982
+ ))
2983
+ .into_owned()
2984
+ };
2985
+ push_call(Call::FileWriterWriteText {
2986
+ request_id,
2987
+ writer_id,
2988
+ text,
2989
+ });
2990
+ }
2991
+
2992
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
2993
+ pub unsafe fn fui_file_writer_write_bytes(
2994
+ request_id: u32,
2995
+ writer_id_ptr: usize,
2996
+ writer_id_len: u32,
2997
+ bytes_ptr: usize,
2998
+ bytes_len: u32,
2999
+ ) {
3000
+ let writer_id = if writer_id_ptr == 0 || writer_id_len == 0 {
3001
+ String::new()
3002
+ } else {
3003
+ String::from_utf8_lossy(std::slice::from_raw_parts(
3004
+ writer_id_ptr as *const u8,
3005
+ writer_id_len as usize,
3006
+ ))
3007
+ .into_owned()
3008
+ };
3009
+ let bytes = if bytes_ptr == 0 || bytes_len == 0 {
3010
+ Vec::new()
3011
+ } else {
3012
+ std::slice::from_raw_parts(bytes_ptr as *const u8, bytes_len as usize).to_vec()
3013
+ };
3014
+ push_call(Call::FileWriterWriteBytes {
3015
+ request_id,
3016
+ writer_id,
3017
+ bytes,
3018
+ });
3019
+ }
3020
+
3021
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3022
+ pub unsafe fn fui_file_writer_finish(request_id: u32, writer_id_ptr: usize, writer_id_len: u32) {
3023
+ let writer_id = if writer_id_ptr == 0 || writer_id_len == 0 {
3024
+ String::new()
3025
+ } else {
3026
+ String::from_utf8_lossy(std::slice::from_raw_parts(
3027
+ writer_id_ptr as *const u8,
3028
+ writer_id_len as usize,
3029
+ ))
3030
+ .into_owned()
3031
+ };
3032
+ push_call(Call::FileWriterFinish {
3033
+ request_id,
3034
+ writer_id,
3035
+ });
3036
+ }
3037
+
3038
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3039
+ pub unsafe fn fui_file_process_worker_start(
3040
+ request_id: u32,
3041
+ worker_wasm_path_ptr: usize,
3042
+ worker_wasm_path_len: u32,
3043
+ worker_entry_ptr: usize,
3044
+ worker_entry_len: u32,
3045
+ file_id_ptr: usize,
3046
+ file_id_len: u32,
3047
+ suggested_name_ptr: usize,
3048
+ suggested_name_len: u32,
3049
+ chunk_bytes: u32,
3050
+ save_to_picked_file: bool,
3051
+ ) {
3052
+ let worker_wasm_path = if worker_wasm_path_ptr == 0 || worker_wasm_path_len == 0 {
3053
+ String::new()
3054
+ } else {
3055
+ String::from_utf8_lossy(std::slice::from_raw_parts(
3056
+ worker_wasm_path_ptr as *const u8,
3057
+ worker_wasm_path_len as usize,
3058
+ ))
3059
+ .into_owned()
3060
+ };
3061
+ let worker_entry_name = if worker_entry_ptr == 0 || worker_entry_len == 0 {
3062
+ String::new()
3063
+ } else {
3064
+ String::from_utf8_lossy(std::slice::from_raw_parts(
3065
+ worker_entry_ptr as *const u8,
3066
+ worker_entry_len as usize,
3067
+ ))
3068
+ .into_owned()
3069
+ };
3070
+ let file_id = if file_id_ptr == 0 || file_id_len == 0 {
3071
+ String::new()
3072
+ } else {
3073
+ String::from_utf8_lossy(std::slice::from_raw_parts(
3074
+ file_id_ptr as *const u8,
3075
+ file_id_len as usize,
3076
+ ))
3077
+ .into_owned()
3078
+ };
3079
+ let suggested_name = if suggested_name_ptr == 0 || suggested_name_len == 0 {
3080
+ String::new()
3081
+ } else {
3082
+ String::from_utf8_lossy(std::slice::from_raw_parts(
3083
+ suggested_name_ptr as *const u8,
3084
+ suggested_name_len as usize,
3085
+ ))
3086
+ .into_owned()
3087
+ };
3088
+ push_call(Call::FileProcessWorkerStart {
3089
+ request_id,
3090
+ worker_wasm_path,
3091
+ worker_entry_name,
3092
+ file_id,
3093
+ suggested_name,
3094
+ chunk_bytes,
3095
+ save_to_picked_file,
3096
+ });
3097
+ }
3098
+
3099
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3100
+ pub unsafe fn fui_file_process_worker_cancel(request_id: u32) {
3101
+ push_call(Call::FileProcessWorkerCancel { request_id });
3102
+ }
3103
+
3104
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3105
+ pub unsafe fn fui_path_create() -> u32 {
3106
+ let path_id = NEXT_PATH_ID.with(|next| {
3107
+ let current = next.get();
3108
+ next.set(current + 1);
3109
+ current
3110
+ });
3111
+ push_call(Call::PathCreate { path_id });
3112
+ path_id
3113
+ }
3114
+
3115
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3116
+ pub unsafe fn fui_path_destroy(path_id: u32) {
3117
+ push_call(Call::PathDestroy { path_id });
3118
+ }
3119
+
3120
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3121
+ pub unsafe fn fui_path_move_to(path_id: u32, x: f32, y: f32) {
3122
+ push_call(Call::PathMoveTo { path_id, x, y });
3123
+ }
3124
+
3125
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3126
+ pub unsafe fn fui_path_line_to(path_id: u32, x: f32, y: f32) {
3127
+ push_call(Call::PathLineTo { path_id, x, y });
3128
+ }
3129
+
3130
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3131
+ pub unsafe fn fui_path_quad_to(path_id: u32, cx: f32, cy: f32, x: f32, y: f32) {
3132
+ push_call(Call::PathQuadTo {
3133
+ path_id,
3134
+ cx,
3135
+ cy,
3136
+ x,
3137
+ y,
3138
+ });
3139
+ }
3140
+
3141
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3142
+ pub unsafe fn fui_path_cubic_to(
3143
+ path_id: u32,
3144
+ cx1: f32,
3145
+ cy1: f32,
3146
+ cx2: f32,
3147
+ cy2: f32,
3148
+ x: f32,
3149
+ y: f32,
3150
+ ) {
3151
+ push_call(Call::PathCubicTo {
3152
+ path_id,
3153
+ cx1,
3154
+ cy1,
3155
+ cx2,
3156
+ cy2,
3157
+ x,
3158
+ y,
3159
+ });
3160
+ }
3161
+
3162
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3163
+ pub unsafe fn fui_path_close(path_id: u32) {
3164
+ push_call(Call::PathClose { path_id });
3165
+ }
3166
+
3167
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3168
+ pub unsafe fn fui_path_add_rect(path_id: u32, x: f32, y: f32, w: f32, h: f32) {
3169
+ push_call(Call::PathAddRect {
3170
+ path_id,
3171
+ x,
3172
+ y,
3173
+ w,
3174
+ h,
3175
+ });
3176
+ }
3177
+
3178
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3179
+ pub unsafe fn fui_path_add_circle(path_id: u32, cx: f32, cy: f32, r: f32) {
3180
+ push_call(Call::PathAddCircle { path_id, cx, cy, r });
3181
+ }
3182
+
3183
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3184
+ pub unsafe fn fui_canvas_draw_rect(
3185
+ canvas_ptr: usize,
3186
+ x: f32,
3187
+ y: f32,
3188
+ w: f32,
3189
+ h: f32,
3190
+ fill_color: u32,
3191
+ stroke_color: u32,
3192
+ stroke_width: f32,
3193
+ ) {
3194
+ push_call(Call::CanvasDrawRect {
3195
+ canvas_ptr,
3196
+ x,
3197
+ y,
3198
+ w,
3199
+ h,
3200
+ fill_color,
3201
+ stroke_color,
3202
+ stroke_width,
3203
+ });
3204
+ }
3205
+
3206
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3207
+ pub unsafe fn fui_canvas_draw_circle(
3208
+ canvas_ptr: usize,
3209
+ cx: f32,
3210
+ cy: f32,
3211
+ radius: f32,
3212
+ fill_color: u32,
3213
+ stroke_color: u32,
3214
+ stroke_width: f32,
3215
+ ) {
3216
+ push_call(Call::CanvasDrawCircle {
3217
+ canvas_ptr,
3218
+ cx,
3219
+ cy,
3220
+ radius,
3221
+ fill_color,
3222
+ stroke_color,
3223
+ stroke_width,
3224
+ });
3225
+ }
3226
+
3227
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3228
+ pub unsafe fn fui_canvas_draw_line(
3229
+ canvas_ptr: usize,
3230
+ x1: f32,
3231
+ y1: f32,
3232
+ x2: f32,
3233
+ y2: f32,
3234
+ color: u32,
3235
+ stroke_width: f32,
3236
+ ) {
3237
+ push_call(Call::CanvasDrawLine {
3238
+ canvas_ptr,
3239
+ x1,
3240
+ y1,
3241
+ x2,
3242
+ y2,
3243
+ color,
3244
+ stroke_width,
3245
+ });
3246
+ }
3247
+
3248
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3249
+ pub unsafe fn fui_canvas_draw_round_rect(
3250
+ canvas_ptr: usize,
3251
+ x: f32,
3252
+ y: f32,
3253
+ w: f32,
3254
+ h: f32,
3255
+ rx: f32,
3256
+ ry: f32,
3257
+ fill_color: u32,
3258
+ stroke_color: u32,
3259
+ stroke_width: f32,
3260
+ ) {
3261
+ push_call(Call::CanvasDrawRoundRect {
3262
+ canvas_ptr,
3263
+ x,
3264
+ y,
3265
+ w,
3266
+ h,
3267
+ rx,
3268
+ ry,
3269
+ fill_color,
3270
+ stroke_color,
3271
+ stroke_width,
3272
+ });
3273
+ }
3274
+
3275
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3276
+ pub unsafe fn fui_canvas_draw_path(
3277
+ canvas_ptr: usize,
3278
+ path_id: u32,
3279
+ fill_color: u32,
3280
+ stroke_color: u32,
3281
+ stroke_width: f32,
3282
+ ) {
3283
+ push_call(Call::CanvasDrawPath {
3284
+ canvas_ptr,
3285
+ path_id,
3286
+ fill_color,
3287
+ stroke_color,
3288
+ stroke_width,
3289
+ });
3290
+ }
3291
+
3292
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3293
+ pub unsafe fn fui_canvas_draw_text_node(
3294
+ canvas_ptr: usize,
3295
+ handle_lo: u32,
3296
+ handle_hi: u32,
3297
+ x: f32,
3298
+ y: f32,
3299
+ ) {
3300
+ push_call(Call::CanvasDrawTextNode {
3301
+ canvas_ptr,
3302
+ handle_lo,
3303
+ handle_hi,
3304
+ x,
3305
+ y,
3306
+ });
3307
+ }
3308
+
3309
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3310
+ pub unsafe fn fui_canvas_draw_image(
3311
+ canvas_ptr: usize,
3312
+ texture_id: u32,
3313
+ x: f32,
3314
+ y: f32,
3315
+ w: f32,
3316
+ h: f32,
3317
+ sampling_kind: u32,
3318
+ max_aniso: u32,
3319
+ ) {
3320
+ push_call(Call::CanvasDrawImage {
3321
+ canvas_ptr,
3322
+ texture_id,
3323
+ x,
3324
+ y,
3325
+ w,
3326
+ h,
3327
+ sampling_kind,
3328
+ max_aniso,
3329
+ });
3330
+ }
3331
+
3332
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3333
+ pub unsafe fn fui_canvas_draw_svg(canvas_ptr: usize, svg_id: u32, x: f32, y: f32, w: f32, h: f32) {
3334
+ push_call(Call::CanvasDrawSvg {
3335
+ canvas_ptr,
3336
+ svg_id,
3337
+ x,
3338
+ y,
3339
+ w,
3340
+ h,
3341
+ });
3342
+ }
3343
+
3344
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3345
+ pub unsafe fn fui_canvas_draw_batch(canvas_ptr: usize, words_ptr: usize, word_count: u32) {
3346
+ let words = if words_ptr == 0 || word_count == 0 {
3347
+ Vec::new()
3348
+ } else {
3349
+ std::slice::from_raw_parts(words_ptr as *const u32, word_count as usize).to_vec()
3350
+ };
3351
+ push_call(Call::CanvasDrawBatch { canvas_ptr, words });
3352
+ }
3353
+
3354
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3355
+ pub unsafe fn fui_canvas_save(canvas_ptr: usize) {
3356
+ push_call(Call::CanvasSave { canvas_ptr });
3357
+ }
3358
+
3359
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3360
+ pub unsafe fn fui_canvas_restore(canvas_ptr: usize) {
3361
+ push_call(Call::CanvasRestore { canvas_ptr });
3362
+ }
3363
+
3364
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3365
+ pub unsafe fn fui_canvas_translate(canvas_ptr: usize, x: f32, y: f32) {
3366
+ push_call(Call::CanvasTranslate { canvas_ptr, x, y });
3367
+ }
3368
+
3369
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3370
+ pub unsafe fn fui_canvas_scale(canvas_ptr: usize, sx: f32, sy: f32) {
3371
+ push_call(Call::CanvasScale { canvas_ptr, sx, sy });
3372
+ }
3373
+
3374
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3375
+ pub unsafe fn fui_canvas_rotate(canvas_ptr: usize, degrees: f32) {
3376
+ push_call(Call::CanvasRotate {
3377
+ canvas_ptr,
3378
+ degrees,
3379
+ });
3380
+ }
3381
+
3382
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3383
+ pub unsafe fn fui_canvas_clip_rect(canvas_ptr: usize, x: f32, y: f32, w: f32, h: f32) {
3384
+ push_call(Call::CanvasClipRect {
3385
+ canvas_ptr,
3386
+ x,
3387
+ y,
3388
+ w,
3389
+ h,
3390
+ });
3391
+ }
3392
+
3393
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3394
+ pub unsafe fn fui_canvas_clip_round_rect(
3395
+ canvas_ptr: usize,
3396
+ x: f32,
3397
+ y: f32,
3398
+ w: f32,
3399
+ h: f32,
3400
+ tl: f32,
3401
+ tr: f32,
3402
+ br: f32,
3403
+ bl: f32,
3404
+ ) {
3405
+ push_call(Call::CanvasClipRoundRect {
3406
+ canvas_ptr,
3407
+ x,
3408
+ y,
3409
+ w,
3410
+ h,
3411
+ tl,
3412
+ tr,
3413
+ br,
3414
+ bl,
3415
+ });
3416
+ }
3417
+
3418
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3419
+ pub unsafe fn fui_canvas_create_offscreen(width: u32, height: u32) -> u32 {
3420
+ let offscreen_id = NEXT_OFFSCREEN_ID.with(|next| {
3421
+ let value = next.get();
3422
+ next.set(value + 1);
3423
+ value
3424
+ });
3425
+ push_call(Call::CanvasCreateOffscreen {
3426
+ width,
3427
+ height,
3428
+ offscreen_id,
3429
+ });
3430
+ offscreen_id
3431
+ }
3432
+
3433
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3434
+ pub unsafe fn fui_canvas_get_offscreen_ptr(offscreen_id: u32) -> usize {
3435
+ push_call(Call::CanvasGetOffscreenPtr { offscreen_id });
3436
+ (0x1000 + offscreen_id as usize) as usize
3437
+ }
3438
+
3439
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3440
+ pub unsafe fn fui_canvas_read_offscreen_pixels(
3441
+ offscreen_id: u32,
3442
+ out_ptr: usize,
3443
+ width: u32,
3444
+ height: u32,
3445
+ ) {
3446
+ push_call(Call::CanvasReadOffscreenPixels {
3447
+ offscreen_id,
3448
+ width,
3449
+ height,
3450
+ });
3451
+ if out_ptr != 0 {
3452
+ std::ptr::write_bytes(
3453
+ out_ptr as *mut u8,
3454
+ 0,
3455
+ (width as usize) * (height as usize) * 4,
3456
+ );
3457
+ }
3458
+ }
3459
+
3460
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3461
+ pub unsafe fn fui_canvas_destroy_offscreen(offscreen_id: u32) {
3462
+ push_call(Call::CanvasDestroyOffscreen { offscreen_id });
3463
+ }
3464
+
3465
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3466
+ pub unsafe fn ui_get_bounds(
3467
+ handle: u64,
3468
+ out_x: *mut f32,
3469
+ out_y: *mut f32,
3470
+ out_width: *mut f32,
3471
+ out_height: *mut f32,
3472
+ ) -> bool {
3473
+ push_call(Call::GetBounds { handle });
3474
+ if !out_x.is_null() {
3475
+ *out_x = 0.0;
3476
+ }
3477
+ if !out_y.is_null() {
3478
+ *out_y = 0.0;
3479
+ }
3480
+ if !out_width.is_null() {
3481
+ *out_width = 100.0;
3482
+ }
3483
+ if !out_height.is_null() {
3484
+ *out_height = 100.0;
3485
+ }
3486
+ true
3487
+ }
3488
+
3489
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3490
+ pub unsafe fn ui_get_visible_bounds(
3491
+ handle: u64,
3492
+ out_x: *mut f32,
3493
+ out_y: *mut f32,
3494
+ out_width: *mut f32,
3495
+ out_height: *mut f32,
3496
+ ) -> bool {
3497
+ push_call(Call::GetVisibleBounds { handle });
3498
+ let bounds = VISIBLE_BOUNDS.with(|slot| *slot.borrow());
3499
+ let Some((x, y, width, height)) = bounds else {
3500
+ if !out_x.is_null() {
3501
+ *out_x = 0.0;
3502
+ }
3503
+ if !out_y.is_null() {
3504
+ *out_y = 0.0;
3505
+ }
3506
+ if !out_width.is_null() {
3507
+ *out_width = 100.0;
3508
+ }
3509
+ if !out_height.is_null() {
3510
+ *out_height = 100.0;
3511
+ }
3512
+ return true;
3513
+ };
3514
+ if width <= 0.0 || height <= 0.0 {
3515
+ return false;
3516
+ }
3517
+ if !out_x.is_null() {
3518
+ *out_x = x;
3519
+ }
3520
+ if !out_y.is_null() {
3521
+ *out_y = y;
3522
+ }
3523
+ if !out_width.is_null() {
3524
+ *out_width = width;
3525
+ }
3526
+ if !out_height.is_null() {
3527
+ *out_height = height;
3528
+ }
3529
+ true
3530
+ }
3531
+
3532
+ #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3533
+ pub unsafe fn ui_get_debug_tree_buffer(out_length: *mut u32) -> *mut u32 {
3534
+ let ptr = DEBUG_TREE_WORDS.with(|slot| {
3535
+ let words = slot.borrow();
3536
+ if !out_length.is_null() {
3537
+ *out_length = words.len() as u32;
3538
+ }
3539
+ words.as_ptr() as *mut u32
3540
+ });
3541
+ ptr
3542
+ }