@nebularstreams/libmui 2.0.13 → 2.0.15

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.
@@ -0,0 +1,1219 @@
1
+ import {defineWidget, Notification, ButtonNew, Icon, Empty, Selector} from "./Basic";
2
+ import CardieWidget from "./CardieWidget";
3
+ import ButtonChoiceWidget from "./ButtonChoiceWidget";
4
+ import InputWidget from "./InputWidget";
5
+ import NoticeWidget from "./NoticeWidget";
6
+ import ComboWidget from "./ComboWidget";
7
+ import ComboPrompt from "./ComboPrompt";
8
+ import SwitchWidget from "./SwitchWidget";
9
+ import ColorJoeWidget from "./ColorJoeWidget";
10
+ import Separator from "./Separator";
11
+ import PlusMinusWidget from "./PlusMinusWidget";
12
+ import RangeWidget from "./RangeWidget";
13
+ import FontSelectorButton from "./FontSelectorButton";
14
+ import SmileysButton from "./SmileysButton.js"
15
+ import InputTemplates from "../meta/InputTemplates.js"
16
+
17
+ import cloneObject from "../util/util.clone.js"
18
+
19
+ import {confirm} from "../util/fuckingconfirm.js"
20
+ import {promptName} from "./OverflowUtils.js"
21
+ import {sanitizeFilename} from "../util/util.tokenizer"
22
+ import {taint} from "../util/tainter"
23
+
24
+ const
25
+
26
+ NEEDS_UPDATE = "needsUpdate",
27
+ REBUILD_CHILDREN = "_rebuild_children",
28
+ NEEDS_DELETE = "delete",
29
+
30
+ ToggleWidget = defineWidget(
31
+ ({attrs}) => m(ButtonNew, {
32
+ text: attrs.text,
33
+ icon: attrs.icon,
34
+ title: attrs.hint,
35
+ iconClass: attrs.iconClass,
36
+ class: (attrs.checked ? attrs.inverted ? "" : "accent " : attrs.inverted ? "accent " : "") + (attrs.class || "") + (attrs.noclass || " tgbutton"),
37
+ onClick: () => attrs.onchange(!attrs.checked)
38
+ })
39
+ ),
40
+ RangeToggleWidget = defineWidget(
41
+ ({attrs}) => m(RangeWidget, {
42
+
43
+ min: 0,
44
+ max: attrs.max || 1,
45
+ step: 0.1,
46
+ ...attrs.mul && {multiplier: attrs.mul},
47
+ class: "tgrange grows innerlabel",
48
+ title: attrs.text,
49
+ value: attrs.value ?? 0,
50
+ hint: attrs.hint,
51
+ onchange: (value) => attrs.onchange(value),
52
+ parser: (v) => v || "OFF"
53
+ })
54
+ ),
55
+
56
+ MultiToggleWidget = defineWidget(
57
+ ({attrs, children}) => m(".flexrow.wrap", {class: attrs.class}, attrs.source
58
+ ? Object.keys(attrs.source)
59
+ .map((key) => m(attrs.widget || ToggleWidget, {
60
+ text: key,
61
+ icon: attrs.icon,
62
+ checked: !!attrs.source[key],
63
+ hint: attrs.hint,
64
+ value: attrs.source[key],
65
+ class: attrs.buttonClass,
66
+ max: attrs.max,
67
+ mul: attrs.mul,
68
+ onchange: (checked) => {
69
+ attrs.source[key] = checked >= 0 ? checked : !!checked;
70
+ attrs.onchange(key);
71
+ }
72
+ }))
73
+ .concat(children)
74
+ : [])
75
+ ),
76
+ PagedMultiToggleWidget = defineWidget(
77
+ ({attrs, state, children}) => [
78
+ ...attrs.keys.length > 1
79
+ ? [
80
+ m(
81
+ ".flexrow.wrap",
82
+ {class: attrs.class},
83
+ attrs.source
84
+ ? attrs.keys
85
+ .map((key) => m(ToggleWidget, {
86
+ text: key,
87
+ checked: state.current === key,
88
+ class: attrs.selectorButtonClass || "transp",
89
+ hint: attrs.hint,
90
+ onchange: () => {
91
+ state.current = key;
92
+ m.redraw();
93
+ }
94
+ }))
95
+ : []
96
+ )
97
+ ]
98
+ : [],
99
+ ...state.current
100
+ ? [
101
+ m(MultiToggleWidget, {
102
+ class: attrs.class,
103
+ source: attrs.source[state.current],
104
+ icon: attrs.icon,
105
+ buttonClass: attrs.buttonClass,
106
+ onchange: attrs.onchange,
107
+ hint: attrs.hint,
108
+ widget: attrs.nocustom !== state.current ? attrs.widget : undefined,
109
+ max: attrs.max,
110
+ mul: attrs.mul
111
+ }, children)
112
+ ]
113
+ : []
114
+ ],
115
+ ({attrs, state}) => {
116
+ state.current = attrs.keys[0];
117
+ }
118
+ ),
119
+ KeyIteratorWidget = defineWidget(
120
+ ({attrs, children}) => {
121
+ const
122
+ keys = attrs.keys || attrs.source && Object.keys(attrs.source),
123
+ expandedView = () => (keys && keys.length) || attrs.add
124
+ ? [
125
+ ...attrs.cardie || attrs.noseparator
126
+ ? []
127
+ : [m(Separator, {
128
+ class: attrs.separatorClass,
129
+ text: attrs.caption
130
+ })],
131
+
132
+ m(".flexrow.wrap", {class: attrs.class},
133
+ (
134
+ attrs.source
135
+ ? keys.map((key) => m(attrs.widget.name, {
136
+ keyName: key,
137
+ class: attrs.widgetClass,
138
+ ...((typeof attrs.widget.attrs === "function" ? attrs.widget.attrs(attrs, key) : attrs.widget.attrs) || {}),
139
+ value: attrs.source[key],
140
+ parameters: attrs.targetParameters,
141
+ onchange: (newValue, event) => {
142
+ if (!newValue && attrs.add && event.shiftKey) {
143
+ delete attrs.source[key];
144
+ } else {
145
+ attrs.source[key] = newValue;
146
+ }
147
+ attrs.onchange(key);
148
+ }
149
+ }))
150
+ : []
151
+ )
152
+ .concat(attrs.add && !attrs.keys ? [
153
+ m(ButtonNew, {
154
+ icon: "plus",
155
+ class: attrs.addButtonClass || "marg-1 transp leftbutton grows unitsizesmall",
156
+ text: `add ${attrs.add}`,
157
+ onClick: () => {
158
+ promptName(
159
+ `Enter new ${attrs.add} name`,
160
+ "",
161
+ `type ${attrs.add} name`,
162
+ (newName) => {
163
+ if (newName) {
164
+ newName = sanitizeFilename(newName)
165
+ .toLowerCase();
166
+ }
167
+ if (newName) {
168
+ if (!attrs.source[newName]) {
169
+ attrs.source[newName] = "";
170
+ m.redraw();
171
+ }
172
+ }
173
+ });
174
+ }
175
+ })
176
+ ] : [])
177
+ .concat(children)
178
+ )
179
+ ]
180
+ : attrs.empty ? m(Empty, attrs.empty) : [];
181
+
182
+ return attrs.cardie
183
+ ? m(CardieWidget, {
184
+ nofold: false,
185
+ size: 1,
186
+ cols: false,
187
+
188
+ title: attrs.caption,
189
+
190
+ cardid: attrs.cardie,
191
+ class: "relative grows" + (attrs.cardieClass ? " " + attrs.cardieClass : ""),
192
+ expandedView
193
+ })
194
+ : expandedView();
195
+ }
196
+ ),
197
+ ToggleStateWidget = defineWidget(
198
+ ({attrs}) => m(ButtonNew, {
199
+ text: attrs.states[Number.parseInt(attrs.checked, 10) || 0] || "---",
200
+ icon: attrs.icon,
201
+ hint: attrs.hint,
202
+ class: "tgbutton " + (attrs.checked ? attrs.inverted ? "" : "accent " : attrs.inverted ? "accent " : "") + (attrs.class || ""),
203
+ onClick: () => {
204
+ let v = Number.parseInt(attrs.checked, 10) || 0;
205
+ v++;
206
+ v %= attrs.states.length;
207
+ attrs.onchange(v);
208
+ }
209
+ })
210
+ ),
211
+
212
+ TemplateWidget = defineWidget(
213
+ ({attrs, state}) => {
214
+
215
+ const
216
+ items = attrs.template.presets
217
+ .concat(state.files || []);
218
+
219
+ return m(".templatepresets.flexrow.wrap", {class: attrs.class}, items.length ? items.map((item) => m(attrs.template.render, {
220
+ item,
221
+ title: "Apply " + attrs.template.name + " to " + attrs.type,
222
+ onClick: () => attrs.onClick(item),
223
+ layer: attrs.layer
224
+ })) : attrs.template.empty ? m(NoticeWidget, attrs.template.empty) : m(".emptybox", "No presets available"));
225
+ },
226
+
227
+ ({attrs, state}) => {
228
+ if (attrs.template.files && attrs.entity) {
229
+ attrs.template.files(attrs.entity)
230
+ .then((files) => {
231
+ state.files = files;
232
+ m.redraw();
233
+ })
234
+ .catch(() => {
235
+ //
236
+ });
237
+ }
238
+ }
239
+ ),
240
+
241
+ ParameterTable = defineWidget(
242
+ ({attrs, state, children}) => {
243
+
244
+ let total = 0;
245
+
246
+ const
247
+
248
+ {
249
+ meta,
250
+ crit = {}, when = {}, sizes = {},
251
+ metaKeys = Object.keys(attrs.meta),
252
+ global,
253
+ parameters, auxParameters, clone, onchange, selfState, itemClass, wrapper,
254
+ empty: vacioperovacio,
255
+ name // new to index a parent
256
+ } = attrs,
257
+
258
+ widgets = metaKeys.map((metaKey) => {
259
+
260
+ const
261
+ metaDef = meta[metaKey],
262
+ whenner = metaDef.when || (when ? when[metaKey] : undefined);
263
+
264
+ if ((whenner && !whenner(parameters, auxParameters))) {
265
+ return [];
266
+ }
267
+
268
+ const
269
+
270
+ isObj = typeof metaDef === "object" && !metaDef.length,
271
+
272
+ isWidget = isObj && metaDef.widget,
273
+ UPDATECODE = isObj ? metaDef.update || crit[metaKey] : false,
274
+
275
+ paramKey = (isObj && metaDef.key) || metaKey,
276
+
277
+ isCardie = isObj && metaDef.type === "group",
278
+ isString = typeof metaDef === "string" || (isObj && metaDef.type === "text"),
279
+ isJson = (isObj && metaDef.type === "json"),
280
+ isBoolean = typeof metaDef === "boolean" || (isObj && metaDef.type === "boolean"),
281
+
282
+ isNumber = isObj && metaDef.type === "number",
283
+ isRange = isObj && !Number.isNaN(metaDef.min),
284
+ isActionButton = isObj && (metaDef.type === "action"),
285
+ isButtonChoice = isObj && (metaDef.choices || metaDef.choose || metaDef.chooseKey),
286
+ isMultiToggle = isObj && metaDef.type === "keytoggle",
287
+ isKeyIterator = isObj && metaDef.type === "iterakey",
288
+ isCombo = isObj && (metaDef.options || metaDef.optionsKey),
289
+ isFullCombo = isObj && metaDef.items,
290
+ isColor = isObj && metaDef.type === "color",
291
+ isPlusMinus = isObj && metaDef.type === "plusminus",
292
+ isSeparator = isObj && metaDef.type === "separator",
293
+ isText = isObj && metaDef.type === "static",
294
+ isEmoji = isObj && metaDef.type === "emoji",
295
+ isFont = isObj && metaDef.type === "font",
296
+ isNotice = isObj && metaDef.type === "notice",
297
+ isAsset = isObj && metaDef.type === "asset",
298
+
299
+ size = isSeparator ? "col-12" : "col-" + (metaDef.size || sizes[metaKey] || 4),
300
+
301
+ targetSource = isObj && ((metaDef.auxTarget && !metaDef.target) || attrs.auxTargetIsDefault)
302
+ ? auxParameters : parameters,
303
+
304
+ targetParameters = isObj && (metaDef.target || metaDef.forTarget)
305
+ ? targetSource[metaDef.target || targetSource.forTarget]
306
+ : targetSource;
307
+
308
+ // TODO
309
+ if (!targetParameters) return [];
310
+
311
+ // situacion: mostrar props f0 (objeto 3d), pero source[f0] no existe
312
+ // targetParameters es NULL en ese caso !
313
+ const
314
+ altMeta = isObj && metaDef.altMeta && meta[metaDef.altMeta],
315
+
316
+ idx = metaDef.idx,
317
+ hasIndex = idx >= 0,
318
+
319
+ rawValue = isObj && metaDef.get
320
+ ? metaDef.get(targetParameters, auxParameters, parameters)
321
+ : hasIndex ? targetParameters[paramKey] ? targetParameters[paramKey][idx] : 0 : targetParameters[paramKey],
322
+
323
+ altMetaKey = altMeta && metaDef.altMeta,
324
+ altKey = altMeta && altMeta.key,
325
+
326
+ internalSet = isObj && metaDef.set
327
+ ? (v) => metaDef.set(
328
+ targetParameters,
329
+ (
330
+ (v && clone && typeof v === "object")
331
+ ? cloneObject(v)
332
+ : v
333
+ ),
334
+ auxParameters,
335
+ parameters,
336
+ idx
337
+ )
338
+ // eslint-disable-next-line no-return-assign
339
+ : (v, nothing, altKey) => {
340
+
341
+ const
342
+ finalKey = altKey || paramKey,
343
+ xdest = hasIndex ? idx : altKey || paramKey;
344
+ let
345
+ xsource = hasIndex ? targetParameters[finalKey] : targetParameters;
346
+
347
+ if (idx >= 0 && !xsource) targetParameters[finalKey] = xsource = [0, 0, 0];
348
+
349
+ return xsource[xdest] = ((v && clone && typeof v === "object")
350
+ ? cloneObject(v)
351
+ : v);
352
+ },
353
+
354
+ set = attrs.onbeforechange
355
+ ? (value, nothing, altKey, altMeta) => {
356
+ if (attrs.onbeforechange(altKey || metaKey, value, altMeta || metaDef)) {
357
+ internalSet(value, undefined, altKey, altMeta);
358
+ return true;
359
+ }
360
+ return false;
361
+ }
362
+ : internalSet;
363
+
364
+ total++;
365
+
366
+ return m(
367
+ ".grows.flexrow." + size,
368
+ {
369
+ class: "mk_" + metaKey
370
+ + (isObj && metaDef.type ? " ptype_" + metaDef.type : "")
371
+ + (isString ? "witharia" : "")
372
+ + ((metaDef.itemClass || itemClass) ? " " + (metaDef.itemClass || itemClass) : ""),
373
+ "aria-label": metaKey
374
+ },
375
+ isCardie
376
+ ? [
377
+ m(CardieWidget, {
378
+ class: "relative grows " + (metaDef.class || "emby w-max") + (metaDef.dynClass ? " " + metaDef.dynClass(parameters, auxParameters) : ""),
379
+ title: metaDef.dynTitle ? metaDef.dynTitle(parameters, auxParameters) : metaDef.title,
380
+ cardid: metaDef.cardid,
381
+ nofold: false,
382
+ size: metaDef.size || 1,
383
+ expandedView: () => [
384
+ m(ParameterTable, {
385
+ meta: metaDef.items,
386
+ crit: {},
387
+ when: {},
388
+ sizes: {},
389
+
390
+ parameters,
391
+ auxParameters,
392
+
393
+ global,
394
+ clone,
395
+ onchange,
396
+ selfState,
397
+ itemClass,
398
+ wrapper,
399
+ empty: vacioperovacio,
400
+ itemsDict: attrs.itemsDict,
401
+ layer: attrs.layer,
402
+ onAction: attrs.onAction,
403
+ optionsDict: attrs.optionsDict,
404
+ play: attrs.play,
405
+ auxTargetIsDefault: attrs.auxTargetIsDefault,
406
+ })
407
+ ],
408
+ titleExpended: metaDef.titleExpanded || metaDef.hint,
409
+ titleCollapsed: metaDef.titleCollapsed || metaDef.hint,
410
+ })
411
+ ]
412
+ : isSeparator
413
+ ? [
414
+ m(Separator, {
415
+ class: metaDef.class || "mini",
416
+ text: typeof metaDef.title === "string"
417
+ ? metaDef.title : metaDef.label || metaKey
418
+ })
419
+ ]
420
+ : isText
421
+ ? [
422
+ m(".innertext", {class: metaDef.class, title: metaDef.hint}, rawValue)
423
+ ]
424
+ : isWidget
425
+ ? [
426
+ m(
427
+ metaDef.widget,
428
+ metaDef.attrs(rawValue, state, (critical, rootParameters) => {
429
+ onchange(critical || UPDATECODE, rootParameters ? parameters : targetParameters, metaKey, undefined, metaDef);
430
+ }, global, attrs, targetParameters),
431
+ metaDef.children
432
+ ? metaDef.children(rawValue, state, (critical, rootParameters) => {
433
+ onchange(critical || UPDATECODE, rootParameters ? parameters : targetParameters, metaKey, undefined, metaDef);
434
+ }, global, attrs, targetParameters)
435
+ : [])
436
+ ]
437
+ : isPlusMinus
438
+ ? [
439
+ m(PlusMinusWidget, {
440
+ max: metaDef.max,
441
+ min: metaDef.min,
442
+ title: metaDef.title,
443
+ label: metaDef.label,
444
+ value: rawValue,
445
+ onchange: (value) => {
446
+ set(value);
447
+ onchange(UPDATECODE, targetParameters, metaKey, undefined, metaDef);
448
+ }
449
+ })
450
+ ]
451
+ : isString || (isJson && !attrs.CodeMirror)
452
+ ? [
453
+ m(InputWidget, {
454
+ containerClass: "grows",
455
+ class: metaDef.inputClass,
456
+ value: rawValue,
457
+ label: metaDef.label,
458
+ hint: isObj ? metaDef.hint : metaDef,
459
+ title: metaDef.title,
460
+ maxlength: isObj ? metaDef.maxlength || 256 : 256,
461
+ ...metaDef.final && {
462
+ oninput: () => {
463
+ }
464
+ },
465
+ multi: metaDef.multi,
466
+ alwaysmulti: metaDef.alwaysmulti,
467
+ onchange: (value) => {
468
+ set(value);
469
+ onchange(UPDATECODE, targetParameters, metaKey, undefined, metaDef);
470
+ }
471
+ })]
472
+ : isJson
473
+ ? [
474
+ m(attrs.CodeMirror, {
475
+ doc: rawValue,
476
+ schema: metaDef.schema,
477
+ hint: metaDef.dynamicHint ? metaDef.dynamicHint(targetParameters) : metaDef.hint,
478
+ empty: metaDef.empty,
479
+ onSave: (content) => {
480
+ if (content !== null) {
481
+ set(content || "");
482
+ onchange(UPDATECODE, targetParameters, metaKey, undefined, metaDef);
483
+ if (!content) {
484
+ Notification.add(metaDef.hint + " cleared");
485
+ }
486
+ }
487
+ }
488
+ })
489
+ ]
490
+ : isNumber
491
+ ? [
492
+ m(InputWidget, {
493
+ containerClass: "grows",
494
+ class: metaDef.inputClass,
495
+ value: (metaDef.step > 0 && metaDef.step < 1 || metaDef.float)
496
+ ? rawValue !== undefined
497
+ ? (parseFloat(rawValue) || 0).toFixed(3)
498
+ : ""
499
+ : rawValue,
500
+ type: "text",
501
+ label: metaDef.label,
502
+ hint: isObj ? metaDef.hint : metaDef,
503
+ title: metaDef.title,
504
+ ...metaDef.final && {
505
+ oninput: () => {
506
+ }
507
+ },
508
+ onchange: (value) => {
509
+
510
+ let
511
+ isFloat = metaDef.step > 0 && metaDef.step < 1 || metaDef.float,
512
+ {min, max} = metaDef;
513
+
514
+ if (value === undefined) {
515
+ set(undefined);
516
+ } else {
517
+
518
+ let val = isFloat ? parseFloat(value) : parseInt(value, 10);
519
+
520
+ if (!isNaN(val)) {
521
+
522
+ if (val < min) val = min;
523
+ if (val > max) val = max;
524
+
525
+ } else {
526
+ val = undefined;
527
+ }
528
+
529
+ set(val);
530
+
531
+ }
532
+
533
+ onchange(UPDATECODE, targetParameters, metaKey, undefined, metaDef);
534
+ }
535
+ })]
536
+ : isNotice
537
+ ? [m(NoticeWidget, metaDef)]
538
+ : isAsset
539
+ ? attrs.AssetButton ? [
540
+ m(attrs.AssetButton, {
541
+ global,
542
+ value: rawValue, // metaDef.values ? metaDef.values[parameters[metaKey].id] : parameters[metaKey],
543
+ confirm: attrs.confirm,
544
+ class: "grows font-125 " + (metaDef.containerClass || "scaff scaff-b1"),
545
+ buttonClass: (metaDef.buttonClass || "unitheight scaff-left"),
546
+ readonly: metaDef.readOnly,
547
+ closeClass: metaDef.closeClass,
548
+ textClass: metaDef.textClass || "",
549
+ iconClass: metaDef.iconClass || "",
550
+ field: metaDef.field,
551
+
552
+ types: metaDef.types,
553
+ subtype: metaDef.subtype,
554
+ file: metaDef.file,
555
+ pack: metaDef.pack,
556
+
557
+ shiftUpdate: metaDef.shiftUpdate,
558
+ shiftIcon: metaDef.shiftIcon,
559
+ removeIcon: metaDef.removeIcon,
560
+ emptyValue: metaDef.emptyText || "off",
561
+ emptyText: metaDef.emptyText || "off",
562
+ emptyIcon: metaDef.emptyIcon || metaDef.icon,
563
+ icon: metaDef.icon,
564
+ title: metaDef.title,
565
+ titleCollapsed: metaDef.titleCollapsed,
566
+ titleClass: "pad-2 pad-v no-pad-bottom",
567
+ parameters,
568
+ auxParameters,
569
+ state: selfState,
570
+ onchange: (value, e) => {
571
+ if (e && e.shiftKey && attrs.onShiftPress) {
572
+ attrs.onShiftPress(metaKey, targetParameters, value);
573
+ } else {
574
+ if (value === undefined) value = metaDef.nullValue || undefined;
575
+ set(value);
576
+ onchange(UPDATECODE, targetParameters, metaKey, undefined, metaDef);
577
+ }
578
+ }
579
+ })]
580
+ : [
581
+ m(ButtonNew, {
582
+ icon: metaDef.icon,
583
+ title: metaDef.title,
584
+ class: "unitheight",
585
+ text: "No Asset Module"
586
+ })
587
+ ]
588
+ : isEmoji
589
+ ? [
590
+ m(SmileysButton, {
591
+ class: "grows " + (metaDef.class || "scaff scaff-b1 unitheight font-200"),
592
+ icon: {glyph: rawValue},
593
+ icons: false,
594
+ state: selfState,
595
+ onchange: (glyph) => {
596
+ set(glyph);
597
+ onchange(UPDATECODE, targetParameters, metaKey, undefined, metaDef);
598
+ }
599
+ })]
600
+ : isFont
601
+ ? [
602
+ m(FontSelectorButton, {
603
+ class: "grows " + (metaDef.class || "scaff-right unitheight"),
604
+ fontFamily: rawValue,
605
+ state: selfState,
606
+ nodelete: metaDef.nodelete,
607
+ onchange: (glyph) => {
608
+ if (metaDef.nodelete && !glyph) return;
609
+ set(glyph);
610
+ // could be erased
611
+ const newTargetParameters = (metaDef.target || metaDef.forTarget) ? parameters[metaDef.target || metaDef.forTarget] : parameters;
612
+ onchange(!glyph ? NEEDS_DELETE : UPDATECODE, newTargetParameters, metaKey, !glyph, metaDef);
613
+ }
614
+ })]
615
+ : isColor
616
+ ? [
617
+ m(ColorJoeWidget, {
618
+ class: "grows " + (metaDef.class || "unitheight") + (altKey ? " withalt" : ""),
619
+ color: rawValue,
620
+ caption: metaDef.caption,
621
+ noalpha: metaDef.noalpha,
622
+ remove: metaDef.remove,
623
+ onchange: (color, colorObject) => {
624
+ let finalColor = color;
625
+ if (finalColor) {
626
+ if (metaDef.hsl) {
627
+ const hsl = colorObject.hsl();
628
+ finalColor = [hsl.hue(), hsl.saturation(), hsl.lightness()];
629
+ } else if (metaDef.rgba) {
630
+ finalColor = [colorObject.r(), colorObject.g(), colorObject.b(), colorObject.a()];
631
+
632
+ }
633
+ }
634
+ set(finalColor);
635
+ onchange(UPDATECODE, targetParameters, metaKey, undefined, metaDef);
636
+ },
637
+ ...altKey && {
638
+ style: {
639
+ "--data-altval": ((((targetParameters[altKey] ?? altMeta.min) - altMeta.min) / (altMeta.max - altMeta.min)) * 100) + "%"
640
+ }
641
+ }
642
+
643
+ },
644
+ altMeta
645
+ ? [
646
+ m(RangeWidget, {
647
+ auto0: altMeta.auto0,
648
+ min: altMeta.min,
649
+ max: altMeta.max,
650
+ step: altMeta.step || 0.1,
651
+ ...altMeta.mul && {multiplier: altMeta.mul},
652
+ class: "col-11 grows innerlabel order-first",
653
+ title: altMeta.title,
654
+ value: targetParameters[altKey] ?? altMeta.min,
655
+ onchange: (value) => {
656
+ set(value, undefined, altKey, altMeta);
657
+ onchange(crit[altMetaKey], targetParameters, altMetaKey, undefined, metaDef);
658
+ }
659
+ })
660
+ ]
661
+ : undefined)]
662
+ : isBoolean
663
+ ? [
664
+ m(
665
+ isObj && metaDef.toggle
666
+ ? metaDef.states ? ToggleStateWidget : ToggleWidget
667
+ : SwitchWidget,
668
+ {
669
+ class: "grows " + (metaDef.class || "unitheight"),
670
+ text: isObj ? metaDef.title || metaDef.label : metaKey,
671
+ icon: isObj ? metaDef.icon : undefined,
672
+ noclass: metaDef.noclass,
673
+ subline: metaDef.subline,
674
+ checked: rawValue,
675
+ title: metaDef.hint,
676
+ hint: metaDef.hint,
677
+ inverted: isObj && metaDef.inverted,
678
+ states: metaDef.states,
679
+ iconClass: metaDef.iconClass,
680
+ onchange: (st) => {
681
+ set(metaDef.states ? st : !!st);
682
+ onchange(UPDATECODE, targetParameters, metaKey, undefined, metaDef);
683
+ }
684
+ }
685
+ )
686
+ ]
687
+ : isActionButton
688
+ ? [
689
+ m(
690
+ ButtonNew,
691
+ {
692
+ class: "grows " + (metaDef.class || "accentbutton unitheight"),
693
+ text: metaDef.label === ""
694
+ ? null
695
+ : metaDef.label || metaDef.text || metaKey,
696
+ icon: metaDef.icon,
697
+ title: metaDef.title || metaDef.hint,
698
+ onClick: (e) => {
699
+
700
+ const runAction = () => {
701
+ if (metaDef.onClick) {
702
+ metaDef.onClick(metaKey, e, targetParameters, auxParameters, global, attrs);
703
+ } else {
704
+ if (attrs.onAction) attrs.onAction(metaKey, e, targetSource);
705
+ }
706
+ };
707
+
708
+ if (metaDef.confirm) {
709
+ confirm(metaDef.confirm, runAction);
710
+ } else {
711
+ runAction();
712
+ }
713
+ }
714
+ }
715
+ )
716
+ ]
717
+ : isMultiToggle
718
+ ? [
719
+ m(metaDef.keys ? PagedMultiToggleWidget : MultiToggleWidget, {
720
+ class: "col-12 " + (metaDef.toggle ? "istoggler" : ""),
721
+ icon: metaDef.icon,
722
+ buttonClass: metaDef.buttonClass,
723
+ selectorClass: metaDef.selectorClass || "grows",
724
+ selectorButtonClass: metaDef.selectorButtonClass,
725
+ keys: metaDef.keys,
726
+ hint: metaDef.hint,
727
+ nocustom: metaDef.nocustom,
728
+ source: rawValue,
729
+ onchange: () => onchange(UPDATECODE, targetParameters, metaKey, undefined, metaDef),
730
+ ...(metaDef.customWidget || {})
731
+ })
732
+ ]
733
+ : isKeyIterator
734
+ ? [
735
+ m(KeyIteratorWidget, {
736
+ class: "col-12" + (metaDef.class ? " " + metaDef.class : ""),
737
+ buttonClass: metaDef.widgetClass,
738
+ cardie: metaDef.cardie,
739
+ cardieClass: metaDef.cardieClass,
740
+ addButtonClass: metaDef.addButtonClass,
741
+ caption: metaDef.caption,
742
+ separatorClass: metaDef.separatorClass,
743
+ noseparator: metaDef.noseparator,
744
+ source: rawValue,
745
+ onchange: () => onchange(UPDATECODE, targetParameters, metaKey, undefined, metaDef),
746
+ widget: metaDef.keyWidget,
747
+ keys: metaDef.keys,
748
+ add: metaDef.add,
749
+ targetParameters,
750
+ auxParameters,
751
+ empty: metaDef.empty
752
+ })
753
+ ]
754
+ : isButtonChoice
755
+ ? [
756
+ m(ButtonChoiceWidget, {
757
+ class: "col-12 " + (metaDef.toggle ? "istoggler" : ""),
758
+ subclass: metaDef.class,
759
+ buttonClass: metaDef.buttonClass,
760
+ choices: metaDef.choices,
761
+ choose: metaDef.choose,
762
+ chooseKey: metaDef.chooseKey,
763
+ chooseDict: attrs.chooseDict,
764
+ label: metaDef.label,
765
+ field: metaDef.field,
766
+ icon: metaDef.icon,
767
+ value: rawValue,
768
+ onchange: (choice) => {
769
+
770
+ let
771
+ {value} = choice;
772
+
773
+ if (value || value >= 0) {
774
+ if (metaDef.toggle && value === rawValue) value = !value;
775
+ set(value, choice);
776
+ onchange(UPDATECODE, targetParameters, metaKey, undefined, metaDef);
777
+ } else {
778
+ set(undefined, choice);
779
+ onchange(UPDATECODE, targetParameters, metaKey, undefined, metaDef);
780
+ }
781
+ taint();
782
+ }
783
+ })
784
+ ]
785
+ : !isCombo
786
+ ? isFullCombo
787
+ ? [
788
+ m(ComboWidget, {
789
+ class: "grows scaff scaff-b1 " + (metaDef.class || "unitheight"),
790
+ value: rawValue,
791
+ emptyText: metaDef.emptyText || "off",
792
+ icon: metaDef.icon,
793
+ title: metaDef.title,
794
+ items: metaDef.items,
795
+ textClass: metaDef.textClass || "",
796
+ onchange: (value) => {
797
+ if (typeof value === "string") value = value.trim();
798
+ if (value) {
799
+ set(value);
800
+ onchange(UPDATECODE, targetParameters, metaKey, undefined, metaDef);
801
+ } else {
802
+ set(undefined);
803
+ onchange(UPDATECODE, targetParameters, metaKey, undefined, metaDef);
804
+ }
805
+ taint();
806
+ }
807
+ })
808
+ ]
809
+ : isRange
810
+ ? [
811
+ m(RangeWidget, {
812
+ auto0: metaDef.auto0,
813
+ relative: !metaDef.auto0 && !metaDef.absolute,
814
+ factor: metaDef.factor,
815
+ min: metaDef.min,
816
+ max: metaDef.max,
817
+ step: metaDef.step || 0.1,
818
+ ...metaDef.mul
819
+ ? {
820
+ multiplier: metaDef.mul
821
+ }
822
+ : {},
823
+ class: "col-11 grows innerlabel",
824
+ title: metaDef.label || metaDef.title || (metaKey.indexOf("-") === -1 ? metaKey : metaKey.substring(metaKey.lastIndexOf("-") + 1)),
825
+ hint: metaDef.hint,
826
+ value: parseFloat(rawValue) ?? metaDef ?? metaDef.min,
827
+ parser: metaDef.parser,
828
+ onchange: (value) => {
829
+ set(value);
830
+ onchange(UPDATECODE, targetParameters, metaKey, undefined, metaDef);
831
+ }
832
+ })
833
+ ]
834
+ : [
835
+ m(RangeWidget, {
836
+ min: metaDef[0],
837
+ max: metaDef[1],
838
+ step: metaDef[2] || 0.1,
839
+ ...metaDef[3]
840
+ ? {
841
+ multiplier: metaDef[3]
842
+ } : {},
843
+ class: "col-11 grows innerlabel",
844
+ title: metaDef[4] || (metaKey.indexOf("-") === -1 ? metaKey : metaKey.substring(metaKey.lastIndexOf("-") + 1)),
845
+ value: parseFloat(rawValue) || metaDef[0],
846
+ onchange: (value) => {
847
+ set(value);
848
+ onchange(UPDATECODE, targetParameters, metaKey, undefined, metaDef);
849
+ }
850
+ })
851
+ ]
852
+ : [
853
+ m(ComboPrompt, {
854
+ class: metaDef.containerClass || "scaff scaff-b1",
855
+ buttonClass: metaDef.class || "unitheightsmall scaff-left",
856
+ closeClass: metaDef.buttonClass || undefined,
857
+ textClass: metaDef.textClass || "",
858
+ locked: metaDef.locked,
859
+ value: rawValue, // metaDef.values ? metaDef.values[parameters[metaKey].id] : parameters[metaKey],
860
+ field: metaDef.field,
861
+ fieldTitle: metaDef.fieldTitle,
862
+ emptyText: metaDef.emptyText || "off",
863
+ emptyIcon: metaDef.emptyIcon || metaDef.icon,
864
+ confirm: metaDef.confirm,
865
+ icon: metaDef.icon || attrs.icon,
866
+ hint: metaDef.title,
867
+ label: metaDef.label,
868
+ itemsKey: typeof metaDef.optionsKey === "function" ? () => {
869
+ return metaDef.optionsKey(targetParameters);
870
+ } : metaDef.optionsKey,
871
+ items: metaDef.options || attrs.optionsDict,
872
+ removeIcon: metaDef.removeIcon,
873
+ nodelete: metaDef.nodelete,
874
+ onchange: (value, event) => {
875
+ if (event.shiftKey) {
876
+ if (metaDef.shiftPress) {
877
+ metaDef.shiftPress(targetParameters, auxParameters);
878
+ }
879
+ return;
880
+ }
881
+ if (typeof value === "string") value = value.trim();
882
+ if (value) {
883
+ set(metaDef.values ? metaDef.values[value] : value, metaDef.clone);
884
+ onchange(UPDATECODE, targetParameters, metaKey, false, metaDef);
885
+ } else {
886
+ set(metaDef.nullValue || undefined);
887
+ onchange(UPDATECODE, targetParameters, metaKey, true, metaDef);
888
+ }
889
+ taint();
890
+ }
891
+ })]);
892
+ });
893
+
894
+ return total || children.length
895
+
896
+ ? wrapper
897
+ ? wrapper(widgets.concat(children))
898
+ : widgets.concat(children)
899
+
900
+ : vacioperovacio && !children.length
901
+ ? m(Empty, vacioperovacio)
902
+ : [];
903
+ }
904
+ ),
905
+
906
+ ParameterCardie = defineWidget(
907
+ ({attrs, children}) => {
908
+
909
+ const
910
+ {
911
+ busy, mainState, parameters, auxParameters, cardid, size, index,
912
+ titleWidget, parametersTitle, parametersBody, rootUpdate, global, layer,
913
+ tableChildren, cols, onLayerReset, onAction, nofold
914
+ } = attrs;
915
+
916
+ return m(CardieWidget, {
917
+
918
+ busy,
919
+ nofold,
920
+ size,
921
+ cols,
922
+
923
+ title: parametersBody.titleCollapsed || parametersBody.title,
924
+ titleCollapsed: parametersBody.titleCollapsed || parametersBody.title,
925
+ titleExpanded: parametersBody.titleExpanded || parametersBody.title,
926
+ expandedClass: attrs.expandedClass,
927
+
928
+ onShiftOpen: () => {
929
+
930
+ },
931
+
932
+ titleWidget: titleWidget || ParameterTable,
933
+ titleAttrs: {
934
+ ...parametersTitle,
935
+ onShiftPress: attrs.onShiftPress,
936
+ confirm: attrs.confirmTitle,
937
+ itemClass: "",
938
+ parameters,
939
+ auxParameters,
940
+ clone: true,
941
+ global, layer, selfState: mainState,
942
+ onAction,
943
+ onchange: (realtime, targetParameters, metaKey, wasDeleted, metaDef) => {
944
+
945
+ taint();
946
+
947
+ if (metaDef?.onchange) {
948
+ metaDef.onchange(realtime, targetParameters, parameters);
949
+ } else if (realtime) {
950
+ if (rootUpdate === 2) {
951
+ parameters[NEEDS_UPDATE] = realtime;
952
+ } else if (rootUpdate === 1) {
953
+ if (targetParameters) targetParameters[NEEDS_UPDATE] = realtime;
954
+ } else if (typeof rootUpdate === "string") {
955
+ if (parameters[rootUpdate]) {
956
+ parameters[rootUpdate][NEEDS_UPDATE] = realtime;
957
+ parameters[NEEDS_UPDATE] = true;
958
+ } else {
959
+ parameters[NEEDS_UPDATE] = REBUILD_CHILDREN;
960
+ }
961
+ } else if (rootUpdate !== -1 && targetParameters) targetParameters[NEEDS_UPDATE] = realtime;
962
+
963
+ } else {
964
+ onLayerReset && onLayerReset();
965
+ }
966
+
967
+ if (attrs.onTitleChange) {
968
+ attrs.onTitleChange(realtime, targetParameters, metaKey, wasDeleted);
969
+ }
970
+
971
+ m.redraw();
972
+ }
973
+ },
974
+
975
+ cardid,
976
+ class: "withbottommargin relative" + (attrs.class ? " " + attrs.class : ""),
977
+ expandedView: () => [
978
+
979
+ ...parametersBody.meta
980
+ ? [
981
+ m(ParameterTable, {
982
+ ...parametersBody,
983
+ confirm: attrs.confirmBody,
984
+ itemClass: "pad-1",
985
+ parameters,
986
+ auxParameters,
987
+ clone: true,
988
+ global, selfState: mainState, layer,
989
+ index,
990
+ play: attrs.play,
991
+ itemsDict: attrs.itemsDict,
992
+ optionsDict: attrs.optionsDict,
993
+ onAction,
994
+ onchange: (realtime, targetParameters, metaKey, wasDeleted, metaDef, event) => {
995
+ taint();
996
+ if (metaDef?.onchange) {
997
+ metaDef.onchange(realtime, targetParameters, parameters);
998
+ } else if (realtime) {
999
+
1000
+ if (rootUpdate === 2) {
1001
+ parameters[NEEDS_UPDATE] = realtime;
1002
+ } else if (rootUpdate === 1) {
1003
+ if (targetParameters) targetParameters[NEEDS_UPDATE] = realtime;
1004
+ } else if (typeof rootUpdate === "string") {
1005
+ if (parameters[rootUpdate]) {
1006
+ parameters[rootUpdate][NEEDS_UPDATE] = realtime;
1007
+ parameters[NEEDS_UPDATE] = true;
1008
+ } else {
1009
+ parameters[NEEDS_UPDATE] = REBUILD_CHILDREN;
1010
+ }
1011
+ } else {
1012
+ if (targetParameters) targetParameters[NEEDS_UPDATE] = realtime;
1013
+ }
1014
+
1015
+ } else {
1016
+ onLayerReset && onLayerReset();
1017
+ }
1018
+
1019
+ if (attrs.onChange) {
1020
+ attrs.onChange(realtime, metaKey, targetParameters, auxParameters, wasDeleted, metaDef, event, attrs);
1021
+ }
1022
+ m.redraw();
1023
+ }
1024
+ }, tableChildren)
1025
+ ]
1026
+ : parametersBody.emptyMeta
1027
+ ? [m(Empty, parametersBody.emptyMeta)]
1028
+ : [],
1029
+
1030
+ ...(children || [])
1031
+ ],
1032
+ collapsedView: attrs.collapsedView
1033
+ });
1034
+ }
1035
+ ),
1036
+
1037
+ TemplatedInputWidget = defineWidget(({attrs, state, children}) => {
1038
+
1039
+ const {
1040
+ layer, property, colorProperty, selfState
1041
+ } = attrs,
1042
+ template = InputTemplates[property],
1043
+ currentProperty = layer[property],
1044
+
1045
+ has = currentProperty !== undefined && currentProperty !== null,
1046
+ hasObject = has && typeof currentProperty === "object" && currentProperty !== null,
1047
+ parameters = hasObject && currentProperty,
1048
+ dynamicExp = parameters && parameters.exp,
1049
+
1050
+ [, meta] = dynamicExp || [],
1051
+ metaKeys = parameters && meta && Object.keys(meta),
1052
+ title = hasObject && currentProperty ? currentProperty.title : currentProperty,
1053
+ hasMeta = metaKeys && metaKeys.length,
1054
+ hasSize = (attrs.size && hasObject);
1055
+
1056
+ // noinspection JSObjectNullOrUndefined
1057
+ return m(
1058
+ "li.coord.witharia.relative.templatedinput",
1059
+ {
1060
+ "aria-label": attrs["aria-label"],
1061
+ class: (state.chooser && template ? attrs.chooserClass : attrs.containerClass) || "col-12"
1062
+ },
1063
+ [
1064
+ ...attrs.docs
1065
+ ? [
1066
+ m(
1067
+ "a.extlink.absolute.to-right.to-top.font-75.pad-2.pointer",
1068
+ {
1069
+ target: "tool",
1070
+ onclick: () => {
1071
+ NIPX.sys.open(attrs.docs.url);
1072
+ }
1073
+ },
1074
+ attrs.docs.caption || "docs"
1075
+ )
1076
+ ]
1077
+ : [],
1078
+
1079
+ attrs.chooser ? [m(".flexrow.grows.fontgroup", [m(ButtonNew, {
1080
+ class: "grows unitheightsmall rectbutton ohidden",
1081
+ text: title || "--- NONE ---",
1082
+ icon: attrs.icon,
1083
+ onClick: (e) => {
1084
+ if (selfState && !state.chooser && e.shiftKey && template.images) {
1085
+ selfState.setTransState("image", undefined, {
1086
+ giphyQuery: "frame",
1087
+ onOverride: (global, item) => {
1088
+ const translated = item && template.images(item);
1089
+ if (translated) {
1090
+ layer[property] = cloneObject(translated);
1091
+ taint();
1092
+ m.redraw();
1093
+ }
1094
+ }
1095
+ });
1096
+ return;
1097
+ }
1098
+ state.chooser = !state.chooser;
1099
+ m.redraw();
1100
+ }
1101
+ }), ...layer[property] ? [m(ButtonNew, {
1102
+ class: "clearfont unitheightsmall bg-accent",
1103
+ text: "X",
1104
+ onClick: () => {
1105
+ delete layer[property];
1106
+ taint();
1107
+ m.redraw();
1108
+ }
1109
+ })] : template.images && selfState && !title ? [m(ButtonNew, {
1110
+ class: "unitsizesmall rectbutton ohidden",
1111
+ icon: "images",
1112
+ onClick: () => selfState.setTransState("image", undefined, {
1113
+ giphyQuery: "frame",
1114
+ onOverride: (global, item) => {
1115
+ const translated = item && template.images(item);
1116
+ if (translated) {
1117
+ layer[property] = cloneObject(translated);
1118
+ taint();
1119
+ m.redraw();
1120
+ }
1121
+ }
1122
+ })
1123
+ })] : []])] : [m(InputWidget, {
1124
+ class: "withicon-2" + (has ? " has" : "") + (attrs.class ? " " + attrs.class : ""),
1125
+ value: layer[property] || "",
1126
+ hint: attrs.hint,
1127
+ title: attrs.title,
1128
+ maxlength: attrs.maxlength || 2048,
1129
+ multi: attrs.multi,
1130
+ actions: [{
1131
+ icon: "plus",
1132
+ onClick: () => {
1133
+ state.chooser = !state.chooser;
1134
+ m.redraw();
1135
+ }
1136
+ }],
1137
+ onchange: (value) => {
1138
+
1139
+ value = value.split("\n")
1140
+ .join(" ")
1141
+ .trim();
1142
+
1143
+ layer[property] = value;
1144
+ taint();
1145
+ m.redraw();
1146
+ }
1147
+ })],
1148
+
1149
+ ...(hasMeta || hasSize) ? [m(".flexrow.wrap.paramgroup", [
1150
+
1151
+ ...hasMeta ? [m(ParameterTable, {
1152
+
1153
+ meta,
1154
+ metaKeys,
1155
+ parameters,
1156
+ onchange: () => {
1157
+ delete currentProperty.calc;
1158
+ taint();
1159
+ m.redraw();
1160
+ }
1161
+ })] : [],
1162
+
1163
+ ...hasSize ? [m(".flexbreak"), m(RangeWidget, {
1164
+ class: "col-6 grows innerlabel",
1165
+ title: "size x",
1166
+ min: 0,
1167
+ max: 100,
1168
+ step: 0.1,
1169
+ relative: true,
1170
+ value: parseFloat(currentProperty.w) || 0,
1171
+ onchange: (value) => {
1172
+ currentProperty.w = value;
1173
+ taint();
1174
+ m.redraw();
1175
+ }
1176
+ }), m(RangeWidget, {
1177
+ class: "col-6 grows innerlabel",
1178
+ title: "size y",
1179
+ min: 0,
1180
+ max: 100,
1181
+ step: 0.1,
1182
+ relative: true,
1183
+ value: parseFloat(currentProperty.h) || 0,
1184
+ onchange: (value) => {
1185
+ currentProperty.h = value;
1186
+ taint();
1187
+ m.redraw();
1188
+ }
1189
+ })] : []])] : [],
1190
+
1191
+ ...(state.chooser && template) ? [m(TemplateWidget, {
1192
+ entity: attrs.entity,
1193
+ template,
1194
+ type: layer.type,
1195
+ layer,
1196
+ onClick: (item) => {
1197
+
1198
+ state.chooser = false;
1199
+
1200
+ layer[property] = typeof item.value === "object"
1201
+ ? cloneObject(item.value)
1202
+ : item.value;
1203
+
1204
+ if (item.color && colorProperty) {
1205
+ layer[colorProperty] = item.color;
1206
+ }
1207
+
1208
+ taint();
1209
+
1210
+ m.redraw();
1211
+
1212
+ }
1213
+ })] : [], ...has ? children : []]
1214
+ );
1215
+ });
1216
+
1217
+ export {
1218
+ TemplatedInputWidget, ParameterTable, ParameterCardie, MultiToggleWidget, RangeToggleWidget
1219
+ };