imxc 0.5.4 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/compile.d.ts +8 -0
- package/dist/compile.js +285 -25
- package/dist/components.js +597 -45
- package/dist/diagnostics.js +3 -2
- package/dist/emitter.d.ts +6 -3
- package/dist/emitter.js +1454 -322
- package/dist/index.js +34 -7
- package/dist/init.d.ts +7 -1
- package/dist/init.js +43 -455
- package/dist/ir.d.ts +437 -5
- package/dist/lowering.d.ts +4 -3
- package/dist/lowering.js +770 -57
- package/dist/parser.d.ts +1 -0
- package/dist/templates/async.d.ts +1 -0
- package/dist/templates/async.js +228 -0
- package/dist/templates/custom.d.ts +15 -0
- package/dist/templates/custom.js +945 -0
- package/dist/templates/filedialog.d.ts +1 -0
- package/dist/templates/filedialog.js +216 -0
- package/dist/templates/hotreload.d.ts +1 -0
- package/dist/templates/hotreload.js +400 -0
- package/dist/templates/index.d.ts +16 -0
- package/dist/templates/index.js +553 -0
- package/dist/templates/minimal.d.ts +1 -0
- package/dist/templates/minimal.js +165 -0
- package/dist/templates/networking.d.ts +1 -0
- package/dist/templates/networking.js +244 -0
- package/dist/templates/persistence.d.ts +1 -0
- package/dist/templates/persistence.js +238 -0
- package/dist/validator.d.ts +1 -0
- package/dist/validator.js +51 -22
- package/dist/watch.d.ts +2 -1
- package/dist/watch.js +21 -4
- package/package.json +2 -4
package/dist/lowering.js
CHANGED
|
@@ -64,6 +64,7 @@ export function lowerComponent(parsed, validation, externalInterfaces) {
|
|
|
64
64
|
setterMap,
|
|
65
65
|
propsParam,
|
|
66
66
|
propsFieldTypes,
|
|
67
|
+
externalInterfaces,
|
|
67
68
|
bufferIndex: 0,
|
|
68
69
|
mapCounter: 0,
|
|
69
70
|
sourceFile: parsed.sourceFile,
|
|
@@ -86,19 +87,27 @@ export function lowerComponent(parsed, validation, externalInterfaces) {
|
|
|
86
87
|
body,
|
|
87
88
|
};
|
|
88
89
|
}
|
|
90
|
+
function normalizePropTypeText(typeText) {
|
|
91
|
+
const trimmed = typeText.trim().replace(/\s*\|\s*undefined$/, '');
|
|
92
|
+
if (trimmed === 'number')
|
|
93
|
+
return 'int';
|
|
94
|
+
if (trimmed === 'boolean')
|
|
95
|
+
return 'bool';
|
|
96
|
+
if (trimmed === 'string')
|
|
97
|
+
return 'string';
|
|
98
|
+
// Array types: boolean[] -> bool*, number[] -> float*
|
|
99
|
+
if (trimmed === 'boolean[]')
|
|
100
|
+
return 'bool*';
|
|
101
|
+
if (trimmed === 'number[]')
|
|
102
|
+
return 'float*';
|
|
103
|
+
return trimmed;
|
|
104
|
+
}
|
|
89
105
|
function inferPropType(member) {
|
|
90
106
|
if (!member.type)
|
|
91
107
|
return 'string';
|
|
92
108
|
if (ts.isFunctionTypeNode(member.type))
|
|
93
109
|
return 'callback';
|
|
94
|
-
|
|
95
|
-
if (text === 'number')
|
|
96
|
-
return 'int';
|
|
97
|
-
if (text === 'boolean')
|
|
98
|
-
return 'bool';
|
|
99
|
-
if (text === 'string')
|
|
100
|
-
return 'string';
|
|
101
|
-
return 'string';
|
|
110
|
+
return normalizePropTypeText(member.type.getText());
|
|
102
111
|
}
|
|
103
112
|
/**
|
|
104
113
|
* Scan the source file for an interface declaration matching `interfaceName`
|
|
@@ -119,26 +128,16 @@ function extractInterfaceFields(interfaceName, sourceFile, fieldTypes) {
|
|
|
119
128
|
fieldTypes.set(fieldName, 'callback');
|
|
120
129
|
continue;
|
|
121
130
|
}
|
|
122
|
-
|
|
123
|
-
if (typeText === 'number' || typeText === 'number | undefined') {
|
|
124
|
-
fieldTypes.set(fieldName, 'float');
|
|
125
|
-
}
|
|
126
|
-
else if (typeText === 'boolean') {
|
|
127
|
-
fieldTypes.set(fieldName, 'bool');
|
|
128
|
-
}
|
|
129
|
-
else if (typeText === 'string') {
|
|
130
|
-
fieldTypes.set(fieldName, 'string');
|
|
131
|
-
}
|
|
132
|
-
else {
|
|
133
|
-
// Array types, nested interfaces, etc. treated as opaque
|
|
134
|
-
fieldTypes.set(fieldName, 'string');
|
|
135
|
-
}
|
|
131
|
+
fieldTypes.set(fieldName, normalizePropTypeText(member.type.getText()));
|
|
136
132
|
}
|
|
137
133
|
}
|
|
138
134
|
return;
|
|
139
135
|
}
|
|
140
136
|
}
|
|
141
137
|
}
|
|
138
|
+
function isIntegerArrayLiteral(expr) {
|
|
139
|
+
return expr.elements.every(e => ts.isNumericLiteral(e) && !e.getText().includes('.'));
|
|
140
|
+
}
|
|
142
141
|
function inferTypeFromExpr(expr) {
|
|
143
142
|
if (ts.isNumericLiteral(expr)) {
|
|
144
143
|
// Use getText() to check original source text, since TS normalizes 5.0 to "5" in .text
|
|
@@ -150,7 +149,10 @@ function inferTypeFromExpr(expr) {
|
|
|
150
149
|
if (expr.kind === ts.SyntaxKind.TrueKeyword || expr.kind === ts.SyntaxKind.FalseKeyword)
|
|
151
150
|
return 'bool';
|
|
152
151
|
if (ts.isArrayLiteralExpression(expr))
|
|
153
|
-
return 'color';
|
|
152
|
+
return isIntegerArrayLiteral(expr) ? 'int_array' : 'color';
|
|
153
|
+
// AsExpression (e.g. [1.0, 0.0] as [number, number]): infer from inner expression
|
|
154
|
+
if (ts.isAsExpression(expr))
|
|
155
|
+
return inferTypeFromExpr(expr.expression);
|
|
154
156
|
// Default to int
|
|
155
157
|
return 'int';
|
|
156
158
|
}
|
|
@@ -165,11 +167,16 @@ function exprToLiteral(expr) {
|
|
|
165
167
|
return 'true';
|
|
166
168
|
if (expr.kind === ts.SyntaxKind.FalseKeyword)
|
|
167
169
|
return 'false';
|
|
170
|
+
// AsExpression (e.g. [1.0, 0.0] as [number, number]): strip the type cast
|
|
171
|
+
if (ts.isAsExpression(expr))
|
|
172
|
+
return exprToLiteral(expr.expression);
|
|
168
173
|
if (ts.isArrayLiteralExpression(expr)) {
|
|
169
174
|
const elements = expr.elements.map(e => {
|
|
170
175
|
const text = e.getText();
|
|
171
|
-
// Ensure float suffix for color array elements
|
|
172
176
|
if (ts.isNumericLiteral(e)) {
|
|
177
|
+
if (isIntegerArrayLiteral(expr)) {
|
|
178
|
+
return text;
|
|
179
|
+
}
|
|
173
180
|
return text.includes('.') ? `${text}f` : `${text}.0f`;
|
|
174
181
|
}
|
|
175
182
|
return text;
|
|
@@ -302,6 +309,10 @@ export function exprToCpp(node, ctx) {
|
|
|
302
309
|
if (ts.isArrayLiteralExpression(node)) {
|
|
303
310
|
return node.elements.map(e => exprToCpp(e, ctx)).join(', ');
|
|
304
311
|
}
|
|
312
|
+
// AsExpression (e.g. expr as Type): strip the type cast, emit inner expression
|
|
313
|
+
if (ts.isAsExpression(node)) {
|
|
314
|
+
return exprToCpp(node.expression, ctx);
|
|
315
|
+
}
|
|
305
316
|
// Fallback: use text representation
|
|
306
317
|
return node.getText();
|
|
307
318
|
}
|
|
@@ -338,6 +349,31 @@ function extractActionStatements(expr, ctx) {
|
|
|
338
349
|
}
|
|
339
350
|
return [code + ';'];
|
|
340
351
|
}
|
|
352
|
+
function lowerItemInteraction(attrs, rawAttrs, ctx) {
|
|
353
|
+
const item = {};
|
|
354
|
+
if (attrs['autoFocus'])
|
|
355
|
+
item.autoFocus = attrs['autoFocus'];
|
|
356
|
+
if (attrs['tooltip'])
|
|
357
|
+
item.tooltip = attrs['tooltip'];
|
|
358
|
+
if (attrs['scrollToHere'])
|
|
359
|
+
item.scrollToHere = attrs['scrollToHere'];
|
|
360
|
+
if (attrs['cursor'])
|
|
361
|
+
item.cursor = attrs['cursor'];
|
|
362
|
+
const callbackAttrs = [
|
|
363
|
+
['onHover', 'onHover'],
|
|
364
|
+
['onActive', 'onActive'],
|
|
365
|
+
['onFocused', 'onFocused'],
|
|
366
|
+
['onClicked', 'onClicked'],
|
|
367
|
+
['onDoubleClicked', 'onDoubleClicked'],
|
|
368
|
+
];
|
|
369
|
+
for (const [field, attrName] of callbackAttrs) {
|
|
370
|
+
const expr = rawAttrs.get(attrName);
|
|
371
|
+
if (expr) {
|
|
372
|
+
item[field] = extractActionStatements(expr, ctx);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
return Object.keys(item).length > 0 ? item : undefined;
|
|
376
|
+
}
|
|
341
377
|
/**
|
|
342
378
|
* Lower a JSX expression (possibly wrapped in parenthesized expr) into IR nodes.
|
|
343
379
|
*/
|
|
@@ -409,11 +445,104 @@ function lowerJsxElement(node, body, ctx) {
|
|
|
409
445
|
if (isHostComponent(name)) {
|
|
410
446
|
const def = HOST_COMPONENTS[name];
|
|
411
447
|
const attrs = getAttributes(node.openingElement.attributes, ctx);
|
|
448
|
+
const rawAttrs = getRawAttributes(node.openingElement.attributes);
|
|
449
|
+
if (name === 'Table') {
|
|
450
|
+
lowerTableElement(node, body, ctx, attrs, rawAttrs, getLoc(node, ctx));
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
if (name === 'TableRow') {
|
|
454
|
+
body.push({ kind: 'begin_table_row', bgColor: attrs['bgColor'], loc: getLoc(node, ctx) });
|
|
455
|
+
for (const child of node.children) {
|
|
456
|
+
lowerJsxChild(child, body, ctx);
|
|
457
|
+
}
|
|
458
|
+
body.push({ kind: 'end_table_row' });
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
if (name === 'TableCell') {
|
|
462
|
+
body.push({ kind: 'begin_table_cell', columnIndex: attrs['columnIndex'], bgColor: attrs['bgColor'], loc: getLoc(node, ctx) });
|
|
463
|
+
for (const child of node.children) {
|
|
464
|
+
lowerJsxChild(child, body, ctx);
|
|
465
|
+
}
|
|
466
|
+
body.push({ kind: 'end_table_cell' });
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
if (name === 'TreeNode') {
|
|
470
|
+
body.push({
|
|
471
|
+
kind: 'begin_tree_node',
|
|
472
|
+
label: attrs['label'] ?? '""',
|
|
473
|
+
defaultOpen: attrs['defaultOpen'],
|
|
474
|
+
forceOpen: attrs['forceOpen'],
|
|
475
|
+
openOnArrow: attrs['openOnArrow'],
|
|
476
|
+
openOnDoubleClick: attrs['openOnDoubleClick'],
|
|
477
|
+
leaf: attrs['leaf'],
|
|
478
|
+
bullet: attrs['bullet'],
|
|
479
|
+
noTreePushOnOpen: attrs['noTreePushOnOpen'],
|
|
480
|
+
item: lowerItemInteraction(attrs, rawAttrs, ctx),
|
|
481
|
+
loc: getLoc(node, ctx),
|
|
482
|
+
});
|
|
483
|
+
for (const child of node.children) {
|
|
484
|
+
lowerJsxChild(child, body, ctx);
|
|
485
|
+
}
|
|
486
|
+
body.push({ kind: 'end_tree_node', noTreePushOnOpen: attrs['noTreePushOnOpen'] });
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
if (name === 'CollapsingHeader') {
|
|
490
|
+
const onClose = rawAttrs.get('onClose');
|
|
491
|
+
const closeInfo = onClose ? lowerParameterizedCallback(onClose, ctx, 'onCloseHeader') : undefined;
|
|
492
|
+
body.push({
|
|
493
|
+
kind: 'begin_collapsing_header',
|
|
494
|
+
label: attrs['label'] ?? '""',
|
|
495
|
+
defaultOpen: attrs['defaultOpen'],
|
|
496
|
+
forceOpen: attrs['forceOpen'],
|
|
497
|
+
closable: attrs['closable'],
|
|
498
|
+
onCloseBody: closeInfo?.bodyCode,
|
|
499
|
+
item: lowerItemInteraction(attrs, rawAttrs, ctx),
|
|
500
|
+
loc: getLoc(node, ctx),
|
|
501
|
+
});
|
|
502
|
+
for (const child of node.children) {
|
|
503
|
+
lowerJsxChild(child, body, ctx);
|
|
504
|
+
}
|
|
505
|
+
body.push({ kind: 'end_collapsing_header', closable: attrs['closable'] });
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
if (name === 'Combo') {
|
|
509
|
+
// Manual combo mode — has children, no items prop
|
|
510
|
+
const label = attrs['label'] ?? '""';
|
|
511
|
+
const preview = attrs['preview'] ?? '""';
|
|
512
|
+
const flagNames = [];
|
|
513
|
+
if (attrs['noArrowButton'] === 'true')
|
|
514
|
+
flagNames.push('ImGuiComboFlags_NoArrowButton');
|
|
515
|
+
if (attrs['noPreview'] === 'true')
|
|
516
|
+
flagNames.push('ImGuiComboFlags_NoPreview');
|
|
517
|
+
if (attrs['heightSmall'] === 'true')
|
|
518
|
+
flagNames.push('ImGuiComboFlags_HeightSmall');
|
|
519
|
+
if (attrs['heightLarge'] === 'true')
|
|
520
|
+
flagNames.push('ImGuiComboFlags_HeightLarge');
|
|
521
|
+
if (attrs['heightRegular'] === 'true')
|
|
522
|
+
flagNames.push('ImGuiComboFlags_HeightRegular');
|
|
523
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
524
|
+
body.push({ kind: 'begin_combo', label, preview, flags: flagNames, width: attrs['width'], style: attrs['style'], item, loc: getLoc(node, ctx) });
|
|
525
|
+
for (const child of node.children) {
|
|
526
|
+
lowerJsxChild(child, body, ctx);
|
|
527
|
+
}
|
|
528
|
+
body.push({ kind: 'end_combo' });
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
531
|
+
if (name === 'ListBox') {
|
|
532
|
+
// Manual ListBox mode — has children, no items prop
|
|
533
|
+
const label = attrs['label'] ?? '""';
|
|
534
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
535
|
+
body.push({ kind: 'begin_list_box', label, width: attrs['width'], height: attrs['height'], style: attrs['style'], item, loc: getLoc(node, ctx) });
|
|
536
|
+
for (const child of node.children) {
|
|
537
|
+
lowerJsxChild(child, body, ctx);
|
|
538
|
+
}
|
|
539
|
+
body.push({ kind: 'end_list_box' });
|
|
540
|
+
return;
|
|
541
|
+
}
|
|
412
542
|
if (def.isContainer) {
|
|
413
543
|
const containerTag = name;
|
|
414
544
|
// Special handling for DragDropTarget — lower onDrop callback with type info
|
|
415
545
|
if (name === 'DragDropTarget') {
|
|
416
|
-
const rawAttrs = getRawAttributes(node.openingElement.attributes);
|
|
417
546
|
const props = {};
|
|
418
547
|
for (const [attrName, expr] of rawAttrs) {
|
|
419
548
|
if (attrName === 'onDrop' && expr && (ts.isArrowFunction(expr) || ts.isFunctionExpression(expr))) {
|
|
@@ -452,8 +581,8 @@ function lowerJsxElement(node, body, ctx) {
|
|
|
452
581
|
body.push({ kind: 'end_container', tag: containerTag });
|
|
453
582
|
return;
|
|
454
583
|
}
|
|
455
|
-
// DockSpace: detect if any child is a MenuBar
|
|
456
|
-
if (containerTag === 'DockSpace') {
|
|
584
|
+
// DockSpace / Window: detect if any child is a MenuBar
|
|
585
|
+
if (containerTag === 'DockSpace' || containerTag === 'Window') {
|
|
457
586
|
const hasMenuBar = node.children.some(c => ts.isJsxElement(c) && ts.isIdentifier(c.openingElement.tagName) && c.openingElement.tagName.text === 'MenuBar');
|
|
458
587
|
if (hasMenuBar)
|
|
459
588
|
attrs['hasMenuBar'] = 'true';
|
|
@@ -505,6 +634,52 @@ function lowerJsxSelfClosing(node, body, ctx) {
|
|
|
505
634
|
const rawAttrs = getRawAttributes(node.attributes);
|
|
506
635
|
const loc = getLoc(node, ctx);
|
|
507
636
|
switch (name) {
|
|
637
|
+
case 'Table': {
|
|
638
|
+
lowerTableSelfClosing(body, ctx, attrs, rawAttrs, loc);
|
|
639
|
+
break;
|
|
640
|
+
}
|
|
641
|
+
case 'TableRow':
|
|
642
|
+
body.push({ kind: 'begin_table_row', bgColor: attrs['bgColor'], loc });
|
|
643
|
+
body.push({ kind: 'end_table_row' });
|
|
644
|
+
break;
|
|
645
|
+
case 'TableCell':
|
|
646
|
+
body.push({ kind: 'begin_table_cell', columnIndex: attrs['columnIndex'], bgColor: attrs['bgColor'], loc });
|
|
647
|
+
body.push({ kind: 'end_table_cell' });
|
|
648
|
+
break;
|
|
649
|
+
case 'TreeNode':
|
|
650
|
+
body.push({
|
|
651
|
+
kind: 'begin_tree_node',
|
|
652
|
+
label: attrs['label'] ?? '""',
|
|
653
|
+
defaultOpen: attrs['defaultOpen'],
|
|
654
|
+
forceOpen: attrs['forceOpen'],
|
|
655
|
+
openOnArrow: attrs['openOnArrow'],
|
|
656
|
+
openOnDoubleClick: attrs['openOnDoubleClick'],
|
|
657
|
+
leaf: attrs['leaf'],
|
|
658
|
+
bullet: attrs['bullet'],
|
|
659
|
+
noTreePushOnOpen: attrs['noTreePushOnOpen'],
|
|
660
|
+
item: lowerItemInteraction(attrs, rawAttrs, ctx),
|
|
661
|
+
loc,
|
|
662
|
+
});
|
|
663
|
+
body.push({ kind: 'end_tree_node', noTreePushOnOpen: attrs['noTreePushOnOpen'] });
|
|
664
|
+
break;
|
|
665
|
+
case 'CollapsingHeader': {
|
|
666
|
+
const closeInfo = rawAttrs.get('onClose') ? lowerParameterizedCallback(rawAttrs.get('onClose'), ctx, 'onCloseHeader') : undefined;
|
|
667
|
+
body.push({
|
|
668
|
+
kind: 'begin_collapsing_header',
|
|
669
|
+
label: attrs['label'] ?? '""',
|
|
670
|
+
defaultOpen: attrs['defaultOpen'],
|
|
671
|
+
forceOpen: attrs['forceOpen'],
|
|
672
|
+
closable: attrs['closable'],
|
|
673
|
+
onCloseBody: closeInfo?.bodyCode,
|
|
674
|
+
item: lowerItemInteraction(attrs, rawAttrs, ctx),
|
|
675
|
+
loc,
|
|
676
|
+
});
|
|
677
|
+
body.push({ kind: 'end_collapsing_header', closable: attrs['closable'] });
|
|
678
|
+
break;
|
|
679
|
+
}
|
|
680
|
+
case 'Shortcut':
|
|
681
|
+
lowerShortcut(attrs, rawAttrs, body, ctx, loc);
|
|
682
|
+
break;
|
|
508
683
|
case 'Button':
|
|
509
684
|
lowerButton(attrs, rawAttrs, body, ctx, loc);
|
|
510
685
|
break;
|
|
@@ -541,22 +716,62 @@ function lowerJsxSelfClosing(node, body, ctx) {
|
|
|
541
716
|
case 'ColorEdit':
|
|
542
717
|
lowerColorEdit(attrs, rawAttrs, body, ctx, loc);
|
|
543
718
|
break;
|
|
719
|
+
case 'ColorEdit3':
|
|
720
|
+
lowerColorEdit3(attrs, rawAttrs, body, ctx, loc);
|
|
721
|
+
break;
|
|
544
722
|
case 'ListBox':
|
|
545
723
|
lowerListBox(attrs, rawAttrs, body, ctx, loc);
|
|
546
724
|
break;
|
|
547
725
|
case 'ProgressBar':
|
|
548
726
|
lowerProgressBar(attrs, rawAttrs, body, ctx, loc);
|
|
549
727
|
break;
|
|
728
|
+
case 'Spacing':
|
|
729
|
+
body.push({ kind: 'spacing', loc });
|
|
730
|
+
break;
|
|
731
|
+
case 'Dummy':
|
|
732
|
+
body.push({
|
|
733
|
+
kind: 'dummy',
|
|
734
|
+
width: attrs['width'] ?? '0',
|
|
735
|
+
height: attrs['height'] ?? '0',
|
|
736
|
+
loc,
|
|
737
|
+
});
|
|
738
|
+
break;
|
|
739
|
+
case 'SameLine':
|
|
740
|
+
body.push({
|
|
741
|
+
kind: 'same_line',
|
|
742
|
+
offset: attrs['offset'] ?? '0',
|
|
743
|
+
spacing: attrs['spacing'] ?? '-1',
|
|
744
|
+
loc,
|
|
745
|
+
});
|
|
746
|
+
break;
|
|
747
|
+
case 'NewLine':
|
|
748
|
+
body.push({ kind: 'new_line', loc });
|
|
749
|
+
break;
|
|
750
|
+
case 'Cursor':
|
|
751
|
+
body.push({
|
|
752
|
+
kind: 'cursor',
|
|
753
|
+
x: attrs['x'] ?? '0',
|
|
754
|
+
y: attrs['y'] ?? '0',
|
|
755
|
+
loc,
|
|
756
|
+
});
|
|
757
|
+
break;
|
|
550
758
|
case 'Tooltip':
|
|
551
759
|
lowerTooltip(attrs, body, ctx, loc);
|
|
552
760
|
break;
|
|
553
761
|
case 'Separator':
|
|
554
762
|
body.push({ kind: 'separator', loc });
|
|
555
763
|
break;
|
|
556
|
-
case '
|
|
557
|
-
|
|
558
|
-
|
|
764
|
+
case 'Bullet':
|
|
765
|
+
body.push({ kind: 'bullet', loc });
|
|
766
|
+
break;
|
|
767
|
+
case 'Text': {
|
|
768
|
+
// Self-closing <Text /> — may have disabled/wrapped/color props
|
|
769
|
+
const disabled = attrs['disabled'] === 'true';
|
|
770
|
+
const wrapped = attrs['wrapped'] === 'true';
|
|
771
|
+
const color = attrs['color'];
|
|
772
|
+
body.push({ kind: 'text', format: '', args: [], color, disabled: disabled || undefined, wrapped: wrapped || undefined, loc });
|
|
559
773
|
break;
|
|
774
|
+
}
|
|
560
775
|
case 'BulletText':
|
|
561
776
|
// Self-closing <BulletText /> - empty bullet
|
|
562
777
|
body.push({ kind: 'bullet_text', format: '', args: [], loc });
|
|
@@ -576,6 +791,9 @@ function lowerJsxSelfClosing(node, body, ctx) {
|
|
|
576
791
|
case 'ColorPicker':
|
|
577
792
|
lowerColorPicker(attrs, rawAttrs, body, ctx, loc);
|
|
578
793
|
break;
|
|
794
|
+
case 'ColorPicker3':
|
|
795
|
+
lowerColorPicker3(attrs, rawAttrs, body, ctx, loc);
|
|
796
|
+
break;
|
|
579
797
|
case 'PlotLines':
|
|
580
798
|
lowerPlotLines(attrs, body, ctx, loc);
|
|
581
799
|
break;
|
|
@@ -619,6 +837,143 @@ function lowerJsxSelfClosing(node, body, ctx) {
|
|
|
619
837
|
body.push({ kind: 'draw_text', pos, text, color, loc });
|
|
620
838
|
break;
|
|
621
839
|
}
|
|
840
|
+
case 'DrawBezierCubic': {
|
|
841
|
+
const p1 = attrs['p1'] ?? '0, 0';
|
|
842
|
+
const p2 = attrs['p2'] ?? '0, 0';
|
|
843
|
+
const p3 = attrs['p3'] ?? '0, 0';
|
|
844
|
+
const p4 = attrs['p4'] ?? '0, 0';
|
|
845
|
+
const color = attrs['color'] ?? '1, 1, 1, 1';
|
|
846
|
+
const thickness = attrs['thickness'] ?? '1.0';
|
|
847
|
+
const segments = attrs['segments'] ?? '0';
|
|
848
|
+
body.push({ kind: 'draw_bezier_cubic', p1, p2, p3, p4, color, thickness, segments, loc });
|
|
849
|
+
break;
|
|
850
|
+
}
|
|
851
|
+
case 'DrawBezierQuadratic': {
|
|
852
|
+
const p1 = attrs['p1'] ?? '0, 0';
|
|
853
|
+
const p2 = attrs['p2'] ?? '0, 0';
|
|
854
|
+
const p3 = attrs['p3'] ?? '0, 0';
|
|
855
|
+
const color = attrs['color'] ?? '1, 1, 1, 1';
|
|
856
|
+
const thickness = attrs['thickness'] ?? '1.0';
|
|
857
|
+
const segments = attrs['segments'] ?? '0';
|
|
858
|
+
body.push({ kind: 'draw_bezier_quadratic', p1, p2, p3, color, thickness, segments, loc });
|
|
859
|
+
break;
|
|
860
|
+
}
|
|
861
|
+
case 'DrawPolyline': {
|
|
862
|
+
const points = attrs['points'] ?? '';
|
|
863
|
+
const color = attrs['color'] ?? '1, 1, 1, 1';
|
|
864
|
+
const thickness = attrs['thickness'] ?? '1.0';
|
|
865
|
+
const closed = attrs['closed'] ?? 'false';
|
|
866
|
+
body.push({ kind: 'draw_polyline', points, color, thickness, closed, loc });
|
|
867
|
+
break;
|
|
868
|
+
}
|
|
869
|
+
case 'DrawConvexPolyFilled': {
|
|
870
|
+
const points = attrs['points'] ?? '';
|
|
871
|
+
const color = attrs['color'] ?? '1, 1, 1, 1';
|
|
872
|
+
body.push({ kind: 'draw_convex_poly_filled', points, color, loc });
|
|
873
|
+
break;
|
|
874
|
+
}
|
|
875
|
+
case 'DrawNgon': {
|
|
876
|
+
const center = attrs['center'] ?? '0, 0';
|
|
877
|
+
const radius = attrs['radius'] ?? '0';
|
|
878
|
+
const color = attrs['color'] ?? '1, 1, 1, 1';
|
|
879
|
+
const numSegments = attrs['numSegments'] ?? '6';
|
|
880
|
+
const thickness = attrs['thickness'] ?? '1.0';
|
|
881
|
+
body.push({ kind: 'draw_ngon', center, radius, color, numSegments, thickness, loc });
|
|
882
|
+
break;
|
|
883
|
+
}
|
|
884
|
+
case 'DrawNgonFilled': {
|
|
885
|
+
const center = attrs['center'] ?? '0, 0';
|
|
886
|
+
const radius = attrs['radius'] ?? '0';
|
|
887
|
+
const color = attrs['color'] ?? '1, 1, 1, 1';
|
|
888
|
+
const numSegments = attrs['numSegments'] ?? '6';
|
|
889
|
+
body.push({ kind: 'draw_ngon_filled', center, radius, color, numSegments, loc });
|
|
890
|
+
break;
|
|
891
|
+
}
|
|
892
|
+
case 'DrawTriangle': {
|
|
893
|
+
const p1 = attrs['p1'] ?? '0, 0';
|
|
894
|
+
const p2 = attrs['p2'] ?? '0, 0';
|
|
895
|
+
const p3 = attrs['p3'] ?? '0, 0';
|
|
896
|
+
const color = attrs['color'] ?? '1, 1, 1, 1';
|
|
897
|
+
const filled = attrs['filled'] ?? 'false';
|
|
898
|
+
const thickness = attrs['thickness'] ?? '1.0';
|
|
899
|
+
body.push({ kind: 'draw_triangle', p1, p2, p3, color, filled, thickness, loc });
|
|
900
|
+
break;
|
|
901
|
+
}
|
|
902
|
+
case 'InputFloat2':
|
|
903
|
+
lowerVectorInput('input_float_n', 2, attrs, rawAttrs, body, ctx, loc);
|
|
904
|
+
break;
|
|
905
|
+
case 'InputFloat3':
|
|
906
|
+
lowerVectorInput('input_float_n', 3, attrs, rawAttrs, body, ctx, loc);
|
|
907
|
+
break;
|
|
908
|
+
case 'InputFloat4':
|
|
909
|
+
lowerVectorInput('input_float_n', 4, attrs, rawAttrs, body, ctx, loc);
|
|
910
|
+
break;
|
|
911
|
+
case 'InputInt2':
|
|
912
|
+
lowerVectorInput('input_int_n', 2, attrs, rawAttrs, body, ctx, loc);
|
|
913
|
+
break;
|
|
914
|
+
case 'InputInt3':
|
|
915
|
+
lowerVectorInput('input_int_n', 3, attrs, rawAttrs, body, ctx, loc);
|
|
916
|
+
break;
|
|
917
|
+
case 'InputInt4':
|
|
918
|
+
lowerVectorInput('input_int_n', 4, attrs, rawAttrs, body, ctx, loc);
|
|
919
|
+
break;
|
|
920
|
+
case 'DragFloat2':
|
|
921
|
+
lowerVectorInput('drag_float_n', 2, attrs, rawAttrs, body, ctx, loc);
|
|
922
|
+
break;
|
|
923
|
+
case 'DragFloat3':
|
|
924
|
+
lowerVectorInput('drag_float_n', 3, attrs, rawAttrs, body, ctx, loc);
|
|
925
|
+
break;
|
|
926
|
+
case 'DragFloat4':
|
|
927
|
+
lowerVectorInput('drag_float_n', 4, attrs, rawAttrs, body, ctx, loc);
|
|
928
|
+
break;
|
|
929
|
+
case 'DragInt2':
|
|
930
|
+
lowerVectorInput('drag_int_n', 2, attrs, rawAttrs, body, ctx, loc);
|
|
931
|
+
break;
|
|
932
|
+
case 'DragInt3':
|
|
933
|
+
lowerVectorInput('drag_int_n', 3, attrs, rawAttrs, body, ctx, loc);
|
|
934
|
+
break;
|
|
935
|
+
case 'DragInt4':
|
|
936
|
+
lowerVectorInput('drag_int_n', 4, attrs, rawAttrs, body, ctx, loc);
|
|
937
|
+
break;
|
|
938
|
+
case 'SliderFloat2':
|
|
939
|
+
lowerVectorInput('slider_float_n', 2, attrs, rawAttrs, body, ctx, loc);
|
|
940
|
+
break;
|
|
941
|
+
case 'SliderFloat3':
|
|
942
|
+
lowerVectorInput('slider_float_n', 3, attrs, rawAttrs, body, ctx, loc);
|
|
943
|
+
break;
|
|
944
|
+
case 'SliderFloat4':
|
|
945
|
+
lowerVectorInput('slider_float_n', 4, attrs, rawAttrs, body, ctx, loc);
|
|
946
|
+
break;
|
|
947
|
+
case 'SliderInt2':
|
|
948
|
+
lowerVectorInput('slider_int_n', 2, attrs, rawAttrs, body, ctx, loc);
|
|
949
|
+
break;
|
|
950
|
+
case 'SliderInt3':
|
|
951
|
+
lowerVectorInput('slider_int_n', 3, attrs, rawAttrs, body, ctx, loc);
|
|
952
|
+
break;
|
|
953
|
+
case 'SliderInt4':
|
|
954
|
+
lowerVectorInput('slider_int_n', 4, attrs, rawAttrs, body, ctx, loc);
|
|
955
|
+
break;
|
|
956
|
+
case 'VSliderFloat':
|
|
957
|
+
lowerVSliderFloat(attrs, rawAttrs, body, ctx, loc);
|
|
958
|
+
break;
|
|
959
|
+
case 'VSliderInt':
|
|
960
|
+
lowerVSliderInt(attrs, rawAttrs, body, ctx, loc);
|
|
961
|
+
break;
|
|
962
|
+
case 'SliderAngle':
|
|
963
|
+
lowerSliderAngle(attrs, rawAttrs, body, ctx, loc);
|
|
964
|
+
break;
|
|
965
|
+
case 'SmallButton':
|
|
966
|
+
lowerSmallButton(attrs, rawAttrs, body, ctx, loc);
|
|
967
|
+
break;
|
|
968
|
+
case 'ArrowButton':
|
|
969
|
+
lowerArrowButton(attrs, rawAttrs, body, ctx, loc);
|
|
970
|
+
break;
|
|
971
|
+
case 'InvisibleButton':
|
|
972
|
+
lowerInvisibleButton(attrs, rawAttrs, body, ctx, loc);
|
|
973
|
+
break;
|
|
974
|
+
case 'ImageButton':
|
|
975
|
+
lowerImageButton(attrs, rawAttrs, body, ctx, loc);
|
|
976
|
+
break;
|
|
622
977
|
default:
|
|
623
978
|
// Container self-closing (e.g., <Window title="X"/>)
|
|
624
979
|
if (HOST_COMPONENTS[name]?.isContainer) {
|
|
@@ -638,14 +993,63 @@ function lowerButton(attrs, rawAttrs, body, ctx, loc) {
|
|
|
638
993
|
}
|
|
639
994
|
const disabled = attrs['disabled'] === 'true' ? true : undefined;
|
|
640
995
|
const style = attrs['style'];
|
|
641
|
-
|
|
996
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
997
|
+
body.push({ kind: 'button', title, action, disabled, style, item, loc });
|
|
998
|
+
}
|
|
999
|
+
function lowerSmallButton(attrs, rawAttrs, body, ctx, loc) {
|
|
1000
|
+
const label = attrs['label'] ?? '""';
|
|
1001
|
+
const onPressExpr = rawAttrs.get('onPress');
|
|
1002
|
+
let action = [];
|
|
1003
|
+
if (onPressExpr) {
|
|
1004
|
+
action = extractActionStatements(onPressExpr, ctx);
|
|
1005
|
+
}
|
|
1006
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1007
|
+
body.push({ kind: 'small_button', label, action, item, loc });
|
|
1008
|
+
}
|
|
1009
|
+
function lowerArrowButton(attrs, rawAttrs, body, ctx, loc) {
|
|
1010
|
+
const id = attrs['id'] ?? '""';
|
|
1011
|
+
const direction = attrs['direction'] ?? '"left"';
|
|
1012
|
+
const onPressExpr = rawAttrs.get('onPress');
|
|
1013
|
+
let action = [];
|
|
1014
|
+
if (onPressExpr) {
|
|
1015
|
+
action = extractActionStatements(onPressExpr, ctx);
|
|
1016
|
+
}
|
|
1017
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1018
|
+
body.push({ kind: 'arrow_button', id, direction, action, item, loc });
|
|
1019
|
+
}
|
|
1020
|
+
function lowerInvisibleButton(attrs, rawAttrs, body, ctx, loc) {
|
|
1021
|
+
const id = attrs['id'] ?? '""';
|
|
1022
|
+
const width = attrs['width'] ?? '0';
|
|
1023
|
+
const height = attrs['height'] ?? '0';
|
|
1024
|
+
const onPressExpr = rawAttrs.get('onPress');
|
|
1025
|
+
let action = [];
|
|
1026
|
+
if (onPressExpr) {
|
|
1027
|
+
action = extractActionStatements(onPressExpr, ctx);
|
|
1028
|
+
}
|
|
1029
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1030
|
+
body.push({ kind: 'invisible_button', id, width, height, action, item, loc });
|
|
1031
|
+
}
|
|
1032
|
+
function lowerImageButton(attrs, rawAttrs, body, ctx, loc) {
|
|
1033
|
+
const id = attrs['id'] ?? '""';
|
|
1034
|
+
const src = attrs['src'] ?? '""';
|
|
1035
|
+
const width = attrs['width'];
|
|
1036
|
+
const height = attrs['height'];
|
|
1037
|
+
const onPressExpr = rawAttrs.get('onPress');
|
|
1038
|
+
let action = [];
|
|
1039
|
+
if (onPressExpr) {
|
|
1040
|
+
action = extractActionStatements(onPressExpr, ctx);
|
|
1041
|
+
}
|
|
1042
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1043
|
+
body.push({ kind: 'image_button', id, src, width, height, action, item, loc });
|
|
642
1044
|
}
|
|
643
1045
|
function lowerTextInput(attrs, rawAttrs, body, ctx, loc) {
|
|
644
1046
|
const label = attrs['label'] ?? '""';
|
|
645
1047
|
const bufferIndex = ctx.bufferIndex++;
|
|
1048
|
+
const width = attrs['width'];
|
|
646
1049
|
const style = attrs['style'];
|
|
647
1050
|
const { stateVar, valueExpr, onChangeExpr, directBind } = lowerValueOnChange(rawAttrs, ctx);
|
|
648
|
-
|
|
1051
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1052
|
+
body.push({ kind: 'text_input', label, bufferIndex, stateVar: stateVar, valueExpr, onChangeExpr, directBind, width, style, item, loc });
|
|
649
1053
|
}
|
|
650
1054
|
function lowerCheckbox(attrs, rawAttrs, body, ctx, loc) {
|
|
651
1055
|
const label = attrs['label'] ?? '""';
|
|
@@ -688,7 +1092,8 @@ function lowerCheckbox(attrs, rawAttrs, body, ctx, loc) {
|
|
|
688
1092
|
}
|
|
689
1093
|
}
|
|
690
1094
|
const style = attrs['style'];
|
|
691
|
-
|
|
1095
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1096
|
+
body.push({ kind: 'checkbox', label, stateVar, valueExpr: valueExprStr, onChangeExpr: onChangeExprStr, directBind, style, item, loc });
|
|
692
1097
|
}
|
|
693
1098
|
function lowerMenuItem(attrs, rawAttrs, body, ctx, loc) {
|
|
694
1099
|
const label = attrs['label'] ?? '""';
|
|
@@ -698,11 +1103,26 @@ function lowerMenuItem(attrs, rawAttrs, body, ctx, loc) {
|
|
|
698
1103
|
if (onPressExpr) {
|
|
699
1104
|
action = extractActionStatements(onPressExpr, ctx);
|
|
700
1105
|
}
|
|
701
|
-
|
|
1106
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1107
|
+
body.push({ kind: 'menu_item', label, shortcut, action, item, loc });
|
|
1108
|
+
}
|
|
1109
|
+
function lowerShortcut(attrs, rawAttrs, body, ctx, loc) {
|
|
1110
|
+
const keys = attrs['keys'] ?? '""';
|
|
1111
|
+
const onPressExpr = rawAttrs.get('onPress');
|
|
1112
|
+
let action = [];
|
|
1113
|
+
if (onPressExpr) {
|
|
1114
|
+
action = extractActionStatements(onPressExpr, ctx);
|
|
1115
|
+
}
|
|
1116
|
+
body.push({ kind: 'shortcut', keys, action, loc });
|
|
702
1117
|
}
|
|
703
1118
|
function lowerTextElement(node, body, ctx, loc) {
|
|
704
1119
|
let format = '';
|
|
705
1120
|
const args = [];
|
|
1121
|
+
// Extract Text props
|
|
1122
|
+
const attrs = getAttributes(node.openingElement.attributes, ctx);
|
|
1123
|
+
const color = attrs['color'];
|
|
1124
|
+
const disabled = attrs['disabled'] === 'true';
|
|
1125
|
+
const wrapped = attrs['wrapped'] === 'true';
|
|
706
1126
|
for (const child of node.children) {
|
|
707
1127
|
if (ts.isJsxText(child)) {
|
|
708
1128
|
// Collapse whitespace (newlines, tabs, runs of spaces) into single spaces,
|
|
@@ -759,7 +1179,7 @@ function lowerTextElement(node, body, ctx, loc) {
|
|
|
759
1179
|
}
|
|
760
1180
|
}
|
|
761
1181
|
}
|
|
762
|
-
body.push({ kind: 'text', format, args, loc });
|
|
1182
|
+
body.push({ kind: 'text', format, args, color, disabled: disabled || undefined, wrapped: wrapped || undefined, loc });
|
|
763
1183
|
}
|
|
764
1184
|
/**
|
|
765
1185
|
* Check if an expression will produce a const char* in C++ (not std::string).
|
|
@@ -781,6 +1201,8 @@ function inferExprType(expr, ctx) {
|
|
|
781
1201
|
return 'string';
|
|
782
1202
|
if (expr.kind === ts.SyntaxKind.TrueKeyword || expr.kind === ts.SyntaxKind.FalseKeyword)
|
|
783
1203
|
return 'bool';
|
|
1204
|
+
if (ts.isArrayLiteralExpression(expr))
|
|
1205
|
+
return isIntegerArrayLiteral(expr) ? 'int_array' : 'color';
|
|
784
1206
|
// Identifier: check state var type
|
|
785
1207
|
if (ts.isIdentifier(expr)) {
|
|
786
1208
|
const slot = ctx.stateVars.get(expr.text);
|
|
@@ -796,8 +1218,30 @@ function inferExprType(expr, ctx) {
|
|
|
796
1218
|
// If accessing a direct field of the props param, look up its type
|
|
797
1219
|
if (ctx.propsParam && ts.isIdentifier(expr.expression) && expr.expression.text === ctx.propsParam) {
|
|
798
1220
|
const ft = ctx.propsFieldTypes.get(prop);
|
|
799
|
-
if (ft && ft !== 'callback')
|
|
800
|
-
|
|
1221
|
+
if (ft && ft !== 'callback') {
|
|
1222
|
+
if (ft === 'int' || ft === 'float' || ft === 'bool' || ft === 'string' || ft === 'color' || ft === 'int_array') {
|
|
1223
|
+
return ft;
|
|
1224
|
+
}
|
|
1225
|
+
return 'string';
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
// Nested access: props.data.field — resolve through external interfaces
|
|
1229
|
+
if (ctx.propsParam && ctx.externalInterfaces && ts.isPropertyAccessExpression(expr.expression)) {
|
|
1230
|
+
const mid = expr.expression;
|
|
1231
|
+
if (ts.isIdentifier(mid.expression) && mid.expression.text === ctx.propsParam) {
|
|
1232
|
+
const midType = ctx.propsFieldTypes.get(mid.name.text);
|
|
1233
|
+
if (midType && midType !== 'callback') {
|
|
1234
|
+
const iface = ctx.externalInterfaces.get(midType);
|
|
1235
|
+
if (iface) {
|
|
1236
|
+
const fieldType = iface.get(prop);
|
|
1237
|
+
if (fieldType && fieldType !== 'callback') {
|
|
1238
|
+
if (fieldType === 'int' || fieldType === 'float' || fieldType === 'bool' || fieldType === 'string' || fieldType === 'color' || fieldType === 'int_array') {
|
|
1239
|
+
return fieldType;
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
801
1245
|
}
|
|
802
1246
|
return 'string';
|
|
803
1247
|
}
|
|
@@ -881,6 +1325,113 @@ function lowerCustomComponent(name, attributes, body, ctx, loc) {
|
|
|
881
1325
|
loc,
|
|
882
1326
|
});
|
|
883
1327
|
}
|
|
1328
|
+
function lowerParameterizedCallback(expr, ctx, defaultParamName) {
|
|
1329
|
+
if (ts.isArrowFunction(expr) || ts.isFunctionExpression(expr)) {
|
|
1330
|
+
const param = expr.parameters[0];
|
|
1331
|
+
const paramName = param && ts.isIdentifier(param.name) ? param.name.text : defaultParamName;
|
|
1332
|
+
const bodyCode = ts.isBlock(expr.body)
|
|
1333
|
+
? expr.body.statements.map(s => stmtToCpp(s, ctx)).join(' ')
|
|
1334
|
+
: `${exprToCpp(expr.body, ctx)};`;
|
|
1335
|
+
return { paramName, bodyCode };
|
|
1336
|
+
}
|
|
1337
|
+
const callbackExpr = exprToCpp(expr, ctx);
|
|
1338
|
+
const bodyCode = (ts.isIdentifier(expr) || ts.isPropertyAccessExpression(expr))
|
|
1339
|
+
? `${callbackExpr}(${defaultParamName});`
|
|
1340
|
+
: `${callbackExpr};`;
|
|
1341
|
+
return { paramName: defaultParamName, bodyCode };
|
|
1342
|
+
}
|
|
1343
|
+
function lowerTableColumns(expr, ctx) {
|
|
1344
|
+
if (!expr || !ts.isArrayLiteralExpression(expr)) {
|
|
1345
|
+
return [];
|
|
1346
|
+
}
|
|
1347
|
+
const columns = [];
|
|
1348
|
+
for (const element of expr.elements) {
|
|
1349
|
+
if (ts.isStringLiteral(element) || ts.isNoSubstitutionTemplateLiteral(element)) {
|
|
1350
|
+
columns.push({ label: JSON.stringify(element.text) });
|
|
1351
|
+
continue;
|
|
1352
|
+
}
|
|
1353
|
+
if (ts.isObjectLiteralExpression(element)) {
|
|
1354
|
+
const column = { label: '""' };
|
|
1355
|
+
for (const prop of element.properties) {
|
|
1356
|
+
if (!ts.isPropertyAssignment(prop) || !ts.isIdentifier(prop.name))
|
|
1357
|
+
continue;
|
|
1358
|
+
const propName = prop.name.text;
|
|
1359
|
+
const value = exprToCpp(prop.initializer, ctx);
|
|
1360
|
+
switch (propName) {
|
|
1361
|
+
case 'label':
|
|
1362
|
+
column.label = value;
|
|
1363
|
+
break;
|
|
1364
|
+
case 'defaultHide':
|
|
1365
|
+
column.defaultHide = value;
|
|
1366
|
+
break;
|
|
1367
|
+
case 'preferSortAscending':
|
|
1368
|
+
column.preferSortAscending = value;
|
|
1369
|
+
break;
|
|
1370
|
+
case 'preferSortDescending':
|
|
1371
|
+
column.preferSortDescending = value;
|
|
1372
|
+
break;
|
|
1373
|
+
case 'noResize':
|
|
1374
|
+
column.noResize = value;
|
|
1375
|
+
break;
|
|
1376
|
+
case 'fixedWidth':
|
|
1377
|
+
column.fixedWidth = value;
|
|
1378
|
+
break;
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
columns.push(column);
|
|
1382
|
+
continue;
|
|
1383
|
+
}
|
|
1384
|
+
columns.push({ label: exprToCpp(element, ctx) });
|
|
1385
|
+
}
|
|
1386
|
+
return columns;
|
|
1387
|
+
}
|
|
1388
|
+
function lowerTableSelfClosing(body, ctx, attrs, rawAttrs, loc) {
|
|
1389
|
+
const onSort = rawAttrs.get('onSort') ?? null;
|
|
1390
|
+
const sortInfo = onSort ? lowerParameterizedCallback(onSort, ctx, 'tableSortSpecs') : undefined;
|
|
1391
|
+
body.push({
|
|
1392
|
+
kind: 'begin_table',
|
|
1393
|
+
columns: lowerTableColumns(rawAttrs.get('columns') ?? null, ctx),
|
|
1394
|
+
sortable: attrs['sortable'],
|
|
1395
|
+
hideable: attrs['hideable'],
|
|
1396
|
+
multiSortable: attrs['multiSortable'],
|
|
1397
|
+
noClip: attrs['noClip'],
|
|
1398
|
+
padOuterX: attrs['padOuterX'],
|
|
1399
|
+
scrollX: attrs['scrollX'],
|
|
1400
|
+
scrollY: attrs['scrollY'],
|
|
1401
|
+
noBorders: attrs['noBorders'],
|
|
1402
|
+
noRowBg: attrs['noRowBg'],
|
|
1403
|
+
onSortBody: sortInfo?.bodyCode,
|
|
1404
|
+
onSortParam: sortInfo?.paramName,
|
|
1405
|
+
style: attrs['style'],
|
|
1406
|
+
loc,
|
|
1407
|
+
});
|
|
1408
|
+
body.push({ kind: 'end_table' });
|
|
1409
|
+
}
|
|
1410
|
+
function lowerTableElement(node, body, ctx, attrs, rawAttrs, loc) {
|
|
1411
|
+
const onSort = rawAttrs.get('onSort') ?? null;
|
|
1412
|
+
const sortInfo = onSort ? lowerParameterizedCallback(onSort, ctx, 'tableSortSpecs') : undefined;
|
|
1413
|
+
body.push({
|
|
1414
|
+
kind: 'begin_table',
|
|
1415
|
+
columns: lowerTableColumns(rawAttrs.get('columns') ?? null, ctx),
|
|
1416
|
+
sortable: attrs['sortable'],
|
|
1417
|
+
hideable: attrs['hideable'],
|
|
1418
|
+
multiSortable: attrs['multiSortable'],
|
|
1419
|
+
noClip: attrs['noClip'],
|
|
1420
|
+
padOuterX: attrs['padOuterX'],
|
|
1421
|
+
scrollX: attrs['scrollX'],
|
|
1422
|
+
scrollY: attrs['scrollY'],
|
|
1423
|
+
noBorders: attrs['noBorders'],
|
|
1424
|
+
noRowBg: attrs['noRowBg'],
|
|
1425
|
+
onSortBody: sortInfo?.bodyCode,
|
|
1426
|
+
onSortParam: sortInfo?.paramName,
|
|
1427
|
+
style: attrs['style'],
|
|
1428
|
+
loc,
|
|
1429
|
+
});
|
|
1430
|
+
for (const child of node.children) {
|
|
1431
|
+
lowerJsxChild(child, body, ctx);
|
|
1432
|
+
}
|
|
1433
|
+
body.push({ kind: 'end_table' });
|
|
1434
|
+
}
|
|
884
1435
|
function lowerNativeWidget(name, attributes, body, ctx, loc) {
|
|
885
1436
|
const props = {};
|
|
886
1437
|
const callbackProps = {};
|
|
@@ -1032,31 +1583,68 @@ function lowerSelectable(attrs, rawAttrs, body, ctx, loc) {
|
|
|
1032
1583
|
action = extractActionStatements(onSelectExpr, ctx);
|
|
1033
1584
|
}
|
|
1034
1585
|
const style = attrs['style'];
|
|
1035
|
-
|
|
1586
|
+
const selectionIndex = attrs['selectionIndex'];
|
|
1587
|
+
const flagParts = [];
|
|
1588
|
+
if (attrs['spanAllColumns'] === 'true')
|
|
1589
|
+
flagParts.push('ImGuiSelectableFlags_SpanAllColumns');
|
|
1590
|
+
if (attrs['allowDoubleClick'] === 'true')
|
|
1591
|
+
flagParts.push('ImGuiSelectableFlags_AllowDoubleClick');
|
|
1592
|
+
if (attrs['dontClosePopups'] === 'true')
|
|
1593
|
+
flagParts.push('ImGuiSelectableFlags_DontClosePopups');
|
|
1594
|
+
const flags = flagParts.length > 0 ? flagParts.join(' | ') : undefined;
|
|
1595
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1596
|
+
body.push({ kind: 'selectable', label, selected, action, selectionIndex, flags, style, item, loc });
|
|
1036
1597
|
}
|
|
1037
1598
|
function lowerRadio(attrs, rawAttrs, body, ctx, loc) {
|
|
1038
1599
|
const label = attrs['label'] ?? '""';
|
|
1039
1600
|
const index = attrs['index'] ?? '0';
|
|
1040
1601
|
const style = attrs['style'];
|
|
1041
1602
|
const { stateVar, valueExpr, onChangeExpr, directBind } = lowerValueOnChange(rawAttrs, ctx);
|
|
1042
|
-
|
|
1603
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1604
|
+
body.push({ kind: 'radio', label, stateVar, valueExpr, onChangeExpr, directBind, index, style, item, loc });
|
|
1043
1605
|
}
|
|
1044
1606
|
function lowerInputTextMultiline(attrs, rawAttrs, body, ctx, loc) {
|
|
1045
1607
|
const label = attrs['label'] ?? '""';
|
|
1046
1608
|
const bufferIndex = ctx.bufferIndex++;
|
|
1609
|
+
const width = attrs['width'];
|
|
1610
|
+
const style = attrs['style'];
|
|
1611
|
+
const { stateVar, valueExpr, onChangeExpr, directBind } = lowerValueOnChange(rawAttrs, ctx);
|
|
1612
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1613
|
+
body.push({ kind: 'input_text_multiline', label, bufferIndex, stateVar, valueExpr, onChangeExpr, directBind, width, style, item, loc });
|
|
1614
|
+
}
|
|
1615
|
+
function lowerColorPicker(attrs, rawAttrs, body, ctx, loc) {
|
|
1616
|
+
const label = attrs['label'] ?? '""';
|
|
1617
|
+
const style = attrs['style'];
|
|
1047
1618
|
let stateVar = '';
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1619
|
+
let valueExpr;
|
|
1620
|
+
let onChangeExpr;
|
|
1621
|
+
let directBind;
|
|
1622
|
+
const valueRaw = rawAttrs.get('value');
|
|
1623
|
+
if (valueRaw && ts.isIdentifier(valueRaw) && ctx.stateVars.has(valueRaw.text)) {
|
|
1624
|
+
stateVar = valueRaw.text;
|
|
1625
|
+
}
|
|
1626
|
+
else if (valueRaw) {
|
|
1627
|
+
valueExpr = exprToCpp(valueRaw, ctx);
|
|
1628
|
+
const onChangeRaw = rawAttrs.get('onChange');
|
|
1629
|
+
if (onChangeRaw) {
|
|
1630
|
+
onChangeExpr = exprToCpp(onChangeRaw, ctx);
|
|
1631
|
+
if (onChangeExpr.startsWith('[')) {
|
|
1632
|
+
onChangeExpr = `(${onChangeExpr})()`;
|
|
1633
|
+
}
|
|
1634
|
+
else if (!onChangeExpr.endsWith(')')) {
|
|
1635
|
+
onChangeExpr = `${onChangeExpr}()`;
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
else if (valueRaw && ts.isPropertyAccessExpression(valueRaw)) {
|
|
1639
|
+
directBind = true;
|
|
1053
1640
|
}
|
|
1054
1641
|
}
|
|
1055
|
-
const
|
|
1056
|
-
body.push({ kind: '
|
|
1642
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1643
|
+
body.push({ kind: 'color_picker', label, stateVar, valueExpr, onChangeExpr, directBind, style, item, loc });
|
|
1057
1644
|
}
|
|
1058
|
-
function
|
|
1645
|
+
function lowerColorPicker3(attrs, rawAttrs, body, ctx, loc) {
|
|
1059
1646
|
const label = attrs['label'] ?? '""';
|
|
1647
|
+
const width = attrs['width'];
|
|
1060
1648
|
const style = attrs['style'];
|
|
1061
1649
|
let stateVar = '';
|
|
1062
1650
|
let valueExpr;
|
|
@@ -1082,7 +1670,8 @@ function lowerColorPicker(attrs, rawAttrs, body, ctx, loc) {
|
|
|
1082
1670
|
directBind = true;
|
|
1083
1671
|
}
|
|
1084
1672
|
}
|
|
1085
|
-
|
|
1673
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1674
|
+
body.push({ kind: 'color_picker3', label, stateVar, valueExpr, onChangeExpr, directBind, width, style, item, loc });
|
|
1086
1675
|
}
|
|
1087
1676
|
function lowerPlotLines(attrs, body, ctx, loc) {
|
|
1088
1677
|
const label = attrs['label'] ?? '""';
|
|
@@ -1150,6 +1739,49 @@ function getRawAttributes(attributes) {
|
|
|
1150
1739
|
}
|
|
1151
1740
|
return result;
|
|
1152
1741
|
}
|
|
1742
|
+
function lowerVectorInput(family, count, attrs, rawAttrs, body, ctx, loc) {
|
|
1743
|
+
const label = attrs['label'] ?? '""';
|
|
1744
|
+
const width = attrs['width'];
|
|
1745
|
+
const style = attrs['style'];
|
|
1746
|
+
const valueRaw = rawAttrs.get('value');
|
|
1747
|
+
let stateVar = '';
|
|
1748
|
+
let valueExpr;
|
|
1749
|
+
let directBind;
|
|
1750
|
+
let onChangeExpr;
|
|
1751
|
+
if (valueRaw && ts.isIdentifier(valueRaw) && ctx.stateVars.has(valueRaw.text)) {
|
|
1752
|
+
stateVar = valueRaw.text;
|
|
1753
|
+
}
|
|
1754
|
+
else if (valueRaw) {
|
|
1755
|
+
valueExpr = exprToCpp(valueRaw, ctx);
|
|
1756
|
+
const onChangeRaw = rawAttrs.get('onChange');
|
|
1757
|
+
if (onChangeRaw) {
|
|
1758
|
+
onChangeExpr = exprToCpp(onChangeRaw, ctx);
|
|
1759
|
+
if (onChangeExpr.startsWith('[')) {
|
|
1760
|
+
onChangeExpr = `(${onChangeExpr})()`;
|
|
1761
|
+
}
|
|
1762
|
+
else if (!onChangeExpr.endsWith(')')) {
|
|
1763
|
+
onChangeExpr = `${onChangeExpr}()`;
|
|
1764
|
+
}
|
|
1765
|
+
}
|
|
1766
|
+
else if (ts.isPropertyAccessExpression(valueRaw)) {
|
|
1767
|
+
directBind = true;
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1770
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1771
|
+
const base = { kind: family, label, count, stateVar, valueExpr, directBind, onChangeExpr, width, style, item, loc };
|
|
1772
|
+
if (family === 'drag_float_n' || family === 'drag_int_n') {
|
|
1773
|
+
base.speed = attrs['speed'] ?? '1.0f';
|
|
1774
|
+
}
|
|
1775
|
+
if (family === 'slider_float_n') {
|
|
1776
|
+
base.min = attrs['min'] ?? '0.0f';
|
|
1777
|
+
base.max = attrs['max'] ?? '1.0f';
|
|
1778
|
+
}
|
|
1779
|
+
if (family === 'slider_int_n') {
|
|
1780
|
+
base.min = attrs['min'] ?? '0';
|
|
1781
|
+
base.max = attrs['max'] ?? '100';
|
|
1782
|
+
}
|
|
1783
|
+
body.push(base);
|
|
1784
|
+
}
|
|
1153
1785
|
function lowerValueOnChange(rawAttrs, ctx) {
|
|
1154
1786
|
let stateVar = '';
|
|
1155
1787
|
let valueExpr;
|
|
@@ -1185,53 +1817,100 @@ function lowerSliderFloat(attrs, rawAttrs, body, ctx, loc) {
|
|
|
1185
1817
|
const label = attrs['label'] ?? '""';
|
|
1186
1818
|
const min = attrs['min'] ?? '0.0f';
|
|
1187
1819
|
const max = attrs['max'] ?? '1.0f';
|
|
1820
|
+
const width = attrs['width'];
|
|
1188
1821
|
const style = attrs['style'];
|
|
1189
1822
|
const { stateVar, valueExpr, onChangeExpr, directBind } = lowerValueOnChange(rawAttrs, ctx);
|
|
1190
|
-
|
|
1823
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1824
|
+
body.push({ kind: 'slider_float', label, stateVar, valueExpr, onChangeExpr, directBind, min, max, width, style, item, loc });
|
|
1191
1825
|
}
|
|
1192
1826
|
function lowerSliderInt(attrs, rawAttrs, body, ctx, loc) {
|
|
1193
1827
|
const label = attrs['label'] ?? '""';
|
|
1194
1828
|
const min = attrs['min'] ?? '0';
|
|
1195
1829
|
const max = attrs['max'] ?? '100';
|
|
1830
|
+
const width = attrs['width'];
|
|
1831
|
+
const style = attrs['style'];
|
|
1832
|
+
const { stateVar, valueExpr, onChangeExpr, directBind } = lowerValueOnChange(rawAttrs, ctx);
|
|
1833
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1834
|
+
body.push({ kind: 'slider_int', label, stateVar, valueExpr, onChangeExpr, directBind, min, max, width, style, item, loc });
|
|
1835
|
+
}
|
|
1836
|
+
function lowerVSliderFloat(attrs, rawAttrs, body, ctx, loc) {
|
|
1837
|
+
const label = attrs['label'] ?? '""';
|
|
1838
|
+
const width = attrs['width'] ?? '20';
|
|
1839
|
+
const height = attrs['height'] ?? '100';
|
|
1840
|
+
const min = attrs['min'] ?? '0.0f';
|
|
1841
|
+
const max = attrs['max'] ?? '1.0f';
|
|
1842
|
+
const style = attrs['style'];
|
|
1843
|
+
const { stateVar, valueExpr, onChangeExpr, directBind } = lowerValueOnChange(rawAttrs, ctx);
|
|
1844
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1845
|
+
body.push({ kind: 'vslider_float', label, stateVar, valueExpr, onChangeExpr, directBind, width, height, min, max, style, item, loc });
|
|
1846
|
+
}
|
|
1847
|
+
function lowerVSliderInt(attrs, rawAttrs, body, ctx, loc) {
|
|
1848
|
+
const label = attrs['label'] ?? '""';
|
|
1849
|
+
const width = attrs['width'] ?? '20';
|
|
1850
|
+
const height = attrs['height'] ?? '100';
|
|
1851
|
+
const min = attrs['min'] ?? '0';
|
|
1852
|
+
const max = attrs['max'] ?? '100';
|
|
1853
|
+
const style = attrs['style'];
|
|
1854
|
+
const { stateVar, valueExpr, onChangeExpr, directBind } = lowerValueOnChange(rawAttrs, ctx);
|
|
1855
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1856
|
+
body.push({ kind: 'vslider_int', label, stateVar, valueExpr, onChangeExpr, directBind, width, height, min, max, style, item, loc });
|
|
1857
|
+
}
|
|
1858
|
+
function lowerSliderAngle(attrs, rawAttrs, body, ctx, loc) {
|
|
1859
|
+
const label = attrs['label'] ?? '""';
|
|
1860
|
+
const min = attrs['min'] ?? '-360.0f';
|
|
1861
|
+
const max = attrs['max'] ?? '360.0f';
|
|
1862
|
+
const width = attrs['width'];
|
|
1196
1863
|
const style = attrs['style'];
|
|
1197
1864
|
const { stateVar, valueExpr, onChangeExpr, directBind } = lowerValueOnChange(rawAttrs, ctx);
|
|
1198
|
-
|
|
1865
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1866
|
+
body.push({ kind: 'slider_angle', label, stateVar, valueExpr, onChangeExpr, directBind, min, max, width, style, item, loc });
|
|
1199
1867
|
}
|
|
1200
1868
|
function lowerDragFloat(attrs, rawAttrs, body, ctx, loc) {
|
|
1201
1869
|
const label = attrs['label'] ?? '""';
|
|
1202
1870
|
const speed = attrs['speed'] ?? '1.0f';
|
|
1871
|
+
const width = attrs['width'];
|
|
1203
1872
|
const style = attrs['style'];
|
|
1204
1873
|
const { stateVar, valueExpr, onChangeExpr, directBind } = lowerValueOnChange(rawAttrs, ctx);
|
|
1205
|
-
|
|
1874
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1875
|
+
body.push({ kind: 'drag_float', label, stateVar, valueExpr, onChangeExpr, directBind, speed, width, style, item, loc });
|
|
1206
1876
|
}
|
|
1207
1877
|
function lowerDragInt(attrs, rawAttrs, body, ctx, loc) {
|
|
1208
1878
|
const label = attrs['label'] ?? '""';
|
|
1209
1879
|
const speed = attrs['speed'] ?? '1.0f';
|
|
1880
|
+
const width = attrs['width'];
|
|
1210
1881
|
const style = attrs['style'];
|
|
1211
1882
|
const { stateVar, valueExpr, onChangeExpr, directBind } = lowerValueOnChange(rawAttrs, ctx);
|
|
1212
|
-
|
|
1883
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1884
|
+
body.push({ kind: 'drag_int', label, stateVar, valueExpr, onChangeExpr, directBind, speed, width, style, item, loc });
|
|
1213
1885
|
}
|
|
1214
1886
|
function lowerCombo(attrs, rawAttrs, body, ctx, loc) {
|
|
1215
1887
|
const label = attrs['label'] ?? '""';
|
|
1216
1888
|
const items = attrs['items'] ?? '';
|
|
1889
|
+
const width = attrs['width'];
|
|
1217
1890
|
const style = attrs['style'];
|
|
1218
1891
|
const { stateVar, valueExpr, onChangeExpr, directBind } = lowerValueOnChange(rawAttrs, ctx);
|
|
1219
|
-
|
|
1892
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1893
|
+
body.push({ kind: 'combo', label, stateVar, valueExpr, onChangeExpr, directBind, items, width, style, item, loc });
|
|
1220
1894
|
}
|
|
1221
1895
|
function lowerInputInt(attrs, rawAttrs, body, ctx, loc) {
|
|
1222
1896
|
const label = attrs['label'] ?? '""';
|
|
1897
|
+
const width = attrs['width'];
|
|
1223
1898
|
const style = attrs['style'];
|
|
1224
1899
|
const { stateVar, valueExpr, onChangeExpr, directBind } = lowerValueOnChange(rawAttrs, ctx);
|
|
1225
|
-
|
|
1900
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1901
|
+
body.push({ kind: 'input_int', label, stateVar, valueExpr, onChangeExpr, directBind, width, style, item, loc });
|
|
1226
1902
|
}
|
|
1227
1903
|
function lowerInputFloat(attrs, rawAttrs, body, ctx, loc) {
|
|
1228
1904
|
const label = attrs['label'] ?? '""';
|
|
1905
|
+
const width = attrs['width'];
|
|
1229
1906
|
const style = attrs['style'];
|
|
1230
1907
|
const { stateVar, valueExpr, onChangeExpr, directBind } = lowerValueOnChange(rawAttrs, ctx);
|
|
1231
|
-
|
|
1908
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1909
|
+
body.push({ kind: 'input_float', label, stateVar, valueExpr, onChangeExpr, directBind, width, style, item, loc });
|
|
1232
1910
|
}
|
|
1233
1911
|
function lowerColorEdit(attrs, rawAttrs, body, ctx, loc) {
|
|
1234
1912
|
const label = attrs['label'] ?? '""';
|
|
1913
|
+
const width = attrs['width'];
|
|
1235
1914
|
const style = attrs['style'];
|
|
1236
1915
|
let stateVar = '';
|
|
1237
1916
|
let valueExpr;
|
|
@@ -1257,14 +1936,48 @@ function lowerColorEdit(attrs, rawAttrs, body, ctx, loc) {
|
|
|
1257
1936
|
directBind = true;
|
|
1258
1937
|
}
|
|
1259
1938
|
}
|
|
1260
|
-
|
|
1939
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1940
|
+
body.push({ kind: 'color_edit', label, stateVar, valueExpr, onChangeExpr, directBind, width, style, item, loc });
|
|
1941
|
+
}
|
|
1942
|
+
function lowerColorEdit3(attrs, rawAttrs, body, ctx, loc) {
|
|
1943
|
+
const label = attrs['label'] ?? '""';
|
|
1944
|
+
const width = attrs['width'];
|
|
1945
|
+
const style = attrs['style'];
|
|
1946
|
+
let stateVar = '';
|
|
1947
|
+
let valueExpr;
|
|
1948
|
+
let onChangeExpr;
|
|
1949
|
+
let directBind;
|
|
1950
|
+
const valueRaw = rawAttrs.get('value');
|
|
1951
|
+
if (valueRaw && ts.isIdentifier(valueRaw) && ctx.stateVars.has(valueRaw.text)) {
|
|
1952
|
+
stateVar = valueRaw.text;
|
|
1953
|
+
}
|
|
1954
|
+
else if (valueRaw) {
|
|
1955
|
+
valueExpr = exprToCpp(valueRaw, ctx);
|
|
1956
|
+
const onChangeRaw = rawAttrs.get('onChange');
|
|
1957
|
+
if (onChangeRaw) {
|
|
1958
|
+
onChangeExpr = exprToCpp(onChangeRaw, ctx);
|
|
1959
|
+
if (onChangeExpr.startsWith('[')) {
|
|
1960
|
+
onChangeExpr = `(${onChangeExpr})()`;
|
|
1961
|
+
}
|
|
1962
|
+
else if (!onChangeExpr.endsWith(')')) {
|
|
1963
|
+
onChangeExpr = `${onChangeExpr}()`;
|
|
1964
|
+
}
|
|
1965
|
+
}
|
|
1966
|
+
else if (valueRaw && ts.isPropertyAccessExpression(valueRaw)) {
|
|
1967
|
+
directBind = true;
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1971
|
+
body.push({ kind: 'color_edit3', label, stateVar, valueExpr, onChangeExpr, directBind, width, style, item, loc });
|
|
1261
1972
|
}
|
|
1262
1973
|
function lowerListBox(attrs, rawAttrs, body, ctx, loc) {
|
|
1263
1974
|
const label = attrs['label'] ?? '""';
|
|
1264
1975
|
const items = attrs['items'] ?? '';
|
|
1976
|
+
const width = attrs['width'];
|
|
1265
1977
|
const style = attrs['style'];
|
|
1266
1978
|
const { stateVar, valueExpr, onChangeExpr, directBind } = lowerValueOnChange(rawAttrs, ctx);
|
|
1267
|
-
|
|
1979
|
+
const item = lowerItemInteraction(attrs, rawAttrs, ctx);
|
|
1980
|
+
body.push({ kind: 'list_box', label, stateVar, valueExpr, onChangeExpr, directBind, items, width, style, item, loc });
|
|
1268
1981
|
}
|
|
1269
1982
|
function lowerProgressBar(attrs, rawAttrs, body, ctx, loc) {
|
|
1270
1983
|
const value = attrs['value'] ?? '0.0f';
|