imxc 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -0
- package/dist/compile.js +66 -4
- package/dist/components.js +10 -10
- package/dist/emitter.d.ts +1 -1
- package/dist/emitter.js +171 -47
- package/dist/init.js +409 -382
- package/dist/ir.d.ts +14 -0
- package/dist/lowering.d.ts +3 -2
- package/dist/lowering.js +128 -32
- package/package.json +1 -1
package/dist/emitter.js
CHANGED
|
@@ -115,7 +115,7 @@ export function emitComponentHeader(comp, sourceFile) {
|
|
|
115
115
|
lines.push('};');
|
|
116
116
|
lines.push('');
|
|
117
117
|
// Function forward declaration
|
|
118
|
-
lines.push(`void ${comp.name}_render(imx::RenderContext& ctx,
|
|
118
|
+
lines.push(`void ${comp.name}_render(imx::RenderContext& ctx, ${comp.name}Props& props);`);
|
|
119
119
|
lines.push('');
|
|
120
120
|
return lines.join('\n');
|
|
121
121
|
}
|
|
@@ -132,24 +132,50 @@ export function emitComponent(comp, imports, sourceFile) {
|
|
|
132
132
|
dragDropSourceStack.length = 0;
|
|
133
133
|
dragDropTargetStack.length = 0;
|
|
134
134
|
currentCompName = comp.name;
|
|
135
|
-
|
|
135
|
+
// hasProps: true for inline prop struct OR named interface
|
|
136
|
+
const hasProps = comp.params.length > 0 || !!comp.namedPropsType;
|
|
137
|
+
// propsTypeName: for named interface use it directly; for inline use ComponentProps convention
|
|
138
|
+
const propsTypeName = comp.namedPropsType ?? (comp.params.length > 0 ? `${comp.name}Props` : undefined);
|
|
136
139
|
const hasColorType = comp.stateSlots.some(s => s.type === 'color');
|
|
137
140
|
// File banner
|
|
138
141
|
if (sourceFile) {
|
|
139
142
|
lines.push(`// Generated from ${sourceFile} by imxc`);
|
|
140
143
|
}
|
|
141
144
|
if (hasProps) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
lines.push('#include <
|
|
145
|
+
if (comp.namedPropsType) {
|
|
146
|
+
// Named interface: include runtime + renderer, plus user header for the struct definition
|
|
147
|
+
lines.push('#include <imx/runtime.h>');
|
|
148
|
+
lines.push('#include <imx/renderer.h>');
|
|
149
|
+
lines.push(`#include "${comp.namedPropsType}.h"`);
|
|
150
|
+
if (hasColorType) {
|
|
151
|
+
lines.push('#include <array>');
|
|
152
|
+
}
|
|
153
|
+
// Include imported component headers
|
|
154
|
+
if (imports && imports.length > 0) {
|
|
155
|
+
for (const imp of imports) {
|
|
156
|
+
lines.push(`#include "${imp.headerFile}"`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// Embed image includes
|
|
160
|
+
const embedKeysNamed = collectEmbedKeys(comp.body);
|
|
161
|
+
for (const key of embedKeysNamed) {
|
|
162
|
+
lines.push(`#include "${key}.embed.h"`);
|
|
163
|
+
}
|
|
164
|
+
lines.push('');
|
|
146
165
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
166
|
+
else {
|
|
167
|
+
// Component with inline props: include its own header instead of redeclaring struct
|
|
168
|
+
lines.push(`#include "${comp.name}.gen.h"`);
|
|
169
|
+
if (hasColorType) {
|
|
170
|
+
lines.push('#include <array>');
|
|
171
|
+
}
|
|
172
|
+
// Embed image includes
|
|
173
|
+
const embedKeysProps = collectEmbedKeys(comp.body);
|
|
174
|
+
for (const key of embedKeysProps) {
|
|
175
|
+
lines.push(`#include "${key}.embed.h"`);
|
|
176
|
+
}
|
|
177
|
+
lines.push('');
|
|
151
178
|
}
|
|
152
|
-
lines.push('');
|
|
153
179
|
}
|
|
154
180
|
else {
|
|
155
181
|
// No props: standard headers
|
|
@@ -185,7 +211,7 @@ export function emitComponent(comp, imports, sourceFile) {
|
|
|
185
211
|
emitDockSetupFunction(dockLayout, comp.name, lines);
|
|
186
212
|
}
|
|
187
213
|
// Function signature
|
|
188
|
-
const propsArg =
|
|
214
|
+
const propsArg = propsTypeName ? `, ${propsTypeName}& props` : '';
|
|
189
215
|
lines.push(`void ${comp.name}_render(imx::RenderContext& ctx${propsArg}) {`);
|
|
190
216
|
// State declarations
|
|
191
217
|
for (const slot of comp.stateSlots) {
|
|
@@ -205,24 +231,57 @@ export function emitComponent(comp, imports, sourceFile) {
|
|
|
205
231
|
lines.push('');
|
|
206
232
|
return lines.join('\n');
|
|
207
233
|
}
|
|
208
|
-
export function emitRoot(rootName, stateCount, bufferCount, sourceFile) {
|
|
234
|
+
export function emitRoot(rootName, stateCount, bufferCount, sourceFile, propsType, namedPropsType) {
|
|
209
235
|
const lines = [];
|
|
210
236
|
if (sourceFile) {
|
|
211
237
|
lines.push(`// Generated from ${sourceFile} by imxc`);
|
|
212
238
|
}
|
|
213
239
|
lines.push('#include <imx/runtime.h>');
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
240
|
+
if (propsType) {
|
|
241
|
+
if (namedPropsType) {
|
|
242
|
+
// Named interface type (e.g. AppState defined in user code).
|
|
243
|
+
// Include the user header so the template specialization sees the full type.
|
|
244
|
+
lines.push(`#include "${propsType}.h"`);
|
|
245
|
+
lines.push('');
|
|
246
|
+
lines.push(`void ${rootName}_render(imx::RenderContext& ctx, ${propsType}& props);`);
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
lines.push(`#include "${rootName}.gen.h"`);
|
|
250
|
+
lines.push('');
|
|
251
|
+
lines.push(`void ${rootName}_render(imx::RenderContext& ctx, ${propsType}& props);`);
|
|
252
|
+
}
|
|
253
|
+
lines.push('');
|
|
254
|
+
lines.push('namespace imx {');
|
|
255
|
+
if (namedPropsType) {
|
|
256
|
+
// Template specialization — matches the template<typename T> declaration in runtime.h
|
|
257
|
+
lines.push('template <>');
|
|
258
|
+
lines.push(`void render_root<${propsType}>(Runtime& runtime, ${propsType}& state) {`);
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
lines.push(`void render_root(Runtime& runtime, ${propsType}& state) {`);
|
|
262
|
+
}
|
|
263
|
+
lines.push(`${INDENT}auto& ctx = runtime.begin_frame();`);
|
|
264
|
+
lines.push(`${INDENT}ctx.begin_instance("${rootName}", 0, ${stateCount}, ${bufferCount});`);
|
|
265
|
+
lines.push(`${INDENT}${rootName}_render(ctx, state);`);
|
|
266
|
+
lines.push(`${INDENT}ctx.end_instance();`);
|
|
267
|
+
lines.push(`${INDENT}runtime.end_frame();`);
|
|
268
|
+
lines.push('}');
|
|
269
|
+
lines.push('} // namespace imx');
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
lines.push('');
|
|
273
|
+
lines.push(`void ${rootName}_render(imx::RenderContext& ctx);`);
|
|
274
|
+
lines.push('');
|
|
275
|
+
lines.push('namespace imx {');
|
|
276
|
+
lines.push('void render_root(Runtime& runtime) {');
|
|
277
|
+
lines.push(`${INDENT}auto& ctx = runtime.begin_frame();`);
|
|
278
|
+
lines.push(`${INDENT}ctx.begin_instance("${rootName}", 0, ${stateCount}, ${bufferCount});`);
|
|
279
|
+
lines.push(`${INDENT}${rootName}_render(ctx);`);
|
|
280
|
+
lines.push(`${INDENT}ctx.end_instance();`);
|
|
281
|
+
lines.push(`${INDENT}runtime.end_frame();`);
|
|
282
|
+
lines.push('}');
|
|
283
|
+
lines.push('} // namespace imx');
|
|
284
|
+
}
|
|
226
285
|
lines.push('');
|
|
227
286
|
return lines.join('\n');
|
|
228
287
|
}
|
|
@@ -563,7 +622,11 @@ function emitBeginContainer(node, lines, indent) {
|
|
|
563
622
|
}
|
|
564
623
|
case 'DockSpace': {
|
|
565
624
|
const style = buildStyleBlock(node, indent, lines);
|
|
566
|
-
|
|
625
|
+
const hasMenuBar = node.props['hasMenuBar'] === 'true';
|
|
626
|
+
if (hasMenuBar) {
|
|
627
|
+
lines.push(`${indent}imx::renderer::begin_dockspace(${style ?? '{}'}, true);`);
|
|
628
|
+
}
|
|
629
|
+
else if (style) {
|
|
567
630
|
lines.push(`${indent}imx::renderer::begin_dockspace(${style});`);
|
|
568
631
|
}
|
|
569
632
|
else {
|
|
@@ -585,8 +648,21 @@ function emitBeginContainer(node, lines, indent) {
|
|
|
585
648
|
const columnNames = columnsRaw.split(',').map(s => s.trim()).filter(s => s.length > 0);
|
|
586
649
|
const count = columnNames.length;
|
|
587
650
|
const varName = `table_cols_${styleCounter++}`;
|
|
651
|
+
const style = buildStyleVar(node.style, indent, lines);
|
|
652
|
+
const scrollY = node.props['scrollY'] === 'true';
|
|
653
|
+
const noBorders = node.props['noBorders'] === 'true';
|
|
654
|
+
const noRowBg = node.props['noRowBg'] === 'true';
|
|
588
655
|
lines.push(`${indent}const char* ${varName}[] = {${columnNames.join(', ')}};`);
|
|
589
|
-
|
|
656
|
+
const styleArg = style ?? '{}';
|
|
657
|
+
if (scrollY || noBorders || noRowBg) {
|
|
658
|
+
lines.push(`${indent}if (imx::renderer::begin_table("##table", ${count}, ${varName}, ${styleArg}, ${scrollY}, ${noBorders}, ${noRowBg})) {`);
|
|
659
|
+
}
|
|
660
|
+
else if (style) {
|
|
661
|
+
lines.push(`${indent}if (imx::renderer::begin_table("##table", ${count}, ${varName}, ${styleArg})) {`);
|
|
662
|
+
}
|
|
663
|
+
else {
|
|
664
|
+
lines.push(`${indent}if (imx::renderer::begin_table("##table", ${count}, ${varName})) {`);
|
|
665
|
+
}
|
|
590
666
|
break;
|
|
591
667
|
}
|
|
592
668
|
case 'TableRow': {
|
|
@@ -918,11 +994,12 @@ function emitText(node, lines, indent) {
|
|
|
918
994
|
function emitButton(node, lines, indent, depth) {
|
|
919
995
|
emitLocComment(node.loc, 'Button', lines, indent);
|
|
920
996
|
const title = asCharPtr(node.title);
|
|
997
|
+
const disabledArg = node.disabled ? ', {}, true' : '';
|
|
921
998
|
if (node.action.length === 0) {
|
|
922
|
-
lines.push(`${indent}imx::renderer::button(${title});`);
|
|
999
|
+
lines.push(`${indent}imx::renderer::button(${title}${disabledArg});`);
|
|
923
1000
|
}
|
|
924
1001
|
else {
|
|
925
|
-
lines.push(`${indent}if (imx::renderer::button(${title})) {`);
|
|
1002
|
+
lines.push(`${indent}if (imx::renderer::button(${title}${disabledArg})) {`);
|
|
926
1003
|
for (const stmt of node.action) {
|
|
927
1004
|
lines.push(`${indent}${INDENT}${stmt}`);
|
|
928
1005
|
}
|
|
@@ -984,6 +1061,10 @@ function emitCheckbox(node, lines, indent) {
|
|
|
984
1061
|
lines.push(`${indent}${INDENT}}`);
|
|
985
1062
|
lines.push(`${indent}}`);
|
|
986
1063
|
}
|
|
1064
|
+
else if (node.directBind && node.valueExpr) {
|
|
1065
|
+
// Direct pointer binding — no temp variable
|
|
1066
|
+
lines.push(`${indent}imx::renderer::checkbox(${label}, &${node.valueExpr});`);
|
|
1067
|
+
}
|
|
987
1068
|
else if (node.valueExpr !== undefined) {
|
|
988
1069
|
// Props-bound / expression-bound case
|
|
989
1070
|
lines.push(`${indent}{`);
|
|
@@ -1017,7 +1098,7 @@ function emitListMap(node, lines, indent, depth) {
|
|
|
1017
1098
|
}
|
|
1018
1099
|
lines.push(`${indent}for (size_t i = 0; i < ${node.array}.size(); i++) {`);
|
|
1019
1100
|
lines.push(`${indent}${INDENT}auto& ${node.itemVar} = ${node.array}[i];`);
|
|
1020
|
-
lines.push(`${indent}${INDENT}ctx.begin_instance("${node.componentName}", i, ${node.stateCount}, ${node.bufferCount});`);
|
|
1101
|
+
lines.push(`${indent}${INDENT}ctx.begin_instance("${node.componentName}", (int)i, ${node.stateCount}, ${node.bufferCount});`);
|
|
1021
1102
|
emitNodes(node.body, lines, depth + 2);
|
|
1022
1103
|
lines.push(`${indent}${INDENT}ctx.end_instance();`);
|
|
1023
1104
|
lines.push(`${indent}}`);
|
|
@@ -1068,20 +1149,25 @@ function ensureFloatLiteral(val) {
|
|
|
1068
1149
|
}
|
|
1069
1150
|
function emitSliderFloat(node, lines, indent) {
|
|
1070
1151
|
emitLocComment(node.loc, 'SliderFloat', lines, indent);
|
|
1152
|
+
const label = asCharPtr(node.label);
|
|
1071
1153
|
const min = ensureFloatLiteral(node.min);
|
|
1072
1154
|
const max = ensureFloatLiteral(node.max);
|
|
1073
1155
|
if (node.stateVar) {
|
|
1074
1156
|
lines.push(`${indent}{`);
|
|
1075
1157
|
lines.push(`${indent}${INDENT}float val = ${node.stateVar}.get();`);
|
|
1076
|
-
lines.push(`${indent}${INDENT}if (imx::renderer::slider_float(${
|
|
1158
|
+
lines.push(`${indent}${INDENT}if (imx::renderer::slider_float(${label}, &val, ${min}, ${max})) {`);
|
|
1077
1159
|
lines.push(`${indent}${INDENT}${INDENT}${node.stateVar}.set(val);`);
|
|
1078
1160
|
lines.push(`${indent}${INDENT}}`);
|
|
1079
1161
|
lines.push(`${indent}}`);
|
|
1080
1162
|
}
|
|
1163
|
+
else if (node.directBind && node.valueExpr) {
|
|
1164
|
+
// Direct pointer binding
|
|
1165
|
+
lines.push(`${indent}imx::renderer::slider_float(${label}, &${node.valueExpr}, ${min}, ${max});`);
|
|
1166
|
+
}
|
|
1081
1167
|
else if (node.valueExpr !== undefined) {
|
|
1082
1168
|
lines.push(`${indent}{`);
|
|
1083
1169
|
lines.push(`${indent}${INDENT}float val = ${node.valueExpr};`);
|
|
1084
|
-
lines.push(`${indent}${INDENT}if (imx::renderer::slider_float(${
|
|
1170
|
+
lines.push(`${indent}${INDENT}if (imx::renderer::slider_float(${label}, &val, ${min}, ${max})) {`);
|
|
1085
1171
|
if (node.onChangeExpr) {
|
|
1086
1172
|
lines.push(`${indent}${INDENT}${INDENT}${node.onChangeExpr};`);
|
|
1087
1173
|
}
|
|
@@ -1091,18 +1177,22 @@ function emitSliderFloat(node, lines, indent) {
|
|
|
1091
1177
|
}
|
|
1092
1178
|
function emitSliderInt(node, lines, indent) {
|
|
1093
1179
|
emitLocComment(node.loc, 'SliderInt', lines, indent);
|
|
1180
|
+
const label = asCharPtr(node.label);
|
|
1094
1181
|
if (node.stateVar) {
|
|
1095
1182
|
lines.push(`${indent}{`);
|
|
1096
1183
|
lines.push(`${indent}${INDENT}int val = ${node.stateVar}.get();`);
|
|
1097
|
-
lines.push(`${indent}${INDENT}if (imx::renderer::slider_int(${
|
|
1184
|
+
lines.push(`${indent}${INDENT}if (imx::renderer::slider_int(${label}, &val, ${node.min}, ${node.max})) {`);
|
|
1098
1185
|
lines.push(`${indent}${INDENT}${INDENT}${node.stateVar}.set(val);`);
|
|
1099
1186
|
lines.push(`${indent}${INDENT}}`);
|
|
1100
1187
|
lines.push(`${indent}}`);
|
|
1101
1188
|
}
|
|
1189
|
+
else if (node.directBind && node.valueExpr) {
|
|
1190
|
+
lines.push(`${indent}imx::renderer::slider_int(${label}, &${node.valueExpr}, ${node.min}, ${node.max});`);
|
|
1191
|
+
}
|
|
1102
1192
|
else if (node.valueExpr !== undefined) {
|
|
1103
1193
|
lines.push(`${indent}{`);
|
|
1104
1194
|
lines.push(`${indent}${INDENT}int val = ${node.valueExpr};`);
|
|
1105
|
-
lines.push(`${indent}${INDENT}if (imx::renderer::slider_int(${
|
|
1195
|
+
lines.push(`${indent}${INDENT}if (imx::renderer::slider_int(${label}, &val, ${node.min}, ${node.max})) {`);
|
|
1106
1196
|
if (node.onChangeExpr) {
|
|
1107
1197
|
lines.push(`${indent}${INDENT}${INDENT}${node.onChangeExpr};`);
|
|
1108
1198
|
}
|
|
@@ -1112,19 +1202,23 @@ function emitSliderInt(node, lines, indent) {
|
|
|
1112
1202
|
}
|
|
1113
1203
|
function emitDragFloat(node, lines, indent) {
|
|
1114
1204
|
emitLocComment(node.loc, 'DragFloat', lines, indent);
|
|
1205
|
+
const label = asCharPtr(node.label);
|
|
1115
1206
|
const speed = ensureFloatLiteral(node.speed);
|
|
1116
1207
|
if (node.stateVar) {
|
|
1117
1208
|
lines.push(`${indent}{`);
|
|
1118
1209
|
lines.push(`${indent}${INDENT}float val = ${node.stateVar}.get();`);
|
|
1119
|
-
lines.push(`${indent}${INDENT}if (imx::renderer::drag_float(${
|
|
1210
|
+
lines.push(`${indent}${INDENT}if (imx::renderer::drag_float(${label}, &val, ${speed})) {`);
|
|
1120
1211
|
lines.push(`${indent}${INDENT}${INDENT}${node.stateVar}.set(val);`);
|
|
1121
1212
|
lines.push(`${indent}${INDENT}}`);
|
|
1122
1213
|
lines.push(`${indent}}`);
|
|
1123
1214
|
}
|
|
1215
|
+
else if (node.directBind && node.valueExpr) {
|
|
1216
|
+
lines.push(`${indent}imx::renderer::drag_float(${label}, &${node.valueExpr}, ${speed});`);
|
|
1217
|
+
}
|
|
1124
1218
|
else if (node.valueExpr !== undefined) {
|
|
1125
1219
|
lines.push(`${indent}{`);
|
|
1126
1220
|
lines.push(`${indent}${INDENT}float val = ${node.valueExpr};`);
|
|
1127
|
-
lines.push(`${indent}${INDENT}if (imx::renderer::drag_float(${
|
|
1221
|
+
lines.push(`${indent}${INDENT}if (imx::renderer::drag_float(${label}, &val, ${speed})) {`);
|
|
1128
1222
|
if (node.onChangeExpr) {
|
|
1129
1223
|
lines.push(`${indent}${INDENT}${INDENT}${node.onChangeExpr};`);
|
|
1130
1224
|
}
|
|
@@ -1134,19 +1228,23 @@ function emitDragFloat(node, lines, indent) {
|
|
|
1134
1228
|
}
|
|
1135
1229
|
function emitDragInt(node, lines, indent) {
|
|
1136
1230
|
emitLocComment(node.loc, 'DragInt', lines, indent);
|
|
1231
|
+
const label = asCharPtr(node.label);
|
|
1137
1232
|
const speed = ensureFloatLiteral(node.speed);
|
|
1138
1233
|
if (node.stateVar) {
|
|
1139
1234
|
lines.push(`${indent}{`);
|
|
1140
1235
|
lines.push(`${indent}${INDENT}int val = ${node.stateVar}.get();`);
|
|
1141
|
-
lines.push(`${indent}${INDENT}if (imx::renderer::drag_int(${
|
|
1236
|
+
lines.push(`${indent}${INDENT}if (imx::renderer::drag_int(${label}, &val, ${speed})) {`);
|
|
1142
1237
|
lines.push(`${indent}${INDENT}${INDENT}${node.stateVar}.set(val);`);
|
|
1143
1238
|
lines.push(`${indent}${INDENT}}`);
|
|
1144
1239
|
lines.push(`${indent}}`);
|
|
1145
1240
|
}
|
|
1241
|
+
else if (node.directBind && node.valueExpr) {
|
|
1242
|
+
lines.push(`${indent}imx::renderer::drag_int(${label}, &${node.valueExpr}, ${speed});`);
|
|
1243
|
+
}
|
|
1146
1244
|
else if (node.valueExpr !== undefined) {
|
|
1147
1245
|
lines.push(`${indent}{`);
|
|
1148
1246
|
lines.push(`${indent}${INDENT}int val = ${node.valueExpr};`);
|
|
1149
|
-
lines.push(`${indent}${INDENT}if (imx::renderer::drag_int(${
|
|
1247
|
+
lines.push(`${indent}${INDENT}if (imx::renderer::drag_int(${label}, &val, ${speed})) {`);
|
|
1150
1248
|
if (node.onChangeExpr) {
|
|
1151
1249
|
lines.push(`${indent}${INDENT}${INDENT}${node.onChangeExpr};`);
|
|
1152
1250
|
}
|
|
@@ -1156,6 +1254,7 @@ function emitDragInt(node, lines, indent) {
|
|
|
1156
1254
|
}
|
|
1157
1255
|
function emitCombo(node, lines, indent) {
|
|
1158
1256
|
emitLocComment(node.loc, 'Combo', lines, indent);
|
|
1257
|
+
const label = asCharPtr(node.label);
|
|
1159
1258
|
const itemsList = node.items.split(',').map(s => s.trim()).filter(s => s.length > 0);
|
|
1160
1259
|
const count = itemsList.length;
|
|
1161
1260
|
const varName = `combo_items_${comboCounter++}`;
|
|
@@ -1163,16 +1262,22 @@ function emitCombo(node, lines, indent) {
|
|
|
1163
1262
|
lines.push(`${indent}{`);
|
|
1164
1263
|
lines.push(`${indent}${INDENT}const char* ${varName}[] = {${itemsList.join(', ')}};`);
|
|
1165
1264
|
lines.push(`${indent}${INDENT}int val = ${node.stateVar}.get();`);
|
|
1166
|
-
lines.push(`${indent}${INDENT}if (imx::renderer::combo(${
|
|
1265
|
+
lines.push(`${indent}${INDENT}if (imx::renderer::combo(${label}, &val, ${varName}, ${count})) {`);
|
|
1167
1266
|
lines.push(`${indent}${INDENT}${INDENT}${node.stateVar}.set(val);`);
|
|
1168
1267
|
lines.push(`${indent}${INDENT}}`);
|
|
1169
1268
|
lines.push(`${indent}}`);
|
|
1170
1269
|
}
|
|
1270
|
+
else if (node.directBind && node.valueExpr) {
|
|
1271
|
+
lines.push(`${indent}{`);
|
|
1272
|
+
lines.push(`${indent}${INDENT}const char* ${varName}[] = {${itemsList.join(', ')}};`);
|
|
1273
|
+
lines.push(`${indent}${INDENT}imx::renderer::combo(${label}, &${node.valueExpr}, ${varName}, ${count});`);
|
|
1274
|
+
lines.push(`${indent}}`);
|
|
1275
|
+
}
|
|
1171
1276
|
else if (node.valueExpr !== undefined) {
|
|
1172
1277
|
lines.push(`${indent}{`);
|
|
1173
1278
|
lines.push(`${indent}${INDENT}const char* ${varName}[] = {${itemsList.join(', ')}};`);
|
|
1174
1279
|
lines.push(`${indent}${INDENT}int val = ${node.valueExpr};`);
|
|
1175
|
-
lines.push(`${indent}${INDENT}if (imx::renderer::combo(${
|
|
1280
|
+
lines.push(`${indent}${INDENT}if (imx::renderer::combo(${label}, &val, ${varName}, ${count})) {`);
|
|
1176
1281
|
if (node.onChangeExpr) {
|
|
1177
1282
|
lines.push(`${indent}${INDENT}${INDENT}${node.onChangeExpr};`);
|
|
1178
1283
|
}
|
|
@@ -1182,18 +1287,22 @@ function emitCombo(node, lines, indent) {
|
|
|
1182
1287
|
}
|
|
1183
1288
|
function emitInputInt(node, lines, indent) {
|
|
1184
1289
|
emitLocComment(node.loc, 'InputInt', lines, indent);
|
|
1290
|
+
const label = asCharPtr(node.label);
|
|
1185
1291
|
if (node.stateVar) {
|
|
1186
1292
|
lines.push(`${indent}{`);
|
|
1187
1293
|
lines.push(`${indent}${INDENT}int val = ${node.stateVar}.get();`);
|
|
1188
|
-
lines.push(`${indent}${INDENT}if (imx::renderer::input_int(${
|
|
1294
|
+
lines.push(`${indent}${INDENT}if (imx::renderer::input_int(${label}, &val)) {`);
|
|
1189
1295
|
lines.push(`${indent}${INDENT}${INDENT}${node.stateVar}.set(val);`);
|
|
1190
1296
|
lines.push(`${indent}${INDENT}}`);
|
|
1191
1297
|
lines.push(`${indent}}`);
|
|
1192
1298
|
}
|
|
1299
|
+
else if (node.directBind && node.valueExpr) {
|
|
1300
|
+
lines.push(`${indent}imx::renderer::input_int(${label}, &${node.valueExpr});`);
|
|
1301
|
+
}
|
|
1193
1302
|
else if (node.valueExpr !== undefined) {
|
|
1194
1303
|
lines.push(`${indent}{`);
|
|
1195
1304
|
lines.push(`${indent}${INDENT}int val = ${node.valueExpr};`);
|
|
1196
|
-
lines.push(`${indent}${INDENT}if (imx::renderer::input_int(${
|
|
1305
|
+
lines.push(`${indent}${INDENT}if (imx::renderer::input_int(${label}, &val)) {`);
|
|
1197
1306
|
if (node.onChangeExpr) {
|
|
1198
1307
|
lines.push(`${indent}${INDENT}${INDENT}${node.onChangeExpr};`);
|
|
1199
1308
|
}
|
|
@@ -1203,18 +1312,22 @@ function emitInputInt(node, lines, indent) {
|
|
|
1203
1312
|
}
|
|
1204
1313
|
function emitInputFloat(node, lines, indent) {
|
|
1205
1314
|
emitLocComment(node.loc, 'InputFloat', lines, indent);
|
|
1315
|
+
const label = asCharPtr(node.label);
|
|
1206
1316
|
if (node.stateVar) {
|
|
1207
1317
|
lines.push(`${indent}{`);
|
|
1208
1318
|
lines.push(`${indent}${INDENT}float val = ${node.stateVar}.get();`);
|
|
1209
|
-
lines.push(`${indent}${INDENT}if (imx::renderer::input_float(${
|
|
1319
|
+
lines.push(`${indent}${INDENT}if (imx::renderer::input_float(${label}, &val)) {`);
|
|
1210
1320
|
lines.push(`${indent}${INDENT}${INDENT}${node.stateVar}.set(val);`);
|
|
1211
1321
|
lines.push(`${indent}${INDENT}}`);
|
|
1212
1322
|
lines.push(`${indent}}`);
|
|
1213
1323
|
}
|
|
1324
|
+
else if (node.directBind && node.valueExpr) {
|
|
1325
|
+
lines.push(`${indent}imx::renderer::input_float(${label}, &${node.valueExpr});`);
|
|
1326
|
+
}
|
|
1214
1327
|
else if (node.valueExpr !== undefined) {
|
|
1215
1328
|
lines.push(`${indent}{`);
|
|
1216
1329
|
lines.push(`${indent}${INDENT}float val = ${node.valueExpr};`);
|
|
1217
|
-
lines.push(`${indent}${INDENT}if (imx::renderer::input_float(${
|
|
1330
|
+
lines.push(`${indent}${INDENT}if (imx::renderer::input_float(${label}, &val)) {`);
|
|
1218
1331
|
if (node.onChangeExpr) {
|
|
1219
1332
|
lines.push(`${indent}${INDENT}${INDENT}${node.onChangeExpr};`);
|
|
1220
1333
|
}
|
|
@@ -1224,10 +1337,11 @@ function emitInputFloat(node, lines, indent) {
|
|
|
1224
1337
|
}
|
|
1225
1338
|
function emitColorEdit(node, lines, indent) {
|
|
1226
1339
|
emitLocComment(node.loc, 'ColorEdit', lines, indent);
|
|
1340
|
+
const label = asCharPtr(node.label);
|
|
1227
1341
|
if (node.stateVar) {
|
|
1228
1342
|
lines.push(`${indent}{`);
|
|
1229
1343
|
lines.push(`${indent}${INDENT}auto val = ${node.stateVar}.get();`);
|
|
1230
|
-
lines.push(`${indent}${INDENT}if (imx::renderer::color_edit(${
|
|
1344
|
+
lines.push(`${indent}${INDENT}if (imx::renderer::color_edit(${label}, val.data())) {`);
|
|
1231
1345
|
lines.push(`${indent}${INDENT}${INDENT}${node.stateVar}.set(val);`);
|
|
1232
1346
|
lines.push(`${indent}${INDENT}}`);
|
|
1233
1347
|
lines.push(`${indent}}`);
|
|
@@ -1235,6 +1349,7 @@ function emitColorEdit(node, lines, indent) {
|
|
|
1235
1349
|
}
|
|
1236
1350
|
function emitListBox(node, lines, indent) {
|
|
1237
1351
|
emitLocComment(node.loc, 'ListBox', lines, indent);
|
|
1352
|
+
const label = asCharPtr(node.label);
|
|
1238
1353
|
const itemsList = node.items.split(',').map(s => s.trim()).filter(s => s.length > 0);
|
|
1239
1354
|
const count = itemsList.length;
|
|
1240
1355
|
const varName = `listbox_items_${listBoxCounter++}`;
|
|
@@ -1242,16 +1357,22 @@ function emitListBox(node, lines, indent) {
|
|
|
1242
1357
|
lines.push(`${indent}{`);
|
|
1243
1358
|
lines.push(`${indent}${INDENT}const char* ${varName}[] = {${itemsList.join(', ')}};`);
|
|
1244
1359
|
lines.push(`${indent}${INDENT}int val = ${node.stateVar}.get();`);
|
|
1245
|
-
lines.push(`${indent}${INDENT}if (imx::renderer::list_box(${
|
|
1360
|
+
lines.push(`${indent}${INDENT}if (imx::renderer::list_box(${label}, &val, ${varName}, ${count})) {`);
|
|
1246
1361
|
lines.push(`${indent}${INDENT}${INDENT}${node.stateVar}.set(val);`);
|
|
1247
1362
|
lines.push(`${indent}${INDENT}}`);
|
|
1248
1363
|
lines.push(`${indent}}`);
|
|
1249
1364
|
}
|
|
1365
|
+
else if (node.directBind && node.valueExpr) {
|
|
1366
|
+
lines.push(`${indent}{`);
|
|
1367
|
+
lines.push(`${indent}${INDENT}const char* ${varName}[] = {${itemsList.join(', ')}};`);
|
|
1368
|
+
lines.push(`${indent}${INDENT}imx::renderer::list_box(${label}, &${node.valueExpr}, ${varName}, ${count});`);
|
|
1369
|
+
lines.push(`${indent}}`);
|
|
1370
|
+
}
|
|
1250
1371
|
else if (node.valueExpr !== undefined) {
|
|
1251
1372
|
lines.push(`${indent}{`);
|
|
1252
1373
|
lines.push(`${indent}${INDENT}const char* ${varName}[] = {${itemsList.join(', ')}};`);
|
|
1253
1374
|
lines.push(`${indent}${INDENT}int val = ${node.valueExpr};`);
|
|
1254
|
-
lines.push(`${indent}${INDENT}if (imx::renderer::list_box(${
|
|
1375
|
+
lines.push(`${indent}${INDENT}if (imx::renderer::list_box(${label}, &val, ${varName}, ${count})) {`);
|
|
1255
1376
|
if (node.onChangeExpr) {
|
|
1256
1377
|
lines.push(`${indent}${INDENT}${INDENT}${node.onChangeExpr};`);
|
|
1257
1378
|
}
|
|
@@ -1315,6 +1436,9 @@ function emitRadio(node, lines, indent) {
|
|
|
1315
1436
|
lines.push(`${indent}${INDENT}}`);
|
|
1316
1437
|
lines.push(`${indent}}`);
|
|
1317
1438
|
}
|
|
1439
|
+
else if (node.directBind && node.valueExpr) {
|
|
1440
|
+
lines.push(`${indent}imx::renderer::radio(${label}, &${node.valueExpr}, ${node.index});`);
|
|
1441
|
+
}
|
|
1318
1442
|
else if (node.valueExpr !== undefined) {
|
|
1319
1443
|
lines.push(`${indent}{`);
|
|
1320
1444
|
lines.push(`${indent}${INDENT}int val = ${node.valueExpr};`);
|